Whamcloud - gitweb
LU-16334 llite: update statx size/ctime for fallocate
[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-14541 277
44 always_except LU-9054  312
45 always_except LU-8411  407
46
47 if $SHARED_KEY; then
48         always_except LU-14181 64e 64f
49 fi
50
51 # skip the grant tests for ARM until they are fixed
52 if [[ $(uname -m) = aarch64 ]]; then
53         always_except LU-11671 45
54 fi
55
56 # skip nfs tests on kernels >= 4.12.0 until they are fixed
57 if [ $LINUX_VERSION_CODE -ge $(version_code 4.12.0) ]; then
58         always_except LU-12661 817
59 fi
60 # skip cgroup tests on RHEL8.1 kernels until they are fixed
61 if (( $LINUX_VERSION_CODE >= $(version_code 4.18.0) &&
62       $LINUX_VERSION_CODE <  $(version_code 5.4.0) )); then
63         always_except LU-13063 411
64 fi
65
66 #                                  5              12     8   12  15   (min)"
67 [ "$SLOW" = "no" ] && EXCEPT_SLOW="27m 60i 64b 68 71 135 136 230d 300o"
68
69 if [ "$mds1_FSTYPE" = "zfs" ]; then
70         #                                               13    (min)"
71         [ "$SLOW" = "no" ] && EXCEPT_SLOW="$EXCEPT_SLOW 51b"
72 fi
73
74 if [ "$ost1_FSTYPE" = "zfs" ]; then
75         always_except LU-1941 130b 130c 130d 130e 130f 130g
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 ]; 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 lctl set_param debug=-1 2> /dev/null || true
174 test_0a() {
175         touch $DIR/$tfile
176         $CHECKSTAT -t file $DIR/$tfile || error "$tfile is not a file"
177         rm $DIR/$tfile
178         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
179 }
180 run_test 0a "touch; rm ====================="
181
182 test_0b() {
183         chmod 0755 $DIR || error "chmod 0755 $DIR failed"
184         $CHECKSTAT -p 0755 $DIR || error "$DIR permission is not 0755"
185 }
186 run_test 0b "chmod 0755 $DIR ============================="
187
188 test_0c() {
189         $LCTL get_param mdc.*.import | grep "state: FULL" ||
190                 error "import not FULL"
191         $LCTL get_param mdc.*.import | grep "target: $FSNAME-MDT" ||
192                 error "bad target"
193 }
194 run_test 0c "check import proc"
195
196 test_0d() { # LU-3397
197         [ $MGS_VERSION -lt $(version_code 2.10.57) ] &&
198                 skip "proc exports not supported before 2.10.57"
199
200         local mgs_exp="mgs.MGS.exports"
201         local client_uuid=$($LCTL get_param -n mgc.*.uuid)
202         local exp_client_nid
203         local exp_client_version
204         local exp_val
205         local imp_val
206         local temp_imp=$DIR/$tfile.import
207         local temp_exp=$DIR/$tfile.export
208
209         # save mgc import file to $temp_imp
210         $LCTL get_param mgc.*.import | tee $temp_imp
211         # Check if client uuid is found in MGS export
212         for exp_client_nid in $(do_facet mgs $LCTL get_param -N $mgs_exp.*); do
213                 [ $(do_facet mgs $LCTL get_param -n $exp_client_nid.uuid) == \
214                         $client_uuid ] &&
215                         break;
216         done
217         # save mgs export file to $temp_exp
218         do_facet mgs $LCTL get_param $exp_client_nid.export | tee $temp_exp
219
220         # Compare the value of field "connect_flags"
221         imp_val=$(grep "connect_flags" $temp_imp)
222         exp_val=$(grep "connect_flags" $temp_exp)
223         [ "$exp_val" == "$imp_val" ] ||
224                 error "export flags '$exp_val' != import flags '$imp_val'"
225
226         # Compare client versions.  Only compare top-3 fields for compatibility
227         exp_client_version=$(awk '/target_version:/ { print $2 }' $temp_exp)
228         exp_val=$(version_code $(cut -d. -f1,2,3 <<<$exp_client_version))
229         imp_val=$(version_code $(lustre_build_version client | cut -d. -f1,2,3))
230         [ "$exp_val" == "$imp_val" ] ||
231                 error "exp version '$exp_client_version'($exp_val) != " \
232                         "'$(lustre_build_version client)'($imp_val)"
233 }
234 run_test 0d "check export proc ============================="
235
236 test_0e() { # LU-13417
237         (( $MDSCOUNT > 1 )) ||
238                 skip "We need at least 2 MDTs for this test"
239
240         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
241                 skip "Need server version at least 2.14.51"
242
243         local default_lmv_count=$($LFS getdirstripe -D -c $MOUNT)
244         local default_lmv_index=$($LFS getdirstripe -D -i $MOUNT)
245
246         [ $default_lmv_count -eq 1 ] ||
247                 error "$MOUNT default stripe count $default_lmv_count"
248
249         [ $default_lmv_index -eq -1 ] ||
250                 error "$MOUNT default stripe index $default_lmv_index"
251
252         mkdir $MOUNT/$tdir.1 || error "mkdir $MOUNT/$tdir.1 failed"
253         mkdir $MOUNT/$tdir.2 || error "mkdir $MOUNT/$tdir.2 failed"
254
255         local mdt_index1=$($LFS getdirstripe -i $MOUNT/$tdir.1)
256         local mdt_index2=$($LFS getdirstripe -i $MOUNT/$tdir.2)
257
258         [ $mdt_index1 -eq $mdt_index2 ] &&
259                 error "directories are on the same MDT $mdt_index1=$mdt_index2"
260
261         rmdir $MOUNT/$tdir.1 $MOUNT/$tdir.2
262 }
263 run_test 0e "Enable DNE MDT balancing for mkdir in the ROOT"
264
265 test_1() {
266         test_mkdir $DIR/$tdir
267         test_mkdir $DIR/$tdir/d2
268         mkdir $DIR/$tdir/d2 && error "we expect EEXIST, but not returned"
269         $CHECKSTAT -t dir $DIR/$tdir/d2 || error "$tdir/d2 is not a dir"
270         rmdir $DIR/$tdir/d2
271         rmdir $DIR/$tdir
272         $CHECKSTAT -a $DIR/$tdir || error "$tdir was not removed"
273 }
274 run_test 1 "mkdir; remkdir; rmdir"
275
276 test_2() {
277         test_mkdir $DIR/$tdir
278         touch $DIR/$tdir/$tfile || error "touch $tdir/$tfile failed"
279         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "$tdir/$tfile not a file"
280         rm -r $DIR/$tdir
281         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$file is not removed"
282 }
283 run_test 2 "mkdir; touch; rmdir; check file"
284
285 test_3() {
286         test_mkdir $DIR/$tdir
287         $CHECKSTAT -t dir $DIR/$tdir || error "$tdir is not a directory"
288         touch $DIR/$tdir/$tfile
289         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "$tdir/$tfile not a file"
290         rm -r $DIR/$tdir
291         $CHECKSTAT -a $DIR/$tdir || error "$tdir is not removed"
292 }
293 run_test 3 "mkdir; touch; rmdir; check dir"
294
295 # LU-4471 - failed rmdir on remote directories still removes directory on MDT0
296 test_4() {
297         test_mkdir -i 1 $DIR/$tdir
298
299         touch $DIR/$tdir/$tfile ||
300                 error "Create file under remote directory failed"
301
302         rmdir $DIR/$tdir &&
303                 error "Expect error removing in-use dir $DIR/$tdir"
304
305         test -d $DIR/$tdir || error "Remote directory disappeared"
306
307         rm -rf $DIR/$tdir || error "remove remote dir error"
308 }
309 run_test 4 "mkdir; touch dir/file; rmdir; checkdir (expect error)"
310
311 test_5() {
312         test_mkdir $DIR/$tdir
313         test_mkdir $DIR/$tdir/d2
314         chmod 0707 $DIR/$tdir/d2 || error "chmod 0707 $tdir/d2 failed"
315         $CHECKSTAT -t dir -p 0707 $DIR/$tdir/d2 || error "$tdir/d2 not mode 707"
316         $CHECKSTAT -t dir $DIR/$tdir/d2 || error "$tdir/d2 is not a directory"
317 }
318 run_test 5 "mkdir .../d5 .../d5/d2; chmod .../d5/d2"
319
320 test_6a() {
321         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
322         chmod 0666 $DIR/$tfile || error "chmod 0666 $tfile failed"
323         $CHECKSTAT -t file -p 0666 -u \#$UID $DIR/$tfile ||
324                 error "$tfile does not have perm 0666 or UID $UID"
325         $RUNAS chmod 0444 $DIR/$tfile && error "chmod $tfile worked on UID $UID"
326         $CHECKSTAT -t file -p 0666 -u \#$UID $DIR/$tfile ||
327                 error "$tfile should be 0666 and owned by UID $UID"
328 }
329 run_test 6a "touch f6a; chmod f6a; $RUNAS chmod f6a (should return error) =="
330
331 test_6c() {
332         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
333
334         touch $DIR/$tfile
335         chown $RUNAS_ID $DIR/$tfile || error "chown $RUNAS_ID $file failed"
336         $CHECKSTAT -t file -u \#$RUNAS_ID $DIR/$tfile ||
337                 error "$tfile should be owned by UID $RUNAS_ID"
338         $RUNAS chown $UID $DIR/$tfile && error "chown $UID $file succeeded"
339         $CHECKSTAT -t file -u \#$RUNAS_ID $DIR/$tfile ||
340                 error "$tfile should be owned by UID $RUNAS_ID"
341 }
342 run_test 6c "touch f6c; chown f6c; $RUNAS chown f6c (should return error) =="
343
344 test_6e() {
345         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
346
347         touch $DIR/$tfile
348         chgrp $RUNAS_ID $DIR/$tfile || error "chgrp $RUNAS_ID $file failed"
349         $CHECKSTAT -t file -u \#$UID -g \#$RUNAS_ID $DIR/$tfile ||
350                 error "$tfile should be owned by GID $UID"
351         $RUNAS chgrp $UID $DIR/$tfile && error "chgrp $UID $file succeeded"
352         $CHECKSTAT -t file -u \#$UID -g \#$RUNAS_ID $DIR/$tfile ||
353                 error "$tfile should be owned by UID $UID and GID $RUNAS_ID"
354 }
355 run_test 6e "touch+chgrp $tfile; $RUNAS chgrp $tfile (should return error)"
356
357 test_6g() {
358         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
359
360         test_mkdir $DIR/$tdir
361         chmod 777 $DIR/$tdir || error "chmod 0777 $tdir failed"
362         $RUNAS mkdir $DIR/$tdir/d || error "mkdir $tdir/d failed"
363         chmod g+s $DIR/$tdir/d || error "chmod g+s $tdir/d failed"
364         test_mkdir $DIR/$tdir/d/subdir
365         $CHECKSTAT -g \#$RUNAS_GID $DIR/$tdir/d/subdir ||
366                 error "$tdir/d/subdir should be GID $RUNAS_GID"
367         if [[ $MDSCOUNT -gt 1 ]]; then
368                 # check remote dir sgid inherite
369                 $LFS mkdir -i 0 $DIR/$tdir.local ||
370                         error "mkdir $tdir.local failed"
371                 chmod g+s $DIR/$tdir.local ||
372                         error "chmod $tdir.local failed"
373                 chgrp $RUNAS_GID $DIR/$tdir.local ||
374                         error "chgrp $tdir.local failed"
375                 $LFS mkdir -i 1 $DIR/$tdir.local/$tdir.remote ||
376                         error "mkdir $tdir.remote failed"
377                 $CHECKSTAT -g \#$RUNAS_GID $DIR/$tdir.local/$tdir.remote ||
378                         error "$tdir.remote should be owned by $UID.$RUNAS_ID"
379                 $CHECKSTAT -p 02755 $DIR/$tdir.local/$tdir.remote ||
380                         error "$tdir.remote should be mode 02755"
381         fi
382 }
383 run_test 6g "verify new dir in sgid dir inherits group"
384
385 test_6h() { # bug 7331
386         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
387
388         touch $DIR/$tfile || error "touch failed"
389         chown $RUNAS_ID:$RUNAS_GID $DIR/$tfile || error "initial chown failed"
390         $RUNAS -G$RUNAS_GID chown $RUNAS_ID:0 $DIR/$tfile &&
391                 error "chown $RUNAS_ID:0 $tfile worked as GID $RUNAS_GID"
392         $CHECKSTAT -t file -u \#$RUNAS_ID -g \#$RUNAS_GID $DIR/$tfile ||
393                 error "$tdir/$tfile should be UID $RUNAS_UID GID $RUNAS_GID"
394 }
395 run_test 6h "$RUNAS chown RUNAS_ID.0 .../$tfile (should return error)"
396
397 test_7a() {
398         test_mkdir $DIR/$tdir
399         $MCREATE $DIR/$tdir/$tfile
400         chmod 0666 $DIR/$tdir/$tfile
401         $CHECKSTAT -t file -p 0666 $DIR/$tdir/$tfile ||
402                 error "$tdir/$tfile should be mode 0666"
403 }
404 run_test 7a "mkdir .../d7; mcreate .../d7/f; chmod .../d7/f ===="
405
406 test_7b() {
407         if [ ! -d $DIR/$tdir ]; then
408                 test_mkdir $DIR/$tdir
409         fi
410         $MCREATE $DIR/$tdir/$tfile
411         echo -n foo > $DIR/$tdir/$tfile
412         [ "$(cat $DIR/$tdir/$tfile)" = "foo" ] || error "$tdir/$tfile not 'foo'"
413         $CHECKSTAT -t file -s 3 $DIR/$tdir/$tfile || error "$tfile size not 3"
414 }
415 run_test 7b "mkdir .../d7; mcreate d7/f2; echo foo > d7/f2 ====="
416
417 test_8() {
418         test_mkdir $DIR/$tdir
419         touch $DIR/$tdir/$tfile
420         chmod 0666 $DIR/$tdir/$tfile
421         $CHECKSTAT -t file -p 0666 $DIR/$tdir/$tfile ||
422                 error "$tfile mode not 0666"
423 }
424 run_test 8 "mkdir .../d8; touch .../d8/f; chmod .../d8/f ======="
425
426 test_9() {
427         test_mkdir $DIR/$tdir
428         test_mkdir $DIR/$tdir/d2
429         test_mkdir $DIR/$tdir/d2/d3
430         $CHECKSTAT -t dir $DIR/$tdir/d2/d3 || error "$tdir/d2/d3 not a dir"
431 }
432 run_test 9 "mkdir .../d9 .../d9/d2 .../d9/d2/d3 ================"
433
434 test_10() {
435         test_mkdir $DIR/$tdir
436         test_mkdir $DIR/$tdir/d2
437         touch $DIR/$tdir/d2/$tfile
438         $CHECKSTAT -t file $DIR/$tdir/d2/$tfile ||
439                 error "$tdir/d2/$tfile not a file"
440 }
441 run_test 10 "mkdir .../d10 .../d10/d2; touch .../d10/d2/f ======"
442
443 test_11() {
444         test_mkdir $DIR/$tdir
445         test_mkdir $DIR/$tdir/d2
446         chmod 0666 $DIR/$tdir/d2
447         chmod 0705 $DIR/$tdir/d2
448         $CHECKSTAT -t dir -p 0705 $DIR/$tdir/d2 ||
449                 error "$tdir/d2 mode not 0705"
450 }
451 run_test 11 "mkdir .../d11 d11/d2; chmod .../d11/d2 ============"
452
453 test_12() {
454         test_mkdir $DIR/$tdir
455         touch $DIR/$tdir/$tfile
456         chmod 0666 $DIR/$tdir/$tfile
457         chmod 0654 $DIR/$tdir/$tfile
458         $CHECKSTAT -t file -p 0654 $DIR/$tdir/$tfile ||
459                 error "$tdir/d2 mode not 0654"
460 }
461 run_test 12 "touch .../d12/f; chmod .../d12/f .../d12/f ========"
462
463 test_13() {
464         test_mkdir $DIR/$tdir
465         dd if=/dev/zero of=$DIR/$tdir/$tfile count=10
466         >  $DIR/$tdir/$tfile
467         $CHECKSTAT -t file -s 0 $DIR/$tdir/$tfile ||
468                 error "$tdir/$tfile size not 0 after truncate"
469 }
470 run_test 13 "creat .../d13/f; dd .../d13/f; > .../d13/f ========"
471
472 test_14() {
473         test_mkdir $DIR/$tdir
474         touch $DIR/$tdir/$tfile
475         rm $DIR/$tdir/$tfile
476         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$tfile not removed"
477 }
478 run_test 14 "touch .../d14/f; rm .../d14/f; rm .../d14/f ======="
479
480 test_15() {
481         test_mkdir $DIR/$tdir
482         touch $DIR/$tdir/$tfile
483         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}_2
484         $CHECKSTAT -t file $DIR/$tdir/${tfile}_2 ||
485                 error "$tdir/${tfile_2} not a file after rename"
486         rm $DIR/$tdir/${tfile}_2 || error "unlink failed after rename"
487 }
488 run_test 15 "touch .../d15/f; mv .../d15/f .../d15/f2 =========="
489
490 test_16() {
491         test_mkdir $DIR/$tdir
492         touch $DIR/$tdir/$tfile
493         rm -rf $DIR/$tdir/$tfile
494         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$tfile not removed"
495 }
496 run_test 16 "touch .../d16/f; rm -rf .../d16/f"
497
498 test_17a() {
499         test_mkdir $DIR/$tdir
500         touch $DIR/$tdir/$tfile
501         ln -s $DIR/$tdir/$tfile $DIR/$tdir/l-exist
502         ls -l $DIR/$tdir
503         $CHECKSTAT -l $DIR/$tdir/$tfile $DIR/$tdir/l-exist ||
504                 error "$tdir/l-exist not a symlink"
505         $CHECKSTAT -f -t f $DIR/$tdir/l-exist ||
506                 error "$tdir/l-exist not referencing a file"
507         rm -f $DIR/$tdir/l-exist
508         $CHECKSTAT -a $DIR/$tdir/l-exist || error "$tdir/l-exist not removed"
509 }
510 run_test 17a "symlinks: create, remove (real)"
511
512 test_17b() {
513         test_mkdir $DIR/$tdir
514         ln -s no-such-file $DIR/$tdir/l-dangle
515         ls -l $DIR/$tdir
516         $CHECKSTAT -l no-such-file $DIR/$tdir/l-dangle ||
517                 error "$tdir/l-dangle not referencing no-such-file"
518         $CHECKSTAT -fa $DIR/$tdir/l-dangle ||
519                 error "$tdir/l-dangle not referencing non-existent file"
520         rm -f $DIR/$tdir/l-dangle
521         $CHECKSTAT -a $DIR/$tdir/l-dangle || error "$tdir/l-dangle not removed"
522 }
523 run_test 17b "symlinks: create, remove (dangling)"
524
525 test_17c() { # bug 3440 - don't save failed open RPC for replay
526         test_mkdir $DIR/$tdir
527         ln -s foo $DIR/$tdir/$tfile
528         cat $DIR/$tdir/$tfile && error "opened non-existent symlink" || true
529 }
530 run_test 17c "symlinks: open dangling (should return error)"
531
532 test_17d() {
533         test_mkdir $DIR/$tdir
534         ln -s foo $DIR/$tdir/$tfile
535         touch $DIR/$tdir/$tfile || error "creating to new symlink"
536 }
537 run_test 17d "symlinks: create dangling"
538
539 test_17e() {
540         test_mkdir $DIR/$tdir
541         local foo=$DIR/$tdir/$tfile
542         ln -s $foo $foo || error "create symlink failed"
543         ls -l $foo || error "ls -l failed"
544         ls $foo && error "ls not failed" || true
545 }
546 run_test 17e "symlinks: create recursive symlink (should return error)"
547
548 test_17f() {
549         test_mkdir $DIR/$tdir
550         ln -s 1234567890/2234567890/3234567890/4234567890 $DIR/$tdir/111
551         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890 $DIR/$tdir/222
552         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890 $DIR/$tdir/333
553         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890 $DIR/$tdir/444
554         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890/c234567890/d234567890/f234567890 $DIR/$tdir/555
555         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
556         ls -l  $DIR/$tdir
557 }
558 run_test 17f "symlinks: long and very long symlink name"
559
560 # str_repeat(S, N) generate a string that is string S repeated N times
561 str_repeat() {
562         local s=$1
563         local n=$2
564         local ret=''
565         while [ $((n -= 1)) -ge 0 ]; do
566                 ret=$ret$s
567         done
568         echo $ret
569 }
570
571 # Long symlinks and LU-2241
572 test_17g() {
573         test_mkdir $DIR/$tdir
574         local TESTS="59 60 61 4094 4095"
575
576         # Fix for inode size boundary in 2.1.4
577         [ $MDS1_VERSION -lt $(version_code 2.1.4) ] &&
578                 TESTS="4094 4095"
579
580         # Patch not applied to 2.2 or 2.3 branches
581         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
582         [ $MDS1_VERSION -le $(version_code 2.3.55) ] &&
583                 TESTS="4094 4095"
584
585         for i in $TESTS; do
586                 local SYMNAME=$(str_repeat 'x' $i)
587                 ln -s $SYMNAME $DIR/$tdir/f$i || error "failed $i-char symlink"
588                 readlink $DIR/$tdir/f$i || error "failed $i-char readlink"
589         done
590 }
591 run_test 17g "symlinks: really long symlink name and inode boundaries"
592
593 test_17h() { #bug 17378
594         [ $PARALLEL == "yes" ] && skip "skip parallel run"
595         remote_mds_nodsh && skip "remote MDS with nodsh"
596
597         local mdt_idx
598
599         test_mkdir $DIR/$tdir
600         mdt_idx=$($LFS getdirstripe -i $DIR/$tdir)
601         $LFS setstripe -c -1 $DIR/$tdir
602         #define OBD_FAIL_MDS_LOV_PREP_CREATE 0x141
603         do_facet mds$((mdt_idx + 1)) lctl set_param fail_loc=0x80000141
604         touch $DIR/$tdir/$tfile || true
605 }
606 run_test 17h "create objects: lov_free_memmd() doesn't lbug"
607
608 test_17i() { #bug 20018
609         [ $PARALLEL == "yes" ] && skip "skip parallel run"
610         remote_mds_nodsh && skip "remote MDS with nodsh"
611
612         local foo=$DIR/$tdir/$tfile
613         local mdt_idx
614
615         test_mkdir -c1 $DIR/$tdir
616         mdt_idx=$($LFS getdirstripe -i $DIR/$tdir)
617         ln -s $foo $foo || error "create symlink failed"
618 #define OBD_FAIL_MDS_READLINK_EPROTO     0x143
619         do_facet mds$((mdt_idx + 1)) lctl set_param fail_loc=0x80000143
620         ls -l $foo && error "error not detected"
621         return 0
622 }
623 run_test 17i "don't panic on short symlink (should return error)"
624
625 test_17k() { #bug 22301
626         [ $PARALLEL == "yes" ] && skip "skip parallel run"
627         [[ -z "$(which rsync 2>/dev/null)" ]] &&
628                 skip "no rsync command"
629         rsync --help | grep -q xattr ||
630                 skip_env "$(rsync --version | head -n1) does not support xattrs"
631         test_mkdir $DIR/$tdir
632         test_mkdir $DIR/$tdir.new
633         touch $DIR/$tdir/$tfile
634         ln -s $DIR/$tdir/$tfile $DIR/$tdir/$tfile.lnk
635         rsync -av -X $DIR/$tdir/ $DIR/$tdir.new ||
636                 error "rsync failed with xattrs enabled"
637 }
638 run_test 17k "symlinks: rsync with xattrs enabled"
639
640 test_17l() { # LU-279
641         [[ -z "$(which getfattr 2>/dev/null)" ]] &&
642                 skip "no getfattr command"
643
644         test_mkdir $DIR/$tdir
645         touch $DIR/$tdir/$tfile
646         ln -s $DIR/$tdir/$tfile $DIR/$tdir/$tfile.lnk
647         for path in "$DIR/$tdir" "$DIR/$tdir/$tfile" "$DIR/$tdir/$tfile.lnk"; do
648                 # -h to not follow symlinks. -m '' to list all the xattrs.
649                 # grep to remove first line: '# file: $path'.
650                 for xattr in `getfattr -hm '' $path 2>/dev/null | grep -v '^#'`;
651                 do
652                         lgetxattr_size_check $path $xattr ||
653                                 error "lgetxattr_size_check $path $xattr failed"
654                 done
655         done
656 }
657 run_test 17l "Ensure lgetxattr's returned xattr size is consistent"
658
659 # LU-1540
660 test_17m() {
661         [ $PARALLEL == "yes" ] && skip "skip parallel run"
662         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
663         remote_mds_nodsh && skip "remote MDS with nodsh"
664         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
665         [ $MDS1_VERSION -le $(version_code 2.2.93) ] &&
666                 skip "MDS 2.2.0-2.2.93 do not NUL-terminate symlinks"
667
668         local short_sym="0123456789"
669         local wdir=$DIR/$tdir
670         local i
671
672         test_mkdir $wdir
673         long_sym=$short_sym
674         # create a long symlink file
675         for ((i = 0; i < 4; ++i)); do
676                 long_sym=${long_sym}${long_sym}
677         done
678
679         echo "create 512 short and long symlink files under $wdir"
680         for ((i = 0; i < 256; ++i)); do
681                 ln -sf ${long_sym}"a5a5" $wdir/long-$i
682                 ln -sf ${short_sym}"a5a5" $wdir/short-$i
683         done
684
685         echo "erase them"
686         rm -f $wdir/*
687         sync
688         wait_delete_completed
689
690         echo "recreate the 512 symlink files with a shorter string"
691         for ((i = 0; i < 512; ++i)); do
692                 # rewrite the symlink file with a shorter string
693                 ln -sf ${long_sym} $wdir/long-$i || error "long_sym failed"
694                 ln -sf ${short_sym} $wdir/short-$i || error "short_sym failed"
695         done
696
697         local mds_index=$(($($LFS getstripe -m $wdir) + 1))
698
699         echo "stop and checking mds${mds_index}:"
700         # e2fsck should not return error
701         stop mds${mds_index}
702         local devname=$(mdsdevname $mds_index)
703         run_e2fsck $(facet_active_host mds${mds_index}) $devname -n
704         rc=$?
705
706         start mds${mds_index} $devname $MDS_MOUNT_OPTS ||
707                 error "start mds${mds_index} failed"
708         df $MOUNT > /dev/null 2>&1
709         [ $rc -eq 0 ] ||
710                 error "e2fsck detected error for short/long symlink: rc=$rc"
711         rm -f $wdir/*
712 }
713 run_test 17m "run e2fsck against MDT which contains short/long symlink"
714
715 check_fs_consistency_17n() {
716         local mdt_index
717         local rc=0
718
719         # create/unlink in 17n only change 2 MDTs(MDT1/MDT2),
720         # so it only check MDT1/MDT2 instead of all of MDTs.
721         for mdt_index in 1 2; do
722                 # e2fsck should not return error
723                 stop mds${mdt_index}
724                 local devname=$(mdsdevname $mdt_index)
725                 run_e2fsck $(facet_active_host mds$mdt_index) $devname -n ||
726                         rc=$((rc + $?))
727
728                 start mds${mdt_index} $devname $MDS_MOUNT_OPTS ||
729                         error "mount mds$mdt_index failed"
730                 df $MOUNT > /dev/null 2>&1
731         done
732         return $rc
733 }
734
735 test_17n() {
736         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
737         [ $PARALLEL == "yes" ] && skip "skip parallel run"
738         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
739         remote_mds_nodsh && skip "remote MDS with nodsh"
740         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
741         [ $MDS1_VERSION -le $(version_code 2.2.93) ] &&
742                 skip "MDS 2.2.0-2.2.93 do not NUL-terminate symlinks"
743
744         local i
745
746         test_mkdir $DIR/$tdir
747         for ((i=0; i<10; i++)); do
748                 $LFS mkdir -i1 -c2 $DIR/$tdir/remote_dir_${i} ||
749                         error "create remote dir error $i"
750                 createmany -o $DIR/$tdir/remote_dir_${i}/f 10 ||
751                         error "create files under remote dir failed $i"
752         done
753
754         check_fs_consistency_17n ||
755                 error "e2fsck report error after create files under remote dir"
756
757         for ((i = 0; i < 10; i++)); do
758                 rm -rf $DIR/$tdir/remote_dir_${i} ||
759                         error "destroy remote dir error $i"
760         done
761
762         check_fs_consistency_17n ||
763                 error "e2fsck report error after unlink files under remote dir"
764
765         [ $MDS1_VERSION -lt $(version_code 2.4.50) ] &&
766                 skip "lustre < 2.4.50 does not support migrate mv"
767
768         for ((i = 0; i < 10; i++)); do
769                 mkdir -p $DIR/$tdir/remote_dir_${i}
770                 createmany -o $DIR/$tdir/remote_dir_${i}/f 10 ||
771                         error "create files under remote dir failed $i"
772                 $LFS migrate --mdt-index 1 $DIR/$tdir/remote_dir_${i} ||
773                         error "migrate remote dir error $i"
774         done
775         check_fs_consistency_17n || error "e2fsck report error after migration"
776
777         for ((i = 0; i < 10; i++)); do
778                 rm -rf $DIR/$tdir/remote_dir_${i} ||
779                         error "destroy remote dir error $i"
780         done
781
782         check_fs_consistency_17n || error "e2fsck report error after unlink"
783 }
784 run_test 17n "run e2fsck against master/slave MDT which contains remote dir"
785
786 test_17o() {
787         remote_mds_nodsh && skip "remote MDS with nodsh"
788         [ $MDS1_VERSION -lt $(version_code 2.3.64) ] &&
789                 skip "Need MDS version at least 2.3.64"
790
791         local wdir=$DIR/${tdir}o
792         local mdt_index
793         local rc=0
794
795         test_mkdir $wdir
796         touch $wdir/$tfile
797         mdt_index=$($LFS getstripe -m $wdir/$tfile)
798         mdt_index=$((mdt_index + 1))
799
800         cancel_lru_locks mdc
801         #fail mds will wait the failover finish then set
802         #following fail_loc to avoid interfer the recovery process.
803         fail mds${mdt_index}
804
805         #define OBD_FAIL_OSD_LMA_INCOMPAT 0x194
806         do_facet mds${mdt_index} lctl set_param fail_loc=0x194
807         ls -l $wdir/$tfile && rc=1
808         do_facet mds${mdt_index} lctl set_param fail_loc=0
809         [[ $rc -eq 0 ]] || error "stat file should fail"
810 }
811 run_test 17o "stat file with incompat LMA feature"
812
813 test_18() {
814         touch $DIR/$tfile || error "Failed to touch $DIR/$tfile: $?"
815         ls $DIR || error "Failed to ls $DIR: $?"
816 }
817 run_test 18 "touch .../f ; ls ... =============================="
818
819 test_19a() {
820         touch $DIR/$tfile
821         ls -l $DIR
822         rm $DIR/$tfile
823         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
824 }
825 run_test 19a "touch .../f19 ; ls -l ... ; rm .../f19 ==========="
826
827 test_19b() {
828         ls -l $DIR/$tfile && error "ls -l $tfile failed"|| true
829 }
830 run_test 19b "ls -l .../f19 (should return error) =============="
831
832 test_19c() {
833         [ $RUNAS_ID -eq $UID ] &&
834                 skip_env "RUNAS_ID = UID = $UID -- skipping"
835
836         $RUNAS touch $DIR/$tfile && error "create non-root file failed" || true
837 }
838 run_test 19c "$RUNAS touch .../f19 (should return error) =="
839
840 test_19d() {
841         cat $DIR/f19 && error || true
842 }
843 run_test 19d "cat .../f19 (should return error) =============="
844
845 test_20() {
846         touch $DIR/$tfile
847         rm $DIR/$tfile
848         touch $DIR/$tfile
849         rm $DIR/$tfile
850         touch $DIR/$tfile
851         rm $DIR/$tfile
852         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
853 }
854 run_test 20 "touch .../f ; ls -l ..."
855
856 test_21() {
857         test_mkdir $DIR/$tdir
858         [ -f $DIR/$tdir/dangle ] && rm -f $DIR/$tdir/dangle
859         ln -s dangle $DIR/$tdir/link
860         echo foo >> $DIR/$tdir/link
861         cat $DIR/$tdir/dangle
862         $CHECKSTAT -t link $DIR/$tdir/link || error "$tdir/link not a link"
863         $CHECKSTAT -f -t file $DIR/$tdir/link ||
864                 error "$tdir/link not linked to a file"
865 }
866 run_test 21 "write to dangling link"
867
868 test_22() {
869         local wdir=$DIR/$tdir
870         test_mkdir $wdir
871         chown $RUNAS_ID:$RUNAS_GID $wdir
872         (cd $wdir || error "cd $wdir failed";
873                 $RUNAS tar cf - /etc/hosts /etc/sysconfig/network |
874                 $RUNAS tar xf -)
875         ls -lR $wdir/etc || error "ls -lR $wdir/etc failed"
876         $CHECKSTAT -t dir $wdir/etc || error "checkstat -t dir failed"
877         $CHECKSTAT -u \#$RUNAS_ID -g \#$RUNAS_GID $wdir/etc ||
878                 error "checkstat -u failed"
879 }
880 run_test 22 "unpack tar archive as non-root user"
881
882 # was test_23
883 test_23a() {
884         test_mkdir $DIR/$tdir
885         local file=$DIR/$tdir/$tfile
886
887         openfile -f O_CREAT:O_EXCL $file || error "$file create failed"
888         openfile -f O_CREAT:O_EXCL $file &&
889                 error "$file recreate succeeded" || true
890 }
891 run_test 23a "O_CREAT|O_EXCL in subdir"
892
893 test_23b() { # bug 18988
894         test_mkdir $DIR/$tdir
895         local file=$DIR/$tdir/$tfile
896
897         rm -f $file
898         echo foo > $file || error "write filed"
899         echo bar >> $file || error "append filed"
900         $CHECKSTAT -s 8 $file || error "wrong size"
901         rm $file
902 }
903 run_test 23b "O_APPEND check"
904
905 # LU-9409, size with O_APPEND and tiny writes
906 test_23c() {
907         local file=$DIR/$tfile
908
909         # single dd
910         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800
911         $CHECKSTAT -s 6400 $file || error "wrong size, expected 6400"
912         rm -f $file
913
914         # racing tiny writes
915         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800 &
916         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800 &
917         wait
918         $CHECKSTAT -s 12800 $file || error "wrong size, expected 12800"
919         rm -f $file
920
921         #racing tiny & normal writes
922         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=4096 count=4 &
923         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=100 &
924         wait
925         $CHECKSTAT -s 17184 $file || error "wrong size, expected 17184"
926         rm -f $file
927
928         #racing tiny & normal writes 2, ugly numbers
929         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=4099 count=11 &
930         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=17 count=173 &
931         wait
932         $CHECKSTAT -s 48030 $file || error "wrong size, expected 48030"
933         rm -f $file
934 }
935 run_test 23c "O_APPEND size checks for tiny writes"
936
937 # LU-11069 file offset is correct after appending writes
938 test_23d() {
939         local file=$DIR/$tfile
940         local offset
941
942         echo CentaurHauls > $file
943         offset=$($MULTIOP $file oO_WRONLY:O_APPEND:w13Zp)
944         if ((offset != 26)); then
945                 error "wrong offset, expected 26, got '$offset'"
946         fi
947 }
948 run_test 23d "file offset is correct after appending writes"
949
950 # rename sanity
951 test_24a() {
952         echo '-- same directory rename'
953         test_mkdir $DIR/$tdir
954         touch $DIR/$tdir/$tfile.1
955         mv $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
956         $CHECKSTAT -t file $DIR/$tdir/$tfile.2 || error "$tfile.2 not a file"
957 }
958 run_test 24a "rename file to non-existent target"
959
960 test_24b() {
961         test_mkdir $DIR/$tdir
962         touch $DIR/$tdir/$tfile.{1,2}
963         mv $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
964         $CHECKSTAT -a $DIR/$tdir/$tfile.1 || error "$tfile.1 exists"
965         $CHECKSTAT -t file $DIR/$tdir/$tfile.2 || error "$tfile.2 not a file"
966 }
967 run_test 24b "rename file to existing target"
968
969 test_24c() {
970         test_mkdir $DIR/$tdir
971         test_mkdir $DIR/$tdir/d$testnum.1
972         mv $DIR/$tdir/d$testnum.1 $DIR/$tdir/d$testnum.2
973         $CHECKSTAT -a $DIR/$tdir/d$testnum.1 || error "d$testnum.1 exists"
974         $CHECKSTAT -t dir $DIR/$tdir/d$testnum.2 || error "d$testnum.2 not dir"
975 }
976 run_test 24c "rename directory to non-existent target"
977
978 test_24d() {
979         test_mkdir -c1 $DIR/$tdir
980         test_mkdir -c1 $DIR/$tdir/d$testnum.1
981         test_mkdir -c1 $DIR/$tdir/d$testnum.2
982         mrename $DIR/$tdir/d$testnum.1 $DIR/$tdir/d$testnum.2
983         $CHECKSTAT -a $DIR/$tdir/d$testnum.1 || error "d$testnum.1 exists"
984         $CHECKSTAT -t dir $DIR/$tdir/d$testnum.2 || error "d$testnum.2 not dir"
985 }
986 run_test 24d "rename directory to existing target"
987
988 test_24e() {
989         echo '-- cross directory renames --'
990         test_mkdir $DIR/R5a
991         test_mkdir $DIR/R5b
992         touch $DIR/R5a/f
993         mv $DIR/R5a/f $DIR/R5b/g
994         $CHECKSTAT -a $DIR/R5a/f || error "$DIR/R5a/f exists"
995         $CHECKSTAT -t file $DIR/R5b/g || error "$DIR/R5b/g not file type"
996 }
997 run_test 24e "touch .../R5a/f; rename .../R5a/f .../R5b/g ======"
998
999 test_24f() {
1000         test_mkdir $DIR/R6a
1001         test_mkdir $DIR/R6b
1002         touch $DIR/R6a/f $DIR/R6b/g
1003         mv $DIR/R6a/f $DIR/R6b/g
1004         $CHECKSTAT -a $DIR/R6a/f || error "$DIR/R6a/f exists"
1005         $CHECKSTAT -t file $DIR/R6b/g || error "$DIR/R6b/g not file type"
1006 }
1007 run_test 24f "touch .../R6a/f R6b/g; mv .../R6a/f .../R6b/g ===="
1008
1009 test_24g() {
1010         test_mkdir $DIR/R7a
1011         test_mkdir $DIR/R7b
1012         test_mkdir $DIR/R7a/d
1013         mv $DIR/R7a/d $DIR/R7b/e
1014         $CHECKSTAT -a $DIR/R7a/d || error "$DIR/R7a/d exists"
1015         $CHECKSTAT -t dir $DIR/R7b/e || error "$DIR/R7b/e not dir type"
1016 }
1017 run_test 24g "mkdir .../R7{a,b}/d; mv .../R7a/d .../R7b/e ======"
1018
1019 test_24h() {
1020         test_mkdir -c1 $DIR/R8a
1021         test_mkdir -c1 $DIR/R8b
1022         test_mkdir -c1 $DIR/R8a/d
1023         test_mkdir -c1 $DIR/R8b/e
1024         mrename $DIR/R8a/d $DIR/R8b/e
1025         $CHECKSTAT -a $DIR/R8a/d || error "$DIR/R8a/d exists"
1026         $CHECKSTAT -t dir $DIR/R8b/e || error "$DIR/R8b/e not dir type"
1027 }
1028 run_test 24h "mkdir .../R8{a,b}/{d,e}; rename .../R8a/d .../R8b/e"
1029
1030 test_24i() {
1031         echo "-- rename error cases"
1032         test_mkdir $DIR/R9
1033         test_mkdir $DIR/R9/a
1034         touch $DIR/R9/f
1035         mrename $DIR/R9/f $DIR/R9/a
1036         $CHECKSTAT -t file $DIR/R9/f || error "$DIR/R9/f not file type"
1037         $CHECKSTAT -t dir  $DIR/R9/a || error "$DIR/R9/a not dir type"
1038         $CHECKSTAT -a $DIR/R9/a/f || error "$DIR/R9/a/f exists"
1039 }
1040 run_test 24i "rename file to dir error: touch f ; mkdir a ; rename f a"
1041
1042 test_24j() {
1043         test_mkdir $DIR/R10
1044         mrename $DIR/R10/f $DIR/R10/g
1045         $CHECKSTAT -t dir $DIR/R10 || error "$DIR/R10 not dir type"
1046         $CHECKSTAT -a $DIR/R10/f || error "$DIR/R10/f exists"
1047         $CHECKSTAT -a $DIR/R10/g || error "$DIR/R10/g exists"
1048 }
1049 run_test 24j "source does not exist ============================"
1050
1051 test_24k() {
1052         test_mkdir $DIR/R11a
1053         test_mkdir $DIR/R11a/d
1054         touch $DIR/R11a/f
1055         mv $DIR/R11a/f $DIR/R11a/d
1056         $CHECKSTAT -a $DIR/R11a/f || error "$DIR/R11a/f exists"
1057         $CHECKSTAT -t file $DIR/R11a/d/f || error "$DIR/R11a/d/f not file type"
1058 }
1059 run_test 24k "touch .../R11a/f; mv .../R11a/f .../R11a/d ======="
1060
1061 # bug 2429 - rename foo foo foo creates invalid file
1062 test_24l() {
1063         f="$DIR/f24l"
1064         $MULTIOP $f OcNs || error "rename of ${f} to itself failed"
1065 }
1066 run_test 24l "Renaming a file to itself ========================"
1067
1068 test_24m() {
1069         f="$DIR/f24m"
1070         $MULTIOP $f OcLN ${f}2 ${f}2 || error "link ${f}2 ${f}2 failed"
1071         # on ext3 this does not remove either the source or target files
1072         # though the "expected" operation would be to remove the source
1073         $CHECKSTAT -t file ${f} || error "${f} missing"
1074         $CHECKSTAT -t file ${f}2 || error "${f}2 missing"
1075 }
1076 run_test 24m "Renaming a file to a hard link to itself ========="
1077
1078 test_24n() {
1079     f="$DIR/f24n"
1080     # this stats the old file after it was renamed, so it should fail
1081     touch ${f}
1082     $CHECKSTAT ${f} || error "${f} missing"
1083     mv ${f} ${f}.rename
1084     $CHECKSTAT ${f}.rename || error "${f}.rename missing"
1085     $CHECKSTAT -a ${f} || error "${f} exists"
1086 }
1087 run_test 24n "Statting the old file after renaming (Posix rename 2)"
1088
1089 test_24o() {
1090         test_mkdir $DIR/$tdir
1091         rename_many -s random -v -n 10 $DIR/$tdir
1092 }
1093 run_test 24o "rename of files during htree split"
1094
1095 test_24p() {
1096         test_mkdir $DIR/R12a
1097         test_mkdir $DIR/R12b
1098         DIRINO=`ls -lid $DIR/R12a | awk '{ print $1 }'`
1099         mrename $DIR/R12a $DIR/R12b
1100         $CHECKSTAT -a $DIR/R12a || error "$DIR/R12a exists"
1101         $CHECKSTAT -t dir $DIR/R12b || error "$DIR/R12b not dir type"
1102         DIRINO2=`ls -lid $DIR/R12b | awk '{ print $1 }'`
1103         [ "$DIRINO" = "$DIRINO2" ] || error "R12a $DIRINO != R12b $DIRINO2"
1104 }
1105 run_test 24p "mkdir .../R12{a,b}; rename .../R12a .../R12b"
1106
1107 cleanup_multiop_pause() {
1108         trap 0
1109         kill -USR1 $MULTIPID
1110 }
1111
1112 test_24q() {
1113         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1114
1115         test_mkdir $DIR/R13a
1116         test_mkdir $DIR/R13b
1117         local DIRINO=$(ls -lid $DIR/R13a | awk '{ print $1 }')
1118         multiop_bg_pause $DIR/R13b D_c || error "multiop failed to start"
1119         MULTIPID=$!
1120
1121         trap cleanup_multiop_pause EXIT
1122         mrename $DIR/R13a $DIR/R13b
1123         $CHECKSTAT -a $DIR/R13a || error "R13a still exists"
1124         $CHECKSTAT -t dir $DIR/R13b || error "R13b does not exist"
1125         local DIRINO2=$(ls -lid $DIR/R13b | awk '{ print $1 }')
1126         [ "$DIRINO" = "$DIRINO2" ] || error "R13a $DIRINO != R13b $DIRINO2"
1127         cleanup_multiop_pause
1128         wait $MULTIPID || error "multiop close failed"
1129 }
1130 run_test 24q "mkdir .../R13{a,b}; open R13b rename R13a R13b ==="
1131
1132 test_24r() { #bug 3789
1133         test_mkdir $DIR/R14a
1134         test_mkdir $DIR/R14a/b
1135         mrename $DIR/R14a $DIR/R14a/b && error "rename to subdir worked!"
1136         $CHECKSTAT -t dir $DIR/R14a || error "$DIR/R14a missing"
1137         $CHECKSTAT -t dir $DIR/R14a/b || error "$DIR/R14a/b missing"
1138 }
1139 run_test 24r "mkdir .../R14a/b; rename .../R14a .../R14a/b ====="
1140
1141 test_24s() {
1142         test_mkdir $DIR/R15a
1143         test_mkdir $DIR/R15a/b
1144         test_mkdir $DIR/R15a/b/c
1145         mrename $DIR/R15a $DIR/R15a/b/c && error "rename to sub-subdir worked!"
1146         $CHECKSTAT -t dir $DIR/R15a || error "$DIR/R15a missing"
1147         $CHECKSTAT -t dir $DIR/R15a/b/c || error "$DIR/R15a/b/c missing"
1148 }
1149 run_test 24s "mkdir .../R15a/b/c; rename .../R15a .../R15a/b/c ="
1150
1151 test_24t() {
1152         test_mkdir $DIR/R16a
1153         test_mkdir $DIR/R16a/b
1154         test_mkdir $DIR/R16a/b/c
1155         mrename $DIR/R16a/b/c $DIR/R16a && error "rename to sub-subdir worked!"
1156         $CHECKSTAT -t dir $DIR/R16a || error "$DIR/R16a missing"
1157         $CHECKSTAT -t dir $DIR/R16a/b/c || error "$DIR/R16a/b/c missing"
1158 }
1159 run_test 24t "mkdir .../R16a/b/c; rename .../R16a/b/c .../R16a ="
1160
1161 test_24u() { # bug12192
1162         $MULTIOP $DIR/$tfile C2w$((2048 * 1024))c || error "multiop failed"
1163         $CHECKSTAT -s $((2048 * 1024)) $DIR/$tfile || error "wrong file size"
1164 }
1165 run_test 24u "create stripe file"
1166
1167 simple_cleanup_common() {
1168         local createmany=$1
1169         local rc=0
1170
1171         [[ -z "$DIR" || -z "$tdir" || ! -d "$DIR/$tdir" ]] && return 0
1172
1173         local start=$SECONDS
1174
1175         [[ -n "$createmany" ]] && unlinkmany $DIR/$tdir/$tfile $createmany
1176         rm -rf $DIR/$tdir || error "cleanup $DIR/$tdir failed"
1177         rc=$?
1178         wait_delete_completed
1179         echo "cleanup time $((SECONDS - start))"
1180         return $rc
1181 }
1182
1183 max_pages_per_rpc() {
1184         local mdtname="$(printf "MDT%04x" ${1:-0})"
1185         $LCTL get_param -n mdc.*$mdtname*.max_pages_per_rpc
1186 }
1187
1188 test_24v() {
1189         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1190
1191         local nrfiles=${COUNT:-100000}
1192         local fname="$DIR/$tdir/$tfile"
1193
1194         # Performance issue on ZFS see LU-4072 (c.f. LU-2887)
1195         [ "$mds1_FSTYPE" = "zfs" ] && nrfiles=${COUNT:-10000}
1196
1197         test_mkdir "$(dirname $fname)"
1198         # assume MDT0000 has the fewest inodes
1199         local stripes=$($LFS getdirstripe -c $(dirname $fname))
1200         local free_inodes=$(($(mdt_free_inodes 0) * ${stripes/#0/1}))
1201         [[ $free_inodes -lt $nrfiles ]] && nrfiles=$free_inodes
1202
1203         stack_trap "simple_cleanup_common $nrfiles"
1204
1205         createmany -m "$fname" $nrfiles
1206
1207         cancel_lru_locks mdc
1208         lctl set_param mdc.*.stats clear
1209
1210         # was previously test_24D: LU-6101
1211         # readdir() returns correct number of entries after cursor reload
1212         local num_ls=$(ls $DIR/$tdir | wc -l)
1213         local num_uniq=$(ls $DIR/$tdir | sort -u | wc -l)
1214         local num_all=$(ls -a $DIR/$tdir | wc -l)
1215         if [ $num_ls -ne $nrfiles ] || [ $num_uniq -ne $nrfiles ] ||
1216                 [ $num_all -ne $((nrfiles + 2)) ]; then
1217                         error "Expected $nrfiles files, got $num_ls " \
1218                                 "($num_uniq unique $num_all .&..)"
1219         fi
1220         # LU-5 large readdir
1221         # dirent_size = 32 bytes for sizeof(struct lu_dirent) +
1222         #               N bytes for name (len($nrfiles) rounded to 8 bytes) +
1223         #               8 bytes for luda_type (4 bytes rounded to 8 bytes)
1224         # take into account of overhead in lu_dirpage header and end mark in
1225         # each page, plus one in rpc_num calculation.
1226         local dirent_size=$((32 + (${#tfile} | 7) + 1 + 8))
1227         local page_entries=$(((PAGE_SIZE - 24) / dirent_size))
1228         local mdt_idx=$($LFS getdirstripe -i $(dirname $fname))
1229         local rpc_pages=$(max_pages_per_rpc $mdt_idx)
1230         local rpc_max=$((nrfiles / (page_entries * rpc_pages) + stripes))
1231         local mds_readpage=$(calc_stats mdc.*.stats mds_readpage)
1232         echo "readpages: $mds_readpage rpc_max: $rpc_max-2/+1"
1233         (( $mds_readpage >= $rpc_max - 2 && $mds_readpage <= $rpc_max + 1)) ||
1234                 error "large readdir doesn't take effect: " \
1235                       "$mds_readpage should be about $rpc_max"
1236 }
1237 run_test 24v "list large directory (test hash collision, b=17560)"
1238
1239 test_24w() { # bug21506
1240         SZ1=234852
1241         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=4096 || return 1
1242         dd if=/dev/zero bs=$SZ1 count=1 >> $DIR/$tfile || return 2
1243         dd if=$DIR/$tfile of=$DIR/${tfile}_left bs=1M skip=4097 || return 3
1244         SZ2=`ls -l $DIR/${tfile}_left | awk '{print $5}'`
1245         [[ "$SZ1" -eq "$SZ2" ]] ||
1246                 error "Error reading at the end of the file $tfile"
1247 }
1248 run_test 24w "Reading a file larger than 4Gb"
1249
1250 test_24x() {
1251         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1252         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1253         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1254                 skip "Need MDS version at least 2.7.56"
1255
1256         local MDTIDX=1
1257         local remote_dir=$DIR/$tdir/remote_dir
1258
1259         test_mkdir $DIR/$tdir
1260         $LFS mkdir -i $MDTIDX $remote_dir ||
1261                 error "create remote directory failed"
1262
1263         test_mkdir $DIR/$tdir/src_dir
1264         touch $DIR/$tdir/src_file
1265         test_mkdir $remote_dir/tgt_dir
1266         touch $remote_dir/tgt_file
1267
1268         mrename $DIR/$tdir/src_dir $remote_dir/tgt_dir ||
1269                 error "rename dir cross MDT failed!"
1270
1271         mrename $DIR/$tdir/src_file $remote_dir/tgt_file ||
1272                 error "rename file cross MDT failed!"
1273
1274         touch $DIR/$tdir/ln_file
1275         ln $DIR/$tdir/ln_file $remote_dir/ln_name ||
1276                 error "ln file cross MDT failed"
1277
1278         rm -rf $DIR/$tdir || error "Can not delete directories"
1279 }
1280 run_test 24x "cross MDT rename/link"
1281
1282 test_24y() {
1283         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1284         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1285
1286         local remote_dir=$DIR/$tdir/remote_dir
1287         local mdtidx=1
1288
1289         test_mkdir $DIR/$tdir
1290         $LFS mkdir -i $mdtidx $remote_dir ||
1291                 error "create remote directory failed"
1292
1293         test_mkdir $remote_dir/src_dir
1294         touch $remote_dir/src_file
1295         test_mkdir $remote_dir/tgt_dir
1296         touch $remote_dir/tgt_file
1297
1298         mrename $remote_dir/src_dir $remote_dir/tgt_dir ||
1299                 error "rename subdir in the same remote dir failed!"
1300
1301         mrename $remote_dir/src_file $remote_dir/tgt_file ||
1302                 error "rename files in the same remote dir failed!"
1303
1304         ln $remote_dir/tgt_file $remote_dir/tgt_file1 ||
1305                 error "link files in the same remote dir failed!"
1306
1307         rm -rf $DIR/$tdir || error "Can not delete directories"
1308 }
1309 run_test 24y "rename/link on the same dir should succeed"
1310
1311 test_24z() {
1312         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1313         [[ $MDS1_VERSION -lt $(version_code 2.12.51) ]] &&
1314                 skip "Need MDS version at least 2.12.51"
1315
1316         local index
1317
1318         for index in 0 1; do
1319                 $LFS mkdir -i $index $DIR/$tdir.$index || error "mkdir failed"
1320                 touch $DIR/$tdir.0/$tfile.$index || error "touch failed"
1321         done
1322
1323         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1 || error "mv $tfile.0 failed"
1324
1325         index=$($LFS getstripe -m $DIR/$tdir.1/$tfile.0)
1326         [ $index -eq 0 ] || error "$tfile.0 is on MDT$index"
1327
1328         local mdts=$(comma_list $(mdts_nodes))
1329
1330         do_nodes $mdts $LCTL set_param mdt.*.enable_remote_rename=0
1331         stack_trap "do_nodes $mdts $LCTL \
1332                 set_param mdt.*.enable_remote_rename=1" EXIT
1333
1334         mv $DIR/$tdir.0/$tfile.1 $DIR/$tdir.1 || error "mv $tfile.1 failed"
1335
1336         index=$($LFS getstripe -m $DIR/$tdir.1/$tfile.1)
1337         [ $index -eq 1 ] || error "$tfile.1 is on MDT$index"
1338 }
1339 run_test 24z "cross-MDT rename is done as cp"
1340
1341 test_24A() { # LU-3182
1342         local NFILES=5000
1343
1344         test_mkdir $DIR/$tdir
1345         stack_trap "simple_cleanup_common $NFILES"
1346         createmany -m $DIR/$tdir/$tfile $NFILES
1347         local t=$(ls $DIR/$tdir | wc -l)
1348         local u=$(ls $DIR/$tdir | sort -u | wc -l)
1349         local v=$(ls -ai $DIR/$tdir | sort -u | wc -l)
1350
1351         (( $t == $NFILES && $u == $NFILES && $v == NFILES + 2 )) ||
1352                 error "Expected $NFILES files, got $t ($u unique $v .&..)"
1353 }
1354 run_test 24A "readdir() returns correct number of entries."
1355
1356 test_24B() { # LU-4805
1357         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1358
1359         local count
1360
1361         test_mkdir $DIR/$tdir
1362         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
1363                 error "create striped dir failed"
1364
1365         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1366         [ $count -eq 2 ] || error "Expected 2, got $count"
1367
1368         touch $DIR/$tdir/striped_dir/a
1369
1370         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1371         [ $count -eq 3 ] || error "Expected 3, got $count"
1372
1373         touch $DIR/$tdir/striped_dir/.f
1374
1375         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1376         [ $count -eq 4 ] || error "Expected 4, got $count"
1377
1378         rm -rf $DIR/$tdir || error "Can not delete directories"
1379 }
1380 run_test 24B "readdir for striped dir return correct number of entries"
1381
1382 test_24C() {
1383         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1384
1385         mkdir $DIR/$tdir
1386         mkdir $DIR/$tdir/d0
1387         mkdir $DIR/$tdir/d1
1388
1389         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/d0/striped_dir ||
1390                 error "create striped dir failed"
1391
1392         cd $DIR/$tdir/d0/striped_dir
1393
1394         local d0_ino=$(ls -i -l -a $DIR/$tdir | grep "d0" | awk '{print $1}')
1395         local d1_ino=$(ls -i -l -a $DIR/$tdir | grep "d1" | awk '{print $1}')
1396         local parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1397
1398         [ "$d0_ino" = "$parent_ino" ] ||
1399                 error ".. wrong, expect $d0_ino, get $parent_ino"
1400
1401         mv $DIR/$tdir/d0/striped_dir $DIR/$tdir/d1/ ||
1402                 error "mv striped dir failed"
1403
1404         parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1405
1406         [ "$d1_ino" = "$parent_ino" ] ||
1407                 error ".. wrong after mv, expect $d1_ino, get $parent_ino"
1408 }
1409 run_test 24C "check .. in striped dir"
1410
1411 test_24E() {
1412         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
1413         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1414
1415         mkdir -p $DIR/$tdir
1416         mkdir $DIR/$tdir/src_dir
1417         $LFS mkdir -i 1 $DIR/$tdir/src_dir/src_child ||
1418                 error "create remote source failed"
1419
1420         touch $DIR/$tdir/src_dir/src_child/a
1421
1422         $LFS mkdir -i 2 $DIR/$tdir/tgt_dir ||
1423                 error "create remote target dir failed"
1424
1425         $LFS mkdir -i 3 $DIR/$tdir/tgt_dir/tgt_child ||
1426                 error "create remote target child failed"
1427
1428         mrename $DIR/$tdir/src_dir/src_child $DIR/$tdir/tgt_dir/tgt_child ||
1429                 error "rename dir cross MDT failed!"
1430
1431         find $DIR/$tdir
1432
1433         $CHECKSTAT -t dir $DIR/$tdir/src_dir/src_child &&
1434                 error "src_child still exists after rename"
1435
1436         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/tgt_child/a ||
1437                 error "missing file(a) after rename"
1438
1439         rm -rf $DIR/$tdir || error "Can not delete directories"
1440 }
1441 run_test 24E "cross MDT rename/link"
1442
1443 test_24F () {
1444         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
1445
1446         local repeats=1000
1447         [ "$SLOW" = "no" ] && repeats=100
1448
1449         mkdir -p $DIR/$tdir
1450
1451         echo "$repeats repeats"
1452         for ((i = 0; i < repeats; i++)); do
1453                 $LFS mkdir -i0 -c2 $DIR/$tdir/test || error "mkdir fails"
1454                 touch $DIR/$tdir/test/a || error "touch fails"
1455                 mkdir $DIR/$tdir/test/b || error "mkdir fails"
1456                 rm -rf $DIR/$tdir/test || error "rmdir fails"
1457         done
1458
1459         true
1460 }
1461 run_test 24F "hash order vs readdir (LU-11330)"
1462
1463 test_24G () {
1464         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
1465
1466         local ino1
1467         local ino2
1468
1469         $LFS mkdir -i 0 $DIR/$tdir-0 || error "mkdir $tdir-0"
1470         $LFS mkdir -i 1 $DIR/$tdir-1 || error "mkdir $tdir-1"
1471         touch $DIR/$tdir-0/f1 || error "touch f1"
1472         ln -s $DIR/$tdir-0/f1 $DIR/$tdir-0/s1 || error "ln s1"
1473         ino1=$(stat -c%i $DIR/$tdir-0/s1)
1474         mv $DIR/$tdir-0/s1 $DIR/$tdir-1 || error "mv s1"
1475         ino2=$(stat -c%i $DIR/$tdir-1/s1)
1476         [ $ino1 -ne $ino2 ] || error "s1 should be migrated"
1477 }
1478 run_test 24G "migrate symlink in rename"
1479
1480 test_24H() {
1481         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
1482         [[ $(hostname) != $(facet_active_host mds2) ]] ||
1483                 skip "MDT1 should be on another node"
1484
1485         test_mkdir -i 1 -c 1 $DIR/$tdir
1486 #define OBD_FAIL_FLD_QUERY_REQ           0x1103
1487         do_facet mds2 $LCTL set_param fail_loc=0x80001103
1488         touch $DIR/$tdir/$tfile || error "touch failed"
1489 }
1490 run_test 24H "repeat FLD_QUERY rpc"
1491
1492 test_25a() {
1493         echo '== symlink sanity ============================================='
1494
1495         test_mkdir $DIR/d25
1496         ln -s d25 $DIR/s25
1497         touch $DIR/s25/foo ||
1498                 error "File creation in symlinked directory failed"
1499 }
1500 run_test 25a "create file in symlinked directory ==============="
1501
1502 test_25b() {
1503         [ ! -d $DIR/d25 ] && test_25a
1504         $CHECKSTAT -t file $DIR/s25/foo || error "$DIR/s25/foo not file type"
1505 }
1506 run_test 25b "lookup file in symlinked directory ==============="
1507
1508 test_26a() {
1509         test_mkdir $DIR/d26
1510         test_mkdir $DIR/d26/d26-2
1511         ln -s d26/d26-2 $DIR/s26
1512         touch $DIR/s26/foo || error "File creation failed"
1513 }
1514 run_test 26a "multiple component symlink ======================="
1515
1516 test_26b() {
1517         test_mkdir -p $DIR/$tdir/d26-2
1518         ln -s $tdir/d26-2/foo $DIR/s26-2
1519         touch $DIR/s26-2 || error "File creation failed"
1520 }
1521 run_test 26b "multiple component symlink at end of lookup ======"
1522
1523 test_26c() {
1524         test_mkdir $DIR/d26.2
1525         touch $DIR/d26.2/foo
1526         ln -s d26.2 $DIR/s26.2-1
1527         ln -s s26.2-1 $DIR/s26.2-2
1528         ln -s s26.2-2 $DIR/s26.2-3
1529         chmod 0666 $DIR/s26.2-3/foo
1530 }
1531 run_test 26c "chain of symlinks"
1532
1533 # recursive symlinks (bug 439)
1534 test_26d() {
1535         ln -s d26-3/foo $DIR/d26-3
1536 }
1537 run_test 26d "create multiple component recursive symlink"
1538
1539 test_26e() {
1540         [ ! -h $DIR/d26-3 ] && test_26d
1541         rm $DIR/d26-3
1542 }
1543 run_test 26e "unlink multiple component recursive symlink"
1544
1545 # recursive symlinks (bug 7022)
1546 test_26f() {
1547         test_mkdir $DIR/$tdir
1548         test_mkdir $DIR/$tdir/$tfile
1549         cd $DIR/$tdir/$tfile           || error "cd $DIR/$tdir/$tfile failed"
1550         test_mkdir -p lndir/bar1
1551         test_mkdir $DIR/$tdir/$tfile/$tfile
1552         cd $tfile                || error "cd $tfile failed"
1553         ln -s .. dotdot          || error "ln dotdot failed"
1554         ln -s dotdot/lndir lndir || error "ln lndir failed"
1555         cd $DIR/$tdir                 || error "cd $DIR/$tdir failed"
1556         output=`ls $tfile/$tfile/lndir/bar1`
1557         [ "$output" = bar1 ] && error "unexpected output"
1558         rm -r $tfile             || error "rm $tfile failed"
1559         $CHECKSTAT -a $DIR/$tfile || error "$tfile not gone"
1560 }
1561 run_test 26f "rm -r of a directory which has recursive symlink"
1562
1563 test_27a() {
1564         test_mkdir $DIR/$tdir
1565         $LFS getstripe $DIR/$tdir
1566         $LFS setstripe -c 1 $DIR/$tdir/$tfile || error "setstripe failed"
1567         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1568         cp /etc/hosts $DIR/$tdir/$tfile || error "Can't copy to one stripe file"
1569 }
1570 run_test 27a "one stripe file"
1571
1572 test_27b() {
1573         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1574
1575         test_mkdir $DIR/$tdir
1576         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1577         $LFS getstripe -c $DIR/$tdir/$tfile
1578         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
1579                 error "two-stripe file doesn't have two stripes"
1580
1581         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1582 }
1583 run_test 27b "create and write to two stripe file"
1584
1585 # 27c family tests specific striping, setstripe -o
1586 test_27ca() {
1587         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1588         test_mkdir -p $DIR/$tdir
1589         local osts="1"
1590
1591         $LFS setstripe -o $osts $DIR/$tdir/$tfile  || error "setstripe failed"
1592         $LFS getstripe -i $DIR/$tdir/$tfile
1593         [ $($LFS getstripe -i $DIR/$tdir/$tfile ) -eq $osts ] ||
1594                 error "stripe not on specified OST"
1595
1596         dd if=/dev/zero of=$DIR/$tdir/$tfile  bs=1M count=4 || error "dd failed"
1597 }
1598 run_test 27ca "one stripe on specified OST"
1599
1600 test_27cb() {
1601         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1602         test_mkdir -p $DIR/$tdir
1603         local osts="1,0"
1604         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1605         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1606         echo "$getstripe"
1607
1608         # Strip getstripe output to a space separated list of OSTs
1609         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1610                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1611         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1612                 error "stripes not on specified OSTs"
1613
1614         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1615 }
1616 run_test 27cb "two stripes on specified OSTs"
1617
1618 test_27cc() {
1619         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1620         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1621                 skip "server does not support overstriping"
1622
1623         test_mkdir -p $DIR/$tdir
1624         local osts="0,0"
1625         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1626         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1627         echo "$getstripe"
1628
1629         # Strip getstripe output to a space separated list of OSTs
1630         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1631                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1632         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1633                 error "stripes not on specified OSTs"
1634
1635         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1636 }
1637 run_test 27cc "two stripes on the same OST"
1638
1639 test_27cd() {
1640         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1641         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1642                 skip "server does not support overstriping"
1643         test_mkdir -p $DIR/$tdir
1644         local osts="0,1,1,0"
1645         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1646         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1647         echo "$getstripe"
1648
1649         # Strip getstripe output to a space separated list of OSTs
1650         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1651                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1652         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1653                 error "stripes not on specified OSTs"
1654
1655         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1656 }
1657 run_test 27cd "four stripes on two OSTs"
1658
1659 test_27ce() {
1660         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
1661                 skip_env "too many osts, skipping"
1662         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1663                 skip "server does not support overstriping"
1664         # We do one more stripe than we have OSTs
1665         [ $OSTCOUNT -lt 159 ] || large_xattr_enabled ||
1666                 skip_env "ea_inode feature disabled"
1667
1668         test_mkdir -p $DIR/$tdir
1669         local osts=""
1670         for i in $(seq 0 $OSTCOUNT);
1671         do
1672                 osts=$osts"0"
1673                 if [ $i -ne $OSTCOUNT ]; then
1674                         osts=$osts","
1675                 fi
1676         done
1677         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1678         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1679         echo "$getstripe"
1680
1681         # Strip getstripe output to a space separated list of OSTs
1682         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1683                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1684         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1685                 error "stripes not on specified OSTs"
1686
1687         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1688 }
1689 run_test 27ce "more stripes than OSTs with -o"
1690
1691 test_27cf() {
1692         local osp_proc="osp.$FSNAME-OST0000-osc-MDT000*.active"
1693         local pid=0
1694
1695         test_mkdir -p $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
1696         do_facet $SINGLEMDS "$LCTL set_param -n $osp_proc=0"
1697         stack_trap "do_facet $SINGLEMDS $LCTL set_param -n $osp_proc=1" EXIT
1698         wait_update_facet $SINGLEMDS "$LCTL get_param -n $osp_proc | grep 1" ||
1699                 error "failed to set $osp_proc=0"
1700
1701         $LFS setstripe -o 0 $DIR/$tdir/$tfile &
1702         pid=$!
1703         sleep 1
1704         do_facet $SINGLEMDS "$LCTL set_param -n $osp_proc=1"
1705         wait_update_facet $SINGLEMDS "$LCTL get_param -n $osp_proc | grep 0" ||
1706                 error "failed to set $osp_proc=1"
1707         wait $pid
1708         [[ $pid -ne 0 ]] ||
1709                 error "should return error due to $osp_proc=0"
1710 }
1711 run_test 27cf "'setstripe -o' on inactive OSTs should return error"
1712
1713 test_27d() {
1714         test_mkdir $DIR/$tdir
1715         $LFS setstripe -c 0 -i -1 -S 0 $DIR/$tdir/$tfile ||
1716                 error "setstripe failed"
1717         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1718         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1719 }
1720 run_test 27d "create file with default settings"
1721
1722 test_27e() {
1723         # LU-5839 adds check for existed layout before setting it
1724         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1725                 skip "Need MDS version at least 2.7.56"
1726
1727         test_mkdir $DIR/$tdir
1728         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1729         $LFS setstripe -c 2 $DIR/$tdir/$tfile && error "setstripe worked twice"
1730         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1731 }
1732 run_test 27e "setstripe existing file (should return error)"
1733
1734 test_27f() {
1735         test_mkdir $DIR/$tdir
1736         $LFS setstripe -S 100 -i 0 -c 1 $DIR/$tdir/$tfile &&
1737                 error "$LFS setstripe $DIR/$tdir/$tfile failed"
1738         $CHECKSTAT -t file $DIR/$tdir/$tfile &&
1739                 error "$CHECKSTAT -t file $DIR/$tdir/$tfile should fail"
1740         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1741         $LFS getstripe $DIR/$tdir/$tfile || error "$LFS getstripe failed"
1742 }
1743 run_test 27f "setstripe with bad stripe size (should return error)"
1744
1745 test_27g() {
1746         test_mkdir $DIR/$tdir
1747         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1748         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "no stripe info" ||
1749                 error "$DIR/$tdir/$tfile has object"
1750 }
1751 run_test 27g "$LFS getstripe with no objects"
1752
1753 test_27ga() {
1754         test_mkdir $DIR/$tdir
1755         touch $DIR/$tdir/$tfile || error "touch failed"
1756         ln -s bogus $DIR/$tdir/$tfile.2 || error "ln failed"
1757         $LFS getstripe -m $DIR/$tdir/$tfile $DIR/$tdir/$tfile.2
1758         local rc=$?
1759         (( rc == 2 )) || error "getstripe did not return ENOENT"
1760 }
1761 run_test 27ga "$LFS getstripe with missing file (should return error)"
1762
1763 test_27i() {
1764         test_mkdir $DIR/$tdir
1765         touch $DIR/$tdir/$tfile || error "touch failed"
1766         [[ $($LFS getstripe -c $DIR/$tdir/$tfile) -gt 0 ]] ||
1767                 error "missing objects"
1768 }
1769 run_test 27i "$LFS getstripe with some objects"
1770
1771 test_27j() {
1772         test_mkdir $DIR/$tdir
1773         $LFS setstripe -i $OSTCOUNT $DIR/$tdir/$tfile &&
1774                 error "setstripe failed" || true
1775 }
1776 run_test 27j "setstripe with bad stripe offset (should return error)"
1777
1778 test_27k() { # bug 2844
1779         test_mkdir $DIR/$tdir
1780         local file=$DIR/$tdir/$tfile
1781         local ll_max_blksize=$((4 * 1024 * 1024))
1782         $LFS setstripe -S 67108864 $file || error "setstripe failed"
1783         local blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1784         [ $blksize -le $ll_max_blksize ] || error "1:$blksize > $ll_max_blksize"
1785         dd if=/dev/zero of=$file bs=4k count=1
1786         blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1787         [ $blksize -le $ll_max_blksize ] || error "2:$blksize > $ll_max_blksize"
1788 }
1789 run_test 27k "limit i_blksize for broken user apps"
1790
1791 test_27l() {
1792         mcreate $DIR/$tfile || error "creating file"
1793         $RUNAS $LFS setstripe -c 1 $DIR/$tfile &&
1794                 error "setstripe should have failed" || true
1795 }
1796 run_test 27l "check setstripe permissions (should return error)"
1797
1798 test_27m() {
1799         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1800
1801         [ -n "$RCLIENTS" -o -n "$MOUNT_2" ] &&
1802                 skip_env "multiple clients -- skipping"
1803
1804         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
1805                    head -n1)
1806         if [[ $ORIGFREE -gt $MAXFREE ]]; then
1807                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
1808         fi
1809         stack_trap simple_cleanup_common
1810         test_mkdir $DIR/$tdir
1811         $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.1
1812         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1024 count=$MAXFREE &&
1813                 error "dd should fill OST0"
1814         i=2
1815         while $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.$i; do
1816                 i=$((i + 1))
1817                 [ $i -gt 256 ] && break
1818         done
1819         i=$((i + 1))
1820         touch $DIR/$tdir/$tfile.$i
1821         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1822             awk '{print $1}'| grep -w "0") ] &&
1823                 error "OST0 was full but new created file still use it"
1824         i=$((i + 1))
1825         touch $DIR/$tdir/$tfile.$i
1826         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1827             awk '{print $1}'| grep -w "0") ] &&
1828                 error "OST0 was full but new created file still use it" || true
1829 }
1830 run_test 27m "create file while OST0 was full"
1831
1832 # OSCs keep a NOSPC flag that will be reset after ~5s (qos_maxage)
1833 # if the OST isn't full anymore.
1834 reset_enospc() {
1835         local ostidx=${1:-""}
1836         local delay
1837         local ready
1838         local get_prealloc
1839
1840         local list=$(comma_list $(osts_nodes))
1841         [ "$ostidx" ] && list=$(facet_host ost$((ostidx + 1)))
1842
1843         do_nodes $list lctl set_param fail_loc=0
1844         wait_delete_completed   # initiate all OST_DESTROYs from MDS to OST
1845         delay=$(do_facet $SINGLEMDS lctl get_param -n lov.*.qos_maxage |
1846                 awk '{print $1 * 2;exit;}')
1847         get_prealloc="$LCTL get_param -n osc.*MDT*.prealloc_status |
1848                         grep -v \"^0$\""
1849         wait_update_facet $SINGLEMDS "$get_prealloc" "" $delay
1850 }
1851
1852 test_27n() {
1853         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1854         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1855         remote_mds_nodsh && skip "remote MDS with nodsh"
1856         remote_ost_nodsh && skip "remote OST with nodsh"
1857
1858         reset_enospc
1859         rm -f $DIR/$tdir/$tfile
1860         exhaust_precreations 0 0x80000215
1861         $LFS setstripe -c -1 $DIR/$tdir || error "setstripe failed"
1862         touch $DIR/$tdir/$tfile || error "touch failed"
1863         $LFS getstripe $DIR/$tdir/$tfile
1864         reset_enospc
1865 }
1866 run_test 27n "create file with some full OSTs"
1867
1868 test_27o() {
1869         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1870         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1871         remote_mds_nodsh && skip "remote MDS with nodsh"
1872         remote_ost_nodsh && skip "remote OST with nodsh"
1873
1874         reset_enospc
1875         rm -f $DIR/$tdir/$tfile
1876         exhaust_all_precreations 0x215
1877
1878         touch $DIR/$tdir/$tfile && error "able to create $DIR/$tdir/$tfile"
1879
1880         reset_enospc
1881         rm -rf $DIR/$tdir/*
1882 }
1883 run_test 27o "create file with all full OSTs (should error)"
1884
1885 function create_and_checktime() {
1886         local fname=$1
1887         local loops=$2
1888         local i
1889
1890         for ((i=0; i < $loops; i++)); do
1891                 local start=$SECONDS
1892                 multiop $fname-$i Oc
1893                 ((SECONDS-start < TIMEOUT)) ||
1894                         error "creation took " $((SECONDS-$start)) && return 1
1895         done
1896 }
1897
1898 test_27oo() {
1899         local mdts=$(comma_list $(mdts_nodes))
1900
1901         [ $MDS1_VERSION -lt $(version_code 2.13.57) ] &&
1902                 skip "Need MDS version at least 2.13.57"
1903
1904         local f0=$DIR/${tfile}-0
1905         local f1=$DIR/${tfile}-1
1906
1907         wait_delete_completed
1908
1909         # refill precreated objects
1910         $LFS setstripe -i0 -c1 $f0
1911
1912         saved=$(do_facet mds1 $LCTL get_param -n lov.*0000*.qos_threshold_rr)
1913         # force QoS allocation policy
1914         do_nodes $mdts $LCTL set_param lov.*.qos_threshold_rr=0%
1915         stack_trap "do_nodes $mdts $LCTL set_param \
1916                 lov.*.qos_threshold_rr=$saved" EXIT
1917         sleep_maxage
1918
1919         # one OST is unavailable, but still have few objects preallocated
1920         stop ost1
1921         stack_trap "start ost1 $(ostdevname 1) $OST_MOUNT_OPTS; \
1922                 rm -rf $f1 $DIR/$tdir*" EXIT
1923
1924         for ((i=0; i < 7; i++)); do
1925                 mkdir $DIR/$tdir$i || error "can't create dir"
1926                 $LFS setstripe -c$((OSTCOUNT-1)) $DIR/$tdir$i ||
1927                         error "can't set striping"
1928         done
1929         for ((i=0; i < 7; i++)); do
1930                 create_and_checktime $DIR/$tdir$i/$tfile 100 &
1931         done
1932         wait
1933 }
1934 run_test 27oo "don't let few threads to reserve too many objects"
1935
1936 test_27p() {
1937         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1938         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1939         remote_mds_nodsh && skip "remote MDS with nodsh"
1940         remote_ost_nodsh && skip "remote OST with nodsh"
1941
1942         reset_enospc
1943         rm -f $DIR/$tdir/$tfile
1944         test_mkdir $DIR/$tdir
1945
1946         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1947         $TRUNCATE $DIR/$tdir/$tfile 80000000 || error "truncate failed"
1948         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
1949
1950         exhaust_precreations 0 0x80000215
1951         echo foo >> $DIR/$tdir/$tfile || error "append failed"
1952         $CHECKSTAT -s 80000004 $DIR/$tdir/$tfile || error "checkstat failed"
1953         $LFS getstripe $DIR/$tdir/$tfile
1954
1955         reset_enospc
1956 }
1957 run_test 27p "append to a truncated file with some full OSTs"
1958
1959 test_27q() {
1960         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1961         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1962         remote_mds_nodsh && skip "remote MDS with nodsh"
1963         remote_ost_nodsh && skip "remote OST with nodsh"
1964
1965         reset_enospc
1966         rm -f $DIR/$tdir/$tfile
1967
1968         mkdir_on_mdt0 $DIR/$tdir
1969         $MCREATE $DIR/$tdir/$tfile || error "mcreate $DIR/$tdir/$tfile failed"
1970         $TRUNCATE $DIR/$tdir/$tfile 80000000 ||
1971                 error "truncate $DIR/$tdir/$tfile failed"
1972         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
1973
1974         exhaust_all_precreations 0x215
1975
1976         echo foo >> $DIR/$tdir/$tfile && error "append succeeded"
1977         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat 2 failed"
1978
1979         reset_enospc
1980 }
1981 run_test 27q "append to truncated file with all OSTs full (should error)"
1982
1983 test_27r() {
1984         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1985         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1986         remote_mds_nodsh && skip "remote MDS with nodsh"
1987         remote_ost_nodsh && skip "remote OST with nodsh"
1988
1989         reset_enospc
1990         rm -f $DIR/$tdir/$tfile
1991         exhaust_precreations 0 0x80000215
1992
1993         $LFS setstripe -i 0 -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1994
1995         reset_enospc
1996 }
1997 run_test 27r "stripe file with some full OSTs (shouldn't LBUG) ="
1998
1999 test_27s() { # bug 10725
2000         test_mkdir $DIR/$tdir
2001         local stripe_size=$((4096 * 1024 * 1024))       # 2^32
2002         local stripe_count=0
2003         [ $OSTCOUNT -eq 1 ] || stripe_count=2
2004         $LFS setstripe -S $stripe_size -c $stripe_count $DIR/$tdir &&
2005                 error "stripe width >= 2^32 succeeded" || true
2006
2007 }
2008 run_test 27s "lsm_xfersize overflow (should error) (bug 10725)"
2009
2010 test_27t() { # bug 10864
2011         WDIR=$(pwd)
2012         WLFS=$(which lfs)
2013         cd $DIR
2014         touch $tfile
2015         $WLFS getstripe $tfile
2016         cd $WDIR
2017 }
2018 run_test 27t "check that utils parse path correctly"
2019
2020 test_27u() { # bug 4900
2021         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2022         remote_mds_nodsh && skip "remote MDS with nodsh"
2023
2024         local index
2025         local list=$(comma_list $(mdts_nodes))
2026
2027 #define OBD_FAIL_MDS_OSC_PRECREATE      0x139
2028         do_nodes $list $LCTL set_param fail_loc=0x139
2029         test_mkdir -p $DIR/$tdir
2030         stack_trap "simple_cleanup_common 1000"
2031         createmany -o $DIR/$tdir/$tfile 1000
2032         do_nodes $list $LCTL set_param fail_loc=0
2033
2034         TLOG=$TMP/$tfile.getstripe
2035         $LFS getstripe $DIR/$tdir > $TLOG
2036         OBJS=$(awk -vobj=0 '($1 == 0) { obj += 1 } END { print obj; }' $TLOG)
2037         [[ $OBJS -gt 0 ]] &&
2038                 error "$OBJS objects created on OST-0. See $TLOG" ||
2039                 rm -f $TLOG
2040 }
2041 run_test 27u "skip object creation on OSC w/o objects"
2042
2043 test_27v() { # bug 4900
2044         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2045         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2046         remote_mds_nodsh && skip "remote MDS with nodsh"
2047         remote_ost_nodsh && skip "remote OST with nodsh"
2048
2049         exhaust_all_precreations 0x215
2050         reset_enospc
2051
2052         $LFS setstripe -c 1 $DIR/$tdir         # 1 stripe / file
2053
2054         touch $DIR/$tdir/$tfile
2055         #define OBD_FAIL_TGT_DELAY_PRECREATE     0x705
2056         # all except ost1
2057         for (( i=1; i < OSTCOUNT; i++ )); do
2058                 do_facet ost$i lctl set_param fail_loc=0x705
2059         done
2060         local START=`date +%s`
2061         createmany -o $DIR/$tdir/$tfile 32
2062
2063         local FINISH=`date +%s`
2064         local TIMEOUT=`lctl get_param -n timeout`
2065         local PROCESS=$((FINISH - START))
2066         [ $PROCESS -ge $((TIMEOUT / 2)) ] && \
2067                error "$FINISH - $START >= $TIMEOUT / 2"
2068         sleep $((TIMEOUT / 2 - PROCESS))
2069         reset_enospc
2070 }
2071 run_test 27v "skip object creation on slow OST"
2072
2073 test_27w() { # bug 10997
2074         test_mkdir $DIR/$tdir
2075         $LFS setstripe -S 65536 $DIR/$tdir/f0 || error "setstripe failed"
2076         [ $($LFS getstripe -S $DIR/$tdir/f0) -ne 65536 ] &&
2077                 error "stripe size $size != 65536" || true
2078         [ $($LFS getstripe -d $DIR/$tdir | grep -c "stripe_count") -eq 0 ] &&
2079                 error "$LFS getstripe -d $DIR/$tdir no 'stripe_count'" || true
2080 }
2081 run_test 27w "check $LFS setstripe -S and getstrip -d options"
2082
2083 test_27wa() {
2084         [[ $OSTCOUNT -lt 2 ]] &&
2085                 skip_env "skipping multiple stripe count/offset test"
2086
2087         test_mkdir $DIR/$tdir
2088         for i in $(seq 1 $OSTCOUNT); do
2089                 offset=$((i - 1))
2090                 $LFS setstripe -c $i -i $offset $DIR/$tdir/f$i ||
2091                         error "setstripe -c $i -i $offset failed"
2092                 count=$($LFS getstripe -c $DIR/$tdir/f$i)
2093                 index=$($LFS getstripe -i $DIR/$tdir/f$i)
2094                 [ $count -ne $i ] && error "stripe count $count != $i" || true
2095                 [ $index -ne $offset ] &&
2096                         error "stripe offset $index != $offset" || true
2097         done
2098 }
2099 run_test 27wa "check $LFS setstripe -c -i options"
2100
2101 test_27x() {
2102         remote_ost_nodsh && skip "remote OST with nodsh"
2103         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2104         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2105
2106         OFFSET=$(($OSTCOUNT - 1))
2107         OSTIDX=0
2108         local OST=$(ostname_from_index $OSTIDX)
2109
2110         test_mkdir $DIR/$tdir
2111         $LFS setstripe -c 1 $DIR/$tdir  # 1 stripe per file
2112         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 1
2113         sleep_maxage
2114         createmany -o $DIR/$tdir/$tfile $OSTCOUNT
2115         for i in $(seq 0 $OFFSET); do
2116                 [ $($LFS getstripe $DIR/$tdir/$tfile$i | grep -A 10 obdidx |
2117                         awk '{print $1}' | grep -w "$OSTIDX") ] &&
2118                 error "OST0 was degraded but new created file still use it"
2119         done
2120         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 0
2121 }
2122 run_test 27x "create files while OST0 is degraded"
2123
2124 test_27y() {
2125         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2126         remote_mds_nodsh && skip "remote MDS with nodsh"
2127         remote_ost_nodsh && skip "remote OST with nodsh"
2128         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2129
2130         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS $FSNAME-OST0000)
2131         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
2132                 osp.$mdtosc.prealloc_last_id)
2133         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
2134                 osp.$mdtosc.prealloc_next_id)
2135         local fcount=$((last_id - next_id))
2136         [[ $fcount -eq 0 ]] && skip "not enough space on OST0"
2137         [[ $fcount -gt $OSTCOUNT ]] && fcount=$OSTCOUNT
2138
2139         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
2140                          awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
2141         local OST_DEACTIVE_IDX=-1
2142         local OSC
2143         local OSTIDX
2144         local OST
2145
2146         for OSC in $MDS_OSCS; do
2147                 OST=$(osc_to_ost $OSC)
2148                 OSTIDX=$(index_from_ostuuid $OST)
2149                 if [ $OST_DEACTIVE_IDX == -1 ]; then
2150                         OST_DEACTIVE_IDX=$OSTIDX
2151                 fi
2152                 if [ $OSTIDX != $OST_DEACTIVE_IDX ]; then
2153                         echo $OSC "is Deactivated:"
2154                         do_facet $SINGLEMDS lctl --device  %$OSC deactivate
2155                 fi
2156         done
2157
2158         OSTIDX=$(index_from_ostuuid $OST)
2159         test_mkdir $DIR/$tdir
2160         $LFS setstripe -c 1 $DIR/$tdir      # 1 stripe / file
2161
2162         for OSC in $MDS_OSCS; do
2163                 OST=$(osc_to_ost $OSC)
2164                 OSTIDX=$(index_from_ostuuid $OST)
2165                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2166                         echo $OST "is degraded:"
2167                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2168                                                 obdfilter.$OST.degraded=1
2169                 fi
2170         done
2171
2172         sleep_maxage
2173         createmany -o $DIR/$tdir/$tfile $fcount
2174
2175         for OSC in $MDS_OSCS; do
2176                 OST=$(osc_to_ost $OSC)
2177                 OSTIDX=$(index_from_ostuuid $OST)
2178                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2179                         echo $OST "is recovered from degraded:"
2180                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2181                                                 obdfilter.$OST.degraded=0
2182                 else
2183                         do_facet $SINGLEMDS lctl --device %$OSC activate
2184                 fi
2185         done
2186
2187         # all osp devices get activated, hence -1 stripe count restored
2188         local stripe_count=0
2189
2190         # sleep 2*lod_qos_maxage seconds waiting for lod qos to notice osp
2191         # devices get activated.
2192         sleep_maxage
2193         $LFS setstripe -c -1 $DIR/$tfile
2194         stripe_count=$($LFS getstripe -c $DIR/$tfile)
2195         rm -f $DIR/$tfile
2196         [ $stripe_count -ne $OSTCOUNT ] &&
2197                 error "Of $OSTCOUNT OSTs, only $stripe_count is available"
2198         return 0
2199 }
2200 run_test 27y "create files while OST0 is degraded and the rest inactive"
2201
2202 check_seq_oid()
2203 {
2204         log "check file $1"
2205
2206         lmm_count=$($LFS getstripe -c $1)
2207         lmm_seq=$($LFS getstripe -v $1 | awk '/lmm_seq/ { print $2 }')
2208         lmm_oid=$($LFS getstripe -v $1 | awk '/lmm_object_id/ { print $2 }')
2209
2210         local old_ifs="$IFS"
2211         IFS=$'[:]'
2212         fid=($($LFS path2fid $1))
2213         IFS="$old_ifs"
2214
2215         log "FID seq ${fid[1]}, oid ${fid[2]} ver ${fid[3]}"
2216         log "LOV seq $lmm_seq, oid $lmm_oid, count: $lmm_count"
2217
2218         # compare lmm_seq and lu_fid->f_seq
2219         [ $lmm_seq = ${fid[1]} ] || { error "SEQ mismatch"; return 1; }
2220         # compare lmm_object_id and lu_fid->oid
2221         [ $lmm_oid = ${fid[2]} ] || { error "OID mismatch"; return 2; }
2222
2223         # check the trusted.fid attribute of the OST objects of the file
2224         local have_obdidx=false
2225         local stripe_nr=0
2226         $LFS getstripe $1 | while read obdidx oid hex seq; do
2227                 # skip lines up to and including "obdidx"
2228                 [ -z "$obdidx" ] && break
2229                 [ "$obdidx" = "obdidx" ] && have_obdidx=true && continue
2230                 $have_obdidx || continue
2231
2232                 local ost=$((obdidx + 1))
2233                 local dev=$(ostdevname $ost)
2234                 local oid_hex
2235
2236                 log "want: stripe:$stripe_nr ost:$obdidx oid:$oid/$hex seq:$seq"
2237
2238                 seq=$(echo $seq | sed -e "s/^0x//g")
2239                 if [ $seq == 0 ] || [ $(facet_fstype ost$ost) == zfs ]; then
2240                         oid_hex=$(echo $oid)
2241                 else
2242                         oid_hex=$(echo $hex | sed -e "s/^0x//g")
2243                 fi
2244                 local obj_file="O/$seq/d$((oid %32))/$oid_hex"
2245
2246                 local ff=""
2247                 #
2248                 # Don't unmount/remount the OSTs if we don't need to do that.
2249                 # LU-2577 changes filter_fid to be smaller, so debugfs needs
2250                 # update too, until that use mount/ll_decode_filter_fid/mount.
2251                 # Re-enable when debugfs will understand new filter_fid.
2252                 #
2253                 if [ $(facet_fstype ost$ost) == ldiskfs ]; then
2254                         ff=$(do_facet ost$ost "$DEBUGFS -c -R 'stat $obj_file' \
2255                                 $dev 2>/dev/null" | grep "parent=")
2256                 fi
2257                 if [ -z "$ff" ]; then
2258                         stop ost$ost
2259                         mount_fstype ost$ost
2260                         ff=$(do_facet ost$ost $LL_DECODE_FILTER_FID \
2261                                 $(facet_mntpt ost$ost)/$obj_file)
2262                         unmount_fstype ost$ost
2263                         start ost$ost $dev $OST_MOUNT_OPTS
2264                         clients_up
2265                 fi
2266
2267                 [ -z "$ff" ] && error "$obj_file: no filter_fid info"
2268
2269                 echo "$ff" | sed -e 's#.*objid=#got: objid=#'
2270
2271                 # /mnt/O/0/d23/23: objid=23 seq=0 parent=[0x200000400:0x1e:0x1]
2272                 # fid: objid=23 seq=0 parent=[0x200000400:0x1e:0x0] stripe=1
2273                 #
2274                 # fid: parent=[0x200000400:0x1e:0x0] stripe=1 stripe_count=2 \
2275                 #       stripe_size=1048576 component_id=1 component_start=0 \
2276                 #       component_end=33554432
2277                 local ff_parent=$(sed -e 's/.*parent=.//' <<<$ff)
2278                 local ff_pseq=$(cut -d: -f1 <<<$ff_parent)
2279                 local ff_poid=$(cut -d: -f2 <<<$ff_parent)
2280                 local ff_pstripe
2281                 if grep -q 'stripe=' <<<$ff; then
2282                         ff_pstripe=$(sed -e 's/.*stripe=//' -e 's/ .*//' <<<$ff)
2283                 else
2284                         # $LL_DECODE_FILTER_FID does not print "stripe="; look
2285                         # into f_ver in this case.  See comment on ff_parent.
2286                         ff_pstripe=$(cut -d: -f3 <<<$ff_parent | sed -e 's/]//')
2287                 fi
2288
2289                 # compare lmm_seq and filter_fid->ff_parent.f_seq
2290                 [ $ff_pseq = $lmm_seq ] ||
2291                         error "FF parent SEQ $ff_pseq != $lmm_seq"
2292                 # compare lmm_object_id and filter_fid->ff_parent.f_oid
2293                 [ $ff_poid = $lmm_oid ] ||
2294                         error "FF parent OID $ff_poid != $lmm_oid"
2295                 (($ff_pstripe == $stripe_nr)) ||
2296                         error "FF stripe $ff_pstripe != $stripe_nr"
2297
2298                 stripe_nr=$((stripe_nr + 1))
2299                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2300                         continue
2301                 if grep -q 'stripe_count=' <<<$ff; then
2302                         local ff_scnt=$(sed -e 's/.*stripe_count=//' \
2303                                             -e 's/ .*//' <<<$ff)
2304                         [ $lmm_count = $ff_scnt ] ||
2305                                 error "FF stripe count $lmm_count != $ff_scnt"
2306                 fi
2307         done
2308 }
2309
2310 test_27z() {
2311         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2312         remote_ost_nodsh && skip "remote OST with nodsh"
2313
2314         test_mkdir $DIR/$tdir
2315         $LFS setstripe -c 1 -i 0 -S 64k $DIR/$tdir/$tfile-1 ||
2316                 { error "setstripe -c -1 failed"; return 1; }
2317         # We need to send a write to every object to get parent FID info set.
2318         # This _should_ also work for setattr, but does not currently.
2319         # touch $DIR/$tdir/$tfile-1 ||
2320         dd if=/dev/zero of=$DIR/$tdir/$tfile-1 bs=1M count=1 ||
2321                 { error "dd $tfile-1 failed"; return 2; }
2322         $LFS setstripe -c -1 -i $((OSTCOUNT - 1)) -S 1M $DIR/$tdir/$tfile-2 ||
2323                 { error "setstripe -c -1 failed"; return 3; }
2324         dd if=/dev/zero of=$DIR/$tdir/$tfile-2 bs=1M count=$OSTCOUNT ||
2325                 { error "dd $tfile-2 failed"; return 4; }
2326
2327         # make sure write RPCs have been sent to OSTs
2328         sync; sleep 5; sync
2329
2330         check_seq_oid $DIR/$tdir/$tfile-1 || return 5
2331         check_seq_oid $DIR/$tdir/$tfile-2 || return 6
2332 }
2333 run_test 27z "check SEQ/OID on the MDT and OST filesystems"
2334
2335 test_27A() { # b=19102
2336         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2337
2338         save_layout_restore_at_exit $MOUNT
2339         $LFS setstripe -c 0 -i -1 -S 0 $MOUNT
2340         wait_update $HOSTNAME "$LFS getstripe -c $MOUNT | sed 's/  *//g'" "1" 20 ||
2341                 error "stripe count $($LFS getstripe -c $MOUNT) != 1"
2342         local default_size=$($LFS getstripe -S $MOUNT)
2343         local default_offset=$($LFS getstripe -i $MOUNT)
2344         local dsize=$(do_facet $SINGLEMDS \
2345                 "$LCTL get_param -n lod.$(facet_svc $SINGLEMDS)*.stripesize")
2346         [ $default_size -eq $dsize ] ||
2347                 error "stripe size $default_size != $dsize"
2348         [ $default_offset -eq -1 ] ||
2349                 error "stripe offset $default_offset != -1"
2350 }
2351 run_test 27A "check filesystem-wide default LOV EA values"
2352
2353 test_27B() { # LU-2523
2354         test_mkdir $DIR/$tdir
2355         rm -f $DIR/$tdir/f0 $DIR/$tdir/f1
2356         touch $DIR/$tdir/f0
2357         # open f1 with O_LOV_DELAY_CREATE
2358         # rename f0 onto f1
2359         # call setstripe ioctl on open file descriptor for f1
2360         # close
2361         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:nB1c \
2362                 $DIR/$tdir/f0
2363
2364         rm -f $DIR/$tdir/f1
2365         # open f1 with O_LOV_DELAY_CREATE
2366         # unlink f1
2367         # call setstripe ioctl on open file descriptor for f1
2368         # close
2369         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:uB1c
2370
2371         # Allow multiop to fail in imitation of NFS's busted semantics.
2372         true
2373 }
2374 run_test 27B "call setstripe on open unlinked file/rename victim"
2375
2376 # 27C family tests full striping and overstriping
2377 test_27Ca() { #LU-2871
2378         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2379
2380         declare -a ost_idx
2381         local index
2382         local found
2383         local i
2384         local j
2385
2386         test_mkdir $DIR/$tdir
2387         cd $DIR/$tdir
2388         for i in $(seq 0 $((OSTCOUNT - 1))); do
2389                 # set stripe across all OSTs starting from OST$i
2390                 $LFS setstripe -i $i -c -1 $tfile$i
2391                 # get striping information
2392                 ost_idx=($($LFS getstripe $tfile$i |
2393                          tail -n $((OSTCOUNT + 1)) | awk '{print $1}'))
2394                 echo "OST Index: ${ost_idx[*]}"
2395
2396                 # check the layout
2397                 [ ${#ost_idx[@]} -eq $OSTCOUNT ] ||
2398                         error "${#ost_idx[@]} != $OSTCOUNT"
2399
2400                 for index in $(seq 0 $((OSTCOUNT - 1))); do
2401                         found=0
2402                         for j in "${ost_idx[@]}"; do
2403                                 if [ $index -eq $j ]; then
2404                                         found=1
2405                                         break
2406                                 fi
2407                         done
2408                         [ $found = 1 ] ||
2409                                 error "Can not find $index in ${ost_idx[*]}"
2410                 done
2411         done
2412 }
2413 run_test 27Ca "check full striping across all OSTs"
2414
2415 test_27Cb() {
2416         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2417                 skip "server does not support overstriping"
2418         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2419                 skip_env "too many osts, skipping"
2420
2421         test_mkdir -p $DIR/$tdir
2422         local setcount=$(($OSTCOUNT * 2))
2423         [ $setcount -lt 160 ] || large_xattr_enabled ||
2424                 skip_env "ea_inode feature disabled"
2425
2426         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2427                 error "setstripe failed"
2428
2429         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2430         [ $count -eq $setcount ] ||
2431                 error "stripe count $count, should be $setcount"
2432
2433         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2434                 error "overstriped should be set in pattern"
2435
2436         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2437                 error "dd failed"
2438 }
2439 run_test 27Cb "more stripes than OSTs with -C"
2440
2441 test_27Cc() {
2442         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2443                 skip "server does not support overstriping"
2444         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2445
2446         test_mkdir -p $DIR/$tdir
2447         local setcount=$(($OSTCOUNT - 1))
2448
2449         [ $setcount -lt 160 ] || large_xattr_enabled ||
2450                 skip_env "ea_inode feature disabled"
2451
2452         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2453                 error "setstripe failed"
2454
2455         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2456         [ $count -eq $setcount ] ||
2457                 error "stripe count $count, should be $setcount"
2458
2459         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" &&
2460                 error "overstriped should not be set in pattern"
2461
2462         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2463                 error "dd failed"
2464 }
2465 run_test 27Cc "fewer stripes than OSTs does not set overstriping"
2466
2467 test_27Cd() {
2468         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2469                 skip "server does not support overstriping"
2470         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2471         large_xattr_enabled || skip_env "ea_inode feature disabled"
2472
2473         test_mkdir -p $DIR/$tdir
2474         local setcount=$LOV_MAX_STRIPE_COUNT
2475
2476         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2477                 error "setstripe failed"
2478
2479         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2480         [ $count -eq $setcount ] ||
2481                 error "stripe count $count, should be $setcount"
2482
2483         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2484                 error "overstriped should be set in pattern"
2485
2486         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2487                 error "dd failed"
2488
2489         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2490 }
2491 run_test 27Cd "test maximum stripe count"
2492
2493 test_27Ce() {
2494         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2495                 skip "server does not support overstriping"
2496         test_mkdir -p $DIR/$tdir
2497
2498         pool_add $TESTNAME || error "Pool creation failed"
2499         pool_add_targets $TESTNAME 0 || error "pool_add_targets failed"
2500
2501         local setcount=8
2502
2503         $LFS setstripe  -C $setcount -p "$TESTNAME" $DIR/$tdir/$tfile ||
2504                 error "setstripe failed"
2505
2506         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2507         [ $count -eq $setcount ] ||
2508                 error "stripe count $count, should be $setcount"
2509
2510         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2511                 error "overstriped should be set in pattern"
2512
2513         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2514                 error "dd failed"
2515
2516         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2517 }
2518 run_test 27Ce "test pool with overstriping"
2519
2520 test_27Cf() {
2521         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2522                 skip "server does not support overstriping"
2523         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2524                 skip_env "too many osts, skipping"
2525
2526         test_mkdir -p $DIR/$tdir
2527
2528         local setcount=$(($OSTCOUNT * 2))
2529         [ $setcount -lt 160 ] || large_xattr_enabled ||
2530                 skip_env "ea_inode feature disabled"
2531
2532         $LFS setstripe  -C $setcount $DIR/$tdir/ ||
2533                 error "setstripe failed"
2534
2535         echo 1 > $DIR/$tdir/$tfile
2536
2537         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2538         [ $count -eq $setcount ] ||
2539                 error "stripe count $count, should be $setcount"
2540
2541         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2542                 error "overstriped should be set in pattern"
2543
2544         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2545                 error "dd failed"
2546
2547         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2548 }
2549 run_test 27Cf "test default inheritance with overstriping"
2550
2551 test_27D() {
2552         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2553         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2554         remote_mds_nodsh && skip "remote MDS with nodsh"
2555
2556         local POOL=${POOL:-testpool}
2557         local first_ost=0
2558         local last_ost=$(($OSTCOUNT - 1))
2559         local ost_step=1
2560         local ost_list=$(seq $first_ost $ost_step $last_ost)
2561         local ost_range="$first_ost $last_ost $ost_step"
2562
2563         test_mkdir $DIR/$tdir
2564         pool_add $POOL || error "pool_add failed"
2565         pool_add_targets $POOL $ost_range || error "pool_add_targets failed"
2566
2567         local skip27D
2568         [ $MDS1_VERSION -lt $(version_code 2.8.55) ] &&
2569                 skip27D+="-s 29"
2570         [ $MDS1_VERSION -lt $(version_code 2.9.55) ] ||
2571                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2572                         skip27D+=" -s 30,31"
2573         [[ ! $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ||
2574           $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2575                 skip27D+=" -s 32,33"
2576         [[ $MDS_VERSION -lt $(version_code $SEL_VER) ]] &&
2577                 skip27D+=" -s 34"
2578         llapi_layout_test -d$DIR/$tdir -p$POOL -o$OSTCOUNT $skip27D ||
2579                 error "llapi_layout_test failed"
2580
2581         destroy_test_pools || error "destroy test pools failed"
2582 }
2583 run_test 27D "validate llapi_layout API"
2584
2585 # Verify that default_easize is increased from its initial value after
2586 # accessing a widely striped file.
2587 test_27E() {
2588         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2589         [ $CLIENT_VERSION -lt $(version_code 2.5.57) ] &&
2590                 skip "client does not have LU-3338 fix"
2591
2592         # 72 bytes is the minimum space required to store striping
2593         # information for a file striped across one OST:
2594         # (sizeof(struct lov_user_md_v3) +
2595         #  sizeof(struct lov_user_ost_data_v1))
2596         local min_easize=72
2597         $LCTL set_param -n llite.*.default_easize $min_easize ||
2598                 error "lctl set_param failed"
2599         local easize=$($LCTL get_param -n llite.*.default_easize)
2600
2601         [ $easize -eq $min_easize ] ||
2602                 error "failed to set default_easize"
2603
2604         $LFS setstripe -c $OSTCOUNT $DIR/$tfile ||
2605                 error "setstripe failed"
2606         # In order to ensure stat() call actually talks to MDS we need to
2607         # do something drastic to this file to shake off all lock, e.g.
2608         # rename it (kills lookup lock forcing cache cleaning)
2609         mv $DIR/$tfile $DIR/${tfile}-1
2610         ls -l $DIR/${tfile}-1
2611         rm $DIR/${tfile}-1
2612
2613         easize=$($LCTL get_param -n llite.*.default_easize)
2614
2615         [ $easize -gt $min_easize ] ||
2616                 error "default_easize not updated"
2617 }
2618 run_test 27E "check that default extended attribute size properly increases"
2619
2620 test_27F() { # LU-5346/LU-7975
2621         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2622         [[ $OSTCOUNT -lt 2 ]] && skip "needs >= 2 OSTs"
2623         [[ $MDS1_VERSION -lt $(version_code 2.8.51) ]] &&
2624                 skip "Need MDS version at least 2.8.51"
2625         remote_ost_nodsh && skip "remote OST with nodsh"
2626
2627         test_mkdir $DIR/$tdir
2628         rm -f $DIR/$tdir/f0
2629         $LFS setstripe -c 2 $DIR/$tdir
2630
2631         # stop all OSTs to reproduce situation for LU-7975 ticket
2632         for num in $(seq $OSTCOUNT); do
2633                 stop ost$num
2634         done
2635
2636         # open/create f0 with O_LOV_DELAY_CREATE
2637         # truncate f0 to a non-0 size
2638         # close
2639         multiop $DIR/$tdir/f0 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T1050000c
2640
2641         $CHECKSTAT -s 1050000 $DIR/$tdir/f0 || error "checkstat failed"
2642         # open/write it again to force delayed layout creation
2643         cat /etc/hosts > $DIR/$tdir/f0 &
2644         catpid=$!
2645
2646         # restart OSTs
2647         for num in $(seq $OSTCOUNT); do
2648                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS ||
2649                         error "ost$num failed to start"
2650         done
2651
2652         wait $catpid || error "cat failed"
2653
2654         cmp /etc/hosts $DIR/$tdir/f0 || error "cmp failed"
2655         [[ $($LFS getstripe -c $DIR/$tdir/f0) == 2 ]] ||
2656                 error "wrong stripecount"
2657
2658 }
2659 run_test 27F "Client resend delayed layout creation with non-zero size"
2660
2661 test_27G() { #LU-10629
2662         [ $MDS1_VERSION -lt $(version_code 2.11.51) ] &&
2663                 skip "Need MDS version at least 2.11.51"
2664         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2665         remote_mds_nodsh && skip "remote MDS with nodsh"
2666         local POOL=${POOL:-testpool}
2667         local ostrange="0 0 1"
2668
2669         test_mkdir $DIR/$tdir
2670         touch $DIR/$tdir/$tfile.nopool
2671         pool_add $POOL || error "pool_add failed"
2672         pool_add_targets $POOL $ostrange || error "pool_add_targets failed"
2673         $LFS setstripe -p $POOL $DIR/$tdir
2674
2675         local pool=$($LFS getstripe -p $DIR/$tdir)
2676
2677         [ "$pool" = "$POOL" ] || error "Striping failed got '$pool' not '$POOL'"
2678         touch $DIR/$tdir/$tfile.default
2679         $LFS setstripe -E 1M --pool $POOL -c 1 -E eof -c 1 $DIR/$tdir/$tfile.pfl
2680         $LFS find $DIR/$tdir -type f --pool $POOL
2681         local found=$($LFS find $DIR/$tdir -type f --pool $POOL | wc -l)
2682         [[ "$found" == "2" ]] ||
2683                 error "found $found != 2 files in '$DIR/$tdir' in '$POOL'"
2684
2685         $LFS setstripe -d $DIR/$tdir
2686
2687         pool=$($LFS getstripe -p -d $DIR/$tdir)
2688
2689         [[ "$pool" != "$POOL" ]] || error "$DIR/$tdir is still '$pool'"
2690 }
2691 run_test 27G "Clear OST pool from stripe"
2692
2693 test_27H() {
2694         [[ $MDS1_VERSION -le $(version_code 2.11.54) ]] &&
2695                 skip "Need MDS version newer than 2.11.54"
2696         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
2697         test_mkdir $DIR/$tdir
2698         $LFS setstripe -o 0 -o 2 $DIR/$tdir || error "setstripe failed"
2699         touch $DIR/$tdir/$tfile
2700         $LFS getstripe -c $DIR/$tdir/$tfile
2701         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
2702                 error "two-stripe file doesn't have two stripes"
2703
2704         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
2705         $LFS getstripe -y $DIR/$tdir/$tfile
2706         (( $($LFS getstripe -y $DIR/$tdir/$tfile |
2707              egrep -c "l_ost_idx: [02]$") == "2" )) ||
2708                 error "expected l_ost_idx: [02]$ not matched"
2709
2710         # make sure ost list has been cleared
2711         local stripesize=$($LFS getstripe -S $DIR/$tdir)
2712         $LFS setstripe -S $((stripesize * 4)) -i 1 \
2713                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
2714         touch $DIR/$tdir/f3
2715         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
2716 }
2717 run_test 27H "Set specific OSTs stripe"
2718
2719 test_27I() {
2720         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2721         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2722         [[ $MDS1_VERSION -gt $(version_code 2.12.52) ]] ||
2723                 skip "Need MDS version newer than 2.12.52"
2724         local pool=$TESTNAME
2725         local ostrange="1 1 1"
2726
2727         save_layout_restore_at_exit $MOUNT
2728         $LFS setstripe -c 2 -i 0 $MOUNT
2729         pool_add $pool || error "pool_add failed"
2730         pool_add_targets $pool $ostrange ||
2731                 error "pool_add_targets failed"
2732         test_mkdir $DIR/$tdir
2733         $LFS setstripe -p $pool $DIR/$tdir
2734         $MULTIOP $DIR/$tdir/$tfile Oc || error "multiop failed"
2735         $LFS getstripe $DIR/$tdir/$tfile
2736 }
2737 run_test 27I "check that root dir striping does not break parent dir one"
2738
2739 test_27J() {
2740         [[ $MDS1_VERSION -le $(version_code 2.12.51) ]] &&
2741                 skip "Need MDS version newer than 2.12.51"
2742
2743         test_mkdir $DIR/$tdir
2744         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2745         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2746
2747         # create foreign file (raw way)
2748         ! $LFS setstripe --flags 0xda08 $DIR/$tdir/$tfile ||
2749                 error "creating $tfile w/ hex flags w/o --foreign should fail"
2750
2751         ! $LFS setstripe --foreign --flags foo \
2752                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tfile ||
2753                         error "creating $tfile with '--flags foo' should fail"
2754
2755         ! $LFS setstripe --foreign --flags 0xffffffff \
2756                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tfile ||
2757                         error "creating $tfile w/ 0xffffffff flags should fail"
2758
2759         create_foreign_file -f $DIR/$tdir/$tfile -x "${uuid1}@${uuid2}" \
2760                 -t 1 -F 0xda08 || error "create_foreign_file failed"
2761
2762         # verify foreign file (raw way)
2763         parse_foreign_file -f $DIR/$tdir/$tfile |
2764                 grep "lov_foreign_magic: 0x0BD70BD0" ||
2765                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign magic"
2766         parse_foreign_file -f $DIR/$tdir/$tfile | grep "lov_xattr_size: 89" ||
2767                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2768         parse_foreign_file -f $DIR/$tdir/$tfile |
2769                 grep "lov_foreign_size: 73" ||
2770                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2771         parse_foreign_file -f $DIR/$tdir/$tfile |
2772                 grep "lov_foreign_type: 1" ||
2773                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign type"
2774         parse_foreign_file -f $DIR/$tdir/$tfile |
2775                 grep "lov_foreign_flags: 0x0000DA08" ||
2776                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign flags"
2777         local lov=$(parse_foreign_file -f $DIR/$tdir/$tfile |
2778                 grep "lov_foreign_value: 0x" |
2779                 sed -e 's/lov_foreign_value: 0x//')
2780         local lov2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160)
2781         [[ $lov = ${lov2// /} ]] ||
2782                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign value"
2783
2784         # create foreign file (lfs + API)
2785         $LFS setstripe --foreign=none --flags 0xda08 \
2786                 -x "${uuid1}@${uuid2}" $DIR/$tdir/${tfile}2 ||
2787                 error "$DIR/$tdir/${tfile}2: create failed"
2788
2789         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2790                 grep "lfm_magic:.*0x0BD70BD0" ||
2791                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign magic"
2792         # lfm_length is LOV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2793         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_length:.*73" ||
2794                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign size"
2795         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_type:.*none" ||
2796                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign type"
2797         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2798                 grep "lfm_flags:.*0x0000DA08" ||
2799                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign flags"
2800         $LFS getstripe $DIR/$tdir/${tfile}2 |
2801                 grep "lfm_value:.*${uuid1}@${uuid2}" ||
2802                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign value"
2803
2804         # modify striping should fail
2805         $LFS setstripe -c 2 $DIR/$tdir/$tfile &&
2806                 error "$DIR/$tdir/$tfile: setstripe should fail"
2807         $LFS setstripe -c 2 $DIR/$tdir/${tfile}2 &&
2808                 error "$DIR/$tdir/${tfile}2: setstripe should fail"
2809
2810         # R/W should fail
2811         cat $DIR/$tdir/$tfile && error "$DIR/$tdir/$tfile: read should fail"
2812         cat $DIR/$tdir/${tfile}2 &&
2813                 error "$DIR/$tdir/${tfile}2: read should fail"
2814         cat /etc/passwd > $DIR/$tdir/$tfile &&
2815                 error "$DIR/$tdir/$tfile: write should fail"
2816         cat /etc/passwd > $DIR/$tdir/${tfile}2 &&
2817                 error "$DIR/$tdir/${tfile}2: write should fail"
2818
2819         # chmod should work
2820         chmod 222 $DIR/$tdir/$tfile ||
2821                 error "$DIR/$tdir/$tfile: chmod failed"
2822         chmod 222 $DIR/$tdir/${tfile}2 ||
2823                 error "$DIR/$tdir/${tfile}2: chmod failed"
2824
2825         # chown should work
2826         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tfile ||
2827                 error "$DIR/$tdir/$tfile: chown failed"
2828         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tfile}2 ||
2829                 error "$DIR/$tdir/${tfile}2: chown failed"
2830
2831         # rename should work
2832         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}.new ||
2833                 error "$DIR/$tdir/$tfile: rename of foreign file has failed"
2834         mv $DIR/$tdir/${tfile}2 $DIR/$tdir/${tfile}2.new ||
2835                 error "$DIR/$tdir/${tfile}2: rename of foreign file has failed"
2836
2837         #remove foreign file
2838         rm $DIR/$tdir/${tfile}.new ||
2839                 error "$DIR/$tdir/${tfile}.new: remove of foreign file has failed"
2840         rm $DIR/$tdir/${tfile}2.new ||
2841                 error "$DIR/$tdir/${tfile}2.new: remove of foreign file has failed"
2842 }
2843 run_test 27J "basic ops on file with foreign LOV"
2844
2845 test_27K() {
2846         [[ $MDS1_VERSION -le $(version_code 2.12.49) ]] &&
2847                 skip "Need MDS version newer than 2.12.49"
2848
2849         test_mkdir $DIR/$tdir
2850         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2851         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2852
2853         # create foreign dir (raw way)
2854         ! $LFS setdirstripe --flags 0xda08 $DIR/$tdir/$tdir ||
2855                 error "creating $tdir w/ hex flags w/o --foreign should fail"
2856
2857         ! $LFS setdirstripe --foreign --flags foo \
2858                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tdir ||
2859                         error "creating $tdir with '--flags foo' should fail"
2860
2861         ! $LFS setdirstripe --foreign --flags 0xffffffff \
2862                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tdir ||
2863                         error "creating $tdir w/ 0xffffffff flags should fail"
2864
2865         create_foreign_dir -d $DIR/$tdir/$tdir -x "${uuid1}@${uuid2}" -t 1 ||
2866                 error "create_foreign_dir FAILED"
2867
2868         # verify foreign dir (raw way)
2869         parse_foreign_dir -d $DIR/$tdir/$tdir |
2870                 grep "lmv_foreign_magic:.*0xcd50cd0" ||
2871                 error "$DIR/$tdir/$tfile: invalid LMV EA magic"
2872         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_xattr_size:.*89$" ||
2873                 error "$DIR/$tdir/$tdir: invalid LMV EA size"
2874         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_foreign_type: 1$" ||
2875                 error "$DIR/$tdir/$tdir: invalid LMV EA type"
2876         parse_foreign_dir -d $DIR/$tdir/$tdir |
2877                 grep "lmv_foreign_flags: 55813$" ||
2878                 error "$DIR/$tdir/$tdir: invalid LMV EA flags"
2879         local lmv=$(parse_foreign_dir -d $DIR/$tdir/$tdir |
2880                 grep "lmv_foreign_value: 0x" |
2881                 sed 's/lmv_foreign_value: 0x//')
2882         local lmv2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160 |
2883                 sed 's/ //g')
2884         [[ $lmv == $lmv2 ]] || error "$DIR/$tdir/$tdir: invalid LMV EA value"
2885
2886         # create foreign dir (lfs + API)
2887         $LFS mkdir --foreign=none --xattr="${uuid1}@${uuid2}" --flags=0xda05 \
2888                 $DIR/$tdir/${tdir}2 ||
2889                 error "$DIR/$tdir/${tdir}2: create failed"
2890
2891         $LFS getdirstripe -v $DIR/$tdir/${tdir}2
2892
2893         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2894                 grep "lfm_magic:.*0x0CD50CD0" ||
2895                 error "$DIR/$tdir/${tdir}2: invalid LMV EA magic"
2896         # lfm_length is LMV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2897         # - sizeof(lfm_type) - sizeof(lfm_flags)
2898         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_length:.*73" ||
2899                 error "$DIR/$tdir/${tdir}2: invalid LMV EA size"
2900         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_type:.*none" ||
2901                 error "$DIR/$tdir/${tdir}2: invalid LMV EA type"
2902         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2903                 grep "lfm_flags:.*0x0000DA05" ||
2904                 error "$DIR/$tdir/${tdir}2: invalid LMV EA flags"
2905         $LFS getdirstripe $DIR/$tdir/${tdir}2 |
2906                 grep "lfm_value.*${uuid1}@${uuid2}" ||
2907                 error "$DIR/$tdir/${tdir}2: invalid LMV EA value"
2908
2909         # file create in dir should fail
2910         touch $DIR/$tdir/$tdir/$tfile && error "$DIR/$tdir: file create should fail"
2911         touch $DIR/$tdir/${tdir}2/$tfile &&
2912                 error "$DIR/${tdir}2: file create should fail"
2913
2914         # chmod should work
2915         chmod 777 $DIR/$tdir/$tdir ||
2916                 error "$DIR/$tdir: chmod failed"
2917         chmod 777 $DIR/$tdir/${tdir}2 ||
2918                 error "$DIR/${tdir}2: chmod failed"
2919
2920         # chown should work
2921         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tdir ||
2922                 error "$DIR/$tdir: chown failed"
2923         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tdir}2 ||
2924                 error "$DIR/${tdir}2: chown failed"
2925
2926         # rename should work
2927         mv $DIR/$tdir/$tdir $DIR/$tdir/${tdir}.new ||
2928                 error "$DIR/$tdir/$tdir: rename of foreign dir has failed"
2929         mv $DIR/$tdir/${tdir}2 $DIR/$tdir/${tdir}2.new ||
2930                 error "$DIR/$tdir/${tdir}2: rename of foreign dir has failed"
2931
2932         #remove foreign dir
2933         rmdir $DIR/$tdir/${tdir}.new ||
2934                 error "$DIR/$tdir/${tdir}.new: remove of foreign dir has failed"
2935         rmdir $DIR/$tdir/${tdir}2.new ||
2936                 error "$DIR/$tdir/${tdir}2.new: remove of foreign dir has failed"
2937 }
2938 run_test 27K "basic ops on dir with foreign LMV"
2939
2940 test_27L() {
2941         remote_mds_nodsh && skip "remote MDS with nodsh"
2942
2943         local POOL=${POOL:-$TESTNAME}
2944
2945         pool_add $POOL || error "pool_add failed"
2946
2947         lfs pool_list $MOUNT | grep -Fx "${FSNAME}.${POOL}" ||
2948                  error "pool_list does not contain ${FSNAME}.${POOL}:" \
2949                        "$(lfs pool_list $MOUNT | grep -F "${POOL}")"
2950 }
2951 run_test 27L "lfs pool_list gives correct pool name"
2952
2953 test_27M() {
2954         [[ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.12.57) ]] &&
2955                 skip "Need MDS version >= than 2.12.57"
2956         remote_mds_nodsh && skip "remote MDS with nodsh"
2957         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2958
2959         # Set default striping on directory
2960         local setcount=4
2961         local stripe_opt
2962         local mdts=$(comma_list $(mdts_nodes))
2963
2964         # if we run against a 2.12 server which lacks overstring support
2965         # then the connect_flag will not report overstriping, even if client
2966         # is 2.14+
2967         if [[ $($LCTL get_param mdc.*.connect_flags) =~ overstriping ]]; then
2968                 stripe_opt="-C $setcount"
2969         elif (( $OSTCOUNT >= $setcount )); then
2970                 stripe_opt="-c $setcount"
2971         else
2972                 skip "server does not support overstriping"
2973         fi
2974
2975         test_mkdir $DIR/$tdir
2976
2977         # Validate existing append_* params and ensure restore
2978         local pool=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_pool)
2979         [[ "$pool" == "" ]] || error "expected append_pool == '', got '$pool'"
2980         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_pool=none"
2981
2982         local orig_count=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_stripe_count)
2983         ((orig_count == 1)) || error "expected append_stripe_count == 1, got $orig_count"
2984         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=1"
2985
2986         $LFS setstripe $stripe_opt $DIR/$tdir
2987
2988         echo 1 > $DIR/$tdir/${tfile}.1
2989         local count=$($LFS getstripe -c $DIR/$tdir/${tfile}.1)
2990         [ $count -eq $setcount ] ||
2991                 error "(1) stripe count $count, should be $setcount"
2992
2993         local appendcount=$orig_count
2994         echo 1 >> $DIR/$tdir/${tfile}.2_append
2995         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.2_append)
2996         [ $count -eq $appendcount ] ||
2997                 error "(2)stripe count $count, should be $appendcount for append"
2998
2999         # Disable O_APPEND striping, verify it works
3000         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
3001
3002         # Should now get the default striping, which is 4
3003         setcount=4
3004         echo 1 >> $DIR/$tdir/${tfile}.3_append
3005         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.3_append)
3006         [ $count -eq $setcount ] ||
3007                 error "(3) stripe count $count, should be $setcount"
3008
3009         # Try changing the stripe count for append files
3010         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=2
3011
3012         # Append striping is now 2 (directory default is still 4)
3013         appendcount=2
3014         echo 1 >> $DIR/$tdir/${tfile}.4_append
3015         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.4_append)
3016         [ $count -eq $appendcount ] ||
3017                 error "(4) stripe count $count, should be $appendcount for append"
3018
3019         # Test append stripe count of -1
3020         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=-1
3021         appendcount=$OSTCOUNT
3022         echo 1 >> $DIR/$tdir/${tfile}.5
3023         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.5)
3024         [ $count -eq $appendcount ] ||
3025                 error "(5) stripe count $count, should be $appendcount for append"
3026
3027         # Set append striping back to default of 1
3028         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=1
3029
3030         # Try a new default striping, PFL + DOM
3031         $LFS setstripe -L mdt -E 1M -E -1 -c 2 $DIR/$tdir
3032
3033         # Create normal DOM file, DOM returns stripe count == 0
3034         setcount=0
3035         touch $DIR/$tdir/${tfile}.6
3036         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.6)
3037         [ $count -eq $setcount ] ||
3038                 error "(6) stripe count $count, should be $setcount"
3039
3040         # Show
3041         appendcount=1
3042         echo 1 >> $DIR/$tdir/${tfile}.7_append
3043         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.7_append)
3044         [ $count -eq $appendcount ] ||
3045                 error "(7) stripe count $count, should be $appendcount for append"
3046
3047         # Clean up DOM layout
3048         $LFS setstripe -d $DIR/$tdir
3049
3050         save_layout_restore_at_exit $MOUNT
3051         # Now test that append striping works when layout is from root
3052         $LFS setstripe -c 2 $MOUNT
3053         # Make a special directory for this
3054         mkdir $DIR/${tdir}/${tdir}.2
3055
3056         # Verify for normal file
3057         setcount=2
3058         echo 1 > $DIR/${tdir}/${tdir}.2/${tfile}.8
3059         count=$($LFS getstripe -c $DIR/$tdir/${tdir}.2/${tfile}.8)
3060         [ $count -eq $setcount ] ||
3061                 error "(8) stripe count $count, should be $setcount"
3062
3063         appendcount=1
3064         echo 1 >> $DIR/${tdir}/${tdir}.2/${tfile}.9_append
3065         count=$($LFS getstripe -c $DIR/${tdir}/${tdir}.2/${tfile}.9_append)
3066         [ $count -eq $appendcount ] ||
3067                 error "(9) stripe count $count, should be $appendcount for append"
3068
3069         # Now test O_APPEND striping with pools
3070         pool_add $TESTNAME || error "pool creation failed"
3071         pool_add_targets $TESTNAME 0 1 || error "Pool add targets failed"
3072         do_nodes $mdts $LCTL set_param mdd.*.append_pool="$TESTNAME"
3073
3074         echo 1 >> $DIR/$tdir/${tfile}.10_append
3075
3076         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.10_append)
3077         [ "$pool" = "$TESTNAME" ] || error "(10) incorrect pool: $pool"
3078
3079         # Check that count is still correct
3080         appendcount=1
3081         echo 1 >> $DIR/$tdir/${tfile}.11_append
3082         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.11_append)
3083         [ $count -eq $appendcount ] ||
3084                 error "(11) stripe count $count, should be $appendcount for append"
3085
3086         # Disable O_APPEND stripe count, verify pool works separately
3087         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
3088
3089         echo 1 >> $DIR/$tdir/${tfile}.12_append
3090
3091         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.12_append)
3092         [ "$pool" = "$TESTNAME" ] || error "(12) incorrect pool: $pool"
3093
3094         # Remove pool setting, verify it's not applied
3095         do_nodes $mdts $LCTL set_param mdd.*.append_pool='none'
3096
3097         echo 1 >> $DIR/$tdir/${tfile}.13_append
3098
3099         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.13_append)
3100         [ "$pool" = "" ] || error "(13) pool found: $pool"
3101 }
3102 run_test 27M "test O_APPEND striping"
3103
3104 test_27N() {
3105         combined_mgs_mds && skip "needs separate MGS/MDT"
3106
3107         pool_add $TESTNAME || error "pool_add failed"
3108         do_facet mgs "$LCTL pool_list $FSNAME" |
3109                 grep -Fx "${FSNAME}.${TESTNAME}" ||
3110                 error "lctl pool_list on MGS failed"
3111 }
3112 run_test 27N "lctl pool_list on separate MGS gives correct pool name"
3113
3114 clean_foreign_symlink() {
3115         trap 0
3116         lctl set_param llite/$FSNAME-*/foreign_symlink_enable=0
3117         for i in $DIR/$tdir/* ; do
3118                 $LFS unlink_foreign $i || true
3119         done
3120 }
3121
3122 test_27O() {
3123         [[ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.12.51) ]] &&
3124                 skip "Need MDS version newer than 2.12.51"
3125
3126         test_mkdir $DIR/$tdir
3127         local uuid1=$(cat /proc/sys/kernel/random/uuid)
3128         local uuid2=$(cat /proc/sys/kernel/random/uuid)
3129
3130         trap clean_foreign_symlink EXIT
3131
3132         # enable foreign_symlink behaviour
3133         $LCTL set_param llite/$FSNAME-*/foreign_symlink_enable=1
3134
3135         # foreign symlink LOV format is a partial path by default
3136
3137         # create foreign file (lfs + API)
3138         $LFS setstripe --foreign=symlink --flags 0xda05 \
3139                 -x "${uuid1}/${uuid2}" --mode 0600 $DIR/$tdir/${tfile} ||
3140                 error "$DIR/$tdir/${tfile}: create failed"
3141
3142         $LFS getstripe -v $DIR/$tdir/${tfile} |
3143                 grep "lfm_magic:.*0x0BD70BD0" ||
3144                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign magic"
3145         $LFS getstripe -v $DIR/$tdir/${tfile} | grep "lfm_type:.*symlink" ||
3146                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign type"
3147         $LFS getstripe -v $DIR/$tdir/${tfile} |
3148                 grep "lfm_flags:.*0x0000DA05" ||
3149                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign flags"
3150         $LFS getstripe $DIR/$tdir/${tfile} |
3151                 grep "lfm_value:.*${uuid1}/${uuid2}" ||
3152                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign value"
3153
3154         # modify striping should fail
3155         $LFS setstripe -c 2 $DIR/$tdir/$tfile &&
3156                 error "$DIR/$tdir/$tfile: setstripe should fail"
3157
3158         # R/W should fail ("/{foreign_symlink_prefix}/${uuid1}/" missing)
3159         cat $DIR/$tdir/$tfile && error "$DIR/$tdir/$tfile: read should fail"
3160         cat /etc/passwd > $DIR/$tdir/$tfile &&
3161                 error "$DIR/$tdir/$tfile: write should fail"
3162
3163         # rename should succeed
3164         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}.new ||
3165                 error "$DIR/$tdir/$tfile: rename has failed"
3166
3167         #remove foreign_symlink file should fail
3168         rm $DIR/$tdir/${tfile}.new &&
3169                 error "$DIR/$tdir/${tfile}.new: remove of foreign_symlink file should fail"
3170
3171         #test fake symlink
3172         mkdir /tmp/${uuid1} ||
3173                 error "/tmp/${uuid1}: mkdir has failed"
3174         echo FOOFOO > /tmp/${uuid1}/${uuid2} ||
3175                 error "/tmp/${uuid1}/${uuid2}: echo has failed"
3176         $LCTL set_param llite/$FSNAME-*/foreign_symlink_prefix=/tmp/
3177         $CHECKSTAT -t link -l /tmp/${uuid1}/${uuid2} $DIR/$tdir/${tfile}.new ||
3178                 error "$DIR/$tdir/${tfile}.new: not seen as a symlink"
3179         #read should succeed now
3180         cat $DIR/$tdir/${tfile}.new | grep FOOFOO ||
3181                 error "$DIR/$tdir/${tfile}.new: symlink resolution has failed"
3182         #write should succeed now
3183         cat /etc/passwd > $DIR/$tdir/${tfile}.new ||
3184                 error "$DIR/$tdir/${tfile}.new: write should succeed"
3185         diff /etc/passwd $DIR/$tdir/${tfile}.new ||
3186                 error "$DIR/$tdir/${tfile}.new: diff has failed"
3187         diff /etc/passwd /tmp/${uuid1}/${uuid2} ||
3188                 error "/tmp/${uuid1}/${uuid2}: diff has failed"
3189
3190         #check that getstripe still works
3191         $LFS getstripe $DIR/$tdir/${tfile}.new ||
3192                 error "$DIR/$tdir/${tfile}.new: getstripe should still work with foreign_symlink enabled"
3193
3194         # chmod should still succeed
3195         chmod 644 $DIR/$tdir/${tfile}.new ||
3196                 error "$DIR/$tdir/${tfile}.new: chmod has failed"
3197
3198         # chown should still succeed
3199         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tfile}.new ||
3200                 error "$DIR/$tdir/${tfile}.new: chown has failed"
3201
3202         # rename should still succeed
3203         mv $DIR/$tdir/${tfile}.new $DIR/$tdir/${tfile} ||
3204                 error "$DIR/$tdir/${tfile}.new: rename has failed"
3205
3206         #remove foreign_symlink file should still fail
3207         rm $DIR/$tdir/${tfile} &&
3208                 error "$DIR/$tdir/${tfile}: remove of foreign_symlink file should fail"
3209
3210         #use special ioctl() to unlink foreign_symlink file
3211         $LFS unlink_foreign $DIR/$tdir/${tfile} ||
3212                 error "$DIR/$tdir/$tfile: unlink/ioctl failed"
3213
3214 }
3215 run_test 27O "basic ops on foreign file of symlink type"
3216
3217 test_27P() {
3218         [[ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.12.49) ]] &&
3219                 skip "Need MDS version newer than 2.12.49"
3220
3221         test_mkdir $DIR/$tdir
3222         local uuid1=$(cat /proc/sys/kernel/random/uuid)
3223         local uuid2=$(cat /proc/sys/kernel/random/uuid)
3224
3225         trap clean_foreign_symlink EXIT
3226
3227         # enable foreign_symlink behaviour
3228         $LCTL set_param llite/$FSNAME-*/foreign_symlink_enable=1
3229
3230         # foreign symlink LMV format is a partial path by default
3231
3232         # create foreign dir (lfs + API)
3233         $LFS mkdir --foreign=symlink --xattr="${uuid1}/${uuid2}" \
3234                 --flags=0xda05 --mode 0750 $DIR/$tdir/${tdir} ||
3235                 error "$DIR/$tdir/${tdir}: create failed"
3236
3237         $LFS getdirstripe -v $DIR/$tdir/${tdir}
3238
3239         $LFS getdirstripe -v $DIR/$tdir/${tdir} |
3240                 grep "lfm_magic:.*0x0CD50CD0" ||
3241                 error "$DIR/$tdir/${tdir}: invalid LMV EA magic"
3242         $LFS getdirstripe -v $DIR/$tdir/${tdir} | grep "lfm_type:.*symlink" ||
3243                 error "$DIR/$tdir/${tdir}: invalid LMV EA type"
3244         $LFS getdirstripe -v $DIR/$tdir/${tdir} |
3245                 grep "lfm_flags:.*0x0000DA05" ||
3246                 error "$DIR/$tdir/${tdir}: invalid LMV EA flags"
3247         $LFS getdirstripe $DIR/$tdir/${tdir} |
3248                 grep "lfm_value.*${uuid1}/${uuid2}" ||
3249                 error "$DIR/$tdir/${tdir}: invalid LMV EA value"
3250
3251         # file create in dir should fail
3252         # ("/{foreign_symlink_prefix}/${uuid1}/${uuid2}/" missing)
3253         touch $DIR/$tdir/$tdir/$tfile && error "$DIR/$tdir: file create should fail"
3254
3255         # rename should succeed
3256         mv $DIR/$tdir/$tdir $DIR/$tdir/${tdir}.new ||
3257                 error "$DIR/$tdir/$tdir: rename of foreign_symlink dir has failed"
3258
3259         #remove foreign_symlink dir should fail
3260         rmdir $DIR/$tdir/${tdir}.new &&
3261                 error "$DIR/$tdir/${tdir}.new: remove of foreign_symlink dir should fail"
3262
3263         #test fake symlink
3264         mkdir -p /tmp/${uuid1}/${uuid2} ||
3265                 error "/tmp/${uuid1}/${uuid2}: mkdir has failed"
3266         echo FOOFOO > /tmp/${uuid1}/${uuid2}/foo ||
3267                 error "/tmp/${uuid1}/${uuid2}/foo: echo has failed"
3268         $LCTL set_param llite/$FSNAME-*/foreign_symlink_prefix=/tmp/
3269         $CHECKSTAT -t link -l /tmp/${uuid1}/${uuid2} $DIR/$tdir/${tdir}.new ||
3270                 error "$DIR/$tdir/${tdir}.new: not seen as a symlink"
3271         cat $DIR/$tdir/${tdir}.new/foo | grep FOOFOO ||
3272                 error "$DIR/$tdir/${tdir}.new: symlink resolution has failed"
3273
3274         #check that getstripe fails now that foreign_symlink enabled
3275         $LFS getdirstripe $DIR/$tdir/${tdir}.new ||
3276                 error "$DIR/$tdir/${tdir}.new: getdirstripe should still work with foreign_symlink enabled"
3277
3278         # file create in dir should work now
3279         cp /etc/passwd $DIR/$tdir/${tdir}.new/$tfile ||
3280                 error "$DIR/$tdir/${tdir}.new/$tfile: file create should fail"
3281         diff /etc/passwd $DIR/$tdir/${tdir}.new/$tfile ||
3282                 error "$DIR/$tdir/${tdir}.new/$tfile: diff has failed"
3283         diff /etc/passwd /tmp/${uuid1}/${uuid2}/$tfile ||
3284                 error "/tmp/${uuid1}/${uuid2}/$tfile: diff has failed"
3285
3286         # chmod should still succeed
3287         chmod 755 $DIR/$tdir/${tdir}.new ||
3288                 error "$DIR/$tdir/${tdir}.new: chmod has failed"
3289
3290         # chown should still succeed
3291         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tdir}.new ||
3292                 error "$DIR/$tdir/${tdir}.new: chown has failed"
3293
3294         # rename should still succeed
3295         mv $DIR/$tdir/${tdir}.new $DIR/$tdir/${tdir} ||
3296                 error "$DIR/$tdir/${tdir}.new: rename of foreign_symlink dir has failed"
3297
3298         #remove foreign_symlink dir should still fail
3299         rmdir $DIR/$tdir/${tdir} &&
3300                 error "$DIR/$tdir/${tdir}: remove of foreign_symlink dir should fail"
3301
3302         #use special ioctl() to unlink foreign_symlink file
3303         $LFS unlink_foreign $DIR/$tdir/${tdir} ||
3304                 error "$DIR/$tdir/$tdir: unlink/ioctl failed"
3305
3306         #created file should still exist
3307         [[ -f /tmp/${uuid1}/${uuid2}/$tfile ]] ||
3308                 error "/tmp/${uuid1}/${uuid2}/$tfile has been removed"
3309         diff /etc/passwd /tmp/${uuid1}/${uuid2}/$tfile ||
3310                 error "/tmp/${uuid1}/${uuid2}/$tfile: diff has failed"
3311 }
3312 run_test 27P "basic ops on foreign dir of foreign_symlink type"
3313
3314 test_27Q() {
3315         rm -f $TMP/$tfile $TMP/$tfile.loop $TMP/$tfile.none $TMP/$tfile.broken
3316         stack_trap "rm -f $TMP/$tfile*"
3317
3318         test_mkdir $DIR/$tdir-1
3319         test_mkdir $DIR/$tdir-2
3320
3321         echo 'It is what it is' > $DIR/$tdir-1/$tfile
3322         lov_getstripe_old $DIR/$tdir-1/$tfile || error "$DIR/$tdir-1/$tfile: rc = $?"
3323
3324         ln -s $DIR/$tdir-1/$tfile $DIR/$tdir-2/$tfile
3325         lov_getstripe_old $DIR/$tdir-2/$tfile || error "$DIR/$tdir-2/$tfile: rc = $?"
3326
3327         ln -s $DIR/$tdir-1/$tfile $TMP/$tfile
3328         lov_getstripe_old $TMP/$tfile || error "$TMP/$tfile: rc = $?"
3329
3330         # Create some bad symlinks and ensure that we don't loop
3331         # forever or something. These should return ELOOP (40) and
3332         # ENOENT (2) but I don't want to test for that because there's
3333         # always some weirdo architecture that needs to ruin
3334         # everything by defining these error numbers differently.
3335
3336         ln -s $TMP/$tfile.loop $TMP/$tfile.loop
3337         lov_getstripe_old $TMP/$tfile.loop && error "$TMP/$tfile.loop: rc = $?"
3338
3339         ln -s $TMP/$tfile.none $TMP/$tfile.broken
3340         lov_getstripe_old $TMP/$tfile.broken && error "$TMP/$tfile.broken: rc = $?"
3341
3342         return 0
3343 }
3344 run_test 27Q "llapi_file_get_stripe() works on symlinks"
3345
3346 test_27R() {
3347         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
3348                 skip "need MDS 2.14.55 or later"
3349         (( $OSTCOUNT >= 2 )) || skip_env "needs at least 2 OSTs"
3350
3351         local testdir="$DIR/$tdir"
3352         test_mkdir -p $testdir
3353         stack_trap "rm -rf $testdir"
3354         $LFS setstripe -c -1 $testdir || error "setstripe failed"
3355
3356         local f1="$testdir/f1"
3357         touch $f1 || error "failed to touch $f1"
3358         local count=$($LFS getstripe -c $f1)
3359         (( $count == $OSTCOUNT )) || error "wrong stripe count"
3360
3361         do_facet $SINGLEMDS $LCTL set_param lod.*.max_stripecount=-1
3362         (( $? == 34 )) || error "setting max_stripecount to -1 should fail and return ERANGE"
3363
3364         local maxcount=$(($OSTCOUNT - 1))
3365         local mdts=$(comma_list $(mdts_nodes))
3366         do_nodes $mdts $LCTL set_param lod.*.max_stripecount=$maxcount
3367         stack_trap "do_nodes $mdts $LCTL set_param lod.*.max_stripecount=0"
3368
3369         local f2="$testdir/f2"
3370         touch $f2 || error "failed to touch $f2"
3371         local count=$($LFS getstripe -c $f2)
3372         (( $count == $maxcount )) || error "wrong stripe count"
3373 }
3374 run_test 27R "test max_stripecount limitation when stripe count is set to -1"
3375
3376 test_27T() {
3377         [ $(facet_host client) == $(facet_host ost1) ] &&
3378                 skip "need ost1 and client on different nodes"
3379
3380 #define OBD_FAIL_OSC_NO_GRANT            0x411
3381         $LCTL set_param fail_loc=0x20000411 fail_val=1
3382 #define OBD_FAIL_OST_ENOSPC              0x215
3383         do_facet ost1 "$LCTL set_param fail_loc=0x80000215"
3384         $LFS setstripe -i 0 -c 1 $DIR/$tfile
3385         $MULTIOP $DIR/$tfile oO_WRONLY:P$((4 * 1024 * 1024 + 10 * 4096))c ||
3386                 error "multiop failed"
3387 }
3388 run_test 27T "no eio on close on partial write due to enosp"
3389
3390 test_27U() {
3391         local dir=$DIR/$tdir
3392         local file=$dir/$tfile
3393         local append_pool=${TESTNAME}-append
3394         local normal_pool=${TESTNAME}-normal
3395         local pool
3396         local stripe_count
3397         local stripe_count2
3398         local mdts=$(comma_list $(mdts_nodes))
3399
3400         # FIMXE
3401         # (( $MDS1_VERSION >= $(version_code 2.15.42) )) ||
3402         #       skip "Need MDS version at least 2.15.42"
3403
3404         # Validate existing append_* params and ensure restore
3405         pool=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_pool)
3406         [[ "$pool" == "" ]] || error "expected append_pool == '', got '$pool'"
3407         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_pool=none"
3408
3409         stripe_count=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_stripe_count)
3410         ((stripe_count == 1)) || error "expected append_stripe_count != 0, got $stripe_count"
3411         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=$stripe_count"
3412
3413         pool_add $append_pool || error "pool creation failed"
3414         pool_add_targets $append_pool 0 1 || error "Pool add targets failed"
3415
3416         pool_add $normal_pool || error "pool creation failed"
3417         pool_add_targets $normal_pool 0 1 || error "Pool add targets failed"
3418
3419         test_mkdir $dir
3420         $LFS setstripe -E 1M -c 1 -p $normal_pool -E 2M -c 2 -p $normal_pool -E eof -c -1 $dir
3421
3422         echo XXX >> $file.1
3423         $LFS getstripe $file.1
3424
3425         pool=$($LFS getstripe -p $file.1)
3426         [[ "$pool" == "$normal_pool" ]] || error "got pool '$pool', expected '$normal_pool'"
3427
3428         stripe_count2=$($LFS getstripe -c $file.1)
3429         ((stripe_count2 == stripe_count)) ||
3430                 error "got stripe_count '$stripe_count2', expected '$stripe_count'"
3431
3432         do_nodes $mdts $LCTL set_param mdd.*.append_pool=$append_pool
3433
3434         echo XXX >> $file.2
3435         $LFS getstripe $file.2
3436
3437         pool=$($LFS getstripe -p $file.2)
3438         [[ "$pool" == "$append_pool" ]] || error "got pool '$pool', expected '$append_pool'"
3439
3440         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=2
3441
3442         echo XXX >> $file.3
3443         $LFS getstripe $file.3
3444
3445         stripe_count2=$($LFS getstripe -c $file.3)
3446         ((stripe_count2 == 2)) || error "got stripe_count '$stripe_count2', expected 2"
3447 }
3448 run_test 27U "append pool and stripe count work with composite default layout"
3449
3450 # createtest also checks that device nodes are created and
3451 # then visible correctly (#2091)
3452 test_28() { # bug 2091
3453         test_mkdir $DIR/d28
3454         $CREATETEST $DIR/d28/ct || error "createtest failed"
3455 }
3456 run_test 28 "create/mknod/mkdir with bad file types ============"
3457
3458 test_29() {
3459         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3460
3461         [ $MDS1_VERSION -ge $(version_code 2.14.51) ] && {
3462                 disable_opencache
3463                 stack_trap "restore_opencache"
3464         }
3465
3466         sync; sleep 1; sync # flush out any dirty pages from previous tests
3467         cancel_lru_locks
3468         test_mkdir $DIR/d29
3469         touch $DIR/d29/foo
3470         log 'first d29'
3471         ls -l $DIR/d29
3472
3473         declare -i LOCKCOUNTORIG=0
3474         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
3475                 let LOCKCOUNTORIG=$LOCKCOUNTORIG+$lock_count
3476         done
3477         [ $LOCKCOUNTORIG -eq 0 ] && error "No mdc lock count" && return 1
3478
3479         declare -i LOCKUNUSEDCOUNTORIG=0
3480         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3481                 let LOCKUNUSEDCOUNTORIG=$LOCKUNUSEDCOUNTORIG+$unused_count
3482         done
3483
3484         log 'second d29'
3485         ls -l $DIR/d29
3486         log 'done'
3487
3488         declare -i LOCKCOUNTCURRENT=0
3489         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
3490                 let LOCKCOUNTCURRENT=$LOCKCOUNTCURRENT+$lock_count
3491         done
3492
3493         declare -i LOCKUNUSEDCOUNTCURRENT=0
3494         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3495                 let LOCKUNUSEDCOUNTCURRENT=$LOCKUNUSEDCOUNTCURRENT+$unused_count
3496         done
3497
3498         if [[ $LOCKCOUNTCURRENT -gt $LOCKCOUNTORIG ]]; then
3499                 $LCTL set_param -n ldlm.dump_namespaces ""
3500                 error "CURRENT: $LOCKCOUNTCURRENT > $LOCKCOUNTORIG"
3501                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3502                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3503                 return 2
3504         fi
3505         if [[ $LOCKUNUSEDCOUNTCURRENT -gt $LOCKUNUSEDCOUNTORIG ]]; then
3506                 error "UNUSED: $LOCKUNUSEDCOUNTCURRENT > $LOCKUNUSEDCOUNTORIG"
3507                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3508                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3509                 return 3
3510         fi
3511 }
3512 run_test 29 "IT_GETATTR regression  ============================"
3513
3514 test_30a() { # was test_30
3515         cp $(which ls) $DIR || cp /bin/ls $DIR
3516         $DIR/ls / || error "Can't execute binary from lustre"
3517         rm $DIR/ls
3518 }
3519 run_test 30a "execute binary from Lustre (execve) =============="
3520
3521 test_30b() {
3522         cp `which ls` $DIR || cp /bin/ls $DIR
3523         chmod go+rx $DIR/ls
3524         $RUNAS $DIR/ls / || error "Can't execute binary from lustre as non-root"
3525         rm $DIR/ls
3526 }
3527 run_test 30b "execute binary from Lustre as non-root ==========="
3528
3529 test_30c() { # b=22376
3530         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3531
3532         cp $(which ls) $DIR || cp /bin/ls $DIR
3533         chmod a-rw $DIR/ls
3534         cancel_lru_locks mdc
3535         cancel_lru_locks osc
3536         $RUNAS $DIR/ls / || error "Can't execute binary from lustre"
3537         rm -f $DIR/ls
3538 }
3539 run_test 30c "execute binary from Lustre without read perms ===="
3540
3541 test_30d() {
3542         cp $(which dd) $DIR || error "failed to copy dd to $DIR/dd"
3543
3544         for i in {1..10}; do
3545                 $DIR/dd bs=1M count=128 if=/dev/zero of=$DIR/$tfile &
3546                 local PID=$!
3547                 sleep 1
3548                 $LCTL set_param ldlm.namespaces.*MDT*.lru_size=clear
3549                 wait $PID || error "executing dd from Lustre failed"
3550                 rm -f $DIR/$tfile
3551         done
3552
3553         rm -f $DIR/dd
3554 }
3555 run_test 30d "execute binary from Lustre while clear locks"
3556
3557 test_31a() {
3558         $OPENUNLINK $DIR/f31 $DIR/f31 || error "openunlink failed"
3559         $CHECKSTAT -a $DIR/f31 || error "$DIR/f31 exists"
3560 }
3561 run_test 31a "open-unlink file =================================="
3562
3563 test_31b() {
3564         touch $DIR/f31 || error "touch $DIR/f31 failed"
3565         ln $DIR/f31 $DIR/f31b || error "ln failed"
3566         $MULTIOP $DIR/f31b Ouc || error "multiop failed"
3567         $CHECKSTAT -t file $DIR/f31 || error "$DIR/f31 not file type"
3568 }
3569 run_test 31b "unlink file with multiple links while open ======="
3570
3571 test_31c() {
3572         touch $DIR/f31 || error "touch $DIR/f31 failed"
3573         ln $DIR/f31 $DIR/f31c || error "ln failed"
3574         multiop_bg_pause $DIR/f31 O_uc ||
3575                 error "multiop_bg_pause for $DIR/f31 failed"
3576         MULTIPID=$!
3577         $MULTIOP $DIR/f31c Ouc
3578         kill -USR1 $MULTIPID
3579         wait $MULTIPID
3580 }
3581 run_test 31c "open-unlink file with multiple links ============="
3582
3583 test_31d() {
3584         opendirunlink $DIR/d31d $DIR/d31d || error "opendirunlink failed"
3585         $CHECKSTAT -a $DIR/d31d || error "$DIR/d31d exists"
3586 }
3587 run_test 31d "remove of open directory ========================="
3588
3589 test_31e() { # bug 2904
3590         openfilleddirunlink $DIR/d31e || error "openfilleddirunlink failed"
3591 }
3592 run_test 31e "remove of open non-empty directory ==============="
3593
3594 test_31f() { # bug 4554
3595         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3596
3597         set -vx
3598         test_mkdir $DIR/d31f
3599         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3600         cp /etc/hosts $DIR/d31f
3601         ls -l $DIR/d31f
3602         $LFS getstripe $DIR/d31f/hosts
3603         multiop_bg_pause $DIR/d31f D_c || return 1
3604         MULTIPID=$!
3605
3606         rm -rv $DIR/d31f || error "first of $DIR/d31f"
3607         test_mkdir $DIR/d31f
3608         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3609         cp /etc/hosts $DIR/d31f
3610         ls -l $DIR/d31f
3611         $LFS getstripe $DIR/d31f/hosts
3612         multiop_bg_pause $DIR/d31f D_c || return 1
3613         MULTIPID2=$!
3614
3615         kill -USR1 $MULTIPID || error "first opendir $MULTIPID not running"
3616         wait $MULTIPID || error "first opendir $MULTIPID failed"
3617
3618         sleep 6
3619
3620         kill -USR1 $MULTIPID2 || error "second opendir $MULTIPID not running"
3621         wait $MULTIPID2 || error "second opendir $MULTIPID2 failed"
3622         set +vx
3623 }
3624 run_test 31f "remove of open directory with open-unlink file ==="
3625
3626 test_31g() {
3627         echo "-- cross directory link --"
3628         test_mkdir -c1 $DIR/${tdir}ga
3629         test_mkdir -c1 $DIR/${tdir}gb
3630         touch $DIR/${tdir}ga/f
3631         ln $DIR/${tdir}ga/f $DIR/${tdir}gb/g
3632         $CHECKSTAT -t file $DIR/${tdir}ga/f || error "source"
3633         [ `stat -c%h $DIR/${tdir}ga/f` == '2' ] || error "source nlink"
3634         $CHECKSTAT -t file $DIR/${tdir}gb/g || error "target"
3635         [ `stat -c%h $DIR/${tdir}gb/g` == '2' ] || error "target nlink"
3636 }
3637 run_test 31g "cross directory link==============="
3638
3639 test_31h() {
3640         echo "-- cross directory link --"
3641         test_mkdir -c1 $DIR/${tdir}
3642         test_mkdir -c1 $DIR/${tdir}/dir
3643         touch $DIR/${tdir}/f
3644         ln $DIR/${tdir}/f $DIR/${tdir}/dir/g
3645         $CHECKSTAT -t file $DIR/${tdir}/f || error "source"
3646         [ `stat -c%h $DIR/${tdir}/f` == '2' ] || error "source nlink"
3647         $CHECKSTAT -t file $DIR/${tdir}/dir/g || error "target"
3648         [ `stat -c%h $DIR/${tdir}/dir/g` == '2' ] || error "target nlink"
3649 }
3650 run_test 31h "cross directory link under child==============="
3651
3652 test_31i() {
3653         echo "-- cross directory link --"
3654         test_mkdir -c1 $DIR/$tdir
3655         test_mkdir -c1 $DIR/$tdir/dir
3656         touch $DIR/$tdir/dir/f
3657         ln $DIR/$tdir/dir/f $DIR/$tdir/g
3658         $CHECKSTAT -t file $DIR/$tdir/dir/f || error "source"
3659         [ `stat -c%h $DIR/$tdir/dir/f` == '2' ] || error "source nlink"
3660         $CHECKSTAT -t file $DIR/$tdir/g || error "target"
3661         [ `stat -c%h $DIR/$tdir/g` == '2' ] || error "target nlink"
3662 }
3663 run_test 31i "cross directory link under parent==============="
3664
3665 test_31j() {
3666         test_mkdir -c1 -p $DIR/$tdir
3667         test_mkdir -c1 -p $DIR/$tdir/dir1
3668         ln $DIR/$tdir/dir1 $DIR/$tdir/dir2 && error "ln for dir"
3669         link $DIR/$tdir/dir1 $DIR/$tdir/dir3 && error "link for dir"
3670         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir4 && error "mlink for dir"
3671         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir1 && error "mlink to the same dir"
3672         return 0
3673 }
3674 run_test 31j "link for directory==============="
3675
3676 test_31k() {
3677         test_mkdir -c1 -p $DIR/$tdir
3678         touch $DIR/$tdir/s
3679         touch $DIR/$tdir/exist
3680         mlink $DIR/$tdir/s $DIR/$tdir/t || error "mlink"
3681         mlink $DIR/$tdir/s $DIR/$tdir/exist && error "mlink to exist file"
3682         mlink $DIR/$tdir/s $DIR/$tdir/s && error "mlink to the same file"
3683         mlink $DIR/$tdir/s $DIR/$tdir && error "mlink to parent dir"
3684         mlink $DIR/$tdir $DIR/$tdir/s && error "mlink parent dir to target"
3685         mlink $DIR/$tdir/not-exist $DIR/$tdir/foo && error "mlink non-existing to new"
3686         mlink $DIR/$tdir/not-exist $DIR/$tdir/s && error "mlink non-existing to exist"
3687         return 0
3688 }
3689 run_test 31k "link to file: the same, non-existing, dir==============="
3690
3691 test_31m() {
3692         mkdir $DIR/d31m
3693         touch $DIR/d31m/s
3694         mkdir $DIR/d31m2
3695         touch $DIR/d31m2/exist
3696         mlink $DIR/d31m/s $DIR/d31m2/t || error "mlink"
3697         mlink $DIR/d31m/s $DIR/d31m2/exist && error "mlink to exist file"
3698         mlink $DIR/d31m/s $DIR/d31m2 && error "mlink to parent dir"
3699         mlink $DIR/d31m2 $DIR/d31m/s && error "mlink parent dir to target"
3700         mlink $DIR/d31m/not-exist $DIR/d31m2/foo && error "mlink non-existing to new"
3701         mlink $DIR/d31m/not-exist $DIR/d31m2/s && error "mlink non-existing to exist"
3702         return 0
3703 }
3704 run_test 31m "link to file: the same, non-existing, dir==============="
3705
3706 test_31n() {
3707         touch $DIR/$tfile || error "cannot create '$DIR/$tfile'"
3708         nlink=$(stat --format=%h $DIR/$tfile)
3709         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3710         local fd=$(free_fd)
3711         local cmd="exec $fd<$DIR/$tfile"
3712         eval $cmd
3713         cmd="exec $fd<&-"
3714         trap "eval $cmd" EXIT
3715         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3716         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3717         rm $DIR/$tfile || error "cannot remove '$DIR/$tfile'"
3718         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3719         [ ${nlink:--1} -eq 0 ] || error "nlink is $nlink, expected 0"
3720         eval $cmd
3721 }
3722 run_test 31n "check link count of unlinked file"
3723
3724 link_one() {
3725         local tempfile=$(mktemp $1_XXXXXX)
3726         mlink $tempfile $1 2> /dev/null &&
3727                 echo "$BASHPID: link $tempfile to $1 succeeded"
3728         munlink $tempfile
3729 }
3730
3731 test_31o() { # LU-2901
3732         test_mkdir $DIR/$tdir
3733         for LOOP in $(seq 100); do
3734                 rm -f $DIR/$tdir/$tfile*
3735                 for THREAD in $(seq 8); do
3736                         link_one $DIR/$tdir/$tfile.$LOOP &
3737                 done
3738                 wait
3739                 local LINKS=$(ls -1 $DIR/$tdir | grep -c $tfile.$LOOP)
3740                 [[ $LINKS -gt 1 ]] && ls $DIR/$tdir &&
3741                         error "$LINKS duplicate links to $tfile.$LOOP" &&
3742                         break || true
3743         done
3744 }
3745 run_test 31o "duplicate hard links with same filename"
3746
3747 test_31p() {
3748         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3749
3750         test_mkdir $DIR/$tdir
3751         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3752         $LFS setdirstripe -D -c2 -H all_char $DIR/$tdir/striped_dir
3753
3754         opendirunlink $DIR/$tdir/striped_dir/test1 ||
3755                 error "open unlink test1 failed"
3756         opendirunlink $DIR/$tdir/striped_dir/test2 ||
3757                 error "open unlink test2 failed"
3758
3759         $CHECKSTAT -a $DIR/$tdir/striped_dir/test1 ||
3760                 error "test1 still exists"
3761         $CHECKSTAT -a $DIR/$tdir/striped_dir/test2 ||
3762                 error "test2 still exists"
3763 }
3764 run_test 31p "remove of open striped directory"
3765
3766 test_31q() {
3767         [ $MDSCOUNT -lt 3 ] && skip_env "needs >= 3 MDTs"
3768
3769         $LFS mkdir -i 3,1 $DIR/$tdir || error "mkdir failed"
3770         index=$($LFS getdirstripe -i $DIR/$tdir)
3771         [ $index -eq 3 ] || error "first stripe index $index != 3"
3772         index=$($LFS getdirstripe $DIR/$tdir | tail -1 | awk '{print $1}')
3773         [ $index -eq 1 ] || error "second stripe index $index != 1"
3774
3775         # when "-c <stripe_count>" is set, the number of MDTs specified after
3776         # "-i" should equal to the stripe count
3777         $LFS mkdir -i 3,1 -c 3 $DIR/$tdir.2 && error "mkdir should fail" || true
3778 }
3779 run_test 31q "create striped directory on specific MDTs"
3780
3781 #LU-14949
3782 test_31r() {
3783         touch $DIR/$tfile.target
3784         touch $DIR/$tfile.source
3785
3786         #OBD_FAIL_LLITE_OPEN_DELAY 0x1419
3787         $LCTL set_param fail_loc=0x1419 fail_val=3
3788         cat $DIR/$tfile.target &
3789         CATPID=$!
3790
3791         # Guarantee open is waiting before we get here
3792         sleep 1
3793         mv $DIR/$tfile.source $DIR/$tfile.target
3794
3795         wait $CATPID
3796         RC=$?
3797         if [[ $RC -ne 0 ]]; then
3798                 error "open with cat failed, rc=$RC"
3799         fi
3800 }
3801 run_test 31r "open-rename(replace) race"
3802
3803 cleanup_test32_mount() {
3804         local rc=0
3805         trap 0
3806         local loopdev=$(losetup -a | grep $EXT2_DEV | sed -ne 's/:.*$//p')
3807         $UMOUNT $DIR/$tdir/ext2-mountpoint || rc=$?
3808         losetup -d $loopdev || true
3809         rm -rf $DIR/$tdir
3810         return $rc
3811 }
3812
3813 test_32a() {
3814         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3815
3816         echo "== more mountpoints and symlinks ================="
3817         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3818         trap cleanup_test32_mount EXIT
3819         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3820         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3821                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3822         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/.. ||
3823                 error "$DIR/$tdir/ext2-mountpoint/.. not dir type"
3824         cleanup_test32_mount
3825 }
3826 run_test 32a "stat d32a/ext2-mountpoint/.. ====================="
3827
3828 test_32b() {
3829         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3830
3831         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3832         trap cleanup_test32_mount EXIT
3833         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3834         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3835                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3836         ls -al $DIR/$tdir/ext2-mountpoint/.. ||
3837                 error "Can't list $DIR/$tdir/ext2-mountpoint/.."
3838         cleanup_test32_mount
3839 }
3840 run_test 32b "open d32b/ext2-mountpoint/.. ====================="
3841
3842 test_32c() {
3843         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3844
3845         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3846         trap cleanup_test32_mount EXIT
3847         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3848         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3849                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3850         test_mkdir -p $DIR/$tdir/d2/test_dir
3851         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3852                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_dir not dir type"
3853         cleanup_test32_mount
3854 }
3855 run_test 32c "stat d32c/ext2-mountpoint/../d2/test_dir ========="
3856
3857 test_32d() {
3858         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3859
3860         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3861         trap cleanup_test32_mount EXIT
3862         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3863         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3864                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3865         test_mkdir -p $DIR/$tdir/d2/test_dir
3866         ls -al $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3867                 error "Can't list $DIR/$tdir/ext2-mountpoint/../d2/test_dir"
3868         cleanup_test32_mount
3869 }
3870 run_test 32d "open d32d/ext2-mountpoint/../d2/test_dir"
3871
3872 test_32e() {
3873         rm -fr $DIR/$tdir
3874         test_mkdir -p $DIR/$tdir/tmp
3875         local tmp_dir=$DIR/$tdir/tmp
3876         ln -s $DIR/$tdir $tmp_dir/symlink11
3877         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3878         $CHECKSTAT -t link $DIR/$tdir/tmp/symlink11 || error "symlink11 bad"
3879         $CHECKSTAT -t link $DIR/$tdir/symlink01 || error "symlink01 bad"
3880 }
3881 run_test 32e "stat d32e/symlink->tmp/symlink->lustre-subdir"
3882
3883 test_32f() {
3884         rm -fr $DIR/$tdir
3885         test_mkdir -p $DIR/$tdir/tmp
3886         local tmp_dir=$DIR/$tdir/tmp
3887         ln -s $DIR/$tdir $tmp_dir/symlink11
3888         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3889         ls $DIR/$tdir/tmp/symlink11  || error "symlink11 bad"
3890         ls $DIR/$tdir/symlink01 || error "symlink01 bad"
3891 }
3892 run_test 32f "open d32f/symlink->tmp/symlink->lustre-subdir"
3893
3894 test_32g() {
3895         local tmp_dir=$DIR/$tdir/tmp
3896         test_mkdir -p $tmp_dir
3897         test_mkdir $DIR/${tdir}2
3898         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3899         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3900         $CHECKSTAT -t link $tmp_dir/symlink12 || error "symlink12 not a link"
3901         $CHECKSTAT -t link $DIR/$tdir/symlink02 || error "symlink02 not a link"
3902         $CHECKSTAT -t dir -f $tmp_dir/symlink12 || error "symlink12 not a dir"
3903         $CHECKSTAT -t dir -f $DIR/$tdir/symlink02 || error "symlink12 not a dir"
3904 }
3905 run_test 32g "stat d32g/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3906
3907 test_32h() {
3908         rm -fr $DIR/$tdir $DIR/${tdir}2
3909         tmp_dir=$DIR/$tdir/tmp
3910         test_mkdir -p $tmp_dir
3911         test_mkdir $DIR/${tdir}2
3912         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3913         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3914         ls $tmp_dir/symlink12 || error "listing symlink12"
3915         ls $DIR/$tdir/symlink02  || error "listing symlink02"
3916 }
3917 run_test 32h "open d32h/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3918
3919 test_32i() {
3920         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3921
3922         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3923         trap cleanup_test32_mount EXIT
3924         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3925         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3926                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3927         touch $DIR/$tdir/test_file
3928         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../test_file ||
3929                 error "$DIR/$tdir/ext2-mountpoint/../test_file not file type"
3930         cleanup_test32_mount
3931 }
3932 run_test 32i "stat d32i/ext2-mountpoint/../test_file ==========="
3933
3934 test_32j() {
3935         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3936
3937         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3938         trap cleanup_test32_mount EXIT
3939         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3940         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3941                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3942         touch $DIR/$tdir/test_file
3943         cat $DIR/$tdir/ext2-mountpoint/../test_file ||
3944                 error "Can't open $DIR/$tdir/ext2-mountpoint/../test_file"
3945         cleanup_test32_mount
3946 }
3947 run_test 32j "open d32j/ext2-mountpoint/../test_file ==========="
3948
3949 test_32k() {
3950         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3951
3952         rm -fr $DIR/$tdir
3953         trap cleanup_test32_mount EXIT
3954         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3955         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3956                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3957         test_mkdir -p $DIR/$tdir/d2
3958         touch $DIR/$tdir/d2/test_file || error "touch failed"
3959         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
3960                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_file not file type"
3961         cleanup_test32_mount
3962 }
3963 run_test 32k "stat d32k/ext2-mountpoint/../d2/test_file ========"
3964
3965 test_32l() {
3966         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3967
3968         rm -fr $DIR/$tdir
3969         trap cleanup_test32_mount EXIT
3970         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3971         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3972                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3973         test_mkdir -p $DIR/$tdir/d2
3974         touch $DIR/$tdir/d2/test_file || error "touch failed"
3975         cat  $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
3976                 error "Can't open $DIR/$tdir/ext2-mountpoint/../d2/test_file"
3977         cleanup_test32_mount
3978 }
3979 run_test 32l "open d32l/ext2-mountpoint/../d2/test_file ========"
3980
3981 test_32m() {
3982         rm -fr $DIR/d32m
3983         test_mkdir -p $DIR/d32m/tmp
3984         TMP_DIR=$DIR/d32m/tmp
3985         ln -s $DIR $TMP_DIR/symlink11
3986         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
3987         $CHECKSTAT -t link $DIR/d32m/tmp/symlink11 ||
3988                 error "symlink11 not a link"
3989         $CHECKSTAT -t link $DIR/d32m/symlink01 ||
3990                 error "symlink01 not a link"
3991 }
3992 run_test 32m "stat d32m/symlink->tmp/symlink->lustre-root ======"
3993
3994 test_32n() {
3995         rm -fr $DIR/d32n
3996         test_mkdir -p $DIR/d32n/tmp
3997         TMP_DIR=$DIR/d32n/tmp
3998         ln -s $DIR $TMP_DIR/symlink11
3999         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
4000         ls -l $DIR/d32n/tmp/symlink11  || error "listing symlink11"
4001         ls -l $DIR/d32n/symlink01 || error "listing symlink01"
4002 }
4003 run_test 32n "open d32n/symlink->tmp/symlink->lustre-root ======"
4004
4005 test_32o() {
4006         touch $DIR/$tfile
4007         test_mkdir -p $DIR/d32o/tmp
4008         TMP_DIR=$DIR/d32o/tmp
4009         ln -s $DIR/$tfile $TMP_DIR/symlink12
4010         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
4011         $CHECKSTAT -t link $DIR/d32o/tmp/symlink12 ||
4012                 error "symlink12 not a link"
4013         $CHECKSTAT -t link $DIR/d32o/symlink02 || error "symlink02 not a link"
4014         $CHECKSTAT -t file -f $DIR/d32o/tmp/symlink12 ||
4015                 error "$DIR/d32o/tmp/symlink12 not file type"
4016         $CHECKSTAT -t file -f $DIR/d32o/symlink02 ||
4017                 error "$DIR/d32o/symlink02 not file type"
4018 }
4019 run_test 32o "stat d32o/symlink->tmp/symlink->lustre-root/$tfile"
4020
4021 test_32p() {
4022         log 32p_1
4023         rm -fr $DIR/d32p
4024         log 32p_2
4025         rm -f $DIR/$tfile
4026         log 32p_3
4027         touch $DIR/$tfile
4028         log 32p_4
4029         test_mkdir -p $DIR/d32p/tmp
4030         log 32p_5
4031         TMP_DIR=$DIR/d32p/tmp
4032         log 32p_6
4033         ln -s $DIR/$tfile $TMP_DIR/symlink12
4034         log 32p_7
4035         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
4036         log 32p_8
4037         cat $DIR/d32p/tmp/symlink12 ||
4038                 error "Can't open $DIR/d32p/tmp/symlink12"
4039         log 32p_9
4040         cat $DIR/d32p/symlink02 || error "Can't open $DIR/d32p/symlink02"
4041         log 32p_10
4042 }
4043 run_test 32p "open d32p/symlink->tmp/symlink->lustre-root/$tfile"
4044
4045 test_32q() {
4046         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4047
4048         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
4049         trap cleanup_test32_mount EXIT
4050         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4051         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
4052         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4053                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4054         ls $DIR/$tdir/ext2-mountpoint | grep "\<under_the_mount\>" && error
4055         cleanup_test32_mount
4056 }
4057 run_test 32q "stat follows mountpoints in Lustre (should return error)"
4058
4059 test_32r() {
4060         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4061
4062         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
4063         trap cleanup_test32_mount EXIT
4064         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4065         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
4066         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4067                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4068         ls $DIR/$tdir/ext2-mountpoint | grep -q under_the_mount && error || true
4069         cleanup_test32_mount
4070 }
4071 run_test 32r "opendir follows mountpoints in Lustre (should return error)"
4072
4073 test_33aa() {
4074         rm -f $DIR/$tfile
4075         touch $DIR/$tfile
4076         chmod 444 $DIR/$tfile
4077         chown $RUNAS_ID $DIR/$tfile
4078         log 33_1
4079         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
4080         log 33_2
4081 }
4082 run_test 33aa "write file with mode 444 (should return error)"
4083
4084 test_33a() {
4085         rm -fr $DIR/$tdir
4086         test_mkdir $DIR/$tdir
4087         chown $RUNAS_ID $DIR/$tdir
4088         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile ||
4089                 error "$RUNAS create $tdir/$tfile failed"
4090         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile &&
4091                 error "open RDWR" || true
4092 }
4093 run_test 33a "test open file(mode=0444) with O_RDWR (should return error)"
4094
4095 test_33b() {
4096         rm -fr $DIR/$tdir
4097         test_mkdir $DIR/$tdir
4098         chown $RUNAS_ID $DIR/$tdir
4099         $RUNAS $OPENFILE -f 1286739555 $DIR/$tdir/$tfile || true
4100 }
4101 run_test 33b "test open file with malformed flags (No panic)"
4102
4103 test_33c() {
4104         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4105         remote_ost_nodsh && skip "remote OST with nodsh"
4106
4107         local ostnum
4108         local ostname
4109         local write_bytes
4110         local all_zeros
4111
4112         all_zeros=true
4113         test_mkdir $DIR/$tdir
4114         # Read: 0, Write: 4, create/destroy: 2/0, stat: 1, punch: 0
4115
4116         sync
4117         for ostnum in $(seq $OSTCOUNT); do
4118                 # test-framework's OST numbering is one-based, while Lustre's
4119                 # is zero-based
4120                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4121                 # check if at least some write_bytes stats are counted
4122                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
4123                               obdfilter.$ostname.stats |
4124                               awk '/^write_bytes/ {print $7}' )
4125                 echo "baseline_write_bytes@ost$ostnum/$ostname=$write_bytes"
4126                 if (( ${write_bytes:-0} > 0 )); then
4127                         all_zeros=false
4128                         break
4129                 fi
4130         done
4131
4132         $all_zeros || return 0
4133
4134         # Write four bytes
4135         echo foo > $DIR/$tdir/bar
4136         # Really write them
4137         sync
4138
4139         # Total up write_bytes after writing.  We'd better find non-zeros.
4140         for ostnum in $(seq $OSTCOUNT); do
4141                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4142                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
4143                               obdfilter/$ostname/stats |
4144                               awk '/^write_bytes/ {print $7}' )
4145                 echo "write_bytes@ost$ostnum/$ostname=$write_bytes"
4146                 if (( ${write_bytes:-0} > 0 )); then
4147                         all_zeros=false
4148                         break
4149                 fi
4150         done
4151
4152         if $all_zeros; then
4153                 for ostnum in $(seq $OSTCOUNT); do
4154                         ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4155                         echo "Check write_bytes is in obdfilter.*.stats:"
4156                         do_facet ost$ostnum lctl get_param -n \
4157                                 obdfilter.$ostname.stats
4158                 done
4159                 error "OST not keeping write_bytes stats (b=22312)"
4160         fi
4161 }
4162 run_test 33c "test write_bytes stats"
4163
4164 test_33d() {
4165         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
4166         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4167
4168         local MDTIDX=1
4169         local remote_dir=$DIR/$tdir/remote_dir
4170
4171         test_mkdir $DIR/$tdir
4172         $LFS mkdir -i $MDTIDX $remote_dir ||
4173                 error "create remote directory failed"
4174
4175         touch $remote_dir/$tfile
4176         chmod 444 $remote_dir/$tfile
4177         chown $RUNAS_ID $remote_dir/$tfile
4178
4179         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
4180
4181         chown $RUNAS_ID $remote_dir
4182         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 ||
4183                                         error "create" || true
4184         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 &&
4185                                     error "open RDWR" || true
4186         $RUNAS $OPENFILE -f 1286739555 $remote_dir/f33 || true
4187 }
4188 run_test 33d "openfile with 444 modes and malformed flags under remote dir"
4189
4190 test_33e() {
4191         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4192
4193         mkdir $DIR/$tdir
4194
4195         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4196         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4197         mkdir $DIR/$tdir/local_dir
4198
4199         local s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4200         local s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4201         local l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4202
4203         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4204                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode"
4205
4206         rmdir $DIR/$tdir/* || error "rmdir failed"
4207
4208         umask 777
4209         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4210         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4211         mkdir $DIR/$tdir/local_dir
4212
4213         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4214         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4215         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4216
4217         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4218                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 777"
4219
4220         rmdir $DIR/$tdir/* || error "rmdir(umask 777) failed"
4221
4222         umask 000
4223         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4224         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4225         mkdir $DIR/$tdir/local_dir
4226
4227         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4228         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4229         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4230
4231         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4232                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 0"
4233 }
4234 run_test 33e "mkdir and striped directory should have same mode"
4235
4236 cleanup_33f() {
4237         trap 0
4238         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=0
4239 }
4240
4241 test_33f() {
4242         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4243         remote_mds_nodsh && skip "remote MDS with nodsh"
4244
4245         mkdir $DIR/$tdir
4246         chmod go+rwx $DIR/$tdir
4247         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=-1
4248         trap cleanup_33f EXIT
4249
4250         $RUNAS lfs mkdir -i 0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
4251                 error "cannot create striped directory"
4252
4253         $RUNAS touch $DIR/$tdir/striped_dir/{0..16} ||
4254                 error "cannot create files in striped directory"
4255
4256         $RUNAS rm $DIR/$tdir/striped_dir/{0..16} ||
4257                 error "cannot remove files in striped directory"
4258
4259         $RUNAS rmdir $DIR/$tdir/striped_dir ||
4260                 error "cannot remove striped directory"
4261
4262         cleanup_33f
4263 }
4264 run_test 33f "nonroot user can create, access, and remove a striped directory"
4265
4266 test_33g() {
4267         mkdir -p $DIR/$tdir/dir2
4268
4269         local err=$($RUNAS mkdir $DIR/$tdir/dir2 2>&1)
4270         echo $err
4271         [[ $err =~ "exists" ]] || error "Not exists error"
4272 }
4273 run_test 33g "nonroot user create already existing root created file"
4274
4275 sub_33h() {
4276         local hash_type=$1
4277         local count=250
4278
4279         test_mkdir -c $MDSCOUNT -H $hash_type $DIR/$tdir ||
4280                 error "lfs mkdir -H $hash_type $tdir failed"
4281         touch $DIR/$tdir/$tfile || error "touch $tfile failed"
4282
4283         local index=$($LFS getstripe -m $DIR/$tdir/$tfile)
4284         local index2
4285         local fname
4286
4287         for fname in $DIR/$tdir/$tfile.bak \
4288                      $DIR/$tdir/$tfile.SAV \
4289                      $DIR/$tdir/$tfile.orig \
4290                      $DIR/$tdir/$tfile~; do
4291                 touch $fname || error "touch $fname failed"
4292                 index2=$($LFS getstripe -m $fname)
4293                 (( $index == $index2 )) ||
4294                         error "$fname MDT index mismatch $index != $index2"
4295         done
4296
4297         local failed=0
4298         local patterns=(".$tfile.XXXXXX" "$tfile.XXXXXXXX")
4299         local pattern
4300
4301         for pattern in ${patterns[*]}; do
4302                 echo "pattern $pattern"
4303                 fname=$DIR/$tdir/$pattern
4304                 for (( i = 0; i < $count; i++ )); do
4305                         fname=$(mktemp $DIR/$tdir/$pattern) ||
4306                                 error "mktemp $DIR/$tdir/$pattern failed"
4307                         index2=$($LFS getstripe -m $fname)
4308                         (( $index == $index2 )) && continue
4309
4310                         failed=$((failed + 1))
4311                         echo "$fname MDT index mismatch $index != $index2"
4312                 done
4313         done
4314
4315         echo "$failed/$count MDT index mismatches, expect ~2-4"
4316         (( failed < 10 )) || error "MDT index mismatch $failed/$count times"
4317
4318         local same=0
4319         local expect
4320
4321         # verify that "crush" is still broken with all files on same MDT,
4322         # crush2 should have about 1/MDSCOUNT files on each MDT, with margin
4323         [[ "$hash_type" == "crush" ]] && expect=$count ||
4324                 expect=$((count / MDSCOUNT))
4325
4326         # crush2 doesn't put all-numeric suffixes on the same MDT,
4327         # filename like $tfile.12345678 should *not* be considered temp
4328         for pattern in ${patterns[*]}; do
4329                 local base=${pattern%%X*}
4330                 local suff=${pattern#$base}
4331
4332                 echo "pattern $pattern"
4333                 for (( i = 0; i < $count; i++ )); do
4334                         fname=$DIR/$tdir/$base$((${suff//X/1} + i))
4335                         touch $fname || error "touch $fname failed"
4336                         index2=$($LFS getstripe -m $fname)
4337                         (( $index != $index2 )) && continue
4338
4339                         same=$((same + 1))
4340                 done
4341         done
4342
4343         # the number of "bad" hashes is random, as it depends on the random
4344         # filenames generated by "mktemp".  Allow some margin in the results.
4345         echo "$((same/${#patterns[*]}))/$count matches, expect ~$expect for $1"
4346         (( same / ${#patterns[*]} <= expect * 9 / 7 &&
4347            same / ${#patterns[*]} > expect * 5 / 7 )) ||
4348                 error "MDT index match $((same / ${#patterns[*]}))/$count times"
4349         same=0
4350
4351         # crush2 doesn't put suffixes with special characters on the same MDT
4352         # filename like $tfile.txt.1234 should *not* be considered temp
4353         for pattern in ${patterns[*]}; do
4354                 local base=${pattern%%X*}
4355                 local suff=${pattern#$base}
4356
4357                 pattern=$base...${suff/XXX}
4358                 echo "pattern=$pattern"
4359                 for (( i = 0; i < $count; i++ )); do
4360                         fname=$(mktemp $DIR/$tdir/$pattern) ||
4361                                 error "touch $fname failed"
4362                         index2=$($LFS getstripe -m $fname)
4363                         (( $index != $index2 )) && continue
4364
4365                         same=$((same + 1))
4366                 done
4367         done
4368
4369         # the number of "bad" hashes is random, as it depends on the random
4370         # filenames generated by "mktemp".  Allow some margin in the results.
4371         echo "$((same/${#patterns[*]}))/$count matches, expect ~$expect for $1"
4372         (( same / ${#patterns[*]} <= expect * 9 / 7 &&
4373            same / ${#patterns[*]} > expect * 5 / 7 )) ||
4374                 error "MDT index match $((same / ${#patterns[*]}))/$count times"
4375 }
4376
4377 test_33h() {
4378         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
4379         (( $MDS1_VERSION >= $(version_code 2.13.50) )) ||
4380                 skip "Need MDS version at least 2.13.50"
4381
4382         sub_33h crush
4383 }
4384 run_test 33h "temp file is located on the same MDT as target (crush)"
4385
4386 test_33hh() {
4387         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
4388         echo "MDS1_VERSION=$MDS1_VERSION version_code=$(version_code 2.15.0)"
4389         (( $MDS1_VERSION > $(version_code 2.15.0) )) ||
4390                 skip "Need MDS version at least 2.15.0 for crush2"
4391
4392         sub_33h crush2
4393 }
4394 run_test 33hh "temp file is located on the same MDT as target (crush2)"
4395
4396 test_33i()
4397 {
4398         (( MDSCOUNT < 2 )) && skip "needs >= 2 MDTs"
4399
4400         local FNAME=$(str_repeat 'f' 250)
4401
4402         test_mkdir -i 0 -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
4403         createmany -o $DIR/$tdir/$FNAME 1000 || error "createmany failed"
4404
4405         local count
4406         local total
4407
4408         count=$($LFS getstripe -m $DIR/$tdir/* | grep -cw 1)
4409
4410         local MDC=$(lctl dl | awk '/MDT0001-mdc-[^M]/ { print $4 }')
4411
4412         lctl --device %$MDC deactivate
4413         stack_trap "lctl --device %$MDC activate"
4414         ls $DIR/$tdir > /dev/null && error "ls should return an error"
4415         total=$(\ls -l $DIR/$tdir | wc -l)
4416         # "ls -l" will list total in the first line
4417         total=$((total - 1))
4418         (( total + count == 1000 )) ||
4419                 error "ls list $total files, $count files on MDT1"
4420 }
4421 run_test 33i "striped directory can be accessed when one MDT is down"
4422
4423 TEST_34_SIZE=${TEST_34_SIZE:-2000000000000}
4424 test_34a() {
4425         rm -f $DIR/f34
4426         $MCREATE $DIR/f34 || error "mcreate failed"
4427         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4428                 error "getstripe failed"
4429         $TRUNCATE $DIR/f34 $TEST_34_SIZE || error "truncate failed"
4430         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4431                 error "getstripe failed"
4432         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4433                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4434 }
4435 run_test 34a "truncate file that has not been opened ==========="
4436
4437 test_34b() {
4438         [ ! -f $DIR/f34 ] && test_34a
4439         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4440                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4441         $OPENFILE -f O_RDONLY $DIR/f34
4442         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4443                 error "getstripe failed"
4444         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4445                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4446 }
4447 run_test 34b "O_RDONLY opening file doesn't create objects ====="
4448
4449 test_34c() {
4450         [ ! -f $DIR/f34 ] && test_34a
4451         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4452                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4453         $OPENFILE -f O_RDWR $DIR/f34
4454         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" &&
4455                 error "$LFS getstripe failed"
4456         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4457                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4458 }
4459 run_test 34c "O_RDWR opening file-with-size works =============="
4460
4461 test_34d() {
4462         [ ! -f $DIR/f34 ] && test_34a
4463         dd if=/dev/zero of=$DIR/f34 conv=notrunc bs=4k count=1 ||
4464                 error "dd failed"
4465         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4466                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4467         rm $DIR/f34
4468 }
4469 run_test 34d "write to sparse file ============================="
4470
4471 test_34e() {
4472         rm -f $DIR/f34e
4473         $MCREATE $DIR/f34e || error "mcreate failed"
4474         $TRUNCATE $DIR/f34e 1000 || error "truncate failed"
4475         $CHECKSTAT -s 1000 $DIR/f34e ||
4476                 error "Size of $DIR/f34e not equal to 1000 bytes"
4477         $OPENFILE -f O_RDWR $DIR/f34e
4478         $CHECKSTAT -s 1000 $DIR/f34e ||
4479                 error "Size of $DIR/f34e not equal to 1000 bytes"
4480 }
4481 run_test 34e "create objects, some with size and some without =="
4482
4483 test_34f() { # bug 6242, 6243
4484         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4485
4486         SIZE34F=48000
4487         rm -f $DIR/f34f
4488         $MCREATE $DIR/f34f || error "mcreate failed"
4489         $TRUNCATE $DIR/f34f $SIZE34F || error "truncating $DIR/f3f to $SIZE34F"
4490         dd if=$DIR/f34f of=$TMP/f34f
4491         $CHECKSTAT -s $SIZE34F $TMP/f34f || error "$TMP/f34f not $SIZE34F bytes"
4492         dd if=/dev/zero of=$TMP/f34fzero bs=$SIZE34F count=1
4493         cmp $DIR/f34f $TMP/f34fzero || error "$DIR/f34f not all zero"
4494         cmp $TMP/f34f $TMP/f34fzero || error "$TMP/f34f not all zero"
4495         rm $TMP/f34f $TMP/f34fzero $DIR/f34f
4496 }
4497 run_test 34f "read from a file with no objects until EOF ======="
4498
4499 test_34g() {
4500         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4501
4502         dd if=/dev/zero of=$DIR/$tfile bs=1 count=100 seek=$TEST_34_SIZE ||
4503                 error "dd failed"
4504         $TRUNCATE $DIR/$tfile $((TEST_34_SIZE / 2))|| error "truncate failed"
4505         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
4506                 error "Size of $DIR/$tfile not equal to $((TEST_34_SIZE / 2))"
4507         cancel_lru_locks osc
4508         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
4509                 error "wrong size after lock cancel"
4510
4511         $TRUNCATE $DIR/$tfile $TEST_34_SIZE || error "truncate failed"
4512         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
4513                 error "expanding truncate failed"
4514         cancel_lru_locks osc
4515         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
4516                 error "wrong expanded size after lock cancel"
4517 }
4518 run_test 34g "truncate long file ==============================="
4519
4520 test_34h() {
4521         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4522
4523         local gid=10
4524         local sz=1000
4525
4526         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 || error "dd failed"
4527         sync # Flush the cache so that multiop below does not block on cache
4528              # flush when getting the group lock
4529         $MULTIOP $DIR/$tfile OG${gid}T${sz}g${gid}c &
4530         MULTIPID=$!
4531
4532         # Since just timed wait is not good enough, let's do a sync write
4533         # that way we are sure enough time for a roundtrip + processing
4534         # passed + 2 seconds of extra margin.
4535         dd if=/dev/zero of=$DIR/${tfile}-1 bs=$PAGE_SIZE oflag=direct count=1
4536         rm $DIR/${tfile}-1
4537         sleep 2
4538
4539         if [[ `ps h -o comm -p $MULTIPID` == "multiop" ]]; then
4540                 error "Multiop blocked on ftruncate, pid=$MULTIPID"
4541                 kill -9 $MULTIPID
4542         fi
4543         wait $MULTIPID
4544         local nsz=`stat -c %s $DIR/$tfile`
4545         [[ $nsz == $sz ]] || error "New size wrong $nsz != $sz"
4546 }
4547 run_test 34h "ftruncate file under grouplock should not block"
4548
4549 test_35a() {
4550         cp /bin/sh $DIR/f35a
4551         chmod 444 $DIR/f35a
4552         chown $RUNAS_ID $DIR/f35a
4553         $RUNAS $DIR/f35a && error || true
4554         rm $DIR/f35a
4555 }
4556 run_test 35a "exec file with mode 444 (should return and not leak)"
4557
4558 test_36a() {
4559         rm -f $DIR/f36
4560         utime $DIR/f36 || error "utime failed for MDS"
4561 }
4562 run_test 36a "MDS utime check (mknod, utime)"
4563
4564 test_36b() {
4565         echo "" > $DIR/f36
4566         utime $DIR/f36 || error "utime failed for OST"
4567 }
4568 run_test 36b "OST utime check (open, utime)"
4569
4570 test_36c() {
4571         rm -f $DIR/d36/f36
4572         test_mkdir $DIR/d36
4573         chown $RUNAS_ID $DIR/d36
4574         $RUNAS utime $DIR/d36/f36 || error "utime failed for MDS as non-root"
4575 }
4576 run_test 36c "non-root MDS utime check (mknod, utime)"
4577
4578 test_36d() {
4579         [ ! -d $DIR/d36 ] && test_36c
4580         echo "" > $DIR/d36/f36
4581         $RUNAS utime $DIR/d36/f36 || error "utime failed for OST as non-root"
4582 }
4583 run_test 36d "non-root OST utime check (open, utime)"
4584
4585 test_36e() {
4586         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID -- skipping"
4587
4588         test_mkdir $DIR/$tdir
4589         touch $DIR/$tdir/$tfile
4590         $RUNAS utime $DIR/$tdir/$tfile &&
4591                 error "utime worked, expected failure" || true
4592 }
4593 run_test 36e "utime on non-owned file (should return error)"
4594
4595 subr_36fh() {
4596         local fl="$1"
4597         local LANG_SAVE=$LANG
4598         local LC_LANG_SAVE=$LC_LANG
4599         export LANG=C LC_LANG=C # for date language
4600
4601         DATESTR="Dec 20  2000"
4602         test_mkdir $DIR/$tdir
4603         lctl set_param fail_loc=$fl
4604         date; date +%s
4605         cp /etc/hosts $DIR/$tdir/$tfile
4606         sync & # write RPC generated with "current" inode timestamp, but delayed
4607         sleep 1
4608         touch --date="$DATESTR" $DIR/$tdir/$tfile # setattr timestamp in past
4609         LS_BEFORE="`ls -l $DIR/$tdir/$tfile`" # old timestamp from client cache
4610         cancel_lru_locks $OSC
4611         LS_AFTER="`ls -l $DIR/$tdir/$tfile`"  # timestamp from OST object
4612         date; date +%s
4613         [ "$LS_BEFORE" != "$LS_AFTER" ] && \
4614                 echo "BEFORE: $LS_BEFORE" && \
4615                 echo "AFTER : $LS_AFTER" && \
4616                 echo "WANT  : $DATESTR" && \
4617                 error "$DIR/$tdir/$tfile timestamps changed" || true
4618
4619         export LANG=$LANG_SAVE LC_LANG=$LC_LANG_SAVE
4620 }
4621
4622 test_36f() {
4623         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4624
4625         #define OBD_FAIL_OST_BRW_PAUSE_BULK 0x214
4626         subr_36fh "0x80000214"
4627 }
4628 run_test 36f "utime on file racing with OST BRW write =========="
4629
4630 test_36g() {
4631         remote_ost_nodsh && skip "remote OST with nodsh"
4632         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4633         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
4634                 skip "Need MDS version at least 2.12.51"
4635
4636         local fmd_max_age
4637         local fmd
4638         local facet="ost1"
4639         local tgt="obdfilter"
4640
4641         [[ $OSC == "mdc" ]] && tgt="mdt" && facet="mds1"
4642
4643         test_mkdir $DIR/$tdir
4644         fmd_max_age=$(do_facet $facet \
4645                 "lctl get_param -n $tgt.*.tgt_fmd_seconds 2> /dev/null | \
4646                 head -n 1")
4647
4648         echo "FMD max age: ${fmd_max_age}s"
4649         touch $DIR/$tdir/$tfile
4650         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4651                 gawk '{cnt=cnt+$1}  END{print cnt}')
4652         echo "FMD before: $fmd"
4653         [[ $fmd == 0 ]] &&
4654                 error "FMD wasn't create by touch"
4655         sleep $((fmd_max_age + 12))
4656         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4657                 gawk '{cnt=cnt+$1}  END{print cnt}')
4658         echo "FMD after: $fmd"
4659         [[ $fmd == 0 ]] ||
4660                 error "FMD wasn't expired by ping"
4661 }
4662 run_test 36g "FMD cache expiry ====================="
4663
4664 test_36h() {
4665         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4666
4667         #define OBD_FAIL_OST_BRW_PAUSE_BULK2 0x227
4668         subr_36fh "0x80000227"
4669 }
4670 run_test 36h "utime on file racing with OST BRW write =========="
4671
4672 test_36i() {
4673         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4674
4675         test_mkdir $DIR/$tdir
4676         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir
4677
4678         local mtime=$(stat -c%Y $DIR/$tdir/striped_dir)
4679         local new_mtime=$((mtime + 200))
4680
4681         #change Modify time of striped dir
4682         touch -m -d @$new_mtime $DIR/$tdir/striped_dir ||
4683                         error "change mtime failed"
4684
4685         local got=$(stat -c%Y $DIR/$tdir/striped_dir)
4686
4687         [ "$new_mtime" = "$got" ] || error "expect $new_mtime got $got"
4688 }
4689 run_test 36i "change mtime on striped directory"
4690
4691 # test_37 - duplicate with tests 32q 32r
4692
4693 test_38() {
4694         local file=$DIR/$tfile
4695         touch $file
4696         openfile -f O_DIRECTORY $file
4697         local RC=$?
4698         local ENOTDIR=20
4699         [ $RC -eq 0 ] && error "opened file $file with O_DIRECTORY" || true
4700         [ $RC -eq $ENOTDIR ] || error "error $RC should be ENOTDIR ($ENOTDIR)"
4701 }
4702 run_test 38 "open a regular file with O_DIRECTORY should return -ENOTDIR ==="
4703
4704 test_39a() { # was test_39
4705         touch $DIR/$tfile
4706         touch $DIR/${tfile}2
4707 #       ls -l  $DIR/$tfile $DIR/${tfile}2
4708 #       ls -lu  $DIR/$tfile $DIR/${tfile}2
4709 #       ls -lc  $DIR/$tfile $DIR/${tfile}2
4710         sleep 2
4711         $OPENFILE -f O_CREAT:O_TRUNC:O_WRONLY $DIR/${tfile}2
4712         if [ ! $DIR/${tfile}2 -nt $DIR/$tfile ]; then
4713                 echo "mtime"
4714                 ls -l --full-time $DIR/$tfile $DIR/${tfile}2
4715                 echo "atime"
4716                 ls -lu --full-time $DIR/$tfile $DIR/${tfile}2
4717                 echo "ctime"
4718                 ls -lc --full-time $DIR/$tfile $DIR/${tfile}2
4719                 error "O_TRUNC didn't change timestamps"
4720         fi
4721 }
4722 run_test 39a "mtime changed on create"
4723
4724 test_39b() {
4725         test_mkdir -c1 $DIR/$tdir
4726         cp -p /etc/passwd $DIR/$tdir/fopen
4727         cp -p /etc/passwd $DIR/$tdir/flink
4728         cp -p /etc/passwd $DIR/$tdir/funlink
4729         cp -p /etc/passwd $DIR/$tdir/frename
4730         ln $DIR/$tdir/funlink $DIR/$tdir/funlink2
4731
4732         sleep 1
4733         echo "aaaaaa" >> $DIR/$tdir/fopen
4734         echo "aaaaaa" >> $DIR/$tdir/flink
4735         echo "aaaaaa" >> $DIR/$tdir/funlink
4736         echo "aaaaaa" >> $DIR/$tdir/frename
4737
4738         local open_new=`stat -c %Y $DIR/$tdir/fopen`
4739         local link_new=`stat -c %Y $DIR/$tdir/flink`
4740         local unlink_new=`stat -c %Y $DIR/$tdir/funlink`
4741         local rename_new=`stat -c %Y $DIR/$tdir/frename`
4742
4743         cat $DIR/$tdir/fopen > /dev/null
4744         ln $DIR/$tdir/flink $DIR/$tdir/flink2
4745         rm -f $DIR/$tdir/funlink2
4746         mv -f $DIR/$tdir/frename $DIR/$tdir/frename2
4747
4748         for (( i=0; i < 2; i++ )) ; do
4749                 local open_new2=`stat -c %Y $DIR/$tdir/fopen`
4750                 local link_new2=`stat -c %Y $DIR/$tdir/flink`
4751                 local unlink_new2=`stat -c %Y $DIR/$tdir/funlink`
4752                 local rename_new2=`stat -c %Y $DIR/$tdir/frename2`
4753
4754                 [ $open_new2 -eq $open_new ] || error "open file reverses mtime"
4755                 [ $link_new2 -eq $link_new ] || error "link file reverses mtime"
4756                 [ $unlink_new2 -eq $unlink_new ] || error "unlink file reverses mtime"
4757                 [ $rename_new2 -eq $rename_new ] || error "rename file reverses mtime"
4758
4759                 cancel_lru_locks $OSC
4760                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4761         done
4762 }
4763 run_test 39b "mtime change on open, link, unlink, rename  ======"
4764
4765 # this should be set to past
4766 TEST_39_MTIME=`date -d "1 year ago" +%s`
4767
4768 # bug 11063
4769 test_39c() {
4770         touch $DIR1/$tfile
4771         sleep 2
4772         local mtime0=`stat -c %Y $DIR1/$tfile`
4773
4774         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4775         local mtime1=`stat -c %Y $DIR1/$tfile`
4776         [ "$mtime1" = $TEST_39_MTIME ] || \
4777                 error "mtime is not set to past: $mtime1, should be $TEST_39_MTIME"
4778
4779         local d1=`date +%s`
4780         echo hello >> $DIR1/$tfile
4781         local d2=`date +%s`
4782         local mtime2=`stat -c %Y $DIR1/$tfile`
4783         [ "$mtime2" -ge "$d1" ] && [ "$mtime2" -le "$d2" ] || \
4784                 error "mtime is not updated on write: $d1 <= $mtime2 <= $d2"
4785
4786         mv $DIR1/$tfile $DIR1/$tfile-1
4787
4788         for (( i=0; i < 2; i++ )) ; do
4789                 local mtime3=`stat -c %Y $DIR1/$tfile-1`
4790                 [ "$mtime2" = "$mtime3" ] || \
4791                         error "mtime ($mtime2) changed (to $mtime3) on rename"
4792
4793                 cancel_lru_locks $OSC
4794                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4795         done
4796 }
4797 run_test 39c "mtime change on rename ==========================="
4798
4799 # bug 21114
4800 test_39d() {
4801         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4802
4803         touch $DIR1/$tfile
4804         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4805
4806         for (( i=0; i < 2; i++ )) ; do
4807                 local mtime=`stat -c %Y $DIR1/$tfile`
4808                 [ $mtime = $TEST_39_MTIME ] || \
4809                         error "mtime($mtime) is not set to $TEST_39_MTIME"
4810
4811                 cancel_lru_locks $OSC
4812                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4813         done
4814 }
4815 run_test 39d "create, utime, stat =============================="
4816
4817 # bug 21114
4818 test_39e() {
4819         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4820
4821         touch $DIR1/$tfile
4822         local mtime1=`stat -c %Y $DIR1/$tfile`
4823
4824         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4825
4826         for (( i=0; i < 2; i++ )) ; do
4827                 local mtime2=`stat -c %Y $DIR1/$tfile`
4828                 [ $mtime2 = $TEST_39_MTIME ] || \
4829                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4830
4831                 cancel_lru_locks $OSC
4832                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4833         done
4834 }
4835 run_test 39e "create, stat, utime, stat ========================"
4836
4837 # bug 21114
4838 test_39f() {
4839         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4840
4841         touch $DIR1/$tfile
4842         mtime1=`stat -c %Y $DIR1/$tfile`
4843
4844         sleep 2
4845         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4846
4847         for (( i=0; i < 2; i++ )) ; do
4848                 local mtime2=`stat -c %Y $DIR1/$tfile`
4849                 [ $mtime2 = $TEST_39_MTIME ] || \
4850                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4851
4852                 cancel_lru_locks $OSC
4853                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4854         done
4855 }
4856 run_test 39f "create, stat, sleep, utime, stat ================="
4857
4858 # bug 11063
4859 test_39g() {
4860         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4861
4862         echo hello >> $DIR1/$tfile
4863         local mtime1=`stat -c %Y $DIR1/$tfile`
4864
4865         sleep 2
4866         chmod o+r $DIR1/$tfile
4867
4868         for (( i=0; i < 2; i++ )) ; do
4869                 local mtime2=`stat -c %Y $DIR1/$tfile`
4870                 [ "$mtime1" = "$mtime2" ] || \
4871                         error "lost mtime: $mtime2, should be $mtime1"
4872
4873                 cancel_lru_locks $OSC
4874                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4875         done
4876 }
4877 run_test 39g "write, chmod, stat ==============================="
4878
4879 # bug 11063
4880 test_39h() {
4881         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4882
4883         touch $DIR1/$tfile
4884         sleep 1
4885
4886         local d1=`date`
4887         echo hello >> $DIR1/$tfile
4888         local mtime1=`stat -c %Y $DIR1/$tfile`
4889
4890         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4891         local d2=`date`
4892         if [ "$d1" != "$d2" ]; then
4893                 echo "write and touch not within one second"
4894         else
4895                 for (( i=0; i < 2; i++ )) ; do
4896                         local mtime2=`stat -c %Y $DIR1/$tfile`
4897                         [ "$mtime2" = $TEST_39_MTIME ] || \
4898                                 error "lost mtime: $mtime2, should be $TEST_39_MTIME"
4899
4900                         cancel_lru_locks $OSC
4901                         if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4902                 done
4903         fi
4904 }
4905 run_test 39h "write, utime within one second, stat ============="
4906
4907 test_39i() {
4908         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4909
4910         touch $DIR1/$tfile
4911         sleep 1
4912
4913         echo hello >> $DIR1/$tfile
4914         local mtime1=`stat -c %Y $DIR1/$tfile`
4915
4916         mv $DIR1/$tfile $DIR1/$tfile-1
4917
4918         for (( i=0; i < 2; i++ )) ; do
4919                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4920
4921                 [ "$mtime1" = "$mtime2" ] || \
4922                         error "lost mtime: $mtime2, should be $mtime1"
4923
4924                 cancel_lru_locks $OSC
4925                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4926         done
4927 }
4928 run_test 39i "write, rename, stat =============================="
4929
4930 test_39j() {
4931         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4932
4933         start_full_debug_logging
4934         touch $DIR1/$tfile
4935         sleep 1
4936
4937         #define OBD_FAIL_OSC_DELAY_SETTIME       0x412
4938         lctl set_param fail_loc=0x80000412
4939         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c ||
4940                 error "multiop failed"
4941         local multipid=$!
4942         local mtime1=`stat -c %Y $DIR1/$tfile`
4943
4944         mv $DIR1/$tfile $DIR1/$tfile-1
4945
4946         kill -USR1 $multipid
4947         wait $multipid || error "multiop close failed"
4948
4949         for (( i=0; i < 2; i++ )) ; do
4950                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4951                 [ "$mtime1" = "$mtime2" ] ||
4952                         error "mtime is lost on close: $mtime2, " \
4953                               "should be $mtime1"
4954
4955                 cancel_lru_locks
4956                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4957         done
4958         lctl set_param fail_loc=0
4959         stop_full_debug_logging
4960 }
4961 run_test 39j "write, rename, close, stat ======================="
4962
4963 test_39k() {
4964         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4965
4966         touch $DIR1/$tfile
4967         sleep 1
4968
4969         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c || error "multiop failed"
4970         local multipid=$!
4971         local mtime1=`stat -c %Y $DIR1/$tfile`
4972
4973         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4974
4975         kill -USR1 $multipid
4976         wait $multipid || error "multiop close failed"
4977
4978         for (( i=0; i < 2; i++ )) ; do
4979                 local mtime2=`stat -c %Y $DIR1/$tfile`
4980
4981                 [ "$mtime2" = $TEST_39_MTIME ] || \
4982                         error "mtime is lost on close: $mtime2, should be $TEST_39_MTIME"
4983
4984                 cancel_lru_locks
4985                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4986         done
4987 }
4988 run_test 39k "write, utime, close, stat ========================"
4989
4990 # this should be set to future
4991 TEST_39_ATIME=`date -d "1 year" +%s`
4992
4993 test_39l() {
4994         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4995         remote_mds_nodsh && skip "remote MDS with nodsh"
4996
4997         local atime_diff=$(do_facet $SINGLEMDS \
4998                                 lctl get_param -n mdd.*MDT0000*.atime_diff)
4999         rm -rf $DIR/$tdir
5000         mkdir_on_mdt0 $DIR/$tdir
5001
5002         # test setting directory atime to future
5003         touch -a -d @$TEST_39_ATIME $DIR/$tdir
5004         local atime=$(stat -c %X $DIR/$tdir)
5005         [ "$atime" = $TEST_39_ATIME ] ||
5006                 error "atime is not set to future: $atime, $TEST_39_ATIME"
5007
5008         # test setting directory atime from future to now
5009         local now=$(date +%s)
5010         touch -a -d @$now $DIR/$tdir
5011
5012         atime=$(stat -c %X $DIR/$tdir)
5013         [ "$atime" -eq "$now"  ] ||
5014                 error "atime is not updated from future: $atime, $now"
5015
5016         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=2
5017         sleep 3
5018
5019         # test setting directory atime when now > dir atime + atime_diff
5020         local d1=$(date +%s)
5021         ls $DIR/$tdir
5022         local d2=$(date +%s)
5023         cancel_lru_locks mdc
5024         atime=$(stat -c %X $DIR/$tdir)
5025         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
5026                 error "atime is not updated  : $atime, should be $d2"
5027
5028         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=60
5029         sleep 3
5030
5031         # test not setting directory atime when now < dir atime + atime_diff
5032         ls $DIR/$tdir
5033         cancel_lru_locks mdc
5034         atime=$(stat -c %X $DIR/$tdir)
5035         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
5036                 error "atime is updated to $atime, should remain $d1<atime<$d2"
5037
5038         do_facet $SINGLEMDS \
5039                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
5040 }
5041 run_test 39l "directory atime update ==========================="
5042
5043 test_39m() {
5044         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5045
5046         touch $DIR1/$tfile
5047         sleep 2
5048         local far_past_mtime=$(date -d "May 29 1953" +%s)
5049         local far_past_atime=$(date -d "Dec 17 1903" +%s)
5050
5051         touch -m -d @$far_past_mtime $DIR1/$tfile
5052         touch -a -d @$far_past_atime $DIR1/$tfile
5053
5054         for (( i=0; i < 2; i++ )) ; do
5055                 local timestamps=$(stat -c "%X %Y" $DIR1/$tfile)
5056                 [ "$timestamps" = "$far_past_atime $far_past_mtime" ] || \
5057                         error "atime or mtime set incorrectly"
5058
5059                 cancel_lru_locks $OSC
5060                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
5061         done
5062 }
5063 run_test 39m "test atime and mtime before 1970"
5064
5065 test_39n() { # LU-3832
5066         remote_mds_nodsh && skip "remote MDS with nodsh"
5067
5068         local atime_diff=$(do_facet $SINGLEMDS \
5069                 lctl get_param -n mdd.*MDT0000*.atime_diff)
5070         local atime0
5071         local atime1
5072         local atime2
5073
5074         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=1
5075
5076         rm -rf $DIR/$tfile
5077         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 status=noxfer
5078         atime0=$(stat -c %X $DIR/$tfile)
5079
5080         sleep 5
5081         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
5082         atime1=$(stat -c %X $DIR/$tfile)
5083
5084         sleep 5
5085         cancel_lru_locks mdc
5086         cancel_lru_locks osc
5087         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
5088         atime2=$(stat -c %X $DIR/$tfile)
5089
5090         do_facet $SINGLEMDS \
5091                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
5092
5093         [ "$atime0" -eq "$atime1" ] || error "atime0 $atime0 != atime1 $atime1"
5094         [ "$atime1" -eq "$atime2" ] || error "atime0 $atime0 != atime1 $atime1"
5095 }
5096 run_test 39n "check that O_NOATIME is honored"
5097
5098 test_39o() {
5099         TESTDIR=$DIR/$tdir/$tfile
5100         [ -e $TESTDIR ] && rm -rf $TESTDIR
5101         mkdir -p $TESTDIR
5102         cd $TESTDIR
5103         links1=2
5104         ls
5105         mkdir a b
5106         ls
5107         links2=$(stat -c %h .)
5108         [ $(($links1 + 2)) != $links2 ] &&
5109                 error "wrong links count $(($links1 + 2)) != $links2"
5110         rmdir b
5111         links3=$(stat -c %h .)
5112         [ $(($links1 + 1)) != $links3 ] &&
5113                 error "wrong links count $links1 != $links3"
5114         return 0
5115 }
5116 run_test 39o "directory cached attributes updated after create"
5117
5118 test_39p() {
5119         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
5120
5121         local MDTIDX=1
5122         TESTDIR=$DIR/$tdir/$tdir
5123         [ -e $TESTDIR ] && rm -rf $TESTDIR
5124         test_mkdir -p $TESTDIR
5125         cd $TESTDIR
5126         links1=2
5127         ls
5128         test_mkdir -i $MDTIDX $TESTDIR/remote_dir1
5129         test_mkdir -i $MDTIDX $TESTDIR/remote_dir2
5130         ls
5131         links2=$(stat -c %h .)
5132         [ $(($links1 + 2)) != $links2 ] &&
5133                 error "wrong links count $(($links1 + 2)) != $links2"
5134         rmdir remote_dir2
5135         links3=$(stat -c %h .)
5136         [ $(($links1 + 1)) != $links3 ] &&
5137                 error "wrong links count $links1 != $links3"
5138         return 0
5139 }
5140 run_test 39p "remote directory cached attributes updated after create ========"
5141
5142 test_39r() {
5143         [ $OST1_VERSION -ge $(version_code 2.13.52) ] ||
5144                 skip "no atime update on old OST"
5145         if [ "$ost1_FSTYPE" != ldiskfs ]; then
5146                 skip_env "ldiskfs only test"
5147         fi
5148
5149         local saved_adiff
5150         saved_adiff=$(do_facet ost1 \
5151                 lctl get_param -n obdfilter.*OST0000.atime_diff)
5152         stack_trap "do_facet ost1 \
5153                 lctl set_param obdfilter.*.atime_diff=$saved_adiff"
5154
5155         do_facet ost1 "lctl set_param obdfilter.*.atime_diff=5"
5156
5157         $LFS setstripe -i 0 $DIR/$tfile
5158         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 ||
5159                 error "can't write initial file"
5160         cancel_lru_locks osc
5161
5162         # exceed atime_diff and access file
5163         sleep 10
5164         dd if=$DIR/$tfile of=/dev/null bs=4k count=1 ||
5165                 error "can't udpate atime"
5166
5167         local atime_cli=$(stat -c %X $DIR/$tfile)
5168         echo "client atime: $atime_cli"
5169         # allow atime update to be written to device
5170         do_facet ost1 "$LCTL set_param -n osd*.*OST*.force_sync 1"
5171         sleep 5
5172
5173         local ostdev=$(ostdevname 1)
5174         local fid=($(lfs getstripe -y $DIR/$tfile |
5175                         awk '/l_fid:/ { print $2 }' | tr ':' ' '))
5176         local objpath="O/0/d$((${fid[1]} % 32))/$((${fid[1]}))"
5177         local cmd="debugfs -c -R \\\"stat $objpath\\\" $ostdev"
5178
5179         echo "OST atime: $(do_facet ost1 "$cmd" |& grep atime)"
5180         local atime_ost=$(do_facet ost1 "$cmd" |&
5181                           awk -F'[: ]' '/atime:/ { print $4 }')
5182         (( atime_cli == atime_ost )) ||
5183                 error "atime on client $atime_cli != ost $atime_ost"
5184 }
5185 run_test 39r "lazy atime update on OST"
5186
5187 test_39q() { # LU-8041
5188         local testdir=$DIR/$tdir
5189         mkdir -p $testdir
5190         multiop_bg_pause $testdir D_c || error "multiop failed"
5191         local multipid=$!
5192         cancel_lru_locks mdc
5193         kill -USR1 $multipid
5194         local atime=$(stat -c %X $testdir)
5195         [ "$atime" -ne 0 ] || error "atime is zero"
5196 }
5197 run_test 39q "close won't zero out atime"
5198
5199 test_40() {
5200         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
5201         $RUNAS $OPENFILE -f O_WRONLY:O_TRUNC $DIR/$tfile &&
5202                 error "openfile O_WRONLY:O_TRUNC $tfile failed"
5203         $CHECKSTAT -t file -s 4096 $DIR/$tfile ||
5204                 error "$tfile is not 4096 bytes in size"
5205 }
5206 run_test 40 "failed open(O_TRUNC) doesn't truncate ============="
5207
5208 test_41() {
5209         # bug 1553
5210         small_write $DIR/f41 18
5211 }
5212 run_test 41 "test small file write + fstat ====================="
5213
5214 count_ost_writes() {
5215         lctl get_param -n ${OSC}.*.stats |
5216                 awk -vwrites=0 '/ost_write/ { writes += $2 } \
5217                         END { printf("%0.0f", writes) }'
5218 }
5219
5220 # decent default
5221 WRITEBACK_SAVE=500
5222 DIRTY_RATIO_SAVE=40
5223 MAX_DIRTY_RATIO=50
5224 BG_DIRTY_RATIO_SAVE=10
5225 MAX_BG_DIRTY_RATIO=25
5226
5227 start_writeback() {
5228         trap 0
5229         # in 2.6, restore /proc/sys/vm/dirty_writeback_centisecs,
5230         # dirty_ratio, dirty_background_ratio
5231         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
5232                 sysctl -w vm.dirty_writeback_centisecs=$WRITEBACK_SAVE
5233                 sysctl -w vm.dirty_background_ratio=$BG_DIRTY_RATIO_SAVE
5234                 sysctl -w vm.dirty_ratio=$DIRTY_RATIO_SAVE
5235         else
5236                 # if file not here, we are a 2.4 kernel
5237                 kill -CONT `pidof kupdated`
5238         fi
5239 }
5240
5241 stop_writeback() {
5242         # setup the trap first, so someone cannot exit the test at the
5243         # exact wrong time and mess up a machine
5244         trap start_writeback EXIT
5245         # in 2.6, save and 0 /proc/sys/vm/dirty_writeback_centisecs
5246         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
5247                 WRITEBACK_SAVE=`sysctl -n vm.dirty_writeback_centisecs`
5248                 sysctl -w vm.dirty_writeback_centisecs=0
5249                 sysctl -w vm.dirty_writeback_centisecs=0
5250                 # save and increase /proc/sys/vm/dirty_ratio
5251                 DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_ratio`
5252                 sysctl -w vm.dirty_ratio=$MAX_DIRTY_RATIO
5253                 # save and increase /proc/sys/vm/dirty_background_ratio
5254                 BG_DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_background_ratio`
5255                 sysctl -w vm.dirty_background_ratio=$MAX_BG_DIRTY_RATIO
5256         else
5257                 # if file not here, we are a 2.4 kernel
5258                 kill -STOP `pidof kupdated`
5259         fi
5260 }
5261
5262 # ensure that all stripes have some grant before we test client-side cache
5263 setup_test42() {
5264         for i in `seq -f $DIR/f42-%g 1 $OSTCOUNT`; do
5265                 dd if=/dev/zero of=$i bs=4k count=1
5266                 rm $i
5267         done
5268 }
5269
5270 # Tests 42* verify that our behaviour is correct WRT caching, file closure,
5271 # file truncation, and file removal.
5272 test_42a() {
5273         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5274
5275         setup_test42
5276         cancel_lru_locks $OSC
5277         stop_writeback
5278         sync; sleep 1; sync # just to be safe
5279         BEFOREWRITES=`count_ost_writes`
5280         lctl get_param -n osc.*[oO][sS][cC][_-]*.cur_grant_bytes | grep "[0-9]"
5281         dd if=/dev/zero of=$DIR/f42a bs=1024 count=100
5282         AFTERWRITES=`count_ost_writes`
5283         [ $BEFOREWRITES -eq $AFTERWRITES ] || \
5284                 error "$BEFOREWRITES < $AFTERWRITES"
5285         start_writeback
5286 }
5287 run_test 42a "ensure that we don't flush on close"
5288
5289 test_42b() {
5290         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5291
5292         setup_test42
5293         cancel_lru_locks $OSC
5294         stop_writeback
5295         sync
5296         dd if=/dev/zero of=$DIR/f42b bs=1024 count=100
5297         BEFOREWRITES=$(count_ost_writes)
5298         $MUNLINK $DIR/f42b || error "$MUNLINK $DIR/f42b: $?"
5299         AFTERWRITES=$(count_ost_writes)
5300         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
5301                 error "$BEFOREWRITES < $AFTERWRITES on unlink"
5302         fi
5303         BEFOREWRITES=$(count_ost_writes)
5304         sync || error "sync: $?"
5305         AFTERWRITES=$(count_ost_writes)
5306         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
5307                 error "$BEFOREWRITES < $AFTERWRITES on sync"
5308         fi
5309         dmesg | grep 'error from obd_brw_async' && error 'error writing back'
5310         start_writeback
5311         return 0
5312 }
5313 run_test 42b "test destroy of file with cached dirty data ======"
5314
5315 # if these tests just want to test the effect of truncation,
5316 # they have to be very careful.  consider:
5317 # - the first open gets a {0,EOF}PR lock
5318 # - the first write conflicts and gets a {0, count-1}PW
5319 # - the rest of the writes are under {count,EOF}PW
5320 # - the open for truncate tries to match a {0,EOF}PR
5321 #   for the filesize and cancels the PWs.
5322 # any number of fixes (don't get {0,EOF} on open, match
5323 # composite locks, do smarter file size management) fix
5324 # this, but for now we want these tests to verify that
5325 # the cancellation with truncate intent works, so we
5326 # start the file with a full-file pw lock to match against
5327 # until the truncate.
5328 trunc_test() {
5329         test=$1
5330         file=$DIR/$test
5331         offset=$2
5332         cancel_lru_locks $OSC
5333         stop_writeback
5334         # prime the file with 0,EOF PW to match
5335         touch $file
5336         $TRUNCATE $file 0
5337         sync; sync
5338         # now the real test..
5339         dd if=/dev/zero of=$file bs=1024 count=100
5340         BEFOREWRITES=`count_ost_writes`
5341         $TRUNCATE $file $offset
5342         cancel_lru_locks $OSC
5343         AFTERWRITES=`count_ost_writes`
5344         start_writeback
5345 }
5346
5347 test_42c() {
5348         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5349
5350         trunc_test 42c 1024
5351         [ $BEFOREWRITES -eq $AFTERWRITES ] &&
5352                 error "beforewrites $BEFOREWRITES == afterwrites $AFTERWRITES on truncate"
5353         rm $file
5354 }
5355 run_test 42c "test partial truncate of file with cached dirty data"
5356
5357 test_42d() {
5358         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5359
5360         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
5361         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
5362         $LCTL set_param debug=+cache
5363
5364         trunc_test 42d 0
5365         [ $BEFOREWRITES -eq $AFTERWRITES ] ||
5366                 error "beforewrites $BEFOREWRITES != afterwrites $AFTERWRITES on truncate"
5367         rm $file
5368 }
5369 run_test 42d "test complete truncate of file with cached dirty data"
5370
5371 test_42e() { # bug22074
5372         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5373
5374         local TDIR=$DIR/${tdir}e
5375         local pages=16 # hardcoded 16 pages, don't change it.
5376         local files=$((OSTCOUNT * 500)) # hopefully 500 files on each OST
5377         local proc_osc0="osc.${FSNAME}-OST0000-osc-[^MDT]*"
5378         local max_dirty_mb
5379         local warmup_files
5380
5381         test_mkdir $DIR/${tdir}e
5382         $LFS setstripe -c 1 $TDIR
5383         createmany -o $TDIR/f $files
5384
5385         max_dirty_mb=$($LCTL get_param -n $proc_osc0/max_dirty_mb)
5386
5387         # we assume that with $OSTCOUNT files, at least one of them will
5388         # be allocated on OST0.
5389         warmup_files=$((OSTCOUNT * max_dirty_mb))
5390         createmany -o $TDIR/w $warmup_files
5391
5392         # write a large amount of data into one file and sync, to get good
5393         # avail_grant number from OST.
5394         for ((i=0; i<$warmup_files; i++)); do
5395                 idx=$($LFS getstripe -i $TDIR/w$i)
5396                 [ $idx -ne 0 ] && continue
5397                 dd if=/dev/zero of=$TDIR/w$i bs="$max_dirty_mb"M count=1
5398                 break
5399         done
5400         [[ $i -gt $warmup_files ]] && error "OST0 is still cold"
5401         sync
5402         $LCTL get_param $proc_osc0/cur_dirty_bytes
5403         $LCTL get_param $proc_osc0/cur_grant_bytes
5404
5405         # create as much dirty pages as we can while not to trigger the actual
5406         # RPCs directly. but depends on the env, VFS may trigger flush during this
5407         # period, hopefully we are good.
5408         for ((i=0; i<$warmup_files; i++)); do
5409                 idx=$($LFS getstripe -i $TDIR/w$i)
5410                 [ $idx -ne 0 ] && continue
5411                 dd if=/dev/zero of=$TDIR/w$i bs=1M count=1 2>/dev/null
5412         done
5413         $LCTL get_param $proc_osc0/cur_dirty_bytes
5414         $LCTL get_param $proc_osc0/cur_grant_bytes
5415
5416         # perform the real test
5417         $LCTL set_param $proc_osc0/rpc_stats 0
5418         for ((;i<$files; i++)); do
5419                 [ $($LFS getstripe -i $TDIR/f$i) -eq 0 ] || continue
5420                 dd if=/dev/zero of=$TDIR/f$i bs=$PAGE_SIZE count=$pages 2>/dev/null
5421         done
5422         sync
5423         $LCTL get_param $proc_osc0/rpc_stats
5424
5425         local percent=0
5426         local have_ppr=false
5427         $LCTL get_param $proc_osc0/rpc_stats |
5428                 while read PPR RRPC RPCT RCUM BAR WRPC WPCT WCUM; do
5429                         # skip lines until we are at the RPC histogram data
5430                         [ "$PPR" == "pages" ] && have_ppr=true && continue
5431                         $have_ppr || continue
5432
5433                         # we only want the percent stat for < 16 pages
5434                         [[ $(echo $PPR | tr -d ':') -ge $pages ]] && break
5435
5436                         percent=$((percent + WPCT))
5437                         if [[ $percent -gt 15 ]]; then
5438                                 error "less than 16-pages write RPCs" \
5439                                       "$percent% > 15%"
5440                                 break
5441                         fi
5442                 done
5443         rm -rf $TDIR
5444 }
5445 run_test 42e "verify sub-RPC writes are not done synchronously"
5446
5447 test_43A() { # was test_43
5448         test_mkdir $DIR/$tdir
5449         cp -p /bin/ls $DIR/$tdir/$tfile
5450         $MULTIOP $DIR/$tdir/$tfile Ow_c &
5451         pid=$!
5452         # give multiop a chance to open
5453         sleep 1
5454
5455         $DIR/$tdir/$tfile && error "execute $DIR/$tdir/$tfile succeeded" || true
5456         kill -USR1 $pid
5457         # Wait for multiop to exit
5458         wait $pid
5459 }
5460 run_test 43A "execution of file opened for write should return -ETXTBSY"
5461
5462 test_43a() {
5463         test_mkdir $DIR/$tdir
5464         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
5465         $DIR/$tdir/sleep 60 &
5466         SLEEP_PID=$!
5467         # Make sure exec of $tdir/sleep wins race with truncate
5468         sleep 1
5469         $MULTIOP $DIR/$tdir/sleep Oc && error "expected error, got success"
5470         kill $SLEEP_PID
5471 }
5472 run_test 43a "open(RDWR) of file being executed should return -ETXTBSY"
5473
5474 test_43b() {
5475         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5476
5477         test_mkdir $DIR/$tdir
5478         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
5479         $DIR/$tdir/sleep 60 &
5480         SLEEP_PID=$!
5481         # Make sure exec of $tdir/sleep wins race with truncate
5482         sleep 1
5483         $TRUNCATE $DIR/$tdir/sleep 0 && error "expected error, got success"
5484         kill $SLEEP_PID
5485 }
5486 run_test 43b "truncate of file being executed should return -ETXTBSY"
5487
5488 test_43c() {
5489         local testdir="$DIR/$tdir"
5490         test_mkdir $testdir
5491         cp $SHELL $testdir/
5492         ( cd $(dirname $SHELL) && md5sum $(basename $SHELL) ) |
5493                 ( cd $testdir && md5sum -c )
5494 }
5495 run_test 43c "md5sum of copy into lustre"
5496
5497 test_44A() { # was test_44
5498         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5499
5500         dd if=/dev/zero of=$DIR/f1 bs=4k count=1 seek=1023
5501         dd if=$DIR/f1 bs=4k count=1 > /dev/null
5502 }
5503 run_test 44A "zero length read from a sparse stripe"
5504
5505 test_44a() {
5506         local nstripe=$($LFS getstripe -c -d $DIR)
5507         [ -z "$nstripe" ] && skip "can't get stripe info"
5508         [[ $nstripe -gt $OSTCOUNT ]] &&
5509                 skip "Wrong default stripe_count: $nstripe OSTCOUNT: $OSTCOUNT"
5510
5511         local stride=$($LFS getstripe -S -d $DIR)
5512         if [[ $nstripe -eq 0 || $nstripe -eq -1 ]]; then
5513                 nstripe=$($LFS df $DIR | grep OST: | wc -l)
5514         fi
5515
5516         OFFSETS="0 $((stride/2)) $((stride-1))"
5517         for offset in $OFFSETS; do
5518                 for i in $(seq 0 $((nstripe-1))); do
5519                         local GLOBALOFFSETS=""
5520                         # size in Bytes
5521                         local size=$((((i + 2 * $nstripe )*$stride + $offset)))
5522                         local myfn=$DIR/d44a-$size
5523                         echo "--------writing $myfn at $size"
5524                         ll_sparseness_write $myfn $size ||
5525                                 error "ll_sparseness_write"
5526                         GLOBALOFFSETS="$GLOBALOFFSETS $size"
5527                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
5528                                 error "ll_sparseness_verify $GLOBALOFFSETS"
5529
5530                         for j in $(seq 0 $((nstripe-1))); do
5531                                 # size in Bytes
5532                                 size=$((((j + $nstripe )*$stride + $offset)))
5533                                 ll_sparseness_write $myfn $size ||
5534                                         error "ll_sparseness_write"
5535                                 GLOBALOFFSETS="$GLOBALOFFSETS $size"
5536                         done
5537                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
5538                                 error "ll_sparseness_verify $GLOBALOFFSETS"
5539                         rm -f $myfn
5540                 done
5541         done
5542 }
5543 run_test 44a "test sparse pwrite ==============================="
5544
5545 dirty_osc_total() {
5546         tot=0
5547         for d in `lctl get_param -n ${OSC}.*.cur_dirty_bytes`; do
5548                 tot=$(($tot + $d))
5549         done
5550         echo $tot
5551 }
5552 do_dirty_record() {
5553         before=`dirty_osc_total`
5554         echo executing "\"$*\""
5555         eval $*
5556         after=`dirty_osc_total`
5557         echo before $before, after $after
5558 }
5559 test_45() {
5560         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5561
5562         f="$DIR/f45"
5563         # Obtain grants from OST if it supports it
5564         echo blah > ${f}_grant
5565         stop_writeback
5566         sync
5567         do_dirty_record "echo blah > $f"
5568         [[ $before -eq $after ]] && error "write wasn't cached"
5569         do_dirty_record "> $f"
5570         [[ $before -gt $after ]] || error "truncate didn't lower dirty count"
5571         do_dirty_record "echo blah > $f"
5572         [[ $before -eq $after ]] && error "write wasn't cached"
5573         do_dirty_record "sync"
5574         [[ $before -gt $after ]] || error "writeback didn't lower dirty count"
5575         do_dirty_record "echo blah > $f"
5576         [[ $before -eq $after ]] && error "write wasn't cached"
5577         do_dirty_record "cancel_lru_locks osc"
5578         [[ $before -gt $after ]] ||
5579                 error "lock cancellation didn't lower dirty count"
5580         start_writeback
5581 }
5582 run_test 45 "osc io page accounting ============================"
5583
5584 # in a 2 stripe file (lov.sh), page 1023 maps to page 511 in its object.  this
5585 # test tickles a bug where re-dirtying a page was failing to be mapped to the
5586 # objects offset and an assert hit when an rpc was built with 1023's mapped
5587 # offset 511 and 511's raw 511 offset. it also found general redirtying bugs.
5588 test_46() {
5589         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5590
5591         f="$DIR/f46"
5592         stop_writeback
5593         sync
5594         dd if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5595         sync
5596         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=1023 count=1
5597         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5598         sync
5599         start_writeback
5600 }
5601 run_test 46 "dirtying a previously written page ================"
5602
5603 # test_47 is removed "Device nodes check" is moved to test_28
5604
5605 test_48a() { # bug 2399
5606         [ "$mds1_FSTYPE" = "zfs" ] &&
5607         [ $MDS1_VERSION -lt $(version_code 2.3.63) ] &&
5608                 skip "MDS prior to 2.3.63 handle ZFS dir .. incorrectly"
5609
5610         test_mkdir $DIR/$tdir
5611         cd $DIR/$tdir
5612         mv $DIR/$tdir $DIR/$tdir.new || error "move directory failed"
5613         test_mkdir $DIR/$tdir
5614         touch foo || error "'touch foo' failed after recreating cwd"
5615         test_mkdir bar
5616         touch .foo || error "'touch .foo' failed after recreating cwd"
5617         test_mkdir .bar
5618         ls . > /dev/null || error "'ls .' failed after recreating cwd"
5619         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5620         cd . || error "'cd .' failed after recreating cwd"
5621         mkdir . && error "'mkdir .' worked after recreating cwd"
5622         rmdir . && error "'rmdir .' worked after recreating cwd"
5623         ln -s . baz || error "'ln -s .' failed after recreating cwd"
5624         cd .. || error "'cd ..' failed after recreating cwd"
5625 }
5626 run_test 48a "Access renamed working dir (should return errors)="
5627
5628 test_48b() { # bug 2399
5629         rm -rf $DIR/$tdir
5630         test_mkdir $DIR/$tdir
5631         cd $DIR/$tdir
5632         rmdir $DIR/$tdir || error "remove cwd $DIR/$tdir failed"
5633         touch foo && error "'touch foo' worked after removing cwd"
5634         mkdir foo && error "'mkdir foo' worked after removing cwd"
5635         touch .foo && error "'touch .foo' worked after removing cwd"
5636         mkdir .foo && error "'mkdir .foo' worked after removing cwd"
5637         ls . > /dev/null && error "'ls .' worked after removing cwd"
5638         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5639         mkdir . && error "'mkdir .' worked after removing cwd"
5640         rmdir . && error "'rmdir .' worked after removing cwd"
5641         ln -s . foo && error "'ln -s .' worked after removing cwd"
5642         cd .. || echo "'cd ..' failed after removing cwd `pwd`"  #bug 3517
5643 }
5644 run_test 48b "Access removed working dir (should return errors)="
5645
5646 test_48c() { # bug 2350
5647         #lctl set_param debug=-1
5648         #set -vx
5649         rm -rf $DIR/$tdir
5650         test_mkdir -p $DIR/$tdir/dir
5651         cd $DIR/$tdir/dir
5652         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5653         $TRACE touch foo && error "touch foo worked after removing cwd"
5654         $TRACE mkdir foo && error "'mkdir foo' worked after removing cwd"
5655         touch .foo && error "touch .foo worked after removing cwd"
5656         mkdir .foo && error "mkdir .foo worked after removing cwd"
5657         $TRACE ls . && error "'ls .' worked after removing cwd"
5658         $TRACE ls .. || error "'ls ..' failed after removing cwd"
5659         $TRACE mkdir . && error "'mkdir .' worked after removing cwd"
5660         $TRACE rmdir . && error "'rmdir .' worked after removing cwd"
5661         $TRACE ln -s . foo && error "'ln -s .' worked after removing cwd"
5662         $TRACE cd .. || echo "'cd ..' failed after removing cwd `pwd`" #bug 3415
5663 }
5664 run_test 48c "Access removed working subdir (should return errors)"
5665
5666 test_48d() { # bug 2350
5667         #lctl set_param debug=-1
5668         #set -vx
5669         rm -rf $DIR/$tdir
5670         test_mkdir -p $DIR/$tdir/dir
5671         cd $DIR/$tdir/dir
5672         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5673         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5674         $TRACE touch foo && error "'touch foo' worked after removing parent"
5675         $TRACE mkdir foo && error "mkdir foo worked after removing parent"
5676         touch .foo && error "'touch .foo' worked after removing parent"
5677         mkdir .foo && error "mkdir .foo worked after removing parent"
5678         $TRACE ls . && error "'ls .' worked after removing parent"
5679         $TRACE ls .. && error "'ls ..' worked after removing parent"
5680         $TRACE mkdir . && error "'mkdir .' worked after removing parent"
5681         $TRACE rmdir . && error "'rmdir .' worked after removing parent"
5682         $TRACE ln -s . foo && error "'ln -s .' worked after removing parent"
5683         true
5684 }
5685 run_test 48d "Access removed parent subdir (should return errors)"
5686
5687 test_48e() { # bug 4134
5688         #lctl set_param debug=-1
5689         #set -vx
5690         rm -rf $DIR/$tdir
5691         test_mkdir -p $DIR/$tdir/dir
5692         cd $DIR/$tdir/dir
5693         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5694         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5695         $TRACE touch $DIR/$tdir || error "'touch $DIR/$tdir' failed"
5696         $TRACE chmod +x $DIR/$tdir || error "'chmod +x $DIR/$tdir' failed"
5697         # On a buggy kernel addition of "touch foo" after cd .. will
5698         # produce kernel oops in lookup_hash_it
5699         touch ../foo && error "'cd ..' worked after recreate parent"
5700         cd $DIR
5701         $TRACE rm $DIR/$tdir || error "rm '$DIR/$tdir' failed"
5702 }
5703 run_test 48e "Access to recreated parent subdir (should return errors)"
5704
5705 test_48f() {
5706         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
5707                 skip "need MDS >= 2.13.55"
5708         [[ $MDSCOUNT -ge 2 ]] || skip "needs >= 2 MDTs"
5709         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] ||
5710                 skip "needs different host for mdt1 mdt2"
5711         [[ $(facet_fstype mds1) == ldiskfs ]] || skip "ldiskfs only"
5712
5713         $LFS mkdir -i0 $DIR/$tdir
5714         $LFS mkdir -i 1 $DIR/$tdir/sub1 $DIR/$tdir/sub2 $DIR/$tdir/sub3
5715
5716         for d in sub1 sub2 sub3; do
5717                 #define OBD_FAIL_OSD_REF_DEL    0x19c
5718                 do_facet mds1 $LCTL set_param fail_loc=0x8000019c
5719                 rm -rf $DIR/$tdir/$d && error "rm $d should fail"
5720         done
5721
5722         rm -d --interactive=never $DIR/$tdir || error "rm $tdir fail"
5723 }
5724 run_test 48f "non-zero nlink dir unlink won't LBUG()"
5725
5726 test_49() { # LU-1030
5727         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5728         remote_ost_nodsh && skip "remote OST with nodsh"
5729
5730         # get ost1 size - $FSNAME-OST0000
5731         ost1_size=$(do_facet ost1 $LFS df | grep ${ost1_svc} |
5732                 awk '{ print $4 }')
5733         # write 800M at maximum
5734         [[ $ost1_size -lt 2 ]] && ost1_size=2
5735         [[ $ost1_size -gt 819200 ]] && ost1_size=819200
5736
5737         $LFS setstripe -c 1 -i 0 $DIR/$tfile
5738         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((ost1_size >> 2)) &
5739         local dd_pid=$!
5740
5741         # change max_pages_per_rpc while writing the file
5742         local osc1_mppc=osc.$(get_osc_import_name client ost1).max_pages_per_rpc
5743         local orig_mppc=$($LCTL get_param -n $osc1_mppc)
5744         # loop until dd process exits
5745         while ps ax -opid | grep -wq $dd_pid; do
5746                 $LCTL set_param $osc1_mppc=$((RANDOM % 256 + 1))
5747                 sleep $((RANDOM % 5 + 1))
5748         done
5749         # restore original max_pages_per_rpc
5750         $LCTL set_param $osc1_mppc=$orig_mppc
5751         rm $DIR/$tfile || error "rm $DIR/$tfile failed"
5752 }
5753 run_test 49 "Change max_pages_per_rpc won't break osc extent"
5754
5755 test_50() {
5756         # bug 1485
5757         test_mkdir $DIR/$tdir
5758         cd $DIR/$tdir
5759         ls /proc/$$/cwd || error "ls /proc/$$/cwd failed"
5760 }
5761 run_test 50 "special situations: /proc symlinks  ==============="
5762
5763 test_51a() {    # was test_51
5764         # bug 1516 - create an empty entry right after ".." then split dir
5765         test_mkdir -c1 $DIR/$tdir
5766         touch $DIR/$tdir/foo
5767         $MCREATE $DIR/$tdir/bar
5768         rm $DIR/$tdir/foo
5769         createmany -m $DIR/$tdir/longfile 201
5770         FNUM=202
5771         while [[ $(ls -sd $DIR/$tdir | awk '{ print $1 }') -eq 4 ]]; do
5772                 $MCREATE $DIR/$tdir/longfile$FNUM
5773                 FNUM=$(($FNUM + 1))
5774                 echo -n "+"
5775         done
5776         echo
5777         ls -l $DIR/$tdir > /dev/null || error "ls -l $DIR/$tdir failed"
5778 }
5779 run_test 51a "special situations: split htree with empty entry =="
5780
5781 cleanup_print_lfs_df () {
5782         trap 0
5783         $LFS df
5784         $LFS df -i
5785 }
5786
5787 test_51b() {
5788         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5789
5790         local dir=$DIR/$tdir
5791         local nrdirs=$((65536 + 100))
5792
5793         # cleanup the directory
5794         rm -fr $dir
5795
5796         mkdir_on_mdt -i $((RANDOM % MDSCOUNT)) $dir
5797
5798         $LFS df
5799         $LFS df -i
5800         local mdtidx=$(printf "%04x" $($LFS getstripe -m $dir))
5801         local numfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.filesfree)
5802         [[ $numfree -lt $nrdirs ]] &&
5803                 skip "not enough free inodes ($numfree) on MDT$mdtidx"
5804
5805         # need to check free space for the directories as well
5806         local blkfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.kbytesavail)
5807         numfree=$(( blkfree / $(fs_inode_ksize) ))
5808         [[ $numfree -lt $nrdirs ]] && skip "not enough blocks ($numfree)"
5809
5810         trap cleanup_print_lfs_df EXIT
5811
5812         # create files
5813         createmany -d $dir/d $nrdirs || {
5814                 unlinkmany $dir/d $nrdirs
5815                 error "failed to create $nrdirs subdirs in MDT$mdtidx:$dir"
5816         }
5817
5818         # really created :
5819         nrdirs=$(ls -U $dir | wc -l)
5820
5821         # unlink all but 100 subdirectories, then check it still works
5822         local left=100
5823         local delete=$((nrdirs - left))
5824
5825         $LFS df
5826         $LFS df -i
5827
5828         # for ldiskfs the nlink count should be 1, but this is OSD specific
5829         # and so this is listed for informational purposes only
5830         echo "nlink before: $(stat -c %h $dir), created before: $nrdirs"
5831         unlinkmany -d $dir/d $delete ||
5832                 error "unlink of first $delete subdirs failed"
5833
5834         echo "nlink between: $(stat -c %h $dir)"
5835         local found=$(ls -U $dir | wc -l)
5836         [ $found -ne $left ] &&
5837                 error "can't find subdirs: found only $found, expected $left"
5838
5839         unlinkmany -d $dir/d $delete $left ||
5840                 error "unlink of second $left subdirs failed"
5841         # regardless of whether the backing filesystem tracks nlink accurately
5842         # or not, the nlink count shouldn't be more than "." and ".." here
5843         local after=$(stat -c %h $dir)
5844         [[ $after -gt 2 ]] && error "nlink after: $after > 2" ||
5845                 echo "nlink after: $after"
5846
5847         cleanup_print_lfs_df
5848 }
5849 run_test 51b "exceed 64k subdirectory nlink limit on create, verify unlink"
5850
5851 test_51d_sub() {
5852         local stripecount=$1
5853         local nfiles=$2
5854
5855         log "create files with stripecount=$stripecount"
5856         $LFS setstripe -C $stripecount $DIR/$tdir
5857         createmany -o $DIR/$tdir/t- $nfiles
5858         $LFS getstripe $DIR/$tdir > $TMP/$tfile
5859         for ((n = 0; n < $OSTCOUNT; n++)); do
5860                 objs[$n]=$(awk -vobjs=0 '($1 == '$n') { objs += 1 } \
5861                            END { printf("%0.0f", objs) }' $TMP/$tfile)
5862                 objs0[$n]=$(grep -A 1 idx $TMP/$tfile | awk -vobjs=0 \
5863                             '($1 == '$n') { objs += 1 } \
5864                             END { printf("%0.0f", objs) }')
5865                 log "OST$n has ${objs[$n]} objects, ${objs0[$n]} are index 0"
5866         done
5867         unlinkmany $DIR/$tdir/t- $nfiles
5868         rm  -f $TMP/$tfile
5869
5870         local nlast
5871         local min=4
5872         local max=6 # allow variance of (1 - $min/$max) = 33% by default
5873
5874         # For some combinations of stripecount and OSTCOUNT current code
5875         # is not ideal, and allocates 50% fewer *first* objects to some OSTs
5876         # than others. Rather than skipping this test entirely, check that
5877         # and keep testing to ensure imbalance does not get worse. LU-15282
5878         (( (OSTCOUNT == 6 && stripecount == 4) ||
5879            (OSTCOUNT == 10 && (stripecount == 4 || stripecount == 8)) ||
5880            (OSTCOUNT == 12 && (stripecount == 8 || stripecount == 9)))) && max=9
5881         for ((nlast=0, n = 1; n < $OSTCOUNT; nlast=n,n++)); do
5882                 (( ${objs[$n]} > ${objs[$nlast]} * 4 / 5 )) ||
5883                         { $LFS df && $LFS df -i &&
5884                         error "stripecount=$stripecount: " \
5885                               "OST $n has fewer objects vs. OST $nlast " \
5886                               "(${objs[$n]} < ${objs[$nlast]} x 4/5)"; }
5887                 (( ${objs[$n]} < ${objs[$nlast]} * 5 / 4 )) ||
5888                         { $LFS df && $LFS df -i &&
5889                         error "stripecount=$stripecount: " \
5890                               "OST $n has more objects vs. OST $nlast " \
5891                               "(${objs[$n]} > ${objs[$nlast]} x 5/4)"; }
5892
5893                 (( ${objs0[$n]} > ${objs0[$nlast]} * $min / $max )) ||
5894                         { $LFS df && $LFS df -i &&
5895                         error "stripecount=$stripecount: " \
5896                               "OST $n has fewer #0 objects vs. OST $nlast " \
5897                               "(${objs0[$n]} < ${objs0[$nlast]} x $min/$max)"; }
5898                 (( ${objs0[$n]} < ${objs0[$nlast]} * $max / $min )) ||
5899                         { $LFS df && $LFS df -i &&
5900                         error "stripecount=$stripecount: " \
5901                               "OST $n has more #0 objects vs. OST $nlast " \
5902                               "(${objs0[$n]} > ${objs0[$nlast]} x $max/$min)"; }
5903         done
5904 }
5905
5906 test_51d() {
5907         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5908         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
5909
5910         local stripecount
5911         local per_ost=100
5912         local nfiles=$((per_ost * OSTCOUNT))
5913         local mdts=$(comma_list $(mdts_nodes))
5914         local param="osp.*.create_count"
5915         local qos_old=$(do_facet mds1 \
5916                 "$LCTL get_param -n lod.$FSNAME-*.qos_threshold_rr" | head -n 1)
5917
5918         do_nodes $mdts \
5919                 "$LCTL set_param lod.$FSNAME-*.qos_threshold_rr=100"
5920         stack_trap "do_nodes $mdts \
5921                 '$LCTL set_param lod.$FSNAME-*.qos_threshold_rr=${qos_old%%%}'"
5922
5923         test_mkdir $DIR/$tdir
5924         local dirstripes=$(lfs getdirstripe -c $DIR/$tdir)
5925         (( dirstripes > 0 )) || dirstripes=1
5926
5927         # Ensure enough OST objects precreated for tests to pass without
5928         # running out of objects.  This is an LOV r-r OST algorithm test,
5929         # not an OST object precreation test.
5930         local old=$(do_facet mds1 "$LCTL get_param -n $param" | head -n 1)
5931         (( old >= nfiles )) ||
5932         {
5933                 local create_count=$((nfiles * OSTCOUNT / dirstripes))
5934
5935                 do_nodes $mdts "$LCTL set_param $param=$create_count"
5936                 stack_trap "do_nodes $mdts $LCTL set_param $param=$old"
5937
5938                 # trigger precreation from all MDTs for all OSTs
5939                 for ((i = 0; i < $MDSCOUNT * 2; i++ )); do
5940                         $LFS setstripe -c -1 $DIR/$tdir/wide.$i
5941                 done
5942         }
5943
5944         for ((stripecount = 3; stripecount <= $OSTCOUNT; stripecount++)); do
5945                 sleep 8  # allow object precreation to catch up
5946                 test_51d_sub $stripecount $nfiles
5947         done
5948 }
5949 run_test 51d "check LOV round-robin OST object distribution"
5950
5951 test_51e() {
5952         if [ "$mds1_FSTYPE" != ldiskfs ]; then
5953                 skip_env "ldiskfs only test"
5954         fi
5955
5956         test_mkdir -c1 $DIR/$tdir
5957         test_mkdir -c1 $DIR/$tdir/d0
5958
5959         touch $DIR/$tdir/d0/foo
5960         createmany -l $DIR/$tdir/d0/foo $DIR/$tdir/d0/f- 65001 &&
5961                 error "file exceed 65000 nlink limit!"
5962         unlinkmany $DIR/$tdir/d0/f- 65001
5963         return 0
5964 }
5965 run_test 51e "check file nlink limit"
5966
5967 test_51f() {
5968         test_mkdir $DIR/$tdir
5969
5970         local max=100000
5971         local ulimit_old=$(ulimit -n)
5972         local spare=20 # number of spare fd's for scripts/libraries, etc.
5973         local mdt=$($LFS getstripe -m $DIR/$tdir)
5974         local numfree=$($LFS df -i $DIR/$tdir | awk '/MDT:'$mdt'/ { print $4 }')
5975
5976         echo "MDT$mdt numfree=$numfree, max=$max"
5977         [[ $numfree -gt $max ]] && numfree=$max || numfree=$((numfree * 7 / 8))
5978         if [ $((numfree + spare)) -gt $ulimit_old ]; then
5979                 while ! ulimit -n $((numfree + spare)); do
5980                         numfree=$((numfree * 3 / 4))
5981                 done
5982                 echo "changed ulimit from $ulimit_old to $((numfree + spare))"
5983         else
5984                 echo "left ulimit at $ulimit_old"
5985         fi
5986
5987         createmany -o -k -t 120 $DIR/$tdir/f $numfree || {
5988                 unlinkmany $DIR/$tdir/f $numfree
5989                 error "create+open $numfree files in $DIR/$tdir failed"
5990         }
5991         ulimit -n $ulimit_old
5992
5993         # if createmany exits at 120s there will be fewer than $numfree files
5994         unlinkmany $DIR/$tdir/f $numfree || true
5995 }
5996 run_test 51f "check many open files limit"
5997
5998 test_52a() {
5999         [ -f $DIR/$tdir/foo ] && chattr -a $DIR/$tdir/foo
6000         test_mkdir $DIR/$tdir
6001         touch $DIR/$tdir/foo
6002         chattr +a $DIR/$tdir/foo || error "chattr +a failed"
6003         echo bar >> $DIR/$tdir/foo || error "append bar failed"
6004         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
6005         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
6006         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
6007                                         error "link worked"
6008         echo foo >> $DIR/$tdir/foo || error "append foo failed"
6009         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
6010         lsattr $DIR/$tdir/foo | egrep -q "^-+a[-e]+ $DIR/$tdir/foo" ||
6011                                                      error "lsattr"
6012         chattr -a $DIR/$tdir/foo || error "chattr -a failed"
6013         cp -r $DIR/$tdir $TMP/
6014         rm -fr $DIR/$tdir $TMP/$tdir || error "cleanup rm failed"
6015 }
6016 run_test 52a "append-only flag test (should return errors)"
6017
6018 test_52b() {
6019         [ -f $DIR/$tdir/foo ] && chattr -i $DIR/$tdir/foo
6020         test_mkdir $DIR/$tdir
6021         touch $DIR/$tdir/foo
6022         chattr +i $DIR/$tdir/foo || error "chattr +i failed"
6023         cat test > $DIR/$tdir/foo && error "cat test worked"
6024         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
6025         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
6026         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
6027                                         error "link worked"
6028         echo foo >> $DIR/$tdir/foo && error "echo worked"
6029         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
6030         [ -f $DIR/$tdir/foo ] || error "$tdir/foo is not a file"
6031         [ -f $DIR/$tdir/foo_ren ] && error "$tdir/foo_ren is not a file"
6032         lsattr $DIR/$tdir/foo | egrep -q "^-+i[-e]+ $DIR/$tdir/foo" ||
6033                                                         error "lsattr"
6034         chattr -i $DIR/$tdir/foo || error "chattr failed"
6035
6036         rm -fr $DIR/$tdir || error "unable to remove $DIR/$tdir"
6037 }
6038 run_test 52b "immutable flag test (should return errors) ======="
6039
6040 test_53() {
6041         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6042         remote_mds_nodsh && skip "remote MDS with nodsh"
6043         remote_ost_nodsh && skip "remote OST with nodsh"
6044
6045         local param
6046         local param_seq
6047         local ostname
6048         local mds_last
6049         local mds_last_seq
6050         local ost_last
6051         local ost_last_seq
6052         local ost_last_id
6053         local ostnum
6054         local node
6055         local found=false
6056         local support_last_seq=true
6057
6058         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
6059                 support_last_seq=false
6060
6061         # only test MDT0000
6062         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS)
6063         local value
6064         for value in $(do_facet $SINGLEMDS \
6065                        $LCTL get_param osp.$mdtosc.prealloc_last_id) ; do
6066                 param=$(echo ${value[0]} | cut -d "=" -f1)
6067                 ostname=$(echo $param | cut -d "." -f2 | cut -d - -f 1-2)
6068
6069                 if $support_last_seq; then
6070                         param_seq=$(echo $param |
6071                                 sed -e s/prealloc_last_id/prealloc_last_seq/g)
6072                         mds_last_seq=$(do_facet $SINGLEMDS \
6073                                        $LCTL get_param -n $param_seq)
6074                 fi
6075                 mds_last=$(do_facet $SINGLEMDS $LCTL get_param -n $param)
6076
6077                 ostnum=$(index_from_ostuuid ${ostname}_UUID)
6078                 node=$(facet_active_host ost$((ostnum+1)))
6079                 param="obdfilter.$ostname.last_id"
6080                 for ost_last in $(do_node $node $LCTL get_param -n $param) ; do
6081                         echo "$ostname.last_id=$ost_last; MDS.last_id=$mds_last"
6082                         ost_last_id=$ost_last
6083
6084                         if $support_last_seq; then
6085                                 ost_last_id=$(echo $ost_last |
6086                                               awk -F':' '{print $2}' |
6087                                               sed -e "s/^0x//g")
6088                                 ost_last_seq=$(echo $ost_last |
6089                                                awk -F':' '{print $1}')
6090                                 [[ $ost_last_seq = $mds_last_seq ]] || continue
6091                         fi
6092
6093                         if [[ $ost_last_id != $mds_last ]]; then
6094                                 error "$ost_last_id != $mds_last"
6095                         else
6096                                 found=true
6097                                 break
6098                         fi
6099                 done
6100         done
6101         $found || error "can not match last_seq/last_id for $mdtosc"
6102         return 0
6103 }
6104 run_test 53 "verify that MDS and OSTs agree on pre-creation ===="
6105
6106 test_54a() {
6107         perl -MSocket -e ';' || skip "no Socket perl module installed"
6108
6109         $SOCKETSERVER $DIR/socket ||
6110                 error "$SOCKETSERVER $DIR/socket failed: $?"
6111         $SOCKETCLIENT $DIR/socket ||
6112                 error "$SOCKETCLIENT $DIR/socket failed: $?"
6113         $MUNLINK $DIR/socket || error "$MUNLINK $DIR/socket failed: $?"
6114 }
6115 run_test 54a "unix domain socket test =========================="
6116
6117 test_54b() {
6118         f="$DIR/f54b"
6119         mknod $f c 1 3
6120         chmod 0666 $f
6121         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1
6122 }
6123 run_test 54b "char device works in lustre ======================"
6124
6125 find_loop_dev() {
6126         [ -b /dev/loop/0 ] && LOOPBASE=/dev/loop/
6127         [ -b /dev/loop0 ] && LOOPBASE=/dev/loop
6128         [ -z "$LOOPBASE" ] && echo "/dev/loop/0 and /dev/loop0 gone?" && return
6129
6130         for i in $(seq 3 7); do
6131                 losetup $LOOPBASE$i > /dev/null 2>&1 && continue
6132                 LOOPDEV=$LOOPBASE$i
6133                 LOOPNUM=$i
6134                 break
6135         done
6136 }
6137
6138 cleanup_54c() {
6139         local rc=0
6140         loopdev="$DIR/loop54c"
6141
6142         trap 0
6143         $UMOUNT $DIR/$tdir || rc=$?
6144         losetup -d $loopdev || true
6145         losetup -d $LOOPDEV || true
6146         rm -rf $loopdev $DIR/$tfile $DIR/$tdir
6147         return $rc
6148 }
6149
6150 test_54c() {
6151         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6152
6153         loopdev="$DIR/loop54c"
6154
6155         find_loop_dev
6156         [ -z "$LOOPNUM" ] && skip_env "couldn't find empty loop device"
6157         trap cleanup_54c EXIT
6158         mknod $loopdev b 7 $LOOPNUM
6159         echo "make a loop file system with $DIR/$tfile on $loopdev ($LOOPNUM)."
6160         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE seek=1024 count=1 > /dev/null
6161         losetup $loopdev $DIR/$tfile ||
6162                 error "can't set up $loopdev for $DIR/$tfile"
6163         mkfs.ext2 $loopdev || error "mke2fs on $loopdev"
6164         test_mkdir $DIR/$tdir
6165         mount -t ext2 $loopdev $DIR/$tdir ||
6166                 error "error mounting $loopdev on $DIR/$tdir"
6167         dd if=/dev/zero of=$DIR/$tdir/tmp bs=$PAGE_SIZE count=30 ||
6168                 error "dd write"
6169         df $DIR/$tdir
6170         dd if=$DIR/$tdir/tmp of=/dev/zero bs=$PAGE_SIZE count=30 ||
6171                 error "dd read"
6172         cleanup_54c
6173 }
6174 run_test 54c "block device works in lustre ====================="
6175
6176 test_54d() {
6177         local pipe="$DIR/$tfile.pipe"
6178         local string="aaaaaa"
6179
6180         mknod $pipe p
6181         echo -n "$string" > $pipe &
6182         local result=$(cat $pipe)
6183         [[ "$result" == "$string" ]] || error "$result != $string"
6184 }
6185 run_test 54d "fifo device works in lustre ======================"
6186
6187 test_54e() {
6188         f="$DIR/f54e"
6189         string="aaaaaa"
6190         cp -aL /dev/console $f
6191         echo $string > $f || error "echo $string to $f failed"
6192 }
6193 run_test 54e "console/tty device works in lustre ======================"
6194
6195 test_56a() {
6196         local numfiles=3
6197         local numdirs=2
6198         local dir=$DIR/$tdir
6199
6200         rm -rf $dir
6201         test_mkdir -p $dir/dir
6202         for i in $(seq $numfiles); do
6203                 touch $dir/file$i
6204                 touch $dir/dir/file$i
6205         done
6206
6207         local numcomp=$($LFS getstripe --component-count $dir)
6208
6209         [[ $numcomp == 0 ]] && numcomp=1
6210
6211         # test lfs getstripe with --recursive
6212         local filenum=$($LFS getstripe -r $dir | egrep -c "obdidx|l_ost_idx")
6213
6214         [[ $filenum -eq $((numfiles * 2)) ]] ||
6215                 error "$LFS getstripe -r: found $filenum != $((numfiles * 2))"
6216         filenum=$($LFS getstripe $dir | egrep -c "obdidx|l_ost_idx")
6217         [[ $filenum -eq $numfiles ]] ||
6218                 error "$LFS getstripe $dir: found $filenum, not $numfiles"
6219         echo "$LFS getstripe showed obdidx or l_ost_idx"
6220
6221         # test lfs getstripe with file instead of dir
6222         filenum=$($LFS getstripe $dir/file1 | egrep -c "obdidx|l_ost_idx")
6223         [[ $filenum -eq 1 ]] ||
6224                 error "$LFS getstripe $dir/file1: found $filenum, not 1"
6225         echo "$LFS getstripe file1 passed"
6226
6227         #test lfs getstripe with --verbose
6228         filenum=$($LFS getstripe --verbose $dir | grep -c lmm_magic)
6229         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
6230                 error "$LFS getstripe --verbose $dir: "\
6231                       "got $filenum want $((numfiles * numcomp)) lmm_magic"
6232         [[ $($LFS getstripe $dir | grep -c lmm_magic) -eq 0 ]] ||
6233                 error "$LFS getstripe $dir: showed lmm_magic"
6234
6235         #test lfs getstripe with -v prints lmm_fid
6236         filenum=$($LFS getstripe -v $dir | grep -c lmm_fid)
6237         local countfids=$((numdirs + numfiles * numcomp))
6238         [[ $filenum -eq $countfids ]] ||
6239                 error "$LFS getstripe -v $dir: "\
6240                       "got $filenum want $countfids lmm_fid"
6241         [[ $($LFS getstripe $dir | grep -c lmm_fid) -eq 0 ]] ||
6242                 error "$LFS getstripe $dir: showed lmm_fid by default"
6243         echo "$LFS getstripe --verbose passed"
6244
6245         #check for FID information
6246         local fid1=$($LFS getstripe --fid $dir/file1)
6247         local fid2=$($LFS getstripe --verbose $dir/file1 |
6248                      awk '/lmm_fid: / { print $2; exit; }')
6249         local fid3=$($LFS path2fid $dir/file1)
6250
6251         [ "$fid1" != "$fid2" ] &&
6252                 error "getstripe --fid '$fid1' != getstripe --verbose '$fid2'"
6253         [ "$fid1" != "$fid3" ] &&
6254                 error "getstripe --fid '$fid1' != lfs path2fid '$fid3'"
6255         echo "$LFS getstripe --fid passed"
6256
6257         #test lfs getstripe with --obd
6258         $LFS getstripe --obd wrong_uuid $dir 2>&1 | grep -q "unknown obduuid" ||
6259                 error "$LFS getstripe --obd wrong_uuid: should return error"
6260
6261         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6262
6263         local ostidx=1
6264         local obduuid=$(ostuuid_from_index $ostidx)
6265         local found=$($LFS getstripe -r --obd $obduuid $dir |
6266                 grep 'lmm_stripe_offset:' | grep -c " $ostidx\$")
6267
6268         filenum=$($LFS getstripe -ir $dir | grep -c "^$ostidx\$")
6269         [[ $($LFS getstripe -id $dir) -ne $ostidx ]] ||
6270                 ((filenum--))
6271         [[ $($LFS getstripe -id $dir/dir) -ne $ostidx ]] ||
6272                 ((filenum--))
6273
6274         [[ $found -eq $filenum ]] ||
6275                 error "$LFS getstripe --obd: found $found expect $filenum"
6276         [[ $($LFS getstripe -r -v --obd $obduuid $dir |
6277                 sed '/^[         ]*'${ostidx}'[  ]/d' |
6278                 sed -n '/^[      ]*[0-9][0-9]*[  ]/p' | wc -l) -eq 0 ]] ||
6279                 error "$LFS getstripe --obd: should not show file on other obd"
6280         echo "$LFS getstripe --obd passed"
6281 }
6282 run_test 56a "check $LFS getstripe"
6283
6284 test_56b() {
6285         local dir=$DIR/$tdir
6286         local numdirs=3
6287
6288         test_mkdir $dir
6289         for i in $(seq $numdirs); do
6290                 test_mkdir $dir/dir$i
6291         done
6292
6293         # test lfs getdirstripe default mode is non-recursion, which is
6294         # different from lfs getstripe
6295         local dircnt=$($LFS getdirstripe $dir | grep -c lmv_stripe_count)
6296
6297         [[ $dircnt -eq 1 ]] ||
6298                 error "$LFS getdirstripe: found $dircnt, not 1"
6299         dircnt=$($LFS getdirstripe --recursive $dir |
6300                 grep -c lmv_stripe_count)
6301         [[ $dircnt -eq $((numdirs + 1)) ]] ||
6302                 error "$LFS getdirstripe -r: $dircnt, != $((numdirs + 1))"
6303 }
6304 run_test 56b "check $LFS getdirstripe"
6305
6306 test_56c() {
6307         remote_ost_nodsh && skip "remote OST with nodsh"
6308
6309         local ost_idx=0
6310         local ost_name=$(ostname_from_index $ost_idx)
6311         local old_status=$(ost_dev_status $ost_idx)
6312         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
6313
6314         [[ -z "$old_status" ]] ||
6315                 skip_env "OST $ost_name is in $old_status status"
6316
6317         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=1
6318         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
6319                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=1
6320         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
6321                 save_lustre_params ost1 osd-*.$ost_name.nonrotational > $p
6322                 do_facet ost1 $LCTL set_param -n osd-*.$ost_name.nonrotational=1
6323         fi
6324
6325         [[ $($LFS df -v $MOUNT |& grep -c "inactive device") -eq 0 ]] ||
6326                 error "$LFS df -v showing inactive devices"
6327         sleep_maxage
6328
6329         local new_status=$(ost_dev_status $ost_idx $MOUNT -v)
6330
6331         [[ "$new_status" =~ "D" ]] ||
6332                 error "$ost_name status is '$new_status', missing 'D'"
6333         if [[ $OST1_VERSION -ge $(version_code 2.12.55) ]]; then
6334                 [[ "$new_status" =~ "N" ]] ||
6335                         error "$ost_name status is '$new_status', missing 'N'"
6336         fi
6337         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
6338                 [[ "$new_status" =~ "f" ]] ||
6339                         error "$ost_name status is '$new_status', missing 'f'"
6340         fi
6341
6342         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=0
6343         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
6344                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=0
6345         [[ -z "$p" ]] && restore_lustre_params < $p || true
6346         sleep_maxage
6347
6348         new_status=$(ost_dev_status $ost_idx)
6349         [[ ! "$new_status" =~ "D" && ! "$new_status" =~ "N" ]] ||
6350                 error "$ost_name status is '$new_status', has 'D' and/or 'N'"
6351         # can't check 'f' as devices may actually be on flash
6352 }
6353 run_test 56c "check 'lfs df' showing device status"
6354
6355 test_56d() {
6356         local mdts=$($LFS df -v $MOUNT | grep -c MDT)
6357         local osts=$($LFS df -v $MOUNT | grep -c OST)
6358
6359         $LFS df $MOUNT
6360
6361         (( mdts == MDSCOUNT )) ||
6362                 error "lfs df -v showed $mdts MDTs, not $MDSCOUNT"
6363         (( osts == OSTCOUNT )) ||
6364                 error "lfs df -v showed $osts OSTs, not $OSTCOUNT"
6365 }
6366 run_test 56d "'lfs df -v' prints only configured devices"
6367
6368 test_56e() {
6369         err_enoent=2 # No such file or directory
6370         err_eopnotsupp=95 # Operation not supported
6371
6372         enoent_mnt=/pmt1 # Invalid dentry. Path not present
6373         notsup_mnt=/tmp  # Valid dentry, but Not a lustreFS
6374
6375         # Check for handling of path not exists
6376         output=$($LFS df $enoent_mnt 2>&1)
6377         ret=$?
6378
6379         fs=$(echo $output | awk -F: '{print $2}' | awk '{print $3}' | tr -d \')
6380         [[ $fs = $enoent_mnt && $ret -eq $err_enoent ]] ||
6381                 error "expect failure $err_enoent, not $ret"
6382
6383         # Check for handling of non-Lustre FS
6384         output=$($LFS df $notsup_mnt)
6385         ret=$?
6386
6387         fs=$(echo $output | awk '{print $1}' | awk -F: '{print $2}')
6388         [[ $fs = $notsup_mnt && $ret -eq $err_eopnotsupp ]] ||
6389                 error "expect success $err_eopnotsupp, not $ret"
6390
6391         # Check for multiple LustreFS argument
6392         output=$($LFS df $MOUNT $MOUNT $MOUNT | grep -c "filesystem_summary:")
6393         ret=$?
6394
6395         [[ $output -eq 3 && $ret -eq 0 ]] ||
6396                 error "expect success 3, not $output, rc = $ret"
6397
6398         # Check for correct non-Lustre FS handling among multiple
6399         # LustreFS argument
6400         output=$($LFS df $MOUNT $notsup_mnt $MOUNT |
6401                 grep -c "filesystem_summary:"; exit ${PIPESTATUS[0]})
6402         ret=$?
6403
6404         [[ $output -eq 2 && $ret -eq $err_eopnotsupp ]] ||
6405                 error "expect success 2, not $output, rc = $ret"
6406 }
6407 run_test 56e "'lfs df' Handle non LustreFS & multiple LustreFS"
6408
6409 NUMFILES=3
6410 NUMDIRS=3
6411 setup_56() {
6412         local local_tdir="$1"
6413         local local_numfiles="$2"
6414         local local_numdirs="$3"
6415         local dir_params="$4"
6416         local dir_stripe_params="$5"
6417
6418         if [ ! -d "$local_tdir" ] ; then
6419                 test_mkdir -p $dir_stripe_params $local_tdir
6420                 [ "$dir_params" ] && $LFS setstripe $dir_params $local_tdir
6421                 for i in $(seq $local_numfiles) ; do
6422                         touch $local_tdir/file$i
6423                 done
6424                 for i in $(seq $local_numdirs) ; do
6425                         test_mkdir $dir_stripe_params $local_tdir/dir$i
6426                         for j in $(seq $local_numfiles) ; do
6427                                 touch $local_tdir/dir$i/file$j
6428                         done
6429                 done
6430         fi
6431 }
6432
6433 setup_56_special() {
6434         local local_tdir=$1
6435         local local_numfiles=$2
6436         local local_numdirs=$3
6437
6438         setup_56 $local_tdir $local_numfiles $local_numdirs
6439
6440         if [ ! -e "$local_tdir/loop${local_numfiles}b" ] ; then
6441                 for i in $(seq $local_numfiles) ; do
6442                         mknod $local_tdir/loop${i}b b 7 $i
6443                         mknod $local_tdir/null${i}c c 1 3
6444                         ln -s $local_tdir/file1 $local_tdir/link${i}
6445                 done
6446                 for i in $(seq $local_numdirs) ; do
6447                         mknod $local_tdir/dir$i/loop${i}b b 7 $i
6448                         mknod $local_tdir/dir$i/null${i}c c 1 3
6449                         ln -s $local_tdir/dir$i/file1 $local_tdir/dir$i/link${i}
6450                 done
6451         fi
6452 }
6453
6454 test_56g() {
6455         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6456         local expected=$(($NUMDIRS + 2))
6457
6458         setup_56 $dir $NUMFILES $NUMDIRS
6459
6460         # test lfs find with -name
6461         for i in $(seq $NUMFILES) ; do
6462                 local nums=$($LFS find -name "*$i" $dir | wc -l)
6463
6464                 [ $nums -eq $expected ] ||
6465                         error "lfs find -name '*$i' $dir wrong: "\
6466                               "found $nums, expected $expected"
6467         done
6468 }
6469 run_test 56g "check lfs find -name"
6470
6471 test_56h() {
6472         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6473         local expected=$(((NUMDIRS + 1) * (NUMFILES - 1) + NUMFILES))
6474
6475         setup_56 $dir $NUMFILES $NUMDIRS
6476
6477         # test lfs find with ! -name
6478         for i in $(seq $NUMFILES) ; do
6479                 local nums=$($LFS find ! -name "*$i" $dir | wc -l)
6480
6481                 [ $nums -eq $expected ] ||
6482                         error "lfs find ! -name '*$i' $dir wrong: "\
6483                               "found $nums, expected $expected"
6484         done
6485 }
6486 run_test 56h "check lfs find ! -name"
6487
6488 test_56i() {
6489         local dir=$DIR/$tdir
6490
6491         test_mkdir $dir
6492
6493         local cmd="$LFS find -ost $(ostuuid_from_index 0 $dir) $dir"
6494         local out=$($cmd)
6495
6496         [ -z "$out" ] || error "'$cmd' returned directory '$out'"
6497 }
6498 run_test 56i "check 'lfs find -ost UUID' skips directories"
6499
6500 test_56j() {
6501         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6502
6503         setup_56_special $dir $NUMFILES $NUMDIRS
6504
6505         local expected=$((NUMDIRS + 1))
6506         local cmd="$LFS find -type d $dir"
6507         local nums=$($cmd | wc -l)
6508
6509         [ $nums -eq $expected ] ||
6510                 error "'$cmd' wrong: found $nums, expected $expected"
6511 }
6512 run_test 56j "check lfs find -type d"
6513
6514 test_56k() {
6515         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6516
6517         setup_56_special $dir $NUMFILES $NUMDIRS
6518
6519         local expected=$(((NUMDIRS + 1) * NUMFILES))
6520         local cmd="$LFS find -type f $dir"
6521         local nums=$($cmd | wc -l)
6522
6523         [ $nums -eq $expected ] ||
6524                 error "'$cmd' wrong: found $nums, expected $expected"
6525 }
6526 run_test 56k "check lfs find -type f"
6527
6528 test_56l() {
6529         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6530
6531         setup_56_special $dir $NUMFILES $NUMDIRS
6532
6533         local expected=$((NUMDIRS + NUMFILES))
6534         local cmd="$LFS find -type b $dir"
6535         local nums=$($cmd | wc -l)
6536
6537         [ $nums -eq $expected ] ||
6538                 error "'$cmd' wrong: found $nums, expected $expected"
6539 }
6540 run_test 56l "check lfs find -type b"
6541
6542 test_56m() {
6543         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6544
6545         setup_56_special $dir $NUMFILES $NUMDIRS
6546
6547         local expected=$((NUMDIRS + NUMFILES))
6548         local cmd="$LFS find -type c $dir"
6549         local nums=$($cmd | wc -l)
6550         [ $nums -eq $expected ] ||
6551                 error "'$cmd' wrong: found $nums, expected $expected"
6552 }
6553 run_test 56m "check lfs find -type c"
6554
6555 test_56n() {
6556         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6557         setup_56_special $dir $NUMFILES $NUMDIRS
6558
6559         local expected=$((NUMDIRS + NUMFILES))
6560         local cmd="$LFS find -type l $dir"
6561         local nums=$($cmd | wc -l)
6562
6563         [ $nums -eq $expected ] ||
6564                 error "'$cmd' wrong: found $nums, expected $expected"
6565 }
6566 run_test 56n "check lfs find -type l"
6567
6568 test_56o() {
6569         local dir=$DIR/$tdir
6570
6571         setup_56 $dir $NUMFILES $NUMDIRS
6572         utime $dir/file1 > /dev/null || error "utime (1)"
6573         utime $dir/file2 > /dev/null || error "utime (2)"
6574         utime $dir/dir1 > /dev/null || error "utime (3)"
6575         utime $dir/dir2 > /dev/null || error "utime (4)"
6576         utime $dir/dir1/file1 > /dev/null || error "utime (5)"
6577         dd if=/dev/zero count=1 >> $dir/dir1/file1 && sync
6578
6579         local expected=4
6580         local nums=$($LFS find -mtime +0 $dir | wc -l)
6581
6582         [ $nums -eq $expected ] ||
6583                 error "lfs find -mtime +0 $dir: found $nums expect $expected"
6584
6585         expected=12
6586         cmd="$LFS find -mtime 0 $dir"
6587         nums=$($cmd | wc -l)
6588         [ $nums -eq $expected ] ||
6589                 error "'$cmd' wrong: found $nums, expected $expected"
6590 }
6591 run_test 56o "check lfs find -mtime for old files"
6592
6593 test_56ob() {
6594         local dir=$DIR/$tdir
6595         local expected=1
6596         local count=0
6597
6598         # just to make sure there is something that won't be found
6599         test_mkdir $dir
6600         touch $dir/$tfile.now
6601
6602         for age in year week day hour min; do
6603                 count=$((count + 1))
6604
6605                 touch $dir/$tfile-a.$age $dir/$tfile-m.$age
6606                 touch --date="$count $age ago" -a $dir/$tfile-a.$age
6607                 touch --date="$count $age ago" -m $dir/$tfile-m.$age
6608
6609                 local cmd="$LFS find $dir -mtime $count${age:0:1}"
6610                 local nums=$($cmd | wc -l)
6611                 [ $nums -eq $expected ] ||
6612                         error "'$cmd' wrong: found $nums, expected $expected"
6613
6614                 cmd="$LFS find $dir -atime $count${age:0:1}"
6615                 nums=$($cmd | wc -l)
6616                 [ $nums -eq $expected ] ||
6617                         error "'$cmd' wrong: found $nums, expected $expected"
6618         done
6619
6620         sleep 2
6621         cmd="$LFS find $dir -ctime +1s -type f"
6622         nums=$($cmd | wc -l)
6623         (( $nums == $count * 2 + 1)) ||
6624                 error "'$cmd' wrong: found $nums, expected $((count * 2 + 1))"
6625 }
6626 run_test 56ob "check lfs find -atime -mtime -ctime with units"
6627
6628 test_newerXY_base() {
6629         local x=$1
6630         local y=$2
6631         local dir=$DIR/$tdir
6632         local ref
6633         local negref
6634
6635         if [ $y == "t" ]; then
6636                 if [ $x == "b" ]; then
6637                         ref=\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\"
6638                 else
6639                         ref=\"$(date +"%Y-%m-%d %H:%M:%S")\"
6640                 fi
6641         else
6642                 ref=$DIR/$tfile.newer.$x$y
6643                 touch $ref || error "touch $ref failed"
6644         fi
6645
6646         echo "before = $ref"
6647         sleep 2
6648         setup_56 $dir $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6649         sleep 2
6650         if [ $y == "t" ]; then
6651                 if [ $x == "b" ]; then
6652                         negref=\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\"
6653                 else
6654                         negref=\"$(date +"%Y-%m-%d %H:%M:%S")\"
6655                 fi
6656         else
6657                 negref=$DIR/$tfile.negnewer.$x$y
6658                 touch $negref || error "touch $negref failed"
6659         fi
6660
6661         echo "after = $negref"
6662         local cmd="$LFS find $dir -newer$x$y $ref"
6663         local nums=$(eval $cmd | wc -l)
6664         local expected=$(((NUMFILES + 2) * NUMDIRS + 1))
6665
6666         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6667                 error "'$cmd' wrong: found $nums newer, expected $expected"  ; }
6668
6669         cmd="$LFS find $dir ! -newer$x$y $negref"
6670         nums=$(eval $cmd | wc -l)
6671         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6672                 error "'$cmd' wrong: found $nums older, expected $expected"  ; }
6673
6674         cmd="$LFS find $dir -newer$x$y $ref ! -newer$x$y $negref"
6675         nums=$(eval $cmd | wc -l)
6676         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6677                 error "'$cmd' wrong: found $nums between, expected $expected"; }
6678
6679         rm -rf $DIR/*
6680 }
6681
6682 test_56oc() {
6683         test_newerXY_base "a" "a"
6684         test_newerXY_base "a" "m"
6685         test_newerXY_base "a" "c"
6686         test_newerXY_base "m" "a"
6687         test_newerXY_base "m" "m"
6688         test_newerXY_base "m" "c"
6689         test_newerXY_base "c" "a"
6690         test_newerXY_base "c" "m"
6691         test_newerXY_base "c" "c"
6692
6693         test_newerXY_base "a" "t"
6694         test_newerXY_base "m" "t"
6695         test_newerXY_base "c" "t"
6696
6697         [[ $MDS1_VERSION -lt $(version_code 2.13.54) ||
6698            $CLIENT_VERSION -lt $(version_code 2.13.54) ]] &&
6699                 ! btime_supported && echo "btime unsupported" && return 0
6700
6701         test_newerXY_base "b" "b"
6702         test_newerXY_base "b" "t"
6703 }
6704 run_test 56oc "check lfs find -newerXY work"
6705
6706 btime_supported() {
6707         local dir=$DIR/$tdir
6708         local rc
6709
6710         mkdir -p $dir
6711         touch $dir/$tfile
6712         $LFS find $dir -btime -1d -type f
6713         rc=$?
6714         rm -rf $dir
6715         return $rc
6716 }
6717
6718 test_56od() {
6719         [ $MDS1_VERSION -lt $(version_code 2.13.53) ] &&
6720                 ! btime_supported && skip "btime unsupported on MDS"
6721
6722         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
6723                 ! btime_supported && skip "btime unsupported on clients"
6724
6725         local dir=$DIR/$tdir
6726         local ref=$DIR/$tfile.ref
6727         local negref=$DIR/$tfile.negref
6728
6729         mkdir $dir || error "mkdir $dir failed"
6730         touch $dir/$tfile.n1 || error "touch $dir/$tfile.n1 failed"
6731         touch $dir/$tfile.n2 || error "touch $dir/$tfile.n2 failed"
6732         mkdir $dir/$tdir.n1 || error "mkdir $dir/$tdir.n1 failed"
6733         mkdir $dir/$tdir.n2 || error "mkdir $dir/$tdir.n2 failed"
6734         touch $ref || error "touch $ref failed"
6735         # sleep 3 seconds at least
6736         sleep 3
6737
6738         local before=$(do_facet mds1 date +%s)
6739         local skew=$(($(date +%s) - before + 1))
6740
6741         if (( skew < 0 && skew > -5 )); then
6742                 sleep $((0 - skew + 1))
6743                 skew=0
6744         fi
6745
6746         # Set the dir stripe params to limit files all on MDT0,
6747         # otherwise we need to calc the max clock skew between
6748         # the client and MDTs.
6749         setup_56 $dir/d.btime $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6750         sleep 2
6751         touch $negref || error "touch $negref failed"
6752
6753         local cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type f"
6754         local nums=$($cmd | wc -l)
6755         local expected=$(((NUMFILES + 1) * NUMDIRS))
6756
6757         [ $nums -eq $expected ] ||
6758                 error "'$cmd' wrong: found $nums, expected $expected"
6759
6760         cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type d"
6761         nums=$($cmd | wc -l)
6762         expected=$((NUMFILES + 1))
6763         [ $nums -eq $expected ] ||
6764                 error "'$cmd' wrong: found $nums, expected $expected"
6765
6766         [ $skew -lt 0 ] && return
6767
6768         local after=$(do_facet mds1 date +%s)
6769         local age=$((after - before + 1 + skew))
6770
6771         cmd="$LFS find $dir -btime -${age}s -type f"
6772         nums=$($cmd | wc -l)
6773         expected=$(((NUMFILES + 1) * NUMDIRS))
6774
6775         echo "Clock skew between client and server: $skew, age:$age"
6776         [ $nums -eq $expected ] ||
6777                 error "'$cmd' wrong: found $nums, expected $expected"
6778
6779         expected=$(($NUMDIRS + 1))
6780         cmd="$LFS find $dir -btime -${age}s -type d"
6781         nums=$($cmd | wc -l)
6782         [ $nums -eq $expected ] ||
6783                 error "'$cmd' wrong: found $nums, expected $expected"
6784         rm -f $ref $negref || error "Failed to remove $ref $negref"
6785 }
6786 run_test 56od "check lfs find -btime with units"
6787
6788 test_56p() {
6789         [ $RUNAS_ID -eq $UID ] &&
6790                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6791
6792         local dir=$DIR/$tdir
6793
6794         setup_56 $dir $NUMFILES $NUMDIRS
6795         chown $RUNAS_ID $dir/file* || error "chown $DIR/${tdir}g/file$i failed"
6796
6797         local expected=$NUMFILES
6798         local cmd="$LFS find -uid $RUNAS_ID $dir"
6799         local nums=$($cmd | wc -l)
6800
6801         [ $nums -eq $expected ] ||
6802                 error "'$cmd' wrong: found $nums, expected $expected"
6803
6804         expected=$(((NUMFILES + 1) * NUMDIRS + 1))
6805         cmd="$LFS find ! -uid $RUNAS_ID $dir"
6806         nums=$($cmd | wc -l)
6807         [ $nums -eq $expected ] ||
6808                 error "'$cmd' wrong: found $nums, expected $expected"
6809 }
6810 run_test 56p "check lfs find -uid and ! -uid"
6811
6812 test_56q() {
6813         [ $RUNAS_ID -eq $UID ] &&
6814                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6815
6816         local dir=$DIR/$tdir
6817
6818         setup_56 $dir $NUMFILES $NUMDIRS
6819         chgrp $RUNAS_GID $dir/file* || error "chown $dir/file$i failed"
6820
6821         local expected=$NUMFILES
6822         local cmd="$LFS find -gid $RUNAS_GID $dir"
6823         local nums=$($cmd | wc -l)
6824
6825         [ $nums -eq $expected ] ||
6826                 error "'$cmd' wrong: found $nums, expected $expected"
6827
6828         expected=$(( ($NUMFILES+1) * $NUMDIRS + 1))
6829         cmd="$LFS find ! -gid $RUNAS_GID $dir"
6830         nums=$($cmd | wc -l)
6831         [ $nums -eq $expected ] ||
6832                 error "'$cmd' wrong: found $nums, expected $expected"
6833 }
6834 run_test 56q "check lfs find -gid and ! -gid"
6835
6836 test_56r() {
6837         local dir=$DIR/$tdir
6838
6839         setup_56 $dir $NUMFILES $NUMDIRS
6840
6841         local expected=12
6842         local cmd="$LFS find -size 0 -type f -lazy $dir"
6843         local nums=$($cmd | wc -l)
6844
6845         [ $nums -eq $expected ] ||
6846                 error "'$cmd' wrong: found $nums, expected $expected"
6847         cmd="$LFS find -size 0 -type f $dir"
6848         nums=$($cmd | wc -l)
6849         [ $nums -eq $expected ] ||
6850                 error "'$cmd' wrong: found $nums, expected $expected"
6851
6852         expected=0
6853         cmd="$LFS find ! -size 0 -type f -lazy $dir"
6854         nums=$($cmd | wc -l)
6855         [ $nums -eq $expected ] ||
6856                 error "'$cmd' wrong: found $nums, expected $expected"
6857         cmd="$LFS find ! -size 0 -type f $dir"
6858         nums=$($cmd | wc -l)
6859         [ $nums -eq $expected ] ||
6860                 error "'$cmd' wrong: found $nums, expected $expected"
6861
6862         echo "test" > $dir/$tfile
6863         echo "test2" > $dir/$tfile.2 && sync
6864         expected=1
6865         cmd="$LFS find -size 5 -type f -lazy $dir"
6866         nums=$($cmd | wc -l)
6867         [ $nums -eq $expected ] ||
6868                 error "'$cmd' wrong: found $nums, expected $expected"
6869         cmd="$LFS find -size 5 -type f $dir"
6870         nums=$($cmd | wc -l)
6871         [ $nums -eq $expected ] ||
6872                 error "'$cmd' wrong: found $nums, expected $expected"
6873
6874         expected=1
6875         cmd="$LFS find -size +5 -type f -lazy $dir"
6876         nums=$($cmd | wc -l)
6877         [ $nums -eq $expected ] ||
6878                 error "'$cmd' wrong: found $nums, expected $expected"
6879         cmd="$LFS find -size +5 -type f $dir"
6880         nums=$($cmd | wc -l)
6881         [ $nums -eq $expected ] ||
6882                 error "'$cmd' wrong: found $nums, expected $expected"
6883
6884         expected=2
6885         cmd="$LFS find -size +0 -type f -lazy $dir"
6886         nums=$($cmd | wc -l)
6887         [ $nums -eq $expected ] ||
6888                 error "'$cmd' wrong: found $nums, expected $expected"
6889         cmd="$LFS find -size +0 -type f $dir"
6890         nums=$($cmd | wc -l)
6891         [ $nums -eq $expected ] ||
6892                 error "'$cmd' wrong: found $nums, expected $expected"
6893
6894         expected=2
6895         cmd="$LFS find ! -size -5 -type f -lazy $dir"
6896         nums=$($cmd | wc -l)
6897         [ $nums -eq $expected ] ||
6898                 error "'$cmd' wrong: found $nums, expected $expected"
6899         cmd="$LFS find ! -size -5 -type f $dir"
6900         nums=$($cmd | wc -l)
6901         [ $nums -eq $expected ] ||
6902                 error "'$cmd' wrong: found $nums, expected $expected"
6903
6904         expected=12
6905         cmd="$LFS find -size -5 -type f -lazy $dir"
6906         nums=$($cmd | wc -l)
6907         [ $nums -eq $expected ] ||
6908                 error "'$cmd' wrong: found $nums, expected $expected"
6909         cmd="$LFS find -size -5 -type f $dir"
6910         nums=$($cmd | wc -l)
6911         [ $nums -eq $expected ] ||
6912                 error "'$cmd' wrong: found $nums, expected $expected"
6913 }
6914 run_test 56r "check lfs find -size works"
6915
6916 test_56ra_sub() {
6917         local expected=$1
6918         local glimpses=$2
6919         local cmd="$3"
6920
6921         cancel_lru_locks $OSC
6922
6923         local rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6924         local nums=$($cmd | wc -l)
6925
6926         [ $nums -eq $expected ] ||
6927                 error "'$cmd' wrong: found $nums, expected $expected"
6928
6929         local rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6930
6931         if (( rpcs_before + glimpses != rpcs_after )); then
6932                 echo "Before: $rpcs_before After: $rpcs_after $NUMFILES"
6933                 $LCTL get_param osc.*.stats | grep ldlm_glimpse_enqueue
6934
6935                 if [[ $glimpses == 0 ]]; then
6936                         error "'$cmd' should not send glimpse RPCs to OST"
6937                 else
6938                         error "'$cmd' should send $glimpses glimpse RPCs to OST"
6939                 fi
6940         fi
6941 }
6942
6943 test_56ra() {
6944         [[ $MDS1_VERSION -gt $(version_code 2.12.58) ]] ||
6945                 skip "MDS < 2.12.58 doesn't return LSOM data"
6946         local dir=$DIR/$tdir
6947         local old_agl=$($LCTL get_param -n llite.*.statahead_agl)
6948
6949         [[ $OSC == "mdc" ]] && skip "statahead not needed for DoM files"
6950
6951         # statahead_agl may cause extra glimpse which confuses results. LU-13017
6952         $LCTL set_param -n llite.*.statahead_agl=0
6953         stack_trap "$LCTL set_param -n llite.*.statahead_agl=$old_agl"
6954
6955         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
6956         # open and close all files to ensure LSOM is updated
6957         cancel_lru_locks $OSC
6958         find $dir -type f | xargs cat > /dev/null
6959
6960         #   expect_found  glimpse_rpcs  command_to_run
6961         test_56ra_sub 12  0 "$LFS find -size 0 -type f -lazy $dir"
6962         test_56ra_sub 12 12 "$LFS find -size 0 -type f $dir"
6963         test_56ra_sub  0  0 "$LFS find ! -size 0 -type f -lazy $dir"
6964         test_56ra_sub  0 12 "$LFS find ! -size 0 -type f $dir"
6965
6966         echo "test" > $dir/$tfile
6967         echo "test2" > $dir/$tfile.2 && sync
6968         cancel_lru_locks $OSC
6969         cat $dir/$tfile $dir/$tfile.2 > /dev/null
6970
6971         test_56ra_sub  1  0 "$LFS find -size 5 -type f -lazy $dir"
6972         test_56ra_sub  1 14 "$LFS find -size 5 -type f $dir"
6973         test_56ra_sub  1  0 "$LFS find -size +5 -type f -lazy $dir"
6974         test_56ra_sub  1 14 "$LFS find -size +5 -type f $dir"
6975
6976         test_56ra_sub  2  0 "$LFS find -size +0 -type f -lazy $dir"
6977         test_56ra_sub  2 14 "$LFS find -size +0 -type f $dir"
6978         test_56ra_sub  2  0 "$LFS find ! -size -5 -type f -lazy $dir"
6979         test_56ra_sub  2 14 "$LFS find ! -size -5 -type f $dir"
6980         test_56ra_sub 12  0 "$LFS find -size -5 -type f -lazy $dir"
6981         test_56ra_sub 12 14 "$LFS find -size -5 -type f $dir"
6982 }
6983 run_test 56ra "check lfs find -size -lazy works for data on OSTs"
6984
6985 test_56rb() {
6986         local dir=$DIR/$tdir
6987         local tmp=$TMP/$tfile.log
6988         local mdt_idx;
6989
6990         test_mkdir -p $dir || error "failed to mkdir $dir"
6991         $LFS setstripe -c 1 -i 0 $dir/$tfile ||
6992                 error "failed to setstripe $dir/$tfile"
6993         mdt_idx=$($LFS getdirstripe -i $dir)
6994         dd if=/dev/zero of=$dir/$tfile bs=1M count=1
6995
6996         stack_trap "rm -f $tmp" EXIT
6997         $LFS find --size +100K --ost 0 $dir |& tee $tmp
6998         ! grep -q obd_uuid $tmp ||
6999                 error "failed to find --size +100K --ost 0 $dir"
7000         $LFS find --size +100K --mdt $mdt_idx $dir |& tee $tmp
7001         ! grep -q obd_uuid $tmp ||
7002                 error "failed to find --size +100K --mdt $mdt_idx $dir"
7003 }
7004 run_test 56rb "check lfs find --size --ost/--mdt works"
7005
7006 test_56rc() {
7007         (( MDSCOUNT >= 2 )) || skip "needs at least 2 MDTs"
7008         local dir=$DIR/$tdir
7009         local found
7010
7011         test_mkdir -c 2 -H all_char $dir || error "failed to mkdir $dir"
7012         $LFS mkdir -c 2 --mdt-hash all_char $dir/$tdir-all{1..10}
7013         (( $MDSCOUNT > 2 )) &&
7014                 $LFS mkdir -c 3 --mdt-hash fnv_1a_64 $dir/$tdir-fnv{1..10}
7015         mkdir $dir/$tdir-{1..10}
7016         touch $dir/$tfile-{1..10}
7017
7018         found=$($LFS find $dir --mdt-count 2 | wc -l)
7019         expect=11
7020         (( $found == $expect )) || error "found $found 2-stripe, expect $expect"
7021
7022         found=$($LFS find $dir -T +1 | wc -l)
7023         (( $MDSCOUNT > 2 )) && expect=$((expect + 10))
7024         (( $found == $expect )) || error "found $found 2+stripe, expect $expect"
7025
7026         found=$($LFS find $dir --mdt-hash all_char | wc -l)
7027         expect=11
7028         (( $found == $expect )) || error "found $found all_char, expect $expect"
7029
7030         found=$($LFS find $dir --mdt-hash fnv_1a_64 | wc -l)
7031         (( $MDSCOUNT > 2 )) && expect=10 || expect=0
7032         (( $found == $expect )) || error "found $found all_char, expect $expect"
7033 }
7034 run_test 56rc "check lfs find --mdt-count/--mdt-hash works"
7035
7036 test_56s() { # LU-611 #LU-9369
7037         [[ $OSTCOUNT -lt 2 ]] && skip_env "need at least 2 OSTs"
7038
7039         local dir=$DIR/$tdir
7040         local onestripe=$(((NUMDIRS + 1) * NUMFILES))
7041
7042         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
7043         for i in $(seq $NUMDIRS); do
7044                 $LFS setstripe -c $((OSTCOUNT + 1)) $dir/dir$i/$tfile
7045         done
7046
7047         local expected=$NUMDIRS
7048         local cmd="$LFS find -c $OSTCOUNT $dir"
7049         local nums=$($cmd | wc -l)
7050
7051         [ $nums -eq $expected ] || {
7052                 $LFS getstripe -R $dir
7053                 error "'$cmd' wrong: found $nums, expected $expected"
7054         }
7055
7056         expected=$((NUMDIRS + onestripe))
7057         cmd="$LFS find -stripe-count +0 -type f $dir"
7058         nums=$($cmd | wc -l)
7059         [ $nums -eq $expected ] || {
7060                 $LFS getstripe -R $dir
7061                 error "'$cmd' wrong: found $nums, expected $expected"
7062         }
7063
7064         expected=$onestripe
7065         cmd="$LFS find -stripe-count 1 -type f $dir"
7066         nums=$($cmd | wc -l)
7067         [ $nums -eq $expected ] || {
7068                 $LFS getstripe -R $dir
7069                 error "'$cmd' wrong: found $nums, expected $expected"
7070         }
7071
7072         cmd="$LFS find -stripe-count -2 -type f $dir"
7073         nums=$($cmd | wc -l)
7074         [ $nums -eq $expected ] || {
7075                 $LFS getstripe -R $dir
7076                 error "'$cmd' wrong: found $nums, expected $expected"
7077         }
7078
7079         expected=0
7080         cmd="$LFS find -stripe-count $((OSTCOUNT + 1)) -type f $dir"
7081         nums=$($cmd | wc -l)
7082         [ $nums -eq $expected ] || {
7083                 $LFS getstripe -R $dir
7084                 error "'$cmd' wrong: found $nums, expected $expected"
7085         }
7086 }
7087 run_test 56s "check lfs find -stripe-count works"
7088
7089 test_56t() { # LU-611 #LU-9369
7090         local dir=$DIR/$tdir
7091
7092         setup_56 $dir 0 $NUMDIRS
7093         for i in $(seq $NUMDIRS); do
7094                 $LFS setstripe -S 8M $dir/dir$i/$tfile
7095         done
7096
7097         local expected=$NUMDIRS
7098         local cmd="$LFS find -S 8M $dir"
7099         local nums=$($cmd | wc -l)
7100
7101         [ $nums -eq $expected ] || {
7102                 $LFS getstripe -R $dir
7103                 error "'$cmd' wrong: found $nums, expected $expected"
7104         }
7105         rm -rf $dir
7106
7107         setup_56 $dir $NUMFILES $NUMDIRS "--stripe-size 512k"
7108
7109         $LFS setstripe -S 256k $dir/$tfile.{0,1,2,3}
7110
7111         expected=$(((NUMDIRS + 1) * NUMFILES))
7112         cmd="$LFS find -stripe-size 512k -type f $dir"
7113         nums=$($cmd | wc -l)
7114         [ $nums -eq $expected ] ||
7115                 error "'$cmd' wrong: found $nums, expected $expected"
7116
7117         cmd="$LFS find -stripe-size +320k -type f $dir"
7118         nums=$($cmd | wc -l)
7119         [ $nums -eq $expected ] ||
7120                 error "'$cmd' wrong: found $nums, expected $expected"
7121
7122         expected=$(((NUMDIRS + 1) * NUMFILES + 4))
7123         cmd="$LFS find -stripe-size +200k -type f $dir"
7124         nums=$($cmd | wc -l)
7125         [ $nums -eq $expected ] ||
7126                 error "'$cmd' wrong: found $nums, expected $expected"
7127
7128         cmd="$LFS find -stripe-size -640k -type f $dir"
7129         nums=$($cmd | wc -l)
7130         [ $nums -eq $expected ] ||
7131                 error "'$cmd' wrong: found $nums, expected $expected"
7132
7133         expected=4
7134         cmd="$LFS find -stripe-size 256k -type f $dir"
7135         nums=$($cmd | wc -l)
7136         [ $nums -eq $expected ] ||
7137                 error "'$cmd' wrong: found $nums, expected $expected"
7138
7139         cmd="$LFS find -stripe-size -320k -type f $dir"
7140         nums=$($cmd | wc -l)
7141         [ $nums -eq $expected ] ||
7142                 error "'$cmd' wrong: found $nums, expected $expected"
7143
7144         expected=0
7145         cmd="$LFS find -stripe-size 1024k -type f $dir"
7146         nums=$($cmd | wc -l)
7147         [ $nums -eq $expected ] ||
7148                 error "'$cmd' wrong: found $nums, expected $expected"
7149 }
7150 run_test 56t "check lfs find -stripe-size works"
7151
7152 test_56u() { # LU-611
7153         local dir=$DIR/$tdir
7154
7155         setup_56 $dir $NUMFILES $NUMDIRS "-i 0 -c 1"
7156
7157         if [[ $OSTCOUNT -gt 1 ]]; then
7158                 $LFS setstripe -i 1 -c 1 $dir/$tfile.{0,1,2,3}
7159                 onestripe=4
7160         else
7161                 onestripe=0
7162         fi
7163
7164         local expected=$(((NUMDIRS + 1) * NUMFILES))
7165         local cmd="$LFS find -stripe-index 0 -type f $dir"
7166         local nums=$($cmd | wc -l)
7167
7168         [ $nums -eq $expected ] ||
7169                 error "'$cmd' wrong: found $nums, expected $expected"
7170
7171         expected=$onestripe
7172         cmd="$LFS find -stripe-index 1 -type f $dir"
7173         nums=$($cmd | wc -l)
7174         [ $nums -eq $expected ] ||
7175                 error "'$cmd' wrong: found $nums, expected $expected"
7176
7177         cmd="$LFS find ! -stripe-index 0 -type f $dir"
7178         nums=$($cmd | wc -l)
7179         [ $nums -eq $expected ] ||
7180                 error "'$cmd' wrong: found $nums, expected $expected"
7181
7182         expected=0
7183         # This should produce an error and not return any files
7184         cmd="$LFS find -stripe-index $OSTCOUNT -type f $dir"
7185         nums=$($cmd 2>/dev/null | wc -l)
7186         [ $nums -eq $expected ] ||
7187                 error "'$cmd' wrong: found $nums, expected $expected"
7188
7189         if [[ $OSTCOUNT -gt 1 ]]; then
7190                 expected=$(((NUMDIRS + 1) * NUMFILES + onestripe))
7191                 cmd="$LFS find -stripe-index 0,1 -type f $dir"
7192                 nums=$($cmd | wc -l)
7193                 [ $nums -eq $expected ] ||
7194                         error "'$cmd' wrong: found $nums, expected $expected"
7195         fi
7196 }
7197 run_test 56u "check lfs find -stripe-index works"
7198
7199 test_56v() {
7200         local mdt_idx=0
7201         local dir=$DIR/$tdir
7202
7203         setup_56 $dir $NUMFILES $NUMDIRS
7204
7205         UUID=$(mdtuuid_from_index $mdt_idx $dir)
7206         [ -z "$UUID" ] && error "mdtuuid_from_index cannot find MDT $mdt_idx"
7207
7208         for file in $($LFS find -m $UUID $dir); do
7209                 file_midx=$($LFS getstripe -m $file)
7210                 [ $file_midx -eq $mdt_idx ] ||
7211                         error "lfs find -m $UUID != getstripe -m $file_midx"
7212         done
7213 }
7214 run_test 56v "check 'lfs find -m match with lfs getstripe -m'"
7215
7216 test_56w() {
7217         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7218         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7219
7220         local dir=$DIR/$tdir
7221
7222         setup_56 $dir $NUMFILES $NUMDIRS "-c $OSTCOUNT" "-c1"
7223
7224         local stripe_size=$($LFS getstripe -S -d $dir) ||
7225                 error "$LFS getstripe -S -d $dir failed"
7226         stripe_size=${stripe_size%% *}
7227
7228         local file_size=$((stripe_size * OSTCOUNT))
7229         local file_num=$((NUMDIRS * NUMFILES + NUMFILES))
7230         local required_space=$((file_num * file_size))
7231         local free_space=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
7232                            head -n1)
7233         [[ $free_space -le $((required_space / 1024)) ]] &&
7234                 skip_env "need $required_space, have $free_space kbytes"
7235
7236         local dd_bs=65536
7237         local dd_count=$((file_size / dd_bs))
7238
7239         # write data into the files
7240         local i
7241         local j
7242         local file
7243
7244         for i in $(seq $NUMFILES); do
7245                 file=$dir/file$i
7246                 yes | dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
7247                         error "write data into $file failed"
7248         done
7249         for i in $(seq $NUMDIRS); do
7250                 for j in $(seq $NUMFILES); do
7251                         file=$dir/dir$i/file$j
7252                         yes|dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
7253                                 error "write data into $file failed"
7254                 done
7255         done
7256
7257         # $LFS_MIGRATE will fail if hard link migration is unsupported
7258         if [[ $MDS1_VERSION -gt $(version_code 2.5.55) ]]; then
7259                 createmany -l$dir/dir1/file1 $dir/dir1/link 200 ||
7260                         error "creating links to $dir/dir1/file1 failed"
7261         fi
7262
7263         local expected=-1
7264
7265         [[ $OSTCOUNT -gt 1 ]] && expected=$((OSTCOUNT - 1))
7266
7267         # lfs_migrate file
7268         local cmd="$LFS_MIGRATE -y -c $expected $dir/file1"
7269
7270         echo "$cmd"
7271         eval $cmd || error "$cmd failed"
7272
7273         check_stripe_count $dir/file1 $expected
7274
7275         if [ $MDS1_VERSION -ge $(version_code 2.6.90) ];
7276         then
7277                 # lfs_migrate file onto OST 0 if it is on OST 1, or onto
7278                 # OST 1 if it is on OST 0. This file is small enough to
7279                 # be on only one stripe.
7280                 file=$dir/migr_1_ost
7281                 dd bs=$dd_bs count=1 if=/dev/urandom of=$file >/dev/null 2>&1 ||
7282                         error "write data into $file failed"
7283                 local obdidx=$($LFS getstripe -i $file)
7284                 local oldmd5=$(md5sum $file)
7285                 local newobdidx=0
7286
7287                 [[ $obdidx -eq 0 ]] && newobdidx=1
7288                 cmd="$LFS migrate -i $newobdidx $file"
7289                 echo $cmd
7290                 eval $cmd || error "$cmd failed"
7291
7292                 local realobdix=$($LFS getstripe -i $file)
7293                 local newmd5=$(md5sum $file)
7294
7295                 [[ $newobdidx -ne $realobdix ]] &&
7296                         error "new OST is different (was=$obdidx, "\
7297                               "wanted=$newobdidx, got=$realobdix)"
7298                 [[ "$oldmd5" != "$newmd5" ]] &&
7299                         error "md5sum differ: $oldmd5, $newmd5"
7300         fi
7301
7302         # lfs_migrate dir
7303         cmd="$LFS_MIGRATE -y -c $expected $dir/dir1"
7304         echo "$cmd"
7305         eval $cmd || error "$cmd failed"
7306
7307         for j in $(seq $NUMFILES); do
7308                 check_stripe_count $dir/dir1/file$j $expected
7309         done
7310
7311         # lfs_migrate works with lfs find
7312         cmd="$LFS find -stripe_count $OSTCOUNT -type f $dir |
7313              $LFS_MIGRATE -y -c $expected"
7314         echo "$cmd"
7315         eval $cmd || error "$cmd failed"
7316
7317         for i in $(seq 2 $NUMFILES); do
7318                 check_stripe_count $dir/file$i $expected
7319         done
7320         for i in $(seq 2 $NUMDIRS); do
7321                 for j in $(seq $NUMFILES); do
7322                 check_stripe_count $dir/dir$i/file$j $expected
7323                 done
7324         done
7325 }
7326 run_test 56w "check lfs_migrate -c stripe_count works"
7327
7328 test_56wb() {
7329         local file1=$DIR/$tdir/file1
7330         local create_pool=false
7331         local initial_pool=$($LFS getstripe -p $DIR)
7332         local pool_list=()
7333         local pool=""
7334
7335         echo -n "Creating test dir..."
7336         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
7337         echo "done."
7338
7339         echo -n "Creating test file..."
7340         touch $file1 || error "cannot create file"
7341         echo "done."
7342
7343         echo -n "Detecting existing pools..."
7344         pool_list=($($LFS pool_list $FSNAME | grep "$FSNAME\." | cut -d. -f2))
7345
7346         if [ ${#pool_list[@]} -gt 0 ]; then
7347                 echo "${pool_list[@]}"
7348                 for thispool in "${pool_list[@]}"; do
7349                         if [[ -z "$initial_pool" ||
7350                               "$initial_pool" != "$thispool" ]]; then
7351                                 pool="$thispool"
7352                                 echo "Using existing pool '$pool'"
7353                                 break
7354                         fi
7355                 done
7356         else
7357                 echo "none detected."
7358         fi
7359         if [ -z "$pool" ]; then
7360                 pool=${POOL:-testpool}
7361                 [ "$initial_pool" = "$pool" ] && pool="testpool2"
7362                 echo -n "Creating pool '$pool'..."
7363                 create_pool=true
7364                 pool_add $pool &> /dev/null ||
7365                         error "pool_add failed"
7366                 echo "done."
7367
7368                 echo -n "Adding target to pool..."
7369                 pool_add_targets $pool 0 0 1 &> /dev/null ||
7370                         error "pool_add_targets failed"
7371                 echo "done."
7372         fi
7373
7374         echo -n "Setting pool using -p option..."
7375         $LFS_MIGRATE -y -q --no-rsync -p $pool $file1 &> /dev/null ||
7376                 error "migrate failed rc = $?"
7377         echo "done."
7378
7379         echo -n "Verifying test file is in pool after migrating..."
7380         [ "$($LFS getstripe -p $file1)" = $pool ] ||
7381                 error "file was not migrated to pool $pool"
7382         echo "done."
7383
7384         echo -n "Removing test file from pool '$pool'..."
7385         # "lfs migrate $file" won't remove the file from the pool
7386         # until some striping information is changed.
7387         $LFS migrate -c 1 $file1 &> /dev/null ||
7388                 error "cannot remove from pool"
7389         [ "$($LFS getstripe -p $file1)" ] &&
7390                 error "pool still set"
7391         echo "done."
7392
7393         echo -n "Setting pool using --pool option..."
7394         $LFS_MIGRATE -y -q --no-rsync --pool $pool $file1 &> /dev/null ||
7395                 error "migrate failed rc = $?"
7396         echo "done."
7397
7398         # Clean up
7399         rm -f $file1
7400         if $create_pool; then
7401                 destroy_test_pools 2> /dev/null ||
7402                         error "destroy test pools failed"
7403         fi
7404 }
7405 run_test 56wb "check lfs_migrate pool support"
7406
7407 test_56wc() {
7408         local file1="$DIR/$tdir/file1"
7409         local parent_ssize
7410         local parent_scount
7411         local cur_ssize
7412         local cur_scount
7413         local orig_ssize
7414
7415         echo -n "Creating test dir..."
7416         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
7417         $LFS setstripe -S 1M -c 1 "$DIR/$tdir" &> /dev/null ||
7418                 error "cannot set stripe by '-S 1M -c 1'"
7419         echo "done"
7420
7421         echo -n "Setting initial stripe for test file..."
7422         $LFS setstripe -S 512K -c 1 "$file1" &> /dev/null ||
7423                 error "cannot set stripe"
7424         cur_ssize=$($LFS getstripe -S "$file1")
7425         [ $cur_ssize -eq 524288 ] || error "setstripe -S $cur_ssize != 524288"
7426         echo "done."
7427
7428         # File currently set to -S 512K -c 1
7429
7430         # Ensure -c and -S options are rejected when -R is set
7431         echo -n "Verifying incompatible options are detected..."
7432         $LFS_MIGRATE -y -R -c 1 "$file1" &> /dev/null &&
7433                 error "incompatible -c and -R options not detected"
7434         $LFS_MIGRATE -y -R -S 1M "$file1" &> /dev/null &&
7435                 error "incompatible -S and -R options not detected"
7436         echo "done."
7437
7438         # Ensure unrecognized options are passed through to 'lfs migrate'
7439         echo -n "Verifying -S option is passed through to lfs migrate..."
7440         $LFS_MIGRATE -y -S 1M "$file1" &> /dev/null ||
7441                 error "migration failed"
7442         cur_ssize=$($LFS getstripe -S "$file1")
7443         [ $cur_ssize -eq 1048576 ] || error "migrate -S $cur_ssize != 1048576"
7444         echo "done."
7445
7446         # File currently set to -S 1M -c 1
7447
7448         # Ensure long options are supported
7449         echo -n "Verifying long options supported..."
7450         $LFS_MIGRATE -y --non-block "$file1" &> /dev/null ||
7451                 error "long option without argument not supported"
7452         $LFS_MIGRATE -y --stripe-size 512K "$file1" &> /dev/null ||
7453                 error "long option with argument not supported"
7454         cur_ssize=$($LFS getstripe -S "$file1")
7455         [ $cur_ssize -eq 524288 ] ||
7456                 error "migrate --stripe-size $cur_ssize != 524288"
7457         echo "done."
7458
7459         # File currently set to -S 512K -c 1
7460
7461         if [ "$OSTCOUNT" -gt 1 ]; then
7462                 echo -n "Verifying explicit stripe count can be set..."
7463                 $LFS_MIGRATE -y -c 2 "$file1" &> /dev/null ||
7464                         error "migrate failed"
7465                 cur_scount=$($LFS getstripe -c "$file1")
7466                 [ $cur_scount -eq 2 ] || error "migrate -c $cur_scount != 2"
7467                 echo "done."
7468         fi
7469
7470         # File currently set to -S 512K -c 1 or -S 512K -c 2
7471
7472         # Ensure parent striping is used if -R is set, and no stripe
7473         # count or size is specified
7474         echo -n "Setting stripe for parent directory..."
7475         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
7476                 error "cannot set stripe '-S 2M -c 1'"
7477         echo "done."
7478
7479         echo -n "Verifying restripe option uses parent stripe settings..."
7480         parent_ssize=$($LFS getstripe -S $DIR/$tdir 2>/dev/null)
7481         parent_scount=$($LFS getstripe -c $DIR/$tdir 2>/dev/null)
7482         $LFS_MIGRATE -y -R "$file1" &> /dev/null ||
7483                 error "migrate failed"
7484         cur_ssize=$($LFS getstripe -S "$file1")
7485         [ $cur_ssize -eq $parent_ssize ] ||
7486                 error "migrate -R stripe_size $cur_ssize != $parent_ssize"
7487         cur_scount=$($LFS getstripe -c "$file1")
7488         [ $cur_scount -eq $parent_scount ] ||
7489                 error "migrate -R stripe_count $cur_scount != $parent_scount"
7490         echo "done."
7491
7492         # File currently set to -S 1M -c 1
7493
7494         # Ensure striping is preserved if -R is not set, and no stripe
7495         # count or size is specified
7496         echo -n "Verifying striping size preserved when not specified..."
7497         orig_ssize=$($LFS getstripe -S "$file1" 2>/dev/null)
7498         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
7499                 error "cannot set stripe on parent directory"
7500         $LFS_MIGRATE -y "$file1" &> /dev/null ||
7501                 error "migrate failed"
7502         cur_ssize=$($LFS getstripe -S "$file1")
7503         [ $cur_ssize -eq $orig_ssize ] ||
7504                 error "migrate by default $cur_ssize != $orig_ssize"
7505         echo "done."
7506
7507         # Ensure file name properly detected when final option has no argument
7508         echo -n "Verifying file name properly detected..."
7509         $LFS_MIGRATE -y "$file1" &> /dev/null ||
7510                 error "file name interpreted as option argument"
7511         echo "done."
7512
7513         # Clean up
7514         rm -f "$file1"
7515 }
7516 run_test 56wc "check unrecognized options for lfs_migrate are passed through"
7517
7518 test_56wd() {
7519         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7520
7521         local file1=$DIR/$tdir/file1
7522
7523         echo -n "Creating test dir..."
7524         test_mkdir $DIR/$tdir || error "cannot create dir"
7525         echo "done."
7526
7527         echo -n "Creating test file..."
7528         touch $file1
7529         echo "done."
7530
7531         # Ensure 'lfs migrate' will fail by using a non-existent option,
7532         # and make sure rsync is not called to recover
7533         echo -n "Make sure --no-rsync option works..."
7534         $LFS_MIGRATE -y --no-rsync --invalid-opt $file1 2>&1 |
7535                 grep -q 'refusing to fall back to rsync' ||
7536                 error "rsync was called with --no-rsync set"
7537         echo "done."
7538
7539         # Ensure rsync is called without trying 'lfs migrate' first
7540         echo -n "Make sure --rsync option works..."
7541         $LFS_MIGRATE -y --rsync --invalid-opt $file1 2>&1 |
7542                 grep -q 'falling back to rsync' &&
7543                 error "lfs migrate was called with --rsync set"
7544         echo "done."
7545
7546         echo -n "Make sure --rsync and --no-rsync options are exclusive..."
7547         $LFS_MIGRATE -y --rsync --no-rsync $file1 2>&1 |
7548                 grep -q 'at the same time' ||
7549                 error "--rsync and --no-rsync accepted concurrently"
7550         echo "done."
7551
7552         # Clean up
7553         rm -f $file1
7554 }
7555 run_test 56wd "check lfs_migrate --rsync and --no-rsync work"
7556
7557 test_56we() {
7558         local td=$DIR/$tdir
7559         local tf=$td/$tfile
7560
7561         test_mkdir $td || error "cannot create $td"
7562         touch $tf || error "cannot touch $tf"
7563
7564         echo -n "Make sure --non-direct|-D works..."
7565         $LFS_MIGRATE -y --non-direct -v $tf 2>&1 |
7566                 grep -q "lfs migrate --non-direct" ||
7567                 error "--non-direct option cannot work correctly"
7568         $LFS_MIGRATE -y -D -v $tf 2>&1 |
7569                 grep -q "lfs migrate -D" ||
7570                 error "-D option cannot work correctly"
7571         echo "done."
7572 }
7573 run_test 56we "check lfs_migrate --non-direct|-D support"
7574
7575 test_56x() {
7576         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7577         check_swap_layouts_support
7578
7579         local dir=$DIR/$tdir
7580         local ref1=/etc/passwd
7581         local file1=$dir/file1
7582
7583         test_mkdir $dir || error "creating dir $dir"
7584         $LFS setstripe -c 2 $file1
7585         cp $ref1 $file1
7586         $LFS migrate -c 1 $file1 || error "migrate failed rc = $?"
7587         stripe=$($LFS getstripe -c $file1)
7588         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
7589         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
7590
7591         # clean up
7592         rm -f $file1
7593 }
7594 run_test 56x "lfs migration support"
7595
7596 test_56xa() {
7597         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7598         check_swap_layouts_support
7599
7600         local dir=$DIR/$tdir/$testnum
7601
7602         test_mkdir -p $dir
7603
7604         local ref1=/etc/passwd
7605         local file1=$dir/file1
7606
7607         $LFS setstripe -c 2 $file1
7608         cp $ref1 $file1
7609         $LFS migrate --block -c 1 $file1 || error "migrate failed rc = $?"
7610
7611         local stripe=$($LFS getstripe -c $file1)
7612
7613         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
7614         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
7615
7616         # clean up
7617         rm -f $file1
7618 }
7619 run_test 56xa "lfs migration --block support"
7620
7621 check_migrate_links() {
7622         local dir="$1"
7623         local file1="$dir/file1"
7624         local begin="$2"
7625         local count="$3"
7626         local runas="$4"
7627         local total_count=$(($begin + $count - 1))
7628         local symlink_count=10
7629         local uniq_count=10
7630
7631         if [ ! -f "$file1" ]; then
7632                 echo -n "creating initial file..."
7633                 $LFS setstripe -c 1 -S "512k" "$file1" ||
7634                         error "cannot setstripe initial file"
7635                 echo "done"
7636
7637                 echo -n "creating symlinks..."
7638                 for s in $(seq 1 $symlink_count); do
7639                         ln -s "$file1" "$dir/slink$s" ||
7640                                 error "cannot create symlinks"
7641                 done
7642                 echo "done"
7643
7644                 echo -n "creating nonlinked files..."
7645                 createmany -o "$dir/uniq" 1 10 &> /dev/null ||
7646                         error "cannot create nonlinked files"
7647                 echo "done"
7648         fi
7649
7650         # create hard links
7651         if [ ! -f "$dir/file$total_count" ]; then
7652                 echo -n "creating hard links $begin:$total_count..."
7653                 createmany -l"$file1" "$dir/file" "$begin" "$count" &>  \
7654                         /dev/null || error "cannot create hard links"
7655                 echo "done"
7656         fi
7657
7658         echo -n "checking number of hard links listed in xattrs..."
7659         local fid=$($LFS getstripe -F "$file1")
7660         local paths=($($LFS fid2path "$MOUNT" "$fid" 2> /dev/null))
7661
7662         echo "${#paths[*]}"
7663         if [ ${#paths[*]} -lt $total_count -a "$begin" -eq 2  ]; then
7664                         skip "hard link list has unexpected size, skipping test"
7665         fi
7666         if [ ${#paths[*]} -ge $total_count -a "$begin" -ne 2  ]; then
7667                         error "link names should exceed xattrs size"
7668         fi
7669
7670         echo -n "migrating files..."
7671         local migrate_out=$($runas $LFS_MIGRATE -y -S '1m' $dir)
7672         local rc=$?
7673         [ $rc -eq 0 ] || error "migrate failed rc = $rc"
7674         echo "done"
7675
7676         # make sure all links have been properly migrated
7677         echo -n "verifying files..."
7678         fid=$($LFS getstripe -F "$file1") ||
7679                 error "cannot get fid for file $file1"
7680         for i in $(seq 2 $total_count); do
7681                 local fid2=$($LFS getstripe -F $dir/file$i)
7682
7683                 [ "$fid2" == "$fid" ] ||
7684                         error "migrated hard link has mismatched FID"
7685         done
7686
7687         # make sure hard links were properly detected, and migration was
7688         # performed only once for the entire link set; nonlinked files should
7689         # also be migrated
7690         local actual=$(grep -c 'done' <<< "$migrate_out")
7691         local expected=$(($uniq_count + 1))
7692
7693         [ "$actual" -eq  "$expected" ] ||
7694                 error "hard links individually migrated ($actual != $expected)"
7695
7696         # make sure the correct number of hard links are present
7697         local hardlinks=$(stat -c '%h' "$file1")
7698
7699         [ $hardlinks -eq $total_count ] ||
7700                 error "num hard links $hardlinks != $total_count"
7701         echo "done"
7702
7703         return 0
7704 }
7705
7706 test_56xb() {
7707         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
7708                 skip "Need MDS version at least 2.10.55"
7709
7710         local dir="$DIR/$tdir"
7711
7712         test_mkdir "$dir" || error "cannot create dir $dir"
7713
7714         echo "testing lfs migrate mode when all links fit within xattrs"
7715         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 2 99
7716
7717         echo "testing rsync mode when all links fit within xattrs"
7718         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 2 99
7719
7720         echo "testing lfs migrate mode when all links do not fit within xattrs"
7721         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100
7722
7723         echo "testing rsync mode when all links do not fit within xattrs"
7724         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 101 100
7725
7726         chown -R $RUNAS_ID $dir
7727         echo "testing non-root lfs migrate mode when not all links are in xattr"
7728         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100 "$RUNAS"
7729
7730         # clean up
7731         rm -rf $dir
7732 }
7733 run_test 56xb "lfs migration hard link support"
7734
7735 test_56xc() {
7736         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7737
7738         local dir="$DIR/$tdir"
7739
7740         test_mkdir "$dir" || error "cannot create dir $dir"
7741
7742         # Test 1: ensure file < 1 GB is always migrated with 1 stripe
7743         echo -n "Setting initial stripe for 20MB test file..."
7744         $LFS setstripe -c 2 -i 0 "$dir/20mb" ||
7745                 error "cannot setstripe 20MB file"
7746         echo "done"
7747         echo -n "Sizing 20MB test file..."
7748         $TRUNCATE "$dir/20mb" 20971520 || error "cannot create 20MB test file"
7749         echo "done"
7750         echo -n "Verifying small file autostripe count is 1..."
7751         $LFS_MIGRATE -y -A -C 1 "$dir/20mb" ||
7752                 error "cannot migrate 20MB file"
7753         local stripe_count=$($LFS getstripe -c "$dir/20mb") ||
7754                 error "cannot get stripe for $dir/20mb"
7755         [ $stripe_count -eq 1 ] ||
7756                 error "unexpected stripe count $stripe_count for 20MB file"
7757         rm -f "$dir/20mb"
7758         echo "done"
7759
7760         # Test 2: File is small enough to fit within the available space on
7761         # sqrt(size_in_gb) + 1 OSTs but is larger than 1GB.  The file must
7762         # have at least an additional 1KB for each desired stripe for test 3
7763         echo -n "Setting stripe for 1GB test file..."
7764         $LFS setstripe -c 1 -i 0 "$dir/1gb" || error "cannot setstripe 1GB file"
7765         echo "done"
7766         echo -n "Sizing 1GB test file..."
7767         # File size is 1GB + 3KB
7768         $TRUNCATE "$dir/1gb" 1073744896 || error "cannot create 1GB test file"
7769         echo "done"
7770
7771         # need at least 512MB per OST for 1GB file to fit in 2 stripes
7772         local avail=$($LCTL get_param -n llite.$FSNAME*.kbytesavail)
7773         if (( avail > 524288 * OSTCOUNT )); then
7774                 echo -n "Migrating 1GB file..."
7775                 $LFS_MIGRATE -y -A -C 1 "$dir/1gb" ||
7776                         error "cannot migrate 1GB file"
7777                 echo "done"
7778                 echo -n "Verifying autostripe count is sqrt(n) + 1..."
7779                 stripe_count=$($LFS getstripe -c "$dir/1gb") ||
7780                         error "cannot getstripe for 1GB file"
7781                 [ $stripe_count -eq 2 ] ||
7782                         error "unexpected stripe count $stripe_count != 2"
7783                 echo "done"
7784         fi
7785
7786         # Test 3: File is too large to fit within the available space on
7787         # sqrt(n) + 1 OSTs.  Simulate limited available space with -X
7788         if [ $OSTCOUNT -ge 3 ]; then
7789                 # The required available space is calculated as
7790                 # file size (1GB + 3KB) / OST count (3).
7791                 local kb_per_ost=349526
7792
7793                 echo -n "Migrating 1GB file with limit..."
7794                 $LFS_MIGRATE -y -A -C 1 -X $kb_per_ost "$dir/1gb" ||
7795                         error "cannot migrate 1GB file with limit"
7796                 echo "done"
7797
7798                 stripe_count=$($LFS getstripe -c "$dir/1gb")
7799                 echo -n "Verifying 1GB autostripe count with limited space..."
7800                 [ "$stripe_count" -a $stripe_count -ge 3 ] ||
7801                         error "unexpected stripe count $stripe_count (min 3)"
7802                 echo "done"
7803         fi
7804
7805         # clean up
7806         rm -rf $dir
7807 }
7808 run_test 56xc "lfs migration autostripe"
7809
7810 test_56xd() {
7811         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7812
7813         local dir=$DIR/$tdir
7814         local f_mgrt=$dir/$tfile.mgrt
7815         local f_yaml=$dir/$tfile.yaml
7816         local f_copy=$dir/$tfile.copy
7817         local layout_yaml="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
7818         local layout_copy="-c 2 -S 2M -i 1"
7819         local yamlfile=$dir/yamlfile
7820         local layout_before;
7821         local layout_after;
7822
7823         test_mkdir "$dir" || error "cannot create dir $dir"
7824         $LFS setstripe $layout_yaml $f_yaml ||
7825                 error "cannot setstripe $f_yaml with layout $layout_yaml"
7826         $LFS getstripe --yaml $f_yaml > $yamlfile
7827         $LFS setstripe $layout_copy $f_copy ||
7828                 error "cannot setstripe $f_copy with layout $layout_copy"
7829         touch $f_mgrt
7830         dd if=/dev/zero of=$f_mgrt bs=1M count=4
7831
7832         # 1. test option --yaml
7833         $LFS_MIGRATE -y --yaml $yamlfile $f_mgrt ||
7834                 error "cannot migrate $f_mgrt with --yaml $yamlfile"
7835         layout_before=$(get_layout_param $f_yaml)
7836         layout_after=$(get_layout_param $f_mgrt)
7837         [ "$layout_after" == "$layout_before" ] ||
7838                 error "lfs_migrate --yaml: $layout_after != $layout_before"
7839
7840         # 2. test option --copy
7841         $LFS_MIGRATE -y --copy $f_copy $f_mgrt ||
7842                 error "cannot migrate $f_mgrt with --copy $f_copy"
7843         layout_before=$(get_layout_param $f_copy)
7844         layout_after=$(get_layout_param $f_mgrt)
7845         [ "$layout_after" == "$layout_before" ] ||
7846                 error "lfs_migrate --copy: $layout_after != $layout_before"
7847 }
7848 run_test 56xd "check lfs_migrate --yaml and --copy support"
7849
7850 test_56xe() {
7851         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7852
7853         local dir=$DIR/$tdir
7854         local f_comp=$dir/$tfile
7855         local layout="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
7856         local layout_before=""
7857         local layout_after=""
7858
7859         test_mkdir "$dir" || error "cannot create dir $dir"
7860         $LFS setstripe $layout $f_comp ||
7861                 error "cannot setstripe $f_comp with layout $layout"
7862         layout_before=$(get_layout_param $f_comp)
7863         dd if=/dev/zero of=$f_comp bs=1M count=4
7864
7865         # 1. migrate a comp layout file by lfs_migrate
7866         $LFS_MIGRATE -y $f_comp || error "cannot migrate $f_comp by lfs_migrate"
7867         layout_after=$(get_layout_param $f_comp)
7868         [ "$layout_before" == "$layout_after" ] ||
7869                 error "lfs_migrate: $layout_before != $layout_after"
7870
7871         # 2. migrate a comp layout file by lfs migrate
7872         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
7873         layout_after=$(get_layout_param $f_comp)
7874         [ "$layout_before" == "$layout_after" ] ||
7875                 error "lfs migrate: $layout_before != $layout_after"
7876 }
7877 run_test 56xe "migrate a composite layout file"
7878
7879 test_56xf() {
7880         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
7881
7882         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
7883                 skip "Need server version at least 2.13.53"
7884
7885         local dir=$DIR/$tdir
7886         local f_comp=$dir/$tfile
7887         local layout="-E 1M -c1 -E -1 -c2"
7888         local fid_before=""
7889         local fid_after=""
7890
7891         test_mkdir "$dir" || error "cannot create dir $dir"
7892         $LFS setstripe $layout $f_comp ||
7893                 error "cannot setstripe $f_comp with layout $layout"
7894         fid_before=$($LFS getstripe --fid $f_comp)
7895         dd if=/dev/zero of=$f_comp bs=1M count=4
7896
7897         # 1. migrate a comp layout file to a comp layout
7898         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
7899         fid_after=$($LFS getstripe --fid $f_comp)
7900         [ "$fid_before" == "$fid_after" ] ||
7901                 error "comp-to-comp migrate: $fid_before != $fid_after"
7902
7903         # 2. migrate a comp layout file to a plain layout
7904         $LFS migrate -c2 $f_comp ||
7905                 error "cannot migrate $f_comp by lfs migrate"
7906         fid_after=$($LFS getstripe --fid $f_comp)
7907         [ "$fid_before" == "$fid_after" ] ||
7908                 error "comp-to-plain migrate: $fid_before != $fid_after"
7909
7910         # 3. migrate a plain layout file to a comp layout
7911         $LFS migrate $layout $f_comp ||
7912                 error "cannot migrate $f_comp by lfs migrate"
7913         fid_after=$($LFS getstripe --fid $f_comp)
7914         [ "$fid_before" == "$fid_after" ] ||
7915                 error "plain-to-comp migrate: $fid_before != $fid_after"
7916 }
7917 run_test 56xf "FID is not lost during migration of a composite layout file"
7918
7919 check_file_ost_range() {
7920         local file="$1"
7921         shift
7922         local range="$*"
7923         local -a file_range
7924         local idx
7925
7926         file_range=($($LFS getstripe -y "$file" |
7927                 awk '/l_ost_idx:/ { print $NF }'))
7928
7929         if [[ "${#file_range[@]}" = 0 ]]; then
7930                 echo "No osts found for $file"
7931                 return 1
7932         fi
7933
7934         for idx in "${file_range[@]}"; do
7935                 [[ " $range " =~ " $idx " ]] ||
7936                         return 1
7937         done
7938
7939         return 0
7940 }
7941
7942 sub_test_56xg() {
7943         local stripe_opt="$1"
7944         local pool="$2"
7945         shift 2
7946         local pool_ostidx="$(seq $* | tr '\n' ' ')"
7947
7948         $LFS migrate $stripe_opt -p $pool $DIR/$tfile ||
7949                 error "Fail to migrate $tfile on $pool"
7950         [[ "$($LFS getstripe -p $DIR/$tfile)" = "$pool" ]] ||
7951                 error "$tfile is not in pool $pool"
7952         check_file_ost_range "$DIR/$tfile" $pool_ostidx ||
7953                 error "$tfile osts mismatch with pool $pool (osts $pool_ostidx)"
7954 }
7955
7956 test_56xg() {
7957         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
7958         [[ $OSTCOUNT -ge 2 ]] || skip "needs >= 2 OSTs"
7959         [[ $MDS1_VERSION -gt $(version_code 2.14.52) ]] ||
7960                 skip "Need MDS version newer than 2.14.52"
7961
7962         local -a pool_names=("${TESTNAME}_0" "${TESTNAME}_1" "${TESTNAME}_2")
7963         local -a pool_ranges=("0 0" "1 1" "0 1")
7964
7965         # init pools
7966         for i in "${!pool_names[@]}"; do
7967                 pool_add ${pool_names[$i]} ||
7968                         error "pool_add failed (pool: ${pool_names[$i]})"
7969                 pool_add_targets ${pool_names[$i]} ${pool_ranges[$i]} ||
7970                         error "pool_add_targets failed (pool: ${pool_names[$i]})"
7971         done
7972
7973         # init the file to migrate
7974         $LFS setstripe -c1 -i1 $DIR/$tfile ||
7975                 error "Unable to create $tfile on OST1"
7976         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=4 status=none ||
7977                 error "Unable to write on $tfile"
7978
7979         echo "1. migrate $tfile on pool ${pool_names[0]}"
7980         sub_test_56xg "-c-1" "${pool_names[0]}" ${pool_ranges[0]}
7981
7982         echo "2. migrate $tfile on pool ${pool_names[2]}"
7983         sub_test_56xg "-c-1 -S2M" "${pool_names[2]}" ${pool_ranges[2]}
7984
7985         echo "3. migrate $tfile on pool ${pool_names[1]}"
7986         sub_test_56xg "-n -c-1" "${pool_names[1]}" ${pool_ranges[1]}
7987
7988         echo "4. migrate $tfile on pool ${pool_names[2]} with default stripe parameters"
7989         sub_test_56xg "" "${pool_names[2]}" ${pool_ranges[2]}
7990         echo
7991
7992         # Clean pools
7993         destroy_test_pools ||
7994                 error "pool_destroy failed"
7995 }
7996 run_test 56xg "lfs migrate pool support"
7997
7998 test_56y() {
7999         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
8000                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
8001
8002         local res=""
8003         local dir=$DIR/$tdir
8004         local f1=$dir/file1
8005         local f2=$dir/file2
8006
8007         test_mkdir -p $dir || error "creating dir $dir"
8008         touch $f1 || error "creating std file $f1"
8009         $MULTIOP $f2 H2c || error "creating released file $f2"
8010
8011         # a directory can be raid0, so ask only for files
8012         res=$($LFS find $dir -L raid0 -type f | wc -l)
8013         [[ $res == 2 ]] || error "search raid0: found $res files != 2"
8014
8015         res=$($LFS find $dir \! -L raid0 -type f | wc -l)
8016         [[ $res == 0 ]] || error "search !raid0: found $res files != 0"
8017
8018         # only files can be released, so no need to force file search
8019         res=$($LFS find $dir -L released)
8020         [[ $res == $f2 ]] || error "search released: found $res != $f2"
8021
8022         res=$($LFS find $dir -type f \! -L released)
8023         [[ $res == $f1 ]] || error "search !released: found $res != $f1"
8024 }
8025 run_test 56y "lfs find -L raid0|released"
8026
8027 test_56z() { # LU-4824
8028         # This checks to make sure 'lfs find' continues after errors
8029         # There are two classes of errors that should be caught:
8030         # - If multiple paths are provided, all should be searched even if one
8031         #   errors out
8032         # - If errors are encountered during the search, it should not terminate
8033         #   early
8034         local dir=$DIR/$tdir
8035         local i
8036
8037         test_mkdir $dir
8038         for i in d{0..9}; do
8039                 test_mkdir $dir/$i
8040                 touch $dir/$i/$tfile
8041         done
8042         $LFS find $DIR/non_existent_dir $dir &&
8043                 error "$LFS find did not return an error"
8044         # Make a directory unsearchable. This should NOT be the last entry in
8045         # directory order.  Arbitrarily pick the 6th entry
8046         chmod 700 $($LFS find $dir -type d | sed '6!d')
8047
8048         $RUNAS $LFS find $DIR/non_existent $dir
8049         local count=$($RUNAS $LFS find $DIR/non_existent $dir | wc -l)
8050
8051         # The user should be able to see 10 directories and 9 files
8052         (( count == 19 )) ||
8053                 error "$LFS find found $count != 19 entries after error"
8054 }
8055 run_test 56z "lfs find should continue after an error"
8056
8057 test_56aa() { # LU-5937
8058         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
8059
8060         local dir=$DIR/$tdir
8061
8062         mkdir $dir
8063         $LFS setdirstripe -c$MDSCOUNT $dir/striped_dir
8064
8065         createmany -o $dir/striped_dir/${tfile}- 1024
8066         local dirs=$($LFS find --size +8k $dir/)
8067
8068         [ -n "$dirs" ] || error "lfs find --size wrong under striped dir"
8069 }
8070 run_test 56aa "lfs find --size under striped dir"
8071
8072 test_56ab() { # LU-10705
8073         test_mkdir $DIR/$tdir
8074         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=8k count=1 seek=2k
8075         dd if=/dev/zero of=$DIR/$tdir/$tfile.2 bs=4k count=1 seek=4k
8076         dd if=/dev/zero of=$DIR/$tdir/$tfile.3 bs=1M count=2 seek=16
8077         # Flush writes to ensure valid blocks.  Need to be more thorough for
8078         # ZFS, since blocks are not allocated/returned to client immediately.
8079         sync_all_data
8080         wait_zfs_commit ost1 2
8081         cancel_lru_locks osc
8082         ls -ls $DIR/$tdir
8083
8084         local files=$($LFS find --size +16M $DIR/$tdir | wc -l)
8085
8086         [[ $files == 3 ]] || error ">16M size files $files isn't 3 as expected"
8087
8088         files=$($LFS find --blocks +1M $DIR/$tdir | wc -l)
8089         [[ $files == 1 ]] || error ">1M blocks files $files isn't 1 as expected"
8090
8091         rm -f $DIR/$tdir/$tfile.[123]
8092 }
8093 run_test 56ab "lfs find --blocks"
8094
8095 # LU-11188
8096 test_56aca() {
8097         local dir="$DIR/$tdir"
8098         local perms=(001 002 003 004 005 006 007
8099                      010 020 030 040 050 060 070
8100                      100 200 300 400 500 600 700
8101                      111 222 333 444 555 666 777)
8102         local perm_minus=(8 8 4 8 4 4 2
8103                           8 8 4 8 4 4 2
8104                           8 8 4 8 4 4 2
8105                           4 4 2 4 2 2 1)
8106         local perm_slash=(8  8 12  8 12 12 14
8107                           8  8 12  8 12 12 14
8108                           8  8 12  8 12 12 14
8109                          16 16 24 16 24 24 28)
8110
8111         test_mkdir "$dir"
8112         for perm in ${perms[*]}; do
8113                 touch "$dir/$tfile.$perm"
8114                 chmod $perm "$dir/$tfile.$perm"
8115         done
8116
8117         for ((i = 0; i < ${#perms[*]}; i++)); do
8118                 local num=$($LFS find $dir -perm ${perms[i]} | wc -l)
8119                 (( $num == 1 )) ||
8120                         error "lfs find -perm ${perms[i]}:"\
8121                               "$num != 1"
8122
8123                 num=$($LFS find $dir -perm -${perms[i]} -type f| wc -l)
8124                 (( $num == ${perm_minus[i]} )) ||
8125                         error "lfs find -perm -${perms[i]}:"\
8126                               "$num != ${perm_minus[i]}"
8127
8128                 num=$($LFS find $dir -perm /${perms[i]} -type f| wc -l)
8129                 (( $num == ${perm_slash[i]} )) ||
8130                         error "lfs find -perm /${perms[i]}:"\
8131                               "$num != ${perm_slash[i]}"
8132         done
8133 }
8134 run_test 56aca "check lfs find -perm with octal representation"
8135
8136 test_56acb() {
8137         local dir=$DIR/$tdir
8138         # p is the permission of write and execute for user, group and other
8139         # without the umask. It is used to test +wx.
8140         local p=$(printf "%o" "$((0333 & ~$(umask)))")
8141         local perms=(1000 000 2000 4000 $p 644 111 110 100 004)
8142         local symbolic=(+t  a+t u+t g+t o+t
8143                         g+s u+s o+s +s o+sr
8144                         o=r,ug+o,u+w
8145                         u+ g+ o+ a+ ugo+
8146                         u- g- o- a- ugo-
8147                         u= g= o= a= ugo=
8148                         o=r,ug+o,u+w u=r,a+u,u+w
8149                         g=r,ugo=g,u+w u+x,+X +X
8150                         u+x,u+X u+X u+x,g+X o+r,+X
8151                         u+x,go+X +wx +rwx)
8152
8153         test_mkdir $dir
8154         for perm in ${perms[*]}; do
8155                 touch "$dir/$tfile.$perm"
8156                 chmod $perm "$dir/$tfile.$perm"
8157         done
8158
8159         for (( i = 0; i < ${#symbolic[*]}; i++ )); do
8160                 local num=$($LFS find $dir -perm ${symbolic[i]} | wc -l)
8161
8162                 (( $num == 1 )) ||
8163                         error "lfs find $dir -perm ${symbolic[i]}: $num != 1"
8164         done
8165 }
8166 run_test 56acb "check lfs find -perm with symbolic representation"
8167
8168 test_56acc() {
8169         local dir=$DIR/$tdir
8170         local tests="17777 787 789 abcd
8171                 ug=uu ug=a ug=gu uo=ou urw
8172                 u+xg+x a=r,u+x,"
8173
8174         test_mkdir $dir
8175         for err in $tests; do
8176                 if $LFS find $dir -perm $err 2>/dev/null; then
8177                         error "lfs find -perm $err: parsing should have failed"
8178                 fi
8179         done
8180 }
8181 run_test 56acc "check parsing error for lfs find -perm"
8182
8183 test_56ba() {
8184         [ $MDS1_VERSION -lt $(version_code 2.10.50) ] &&
8185                 skip "Need MDS version at least 2.10.50"
8186
8187         # Create composite files with one component
8188         local dir=$DIR/$tdir
8189
8190         setup_56 $dir/1Mfiles 5 1 "-S 1M --component-end 1M"
8191         # Create composite files with three components
8192         setup_56 $dir/2Mfiles 5 2 "-E 2M -S 1M -E 4M -E 6M"
8193         # Create non-composite files
8194         createmany -o $dir/${tfile}- 10
8195
8196         local nfiles=$($LFS find --component-end 1M --type f $dir | wc -l)
8197
8198         [[ $nfiles == 10 ]] ||
8199                 error "lfs find -E 1M found $nfiles != 10 files"
8200
8201         nfiles=$($LFS find ! -E 1M --type f $dir | wc -l)
8202         [[ $nfiles == 25 ]] ||
8203                 error "lfs find ! -E 1M found $nfiles != 25 files"
8204
8205         # All files have a component that starts at 0
8206         nfiles=$($LFS find --component-start 0 --type f $dir | wc -l)
8207         [[ $nfiles == 35 ]] ||
8208                 error "lfs find --component-start 0 - $nfiles != 35 files"
8209
8210         nfiles=$($LFS find --component-start 2M --type f $dir | wc -l)
8211         [[ $nfiles == 15 ]] ||
8212                 error "lfs find --component-start 2M - $nfiles != 15 files"
8213
8214         # All files created here have a componenet that does not starts at 2M
8215         nfiles=$($LFS find ! --component-start 2M --type f $dir | wc -l)
8216         [[ $nfiles == 35 ]] ||
8217                 error "lfs find ! --component-start 2M - $nfiles != 35 files"
8218
8219         # Find files with a specified number of components
8220         local nfiles=$($LFS find --component-count 3 --type f $dir | wc -l)
8221         [[ $nfiles == 15 ]] ||
8222                 error "lfs find --component-count 3 - $nfiles != 15 files"
8223
8224         # Remember non-composite files have a component count of zero
8225         local nfiles=$($LFS find --component-count 0 --type f $dir | wc -l)
8226         [[ $nfiles == 10 ]] ||
8227                 error "lfs find --component-count 0 - $nfiles != 10 files"
8228
8229         nfiles=$($LFS find ! --component-count 3 --type f $dir | wc -l)
8230         [[ $nfiles == 20 ]] ||
8231                 error "lfs find ! --component-count 3 - $nfiles != 20 files"
8232
8233         # All files have a flag called "init"
8234         local nfiles=$($LFS find --component-flags init --type f $dir | wc -l)
8235         [[ $nfiles == 35 ]] ||
8236                 error "lfs find --component-flags init - $nfiles != 35 files"
8237
8238         # Multi-component files will have a component not initialized
8239         local nfiles=$($LFS find ! --component-flags init --type f $dir | wc -l)
8240         [[ $nfiles == 15 ]] ||
8241                 error "lfs find !--component-flags init - $nfiles != 15 files"
8242
8243         rm -rf $dir
8244
8245 }
8246 run_test 56ba "test lfs find --component-end, -start, -count, and -flags"
8247
8248 test_56ca() {
8249         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
8250                 skip "Need MDS version at least 2.10.57"
8251
8252         local td=$DIR/$tdir
8253         local tf=$td/$tfile
8254         local dir
8255         local nfiles
8256         local cmd
8257         local i
8258         local j
8259
8260         # create mirrored directories and mirrored files
8261         mkdir $td || error "mkdir $td failed"
8262         $LFS mirror create -N3 $td || error "create mirrored dir $td failed"
8263         createmany -o $tf- 10 || error "create $tf- failed"
8264
8265         for i in $(seq 2); do
8266                 dir=$td/dir$i
8267                 mkdir $dir || error "mkdir $dir failed"
8268                 $LFS mirror create -N$((3 + i)) $dir ||
8269                         error "create mirrored dir $dir failed"
8270                 createmany -o $dir/$tfile- 10 ||
8271                         error "create $dir/$tfile- failed"
8272         done
8273
8274         # change the states of some mirrored files
8275         echo foo > $tf-6
8276         for i in $(seq 2); do
8277                 dir=$td/dir$i
8278                 for j in $(seq 4 9); do
8279                         echo foo > $dir/$tfile-$j
8280                 done
8281         done
8282
8283         # find mirrored files with specific mirror count
8284         cmd="$LFS find --mirror-count 3 --type f $td"
8285         nfiles=$($cmd | wc -l)
8286         [[ $nfiles = 10 ]] || error "$cmd: $nfiles != 10 files"
8287
8288         cmd="$LFS find ! --mirror-count 3 --type f $td"
8289         nfiles=$($cmd | wc -l)
8290         [[ $nfiles = 20 ]] || error "$cmd: $nfiles != 20 files"
8291
8292         cmd="$LFS find --mirror-count +2 --type f $td"
8293         nfiles=$($cmd | wc -l)
8294         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8295
8296         cmd="$LFS find --mirror-count -6 --type f $td"
8297         nfiles=$($cmd | wc -l)
8298         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8299
8300         # find mirrored files with specific file state
8301         cmd="$LFS find --maxdepth 1 --mirror-state=^ro --type f $td"
8302         [[ $($cmd) = $tf-6 ]] || error "$cmd: didn't return $tf-6"
8303
8304         cmd="$LFS find --mirror-state=ro --type f $td"
8305         nfiles=$($cmd | wc -l)
8306         [[ $nfiles = 17 ]] || error "$cmd: $nfiles != 17 files"
8307
8308         cmd="$LFS find ! --mirror-state=ro --type f $td"
8309         nfiles=$($cmd | wc -l)
8310         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
8311
8312         cmd="$LFS find --mirror-state=wp --type f $td"
8313         nfiles=$($cmd | wc -l)
8314         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
8315
8316         cmd="$LFS find ! --mirror-state=sp --type f $td"
8317         nfiles=$($cmd | wc -l)
8318         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8319 }
8320 run_test 56ca "check lfs find --mirror-count|-N and --mirror-state"
8321
8322 test_56da() { # LU-14179
8323         local path=$DIR/$tdir
8324
8325         test_mkdir $path
8326         cd $path
8327
8328         local longdir=$(str_repeat 'a' 255)
8329
8330         for i in {1..15}; do
8331                 path=$path/$longdir
8332                 test_mkdir $longdir
8333                 cd $longdir
8334         done
8335
8336         local len=${#path}
8337         local lastdir=$(str_repeat 'a' $((4096 - 1 - $len - 1)))
8338
8339         test_mkdir $lastdir
8340         cd $lastdir
8341         # PATH_MAX-1
8342         (( ${#PWD} == 4095 )) || error "bad PWD length ${#PWD}, expect 4095"
8343
8344         # NAME_MAX
8345         touch $(str_repeat 'f' 255)
8346
8347         $LFS find $DIR/$tdir --type d |& grep "lfs find: error" &&
8348                 error "lfs find reported an error"
8349
8350         rm -rf $DIR/$tdir
8351 }
8352 run_test 56da "test lfs find with long paths"
8353
8354 test_56ea() { #LU-10378
8355         local path=$DIR/$tdir
8356         local pool=$TESTNAME
8357
8358         # Create ost pool
8359         pool_add $pool || error "pool_add $pool failed"
8360         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
8361                 error "adding targets to $pool failed"
8362
8363         # Set default pool on directory before creating file
8364         mkdir $path || error "mkdir $path failed"
8365         $LFS setstripe -p $pool $path ||
8366                 error "set OST pool on $pool failed"
8367         touch $path/$tfile || error "touch $path/$tfile failed"
8368
8369         # Compare basic file attributes from -printf and stat
8370         local attr_printf=$($LFS find $path/$tfile -printf "%A@ %T@ %C@ %U %G")
8371         local attr_stat=$(stat -c "%X %Y %Z %u %g" $path/$tfile)
8372
8373         [[ "${attr_printf}" == "${attr_stat}" ]] ||
8374                 error "Attrs from lfs find and stat don't match"
8375
8376         # Compare Lustre attributes from lfs find and lfs getstripe
8377         local lattr_printf=$($LFS find $path/$tfile -printf "%Lc %LS %Li %Lp")
8378         local str_cnt=$($LFS getstripe --stripe-count $path/$tfile)
8379         local str_size=$($LFS getstripe --stripe-size $path/$tfile)
8380         local str_idx=$($LFS getstripe --stripe-index $path/$tfile)
8381         local fpool=$($LFS getstripe --pool $path/$tfile)
8382         local lattr_getstr="${str_cnt} ${str_size} ${str_idx} ${fpool}"
8383
8384         [[ "${lattr_printf}" == "${lattr_getstr}" ]] ||
8385                 error "Attrs from lfs find and lfs getstripe don't match"
8386
8387         # Verify behavior for unknown escape/format sequences
8388         local esc_printf=$($LFS find $path/$tfile -printf '\\ %% \Q %Q')
8389
8390         [[ "${esc_printf}" == '\ % \Q %Q' ]] ||
8391                 error "Escape/format codes don't match"
8392 }
8393 run_test 56ea "test lfs find -printf option"
8394
8395 test_57a() {
8396         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8397         # note test will not do anything if MDS is not local
8398         if [ "$mds1_FSTYPE" != ldiskfs ]; then
8399                 skip_env "ldiskfs only test"
8400         fi
8401         remote_mds_nodsh && skip "remote MDS with nodsh"
8402
8403         local MNTDEV="osd*.*MDT*.mntdev"
8404         DEV=$(do_facet $SINGLEMDS lctl get_param -n $MNTDEV)
8405         [ -z "$DEV" ] && error "can't access $MNTDEV"
8406         for DEV in $(do_facet $SINGLEMDS lctl get_param -n $MNTDEV); do
8407                 do_facet $SINGLEMDS $DUMPE2FS -h $DEV > $TMP/t57a.dump ||
8408                         error "can't access $DEV"
8409                 DEVISIZE=$(awk '/Inode size:/ { print $3 }' $TMP/t57a.dump)
8410                 [[ $DEVISIZE -gt 128 ]] || error "inode size $DEVISIZE"
8411                 rm $TMP/t57a.dump
8412         done
8413 }
8414 run_test 57a "verify MDS filesystem created with large inodes =="
8415
8416 test_57b() {
8417         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8418         if [ "$mds1_FSTYPE" != ldiskfs ]; then
8419                 skip_env "ldiskfs only test"
8420         fi
8421         remote_mds_nodsh && skip "remote MDS with nodsh"
8422
8423         local dir=$DIR/$tdir
8424         local filecount=100
8425         local file1=$dir/f1
8426         local fileN=$dir/f$filecount
8427
8428         rm -rf $dir || error "removing $dir"
8429         test_mkdir -c1 $dir
8430         local mdtidx=$($LFS getstripe -m $dir)
8431         local mdtname=MDT$(printf %04x $mdtidx)
8432         local facet=mds$((mdtidx + 1))
8433
8434         echo "mcreating $filecount files"
8435         createmany -m $dir/f 1 $filecount || error "creating files in $dir"
8436
8437         # verify that files do not have EAs yet
8438         $LFS getstripe $file1 2>&1 | grep -q "no stripe" ||
8439                 error "$file1 has an EA"
8440         $LFS getstripe $fileN 2>&1 | grep -q "no stripe" ||
8441                 error "$fileN has an EA"
8442
8443         sync
8444         sleep 1
8445         df $dir  #make sure we get new statfs data
8446         local mdsfree=$(do_facet $facet \
8447                         lctl get_param -n osd*.*$mdtname.kbytesfree)
8448         local mdcfree=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
8449         local file
8450
8451         echo "opening files to create objects/EAs"
8452         for file in $(seq -f $dir/f%g 1 $filecount); do
8453                 $OPENFILE -f O_RDWR $file > /dev/null 2>&1 ||
8454                         error "opening $file"
8455         done
8456
8457         # verify that files have EAs now
8458         $LFS getstripe $file1 | grep -q "obdidx" || error "$file1 missing EA"
8459         $LFS getstripe $fileN | grep -q "obdidx" || error "$fileN missing EA"
8460
8461         sleep 1  #make sure we get new statfs data
8462         df $dir
8463         local mdsfree2=$(do_facet $facet \
8464                          lctl get_param -n osd*.*$mdtname.kbytesfree)
8465         local mdcfree2=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
8466
8467         if [[ $mdcfree2 -lt $((mdcfree - 16)) ]]; then
8468                 if [ "$mdsfree" != "$mdsfree2" ]; then
8469                         error "MDC before $mdcfree != after $mdcfree2"
8470                 else
8471                         echo "MDC before $mdcfree != after $mdcfree2"
8472                         echo "unable to confirm if MDS has large inodes"
8473                 fi
8474         fi
8475         rm -rf $dir
8476 }
8477 run_test 57b "default LOV EAs are stored inside large inodes ==="
8478
8479 test_58() {
8480         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8481         [ -z "$(which wiretest 2>/dev/null)" ] &&
8482                         skip_env "could not find wiretest"
8483
8484         wiretest
8485 }
8486 run_test 58 "verify cross-platform wire constants =============="
8487
8488 test_59() {
8489         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8490
8491         echo "touch 130 files"
8492         createmany -o $DIR/f59- 130
8493         echo "rm 130 files"
8494         unlinkmany $DIR/f59- 130
8495         sync
8496         # wait for commitment of removal
8497         wait_delete_completed
8498 }
8499 run_test 59 "verify cancellation of llog records async ========="
8500
8501 TEST60_HEAD="test_60 run $RANDOM"
8502 test_60a() {
8503         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8504         remote_mgs_nodsh && skip "remote MGS with nodsh"
8505         do_facet mgs "! which run-llog.sh &> /dev/null" &&
8506                 do_facet mgs "! ls run-llog.sh &> /dev/null" &&
8507                         skip_env "missing subtest run-llog.sh"
8508
8509         log "$TEST60_HEAD - from kernel mode"
8510         do_facet mgs "$LCTL dk > /dev/null"
8511         do_facet mgs "bash run-llog.sh" || error "run-llog.sh failed"
8512         do_facet mgs $LCTL dk > $TMP/$tfile
8513
8514         # LU-6388: test llog_reader
8515         local llog_reader=$(do_facet mgs "which llog_reader 2> /dev/null")
8516         llog_reader=${llog_reader:-$LUSTRE/utils/llog_reader}
8517         [ -z $(do_facet mgs ls -d $llog_reader 2> /dev/null) ] &&
8518                         skip_env "missing llog_reader"
8519         local fstype=$(facet_fstype mgs)
8520         [ $fstype != ldiskfs -a $fstype != zfs ] &&
8521                 skip_env "Only for ldiskfs or zfs type mgs"
8522
8523         local mntpt=$(facet_mntpt mgs)
8524         local mgsdev=$(mgsdevname 1)
8525         local fid_list
8526         local fid
8527         local rec_list
8528         local rec
8529         local rec_type
8530         local obj_file
8531         local path
8532         local seq
8533         local oid
8534         local pass=true
8535
8536         #get fid and record list
8537         fid_list=($(awk '/9_sub.*record/ { print $NF }' $TMP/$tfile |
8538                 tail -n 4))
8539         rec_list=($(awk '/9_sub.*record/ { print $((NF-3)) }' $TMP/$tfile |
8540                 tail -n 4))
8541         #remount mgs as ldiskfs or zfs type
8542         stop mgs || error "stop mgs failed"
8543         mount_fstype mgs || error "remount mgs failed"
8544         for ((i = 0; i < ${#fid_list[@]}; i++)); do
8545                 fid=${fid_list[i]}
8546                 rec=${rec_list[i]}
8547                 seq=$(echo $fid | awk -F ':' '{ print $1 }' | sed -e "s/^0x//g")
8548                 oid=$(echo $fid | awk -F ':' '{ print $2 }' | sed -e "s/^0x//g")
8549                 oid=$((16#$oid))
8550
8551                 case $fstype in
8552                         ldiskfs )
8553                                 obj_file=$mntpt/O/$seq/d$((oid%32))/$oid ;;
8554                         zfs )
8555                                 obj_file=$mntpt/oi.$(($((16#$seq))&127))/$fid ;;
8556                 esac
8557                 echo "obj_file is $obj_file"
8558                 do_facet mgs $llog_reader $obj_file
8559
8560                 rec_type=$(do_facet mgs $llog_reader $obj_file | grep "type=" |
8561                         awk '{ print $3 }' | sed -e "s/^type=//g")
8562                 if [ $rec_type != $rec ]; then
8563                         echo "FAILED test_60a wrong record type $rec_type," \
8564                               "should be $rec"
8565                         pass=false
8566                         break
8567                 fi
8568
8569                 #check obj path if record type is LLOG_LOGID_MAGIC
8570                 if [ "$rec" == "1064553b" ]; then
8571                         path=$(do_facet mgs $llog_reader $obj_file |
8572                                 grep "path=" | awk '{ print $NF }' |
8573                                 sed -e "s/^path=//g")
8574                         if [ $obj_file != $mntpt/$path ]; then
8575                                 echo "FAILED test_60a wrong obj path" \
8576                                       "$montpt/$path, should be $obj_file"
8577                                 pass=false
8578                                 break
8579                         fi
8580                 fi
8581         done
8582         rm -f $TMP/$tfile
8583         #restart mgs before "error", otherwise it will block the next test
8584         stop mgs || error "stop mgs failed"
8585         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
8586         $pass || error "test failed, see FAILED test_60a messages for specifics"
8587 }
8588 run_test 60a "llog_test run from kernel module and test llog_reader"
8589
8590 test_60b() { # bug 6411
8591         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8592
8593         dmesg > $DIR/$tfile
8594         LLOG_COUNT=$(do_facet mgs dmesg |
8595                      awk "/$TEST60_HEAD/ { marker = 1; from_marker = 0; }
8596                           /llog_[a-z]*.c:[0-9]/ {
8597                                 if (marker)
8598                                         from_marker++
8599                                 from_begin++
8600                           }
8601                           END {
8602                                 if (marker)
8603                                         print from_marker
8604                                 else
8605                                         print from_begin
8606                           }")
8607
8608         [[ $LLOG_COUNT -gt 120 ]] &&
8609                 error "CDEBUG_LIMIT not limiting messages ($LLOG_COUNT)" || true
8610 }
8611 run_test 60b "limit repeated messages from CERROR/CWARN"
8612
8613 test_60c() {
8614         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8615
8616         echo "create 5000 files"
8617         createmany -o $DIR/f60c- 5000
8618 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED  0x137
8619         lctl set_param fail_loc=0x80000137
8620         unlinkmany $DIR/f60c- 5000
8621         lctl set_param fail_loc=0
8622 }
8623 run_test 60c "unlink file when mds full"
8624
8625 test_60d() {
8626         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8627
8628         SAVEPRINTK=$(lctl get_param -n printk)
8629         # verify "lctl mark" is even working"
8630         MESSAGE="test message ID $RANDOM $$"
8631         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
8632         dmesg | grep -q "$MESSAGE" || error "didn't find debug marker in log"
8633
8634         lctl set_param printk=0 || error "set lnet.printk failed"
8635         lctl get_param -n printk | grep emerg || error "lnet.printk dropped emerg"
8636         MESSAGE="new test message ID $RANDOM $$"
8637         # Assume here that libcfs_debug_mark_buffer() uses D_WARNING
8638         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
8639         dmesg | grep -q "$MESSAGE" && error "D_WARNING wasn't masked" || true
8640
8641         lctl set_param -n printk="$SAVEPRINTK"
8642 }
8643 run_test 60d "test printk console message masking"
8644
8645 test_60e() {
8646         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8647         remote_mds_nodsh && skip "remote MDS with nodsh"
8648
8649         touch $DIR/$tfile
8650 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED2  0x15b
8651         do_facet mds1 lctl set_param fail_loc=0x15b
8652         rm $DIR/$tfile
8653 }
8654 run_test 60e "no space while new llog is being created"
8655
8656 test_60f() {
8657         local old_path=$($LCTL get_param -n debug_path)
8658
8659         stack_trap "$LCTL set_param debug_path=$old_path"
8660         stack_trap "rm -f $TMP/$tfile*"
8661         rm -f $TMP/$tfile* 2> /dev/null
8662         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
8663         $LCTL set_param debug_path=$TMP/$tfile fail_loc=0x8000050e
8664         test_mkdir $DIR/$tdir
8665         # retry in case the open is cached and not released
8666         for (( i = 0; i < 100 && $(ls $TMP/$tfile* | wc -l) == 0; i++ )); do
8667                 echo $i > $DIR/$tdir/$tfile.$i && cat $DIR/$tdir/$tfile.$i
8668                 sleep 0.1
8669         done
8670         ls $TMP/$tfile*
8671         (( $(ls $TMP/$tfile* | wc -l) > 0 )) || error "$TMP/$tfile not dumped"
8672 }
8673 run_test 60f "change debug_path works"
8674
8675 test_60g() {
8676         local pid
8677         local i
8678
8679         test_mkdir -c $MDSCOUNT $DIR/$tdir
8680
8681         (
8682                 local index=0
8683                 while true; do
8684                         $LFS setdirstripe -i $(($index % $MDSCOUNT)) \
8685                                 -c $MDSCOUNT $DIR/$tdir/subdir$index \
8686                                 2>/dev/null
8687                         mkdir $DIR/$tdir/subdir$index 2>/dev/null
8688                         rmdir $DIR/$tdir/subdir$index 2>/dev/null
8689                         index=$((index + 1))
8690                 done
8691         ) &
8692
8693         pid=$!
8694
8695         for i in {0..100}; do
8696                 # define OBD_FAIL_OSD_TXN_START    0x19a
8697                 local index=$((i % MDSCOUNT + 1))
8698
8699                 do_facet mds$index $LCTL set_param fail_loc=0x8000019a \
8700                         > /dev/null
8701                 sleep 0.01
8702         done
8703
8704         kill -9 $pid
8705
8706         for i in $(seq $MDSCOUNT); do
8707                 do_facet mds$i $LCTL set_param fail_loc=0 > /dev/null
8708         done
8709
8710         mkdir $DIR/$tdir/new || error "mkdir failed"
8711         rmdir $DIR/$tdir/new || error "rmdir failed"
8712
8713         do_facet mds1 $LCTL lfsck_start -M $(facet_svc mds1) -A -C \
8714                 -t namespace
8715         for i in $(seq $MDSCOUNT); do
8716                 wait_update_facet mds$i "$LCTL get_param -n \
8717                         mdd.$(facet_svc mds$i).lfsck_namespace |
8718                         awk '/^status/ { print \\\$2 }'" "completed"
8719         done
8720
8721         ls -R $DIR/$tdir
8722         rm -rf $DIR/$tdir || error "rmdir failed"
8723 }
8724 run_test 60g "transaction abort won't cause MDT hung"
8725
8726 test_60h() {
8727         [ $MDS1_VERSION -le $(version_code 2.12.52) ] &&
8728                 skip "Need MDS version at least 2.12.52"
8729         [ $MDSCOUNT -lt 2 ] && skip "Need at least 2 MDTs"
8730
8731         local f
8732
8733         #define OBD_FAIL_MDS_STRIPE_CREATE       0x188
8734         #define OBD_FAIL_MDS_STRIPE_FID          0x189
8735         for fail_loc in 0x80000188 0x80000189; do
8736                 do_facet mds1 "$LCTL set_param fail_loc=$fail_loc"
8737                 $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir-$fail_loc ||
8738                         error "mkdir $dir-$fail_loc failed"
8739                 for i in {0..10}; do
8740                         # create may fail on missing stripe
8741                         echo $i > $DIR/$tdir-$fail_loc/$i
8742                 done
8743                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
8744                         error "getdirstripe $tdir-$fail_loc failed"
8745                 $LFS migrate -m 1 $DIR/$tdir-$fail_loc ||
8746                         error "migrate $tdir-$fail_loc failed"
8747                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
8748                         error "getdirstripe $tdir-$fail_loc failed"
8749                 pushd $DIR/$tdir-$fail_loc
8750                 for f in *; do
8751                         echo $f | cmp $f - || error "$f data mismatch"
8752                 done
8753                 popd
8754                 rm -rf $DIR/$tdir-$fail_loc
8755         done
8756 }
8757 run_test 60h "striped directory with missing stripes can be accessed"
8758
8759 function t60i_load() {
8760         mkdir $DIR/$tdir
8761         #define OBD_FAIL_LLOG_PAUSE_AFTER_PAD               0x131c
8762         $LCTL set_param fail_loc=0x131c fail_val=1
8763         for ((i=0; i<5000; i++)); do
8764                 touch $DIR/$tdir/f$i
8765         done
8766 }
8767
8768 test_60i() {
8769         changelog_register || error "changelog_register failed"
8770         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
8771         changelog_users $SINGLEMDS | grep -q $cl_user ||
8772                 error "User $cl_user not found in changelog_users"
8773         changelog_chmask "ALL"
8774         t60i_load &
8775         local PID=$!
8776         for((i=0; i<100; i++)); do
8777                 changelog_dump >/dev/null ||
8778                         error "can't read changelog"
8779         done
8780         kill $PID
8781         wait $PID
8782         changelog_deregister || error "changelog_deregister failed"
8783         $LCTL set_param fail_loc=0
8784 }
8785 run_test 60i "llog: new record vs reader race"
8786
8787 test_60j() {
8788         (( $MDS1_VERSION >= $(version_code 2.15.50) )) ||
8789                 skip "need MDS version at least 2.15.50"
8790         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
8791         remote_mds_nodsh && skip "remote MDS with nodsh"
8792         [[ "$mds1_FSTYPE" == "ldiskfs" ]] || skip "ldiskfs only test"
8793
8794         changelog_users $SINGLEMDS | grep "^cl" &&
8795                 skip "active changelog user"
8796
8797         local llog_reader=$(do_facet $SINGLEMDS "which llog_reader 2> /dev/null")
8798
8799         [[ -z $(do_facet $SINGLEMDS ls -d $llog_reader 2> /dev/null) ]] &&
8800                 skip_env "missing llog_reader"
8801
8802         mkdir_on_mdt0 $DIR/$tdir
8803
8804         local f=$DIR/$tdir/$tfile
8805         local mdt_dev
8806         local tmpfile
8807         local plain
8808
8809         changelog_register || error "cannot register changelog user"
8810
8811         # set changelog_mask to ALL
8812         changelog_chmask "ALL"
8813         changelog_clear
8814
8815         createmany -o ${f}- 100 || error "createmany failed as $RUNAS_ID"
8816         unlinkmany ${f}- 100 || error "unlinkmany failed"
8817
8818         tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
8819         mdt_dev=$(facet_device $SINGLEMDS)
8820
8821         do_facet $SINGLEMDS sync
8822         plain=$(do_facet $SINGLEMDS "$DEBUGFS -c -R 'dump changelog_catalog \
8823                 $tmpfile' $mdt_dev; $llog_reader $tmpfile" |
8824                 awk '{match($0,"path=([^ ]+)",a)}END{print a[1]}')
8825
8826         stack_trap "do_facet $SINGLEMDS rm -f $tmpfile"
8827
8828         # if $tmpfile is not on EXT3 filesystem for some reason
8829         [[ ${plain:0:1} == 'O' ]] ||
8830                 skip "path $plain is not in 'O/1/d<n>/<n>' format"
8831
8832         size=$(do_facet $SINGLEMDS "$DEBUGFS -c -R 'dump $plain $tmpfile' \
8833                 $mdt_dev; stat -c %s $tmpfile")
8834         echo "Truncate llog from $size to $((size - size % 8192))"
8835         size=$((size - size % 8192))
8836         do_facet $SINGLEMDS $TRUNCATE $tmpfile $size
8837         errs=$(do_facet $SINGLEMDS "$llog_reader $tmpfile" |
8838                 grep -c 'in bitmap only')
8839         (( $errs > 0 )) || error "llog_reader didn't find lost records"
8840
8841         size=$((size - 9000))
8842         echo "Corrupt llog in the middle at $size"
8843         do_facet $SINGLEMDS dd if=/dev/urandom of=$tmpfile bs=1 seek=$size \
8844                 count=333 conv=notrunc
8845         errs=$(do_facet $SINGLEMDS "$llog_reader $tmpfile" |
8846                 grep -c 'next chunk')
8847         (( $errs > 0 )) || error "llog_reader didn't skip bad chunk"
8848 }
8849 run_test 60j "llog_reader reports corruptions"
8850
8851 test_61a() {
8852         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8853
8854         f="$DIR/f61"
8855         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1 || error "dd $f failed"
8856         cancel_lru_locks osc
8857         $MULTIOP $f OSMWUc || error "$MULTIOP $f failed"
8858         sync
8859 }
8860 run_test 61a "mmap() writes don't make sync hang ================"
8861
8862 test_61b() {
8863         mmap_mknod_test $DIR/$tfile || error "mmap_mknod_test failed"
8864 }
8865 run_test 61b "mmap() of unstriped file is successful"
8866
8867 # bug 2330 - insufficient obd_match error checking causes LBUG
8868 test_62() {
8869         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8870
8871         f="$DIR/f62"
8872         echo foo > $f
8873         cancel_lru_locks osc
8874         lctl set_param fail_loc=0x405
8875         cat $f && error "cat succeeded, expect -EIO"
8876         lctl set_param fail_loc=0
8877 }
8878 # This test is now irrelevant (as of bug 10718 inclusion), we no longer
8879 # match every page all of the time.
8880 #run_test 62 "verify obd_match failure doesn't LBUG (should -EIO)"
8881
8882 # bug 2319 - oig_wait() interrupted causes crash because of invalid waitq.
8883 # Though this test is irrelevant anymore, it helped to reveal some
8884 # other grant bugs (LU-4482), let's keep it.
8885 test_63a() {   # was test_63
8886         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8887
8888         MAX_DIRTY_MB=$(lctl get_param -n osc.*.max_dirty_mb | head -n 1)
8889
8890         for i in `seq 10` ; do
8891                 dd if=/dev/zero of=$DIR/f63 bs=8k &
8892                 sleep 5
8893                 kill $!
8894                 sleep 1
8895         done
8896
8897         rm -f $DIR/f63 || true
8898 }
8899 run_test 63a "Verify oig_wait interruption does not crash ======="
8900
8901 # bug 2248 - async write errors didn't return to application on sync
8902 # bug 3677 - async write errors left page locked
8903 test_63b() {
8904         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8905
8906         debugsave
8907         lctl set_param debug=-1
8908
8909         # ensure we have a grant to do async writes
8910         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1
8911         rm $DIR/$tfile
8912
8913         sync    # sync lest earlier test intercept the fail_loc
8914
8915         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
8916         lctl set_param fail_loc=0x80000406
8917         $MULTIOP $DIR/$tfile Owy && \
8918                 error "sync didn't return ENOMEM"
8919         sync; sleep 2; sync     # do a real sync this time to flush page
8920         lctl get_param -n llite.*.dump_page_cache | grep locked && \
8921                 error "locked page left in cache after async error" || true
8922         debugrestore
8923 }
8924 run_test 63b "async write errors should be returned to fsync ==="
8925
8926 test_64a () {
8927         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8928
8929         lfs df $DIR
8930         lctl get_param osc.*[oO][sS][cC][_-]*.cur* | grep "=[1-9]"
8931 }
8932 run_test 64a "verify filter grant calculations (in kernel) ====="
8933
8934 test_64b () {
8935         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8936
8937         bash oos.sh $MOUNT || error "oos.sh failed: $?"
8938 }
8939 run_test 64b "check out-of-space detection on client"
8940
8941 test_64c() {
8942         $LCTL set_param osc.*OST0000-osc-[^mM]*.cur_grant_bytes=0
8943 }
8944 run_test 64c "verify grant shrink"
8945
8946 import_param() {
8947         local tgt=$1
8948         local param=$2
8949
8950         $LCTL get_param osc.$tgt.import | awk "/$param/ { print \$2 }"
8951 }
8952
8953 # this does exactly what osc_request.c:osc_announce_cached() does in
8954 # order to calculate max amount of grants to ask from server
8955 want_grant() {
8956         local tgt=$1
8957
8958         local nrpages=$($LCTL get_param -n osc.$tgt.max_pages_per_rpc)
8959         local rpc_in_flight=$($LCTL get_param -n osc.$tgt.max_rpcs_in_flight)
8960
8961         ((rpc_in_flight++));
8962         nrpages=$((nrpages * rpc_in_flight))
8963
8964         local dirty_max_pages=$($LCTL get_param -n osc.$tgt.max_dirty_mb)
8965
8966         dirty_max_pages=$((dirty_max_pages * 1024 * 1024 / PAGE_SIZE))
8967
8968         [[ $dirty_max_pages -gt $nrpages ]] && nrpages=$dirty_max_pages
8969         local undirty=$((nrpages * PAGE_SIZE))
8970
8971         local max_extent_pages
8972         max_extent_pages=$(import_param $tgt grant_max_extent_size)
8973         max_extent_pages=$((max_extent_pages / PAGE_SIZE))
8974         local nrextents=$(((nrpages + max_extent_pages - 1) / max_extent_pages))
8975         local grant_extent_tax
8976         grant_extent_tax=$(import_param $tgt grant_extent_tax)
8977
8978         undirty=$((undirty + nrextents * grant_extent_tax))
8979
8980         echo $undirty
8981 }
8982
8983 # this is size of unit for grant allocation. It should be equal to
8984 # what tgt_grant.c:tgt_grant_chunk() calculates
8985 grant_chunk() {
8986         local tgt=$1
8987         local max_brw_size
8988         local grant_extent_tax
8989
8990         max_brw_size=$(import_param $tgt max_brw_size)
8991
8992         grant_extent_tax=$(import_param $tgt grant_extent_tax)
8993
8994         echo $(((max_brw_size + grant_extent_tax) * 2))
8995 }
8996
8997 test_64d() {
8998         [ $OST1_VERSION -ge $(version_code 2.10.56) ] ||
8999                 skip "OST < 2.10.55 doesn't limit grants enough"
9000
9001         local tgt=$($LCTL dl | awk '/OST0000-osc-[^mM]/ { print $4 }')
9002
9003         [[ "$($LCTL get_param osc.${tgt}.import)" =~ "grant_param" ]] ||
9004                 skip "no grant_param connect flag"
9005
9006         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
9007
9008         $LCTL set_param -n -n debug="$OLDDEBUG" || true
9009         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
9010
9011
9012         local max_cur_granted=$(($(want_grant $tgt) + $(grant_chunk $tgt)))
9013         stack_trap "rm -f $DIR/$tfile && wait_delete_completed" EXIT
9014
9015         $LFS setstripe $DIR/$tfile -i 0 -c 1
9016         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1000 &
9017         ddpid=$!
9018
9019         while kill -0 $ddpid; do
9020                 local cur_grant=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
9021
9022                 if [[ $cur_grant -gt $max_cur_granted ]]; then
9023                         kill $ddpid
9024                         error "cur_grant $cur_grant > $max_cur_granted"
9025                 fi
9026
9027                 sleep 1
9028         done
9029 }
9030 run_test 64d "check grant limit exceed"
9031
9032 check_grants() {
9033         local tgt=$1
9034         local expected=$2
9035         local msg=$3
9036         local cur_grants=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
9037
9038         ((cur_grants == expected)) ||
9039                 error "$msg: grants mismatch: $cur_grants, expected $expected"
9040 }
9041
9042 round_up_p2() {
9043         echo $((($1 + $2 - 1) & ~($2 - 1)))
9044 }
9045
9046 test_64e() {
9047         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9048         [ $OST1_VERSION -ge $(version_code 2.11.56) ] ||
9049                 skip "Need OSS version at least 2.11.56"
9050
9051         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
9052         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
9053         $LCTL set_param debug=+cache
9054
9055         # Remount client to reset grant
9056         remount_client $MOUNT || error "failed to remount client"
9057         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9058
9059         local init_grants=$(import_param $osc_tgt initial_grant)
9060
9061         check_grants $osc_tgt $init_grants "init grants"
9062
9063         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
9064         local max_brw_size=$(import_param $osc_tgt max_brw_size)
9065         local gbs=$(import_param $osc_tgt grant_block_size)
9066
9067         # write random number of bytes from max_brw_size / 4 to max_brw_size
9068         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
9069         # align for direct io
9070         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
9071         # round to grant consumption unit
9072         local wb_round_up=$(round_up_p2 $write_bytes gbs)
9073
9074         local grants=$((wb_round_up + extent_tax))
9075
9076         $LFS setstripe -c 1 -i 0 $DIR/$tfile  || error "lfs setstripe failed"
9077
9078         # define OBD_FAIL_TGT_NO_GRANT 0x725
9079         # make the server not grant more back
9080         do_facet ost1 $LCTL set_param fail_loc=0x725
9081         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct
9082
9083         do_facet ost1 $LCTL set_param fail_loc=0
9084
9085         check_grants $osc_tgt $((init_grants - grants)) "dio w/o grant alloc"
9086
9087         rm -f $DIR/$tfile || error "rm failed"
9088
9089         # Remount client to reset grant
9090         remount_client $MOUNT || error "failed to remount client"
9091         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9092
9093         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
9094
9095         # define OBD_FAIL_TGT_NO_GRANT 0x725
9096         # make the server not grant more back
9097         do_facet ost1 $LCTL set_param fail_loc=0x725
9098         $MULTIOP $DIR/$tfile "oO_WRONLY:w${write_bytes}yc"
9099         do_facet ost1 $LCTL set_param fail_loc=0
9100
9101         check_grants $osc_tgt $((init_grants - grants)) "buf io w/o grant alloc"
9102 }
9103 run_test 64e "check grant consumption (no grant allocation)"
9104
9105 test_64f() {
9106         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9107
9108         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
9109         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
9110         $LCTL set_param debug=+cache
9111
9112         # Remount client to reset grant
9113         remount_client $MOUNT || error "failed to remount client"
9114         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9115
9116         local init_grants=$(import_param $osc_tgt initial_grant)
9117         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
9118         local max_brw_size=$(import_param $osc_tgt max_brw_size)
9119         local gbs=$(import_param $osc_tgt grant_block_size)
9120         local chunk=$(grant_chunk $osc_tgt)
9121
9122         # write random number of bytes from max_brw_size / 4 to max_brw_size
9123         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
9124         # align for direct io
9125         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
9126         # round to grant consumption unit
9127         local wb_round_up=$(round_up_p2 $write_bytes gbs)
9128
9129         local grants=$((wb_round_up + extent_tax))
9130
9131         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
9132         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct ||
9133                 error "error writing to $DIR/$tfile"
9134
9135         check_grants $osc_tgt $((init_grants - grants + chunk)) \
9136                 "direct io with grant allocation"
9137
9138         rm -f $DIR/$tfile || error "rm failed"
9139
9140         # Remount client to reset grant
9141         remount_client $MOUNT || error "failed to remount client"
9142         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9143
9144         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
9145
9146         local cmd="oO_WRONLY:w${write_bytes}_yc"
9147
9148         $MULTIOP $DIR/$tfile $cmd &
9149         MULTIPID=$!
9150         sleep 1
9151
9152         check_grants $osc_tgt $((init_grants - grants)) \
9153                 "buffered io, not write rpc"
9154
9155         kill -USR1 $MULTIPID
9156         wait
9157
9158         check_grants $osc_tgt $((init_grants - grants + chunk)) \
9159                 "buffered io, one RPC"
9160 }
9161 run_test 64f "check grant consumption (with grant allocation)"
9162
9163 test_64g() {
9164         (( $MDS1_VERSION >= $(version_code 2.14.56) )) ||
9165                 skip "Need MDS version at least 2.14.56"
9166
9167         local mdts=$(comma_list $(mdts_nodes))
9168
9169         local old=$($LCTL get_param mdc.$FSNAME-*.grant_shrink_interval |
9170                         tr '\n' ' ')
9171         stack_trap "$LCTL set_param $old"
9172
9173         # generate dirty pages and increase dirty granted on MDT
9174         stack_trap "rm -f $DIR/$tfile-*"
9175         for (( i = 0; i < 10; i++)); do
9176                 $LFS setstripe -E 1M -L mdt $DIR/$tfile-$i ||
9177                         error "can't set stripe"
9178                 dd if=/dev/zero of=$DIR/$tfile-$i bs=128k count=1 ||
9179                         error "can't dd"
9180                 $LFS getstripe $DIR/$tfile-$i | grep -q pattern.*mdt || {
9181                         $LFS getstripe $DIR/$tfile-$i
9182                         error "not DoM file"
9183                 }
9184         done
9185
9186         # flush dirty pages
9187         sync
9188
9189         # wait until grant shrink reset grant dirty on MDTs
9190         for ((i = 0; i < 120; i++)); do
9191                 grant_dirty=$(do_nodes $mdts $LCTL get_param -n  mdt.*.tot_dirty |
9192                         awk '{sum=sum+$1} END {print sum}')
9193                 vm_dirty=$(awk '/Dirty:/{print $2}' /proc/meminfo)
9194                 echo "$grant_dirty grants, $vm_dirty pages"
9195                 (( grant_dirty + vm_dirty == 0 )) && break
9196                 (( i == 3 )) && sync &&
9197                         $LCTL set_param mdc.$FSNAME-*.grant_shrink_interval=5
9198                 sleep 1
9199         done
9200
9201         grant_dirty=$(do_nodes $mdts $LCTL get_param -n  mdt.*.tot_dirty |
9202                 awk '{sum=sum+$1} END {print sum}')
9203         (( grant_dirty == 0 )) || error "$grant_dirty on MDT"
9204 }
9205 run_test 64g "grant shrink on MDT"
9206
9207 test_64h() {
9208         (( $OST1_VERSION >= $(version_code 2.14.56) )) ||
9209                 skip "need OST at least 2.14.56 to avoid grant shrink on read"
9210
9211         local instance=$($LFS getname -i $DIR)
9212         local osc_tgt="$FSNAME-OST0000-osc-$instance"
9213         local num_exps=$(do_facet ost1 \
9214             $LCTL get_param -n obdfilter.*OST0000*.num_exports)
9215         local max_brw_size=$(import_param $osc_tgt max_brw_size)
9216         local avail=$($LCTL get_param -n osc.*OST0000-osc-$instance.kbytesavail)
9217         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
9218
9219         # 10MiB is for file to be written, max_brw_size * 16 *
9220         # num_exps is space reserve so that tgt_grant_shrink() decided
9221         # to not shrink
9222         local expect=$((max_brw_size * 16 * num_exps + 10 * 1048576))
9223         (( avail * 1024 < expect )) &&
9224                 skip "need $expect bytes on ost1, have $(( avail * 1024 )) only"
9225
9226         save_lustre_params client "osc.*OST0000*.grant_shrink" > $p
9227         save_lustre_params client "osc.*OST0000*.grant_shrink_interval" >> $p
9228         stack_trap "restore_lustre_params < $p; rm -f $save" EXIT
9229         $LCTL set_param osc.*OST0000*.grant_shrink=1
9230         $LCTL set_param osc.*OST0000*.grant_shrink_interval=10
9231
9232         $LFS setstripe -c 1 -i 0 $DIR/$tfile
9233         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 oflag=sync
9234
9235         # drop cache so that coming read would do rpc
9236         cancel_lru_locks osc
9237
9238         # shrink interval is set to 10, pause for 7 seconds so that
9239         # grant thread did not wake up yet but coming read entered
9240         # shrink mode for rpc (osc_should_shrink_grant())
9241         sleep 7
9242
9243         declare -a cur_grant_bytes
9244         declare -a tot_granted
9245         cur_grant_bytes[0]=$($LCTL get_param -n osc.*OST0000*.cur_grant_bytes)
9246         tot_granted[0]=$(do_facet ost1 \
9247             $LCTL get_param -n obdfilter.*OST0000*.tot_granted)
9248
9249         dd if=$DIR/$tfile bs=4K count=1 of=/dev/null
9250
9251         cur_grant_bytes[1]=$($LCTL get_param -n osc.*OST0000*.cur_grant_bytes)
9252         tot_granted[1]=$(do_facet ost1 \
9253             $LCTL get_param -n obdfilter.*OST0000*.tot_granted)
9254
9255         # grant change should be equal on both sides
9256         (( cur_grant_bytes[0] - cur_grant_bytes[1] ==
9257                 tot_granted[0] - tot_granted[1])) ||
9258                 error "grant change mismatch, "                                \
9259                         "server: ${tot_granted[0]} to ${tot_granted[1]}, "     \
9260                         "client: ${cur_grant_bytes[0]} to ${cur_grant_bytes[1]}"
9261 }
9262 run_test 64h "grant shrink on read"
9263
9264 test_64i() {
9265         (( $OST1_VERSION >= $(version_code 2.14.56) )) ||
9266                 skip "need OST at least 2.14.56 to avoid grant shrink on replay"
9267
9268         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9269         remote_ost_nodsh && skip "remote OSTs with nodsh"
9270
9271         $LFS setstripe -c 1 -i 0 $DIR/$tfile
9272
9273         dd if=/dev/zero of=$DIR/$tfile bs=1M count=64
9274
9275         # lustre-ffff9fc75e850800 /mnt/lustre -> ffff9fc75e850800
9276         local instance=$($LFS getname -i $DIR)
9277
9278         local osc_tgt="$FSNAME-OST0000-osc-$instance"
9279         local cgb=$($LCTL get_param -n osc.$osc_tgt.cur_grant_bytes)
9280
9281         # shrink grants and simulate rpc loss
9282         #define OBD_FAIL_PTLRPC_DROP_REQ_OPC     0x513
9283         do_facet ost1 "$LCTL set_param fail_loc=0x80000513 fail_val=17"
9284         $LCTL set_param osc.$osc_tgt.cur_grant_bytes=$((cgb/2))B
9285
9286         fail ost1
9287
9288         dd if=/dev/zero of=$DIR/$tfile oflag=append bs=1M count=8 conv=notrunc
9289
9290         local testid=$(echo $TESTNAME | tr '_' ' ')
9291
9292         do_facet ost1 dmesg | tac | sed "/$testid/,$ d" |
9293                 grep "GRANT, real grant" &&
9294                 error "client has more grants then it owns" || true
9295 }
9296 run_test 64i "shrink on reconnect"
9297
9298 # bug 1414 - set/get directories' stripe info
9299 test_65a() {
9300         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9301
9302         test_mkdir $DIR/$tdir
9303         touch $DIR/$tdir/f1
9304         $LVERIFY $DIR/$tdir $DIR/$tdir/f1 || error "lverify failed"
9305 }
9306 run_test 65a "directory with no stripe info"
9307
9308 test_65b() {
9309         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9310
9311         test_mkdir $DIR/$tdir
9312         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9313
9314         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
9315                                                 error "setstripe"
9316         touch $DIR/$tdir/f2
9317         $LVERIFY $DIR/$tdir $DIR/$tdir/f2 || error "lverify failed"
9318 }
9319 run_test 65b "directory setstripe -S stripe_size*2 -i 0 -c 1"
9320
9321 test_65c() {
9322         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9323         [ $OSTCOUNT -lt 2 ] && skip_env "need at least 2 OSTs"
9324
9325         test_mkdir $DIR/$tdir
9326         local stripesize=$($LFS getstripe -S $DIR/$tdir)
9327
9328         $LFS setstripe -S $((stripesize * 4)) -i 1 \
9329                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
9330         touch $DIR/$tdir/f3
9331         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
9332 }
9333 run_test 65c "directory setstripe -S stripe_size*4 -i 1 -c $((OSTCOUNT-1))"
9334
9335 test_65d() {
9336         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9337
9338         test_mkdir $DIR/$tdir
9339         local STRIPECOUNT=$($LFS getstripe -c $DIR/$tdir)
9340         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9341
9342         if [[ $STRIPECOUNT -le 0 ]]; then
9343                 sc=1
9344         elif [[ $STRIPECOUNT -gt $LOV_MAX_STRIPE_COUNT ]]; then
9345                 [[ $OSTCOUNT -gt $LOV_MAX_STRIPE_COUNT ]] &&
9346                         sc=$LOV_MAX_STRIPE_COUNT || sc=$(($OSTCOUNT - 1))
9347         else
9348                 sc=$(($STRIPECOUNT - 1))
9349         fi
9350         $LFS setstripe -S $STRIPESIZE -c $sc $DIR/$tdir || error "setstripe"
9351         touch $DIR/$tdir/f4 $DIR/$tdir/f5
9352         $LVERIFY $DIR/$tdir $DIR/$tdir/f4 $DIR/$tdir/f5 ||
9353                 error "lverify failed"
9354 }
9355 run_test 65d "directory setstripe -S stripe_size -c stripe_count"
9356
9357 test_65e() {
9358         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9359
9360         test_mkdir $DIR/$tdir
9361
9362         $LFS setstripe $DIR/$tdir || error "setstripe"
9363         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
9364                                         error "no stripe info failed"
9365         touch $DIR/$tdir/f6
9366         $LVERIFY $DIR/$tdir $DIR/$tdir/f6 || error "lverify failed"
9367 }
9368 run_test 65e "directory setstripe defaults"
9369
9370 test_65f() {
9371         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9372
9373         test_mkdir $DIR/${tdir}f
9374         $RUNAS $LFS setstripe $DIR/${tdir}f &&
9375                 error "setstripe succeeded" || true
9376 }
9377 run_test 65f "dir setstripe permission (should return error) ==="
9378
9379 test_65g() {
9380         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9381
9382         test_mkdir $DIR/$tdir
9383         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9384
9385         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
9386                 error "setstripe -S failed"
9387         $LFS setstripe -d $DIR/$tdir || error "setstripe -d failed"
9388         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
9389                 error "delete default stripe failed"
9390 }
9391 run_test 65g "directory setstripe -d"
9392
9393 test_65h() {
9394         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9395
9396         test_mkdir $DIR/$tdir
9397         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9398
9399         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
9400                 error "setstripe -S failed"
9401         test_mkdir $DIR/$tdir/dd1
9402         [ $($LFS getstripe -c $DIR/$tdir) = $($LFS getstripe -c $DIR/$tdir/dd1) ] ||
9403                 error "stripe info inherit failed"
9404 }
9405 run_test 65h "directory stripe info inherit ===================="
9406
9407 test_65i() {
9408         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9409
9410         save_layout_restore_at_exit $MOUNT
9411
9412         # bug6367: set non-default striping on root directory
9413         $LFS setstripe -S 65536 -c -1 $MOUNT || error "error setting stripe"
9414
9415         # bug12836: getstripe on -1 default directory striping
9416         $LFS getstripe $MOUNT || error "getstripe $MOUNT failed"
9417
9418         # bug12836: getstripe -v on -1 default directory striping
9419         $LFS getstripe -v $MOUNT || error "getstripe -v $MOUNT failed"
9420
9421         # bug12836: new find on -1 default directory striping
9422         $LFS find -mtime -1 $MOUNT > /dev/null || error "find $MOUNT failed"
9423 }
9424 run_test 65i "various tests to set root directory striping"
9425
9426 test_65j() { # bug6367
9427         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9428
9429         sync; sleep 1
9430
9431         # if we aren't already remounting for each test, do so for this test
9432         if [ "$I_MOUNTED" = "yes" ]; then
9433                 cleanup || error "failed to unmount"
9434                 setup
9435         fi
9436
9437         save_layout_restore_at_exit $MOUNT
9438
9439         $LFS setstripe -d $MOUNT || error "setstripe failed"
9440 }
9441 run_test 65j "set default striping on root directory (bug 6367)="
9442
9443 cleanup_65k() {
9444         rm -rf $DIR/$tdir
9445         wait_delete_completed
9446         do_facet $SINGLEMDS "lctl set_param -n \
9447                 osp.$ost*MDT0000.max_create_count=$max_count"
9448         do_facet $SINGLEMDS "lctl set_param -n \
9449                 osp.$ost*MDT0000.create_count=$count"
9450         do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
9451         echo $INACTIVE_OSC "is Activate"
9452
9453         wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
9454 }
9455
9456 test_65k() { # bug11679
9457         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9458         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9459         remote_mds_nodsh && skip "remote MDS with nodsh"
9460
9461         local disable_precreate=true
9462         [ $MDS1_VERSION -le $(version_code 2.8.54) ] &&
9463                 disable_precreate=false
9464
9465         echo "Check OST status: "
9466         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
9467                 awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
9468
9469         for OSC in $MDS_OSCS; do
9470                 echo $OSC "is active"
9471                 do_facet $SINGLEMDS lctl --device %$OSC activate
9472         done
9473
9474         for INACTIVE_OSC in $MDS_OSCS; do
9475                 local ost=$(osc_to_ost $INACTIVE_OSC)
9476                 local ostnum=$(do_facet $SINGLEMDS lctl get_param -n \
9477                                lov.*md*.target_obd |
9478                                awk -F: /$ost/'{ print $1 }' | head -n 1)
9479
9480                 mkdir -p $DIR/$tdir
9481                 $LFS setstripe -i $ostnum -c 1 $DIR/$tdir
9482                 createmany -o $DIR/$tdir/$tfile.$ostnum. 1000
9483
9484                 echo "Deactivate: " $INACTIVE_OSC
9485                 do_facet $SINGLEMDS lctl --device %$INACTIVE_OSC deactivate
9486
9487                 local count=$(do_facet $SINGLEMDS "lctl get_param -n \
9488                               osp.$ost*MDT0000.create_count")
9489                 local max_count=$(do_facet $SINGLEMDS "lctl get_param -n \
9490                                   osp.$ost*MDT0000.max_create_count")
9491                 $disable_precreate &&
9492                         do_facet $SINGLEMDS "lctl set_param -n \
9493                                 osp.$ost*MDT0000.max_create_count=0"
9494
9495                 for idx in $(seq 0 $((OSTCOUNT - 1))); do
9496                         [ -f $DIR/$tdir/$idx ] && continue
9497                         echo "$LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx"
9498                         $LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx ||
9499                                 { cleanup_65k;
9500                                   error "setstripe $idx should succeed"; }
9501                         rm -f $DIR/$tdir/$idx || error "rm $idx failed"
9502                 done
9503                 unlinkmany $DIR/$tdir/$tfile.$ostnum. 1000
9504                 rmdir $DIR/$tdir
9505
9506                 do_facet $SINGLEMDS "lctl set_param -n \
9507                         osp.$ost*MDT0000.max_create_count=$max_count"
9508                 do_facet $SINGLEMDS "lctl set_param -n \
9509                         osp.$ost*MDT0000.create_count=$count"
9510                 do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
9511                 echo $INACTIVE_OSC "is Activate"
9512
9513                 wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
9514         done
9515 }
9516 run_test 65k "validate manual striping works properly with deactivated OSCs"
9517
9518 test_65l() { # bug 12836
9519         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9520
9521         test_mkdir -p $DIR/$tdir/test_dir
9522         $LFS setstripe -c -1 $DIR/$tdir/test_dir
9523         $LFS find -mtime -1 $DIR/$tdir >/dev/null
9524 }
9525 run_test 65l "lfs find on -1 stripe dir ========================"
9526
9527 test_65m() {
9528         local layout=$(save_layout $MOUNT)
9529         $RUNAS $LFS setstripe -c 2 $MOUNT && {
9530                 restore_layout $MOUNT $layout
9531                 error "setstripe should fail by non-root users"
9532         }
9533         true
9534 }
9535 run_test 65m "normal user can't set filesystem default stripe"
9536
9537 test_65n() {
9538         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
9539         [[ $MDS1_VERSION -ge $(version_code 2.12.50) ]] ||
9540                 skip "Need MDS version at least 2.12.50"
9541         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
9542
9543         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
9544         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
9545         which setfattr > /dev/null 2>&1 || skip_env "no setfattr command"
9546
9547         save_layout_restore_at_exit $MOUNT
9548
9549         # new subdirectory under root directory should not inherit
9550         # the default layout from root
9551         local dir1=$MOUNT/$tdir-1
9552         mkdir $dir1 || error "mkdir $dir1 failed"
9553         ! getfattr -n trusted.lov $dir1 &> /dev/null ||
9554                 error "$dir1 shouldn't have LOV EA"
9555
9556         # delete the default layout on root directory
9557         $LFS setstripe -d $MOUNT || error "delete root default layout failed"
9558
9559         local dir2=$MOUNT/$tdir-2
9560         mkdir $dir2 || error "mkdir $dir2 failed"
9561         ! getfattr -n trusted.lov $dir2 &> /dev/null ||
9562                 error "$dir2 shouldn't have LOV EA"
9563
9564         # set a new striping pattern on root directory
9565         local def_stripe_size=$($LFS getstripe -S $MOUNT)
9566         local new_def_stripe_size=$((def_stripe_size * 2))
9567         $LFS setstripe -S $new_def_stripe_size $MOUNT ||
9568                 error "set stripe size on $MOUNT failed"
9569
9570         # new file created in $dir2 should inherit the new stripe size from
9571         # the filesystem default
9572         local file2=$dir2/$tfile-2
9573         touch $file2 || error "touch $file2 failed"
9574
9575         local file2_stripe_size=$($LFS getstripe -S $file2)
9576         [[ $file2_stripe_size -eq $new_def_stripe_size ]] ||
9577         {
9578                 echo "file2_stripe_size: '$file2_stripe_size'"
9579                 echo "new_def_stripe_size: '$new_def_stripe_size'"
9580                 error "$file2 didn't inherit stripe size $new_def_stripe_size"
9581         }
9582
9583         local dir3=$MOUNT/$tdir-3
9584         mkdir $dir3 || error "mkdir $dir3 failed"
9585         # $dir3 shouldn't have LOV EA, but "lfs getstripe -d $dir3" should show
9586         # the root layout, which is the actual default layout that will be used
9587         # when new files are created in $dir3.
9588         local dir3_layout=$(get_layout_param $dir3)
9589         local root_dir_layout=$(get_layout_param $MOUNT)
9590         [[ "$dir3_layout" = "$root_dir_layout" ]] ||
9591         {
9592                 echo "dir3_layout: '$dir3_layout'"
9593                 echo "root_dir_layout: '$root_dir_layout'"
9594                 error "$dir3 should show the default layout from $MOUNT"
9595         }
9596
9597         # set OST pool on root directory
9598         local pool=$TESTNAME
9599         pool_add $pool || error "add $pool failed"
9600         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
9601                 error "add targets to $pool failed"
9602
9603         $LFS setstripe -p $pool $MOUNT ||
9604                 error "set OST pool on $MOUNT failed"
9605
9606         # new file created in $dir3 should inherit the pool from
9607         # the filesystem default
9608         local file3=$dir3/$tfile-3
9609         touch $file3 || error "touch $file3 failed"
9610
9611         local file3_pool=$($LFS getstripe -p $file3)
9612         [[ "$file3_pool" = "$pool" ]] ||
9613                 error "$file3 ('$file3_pool') didn't inherit OST pool '$pool'"
9614
9615         local dir4=$MOUNT/$tdir-4
9616         mkdir $dir4 || error "mkdir $dir4 failed"
9617         local dir4_layout=$(get_layout_param $dir4)
9618         root_dir_layout=$(get_layout_param $MOUNT)
9619         echo "$LFS getstripe -d $dir4"
9620         $LFS getstripe -d $dir4
9621         echo "$LFS getstripe -d $MOUNT"
9622         $LFS getstripe -d $MOUNT
9623         [[ "$dir4_layout" = "$root_dir_layout" ]] ||
9624         {
9625                 echo "dir4_layout: '$dir4_layout'"
9626                 echo "root_dir_layout: '$root_dir_layout'"
9627                 error "$dir4 should show the default layout from $MOUNT"
9628         }
9629
9630         # new file created in $dir4 should inherit the pool from
9631         # the filesystem default
9632         local file4=$dir4/$tfile-4
9633         touch $file4 || error "touch $file4 failed"
9634
9635         local file4_pool=$($LFS getstripe -p $file4)
9636         [[ "$file4_pool" = "$pool" ]] ||
9637                 error "$file4 ('$file4_pool') didn't inherit OST pool $pool"
9638
9639         # new subdirectory under non-root directory should inherit
9640         # the default layout from its parent directory
9641         $LFS setstripe -S $new_def_stripe_size -p $pool $dir4 ||
9642                 error "set directory layout on $dir4 failed"
9643
9644         local dir5=$dir4/$tdir-5
9645         mkdir $dir5 || error "mkdir $dir5 failed"
9646
9647         dir4_layout=$(get_layout_param $dir4)
9648         local dir5_layout=$(get_layout_param $dir5)
9649         [[ "$dir4_layout" = "$dir5_layout" ]] ||
9650         {
9651                 echo "dir4_layout: '$dir4_layout'"
9652                 echo "dir5_layout: '$dir5_layout'"
9653                 error "$dir5 should inherit the default layout from $dir4"
9654         }
9655
9656         # though subdir under ROOT doesn't inherit default layout, but
9657         # its sub dir/file should be created with default layout.
9658         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
9659         [[ $MDS1_VERSION -ge $(version_code 2.12.59) ]] ||
9660                 skip "Need MDS version at least 2.12.59"
9661
9662         local default_lmv_count=$($LFS getdirstripe -D -c $MOUNT)
9663         local default_lmv_index=$($LFS getdirstripe -D -i $MOUNT)
9664         local default_lmv_hash=$($LFS getdirstripe -D -H $MOUNT)
9665
9666         if [ $default_lmv_hash == "none" ]; then
9667                 stack_trap "$LFS setdirstripe -D -d $MOUNT" EXIT
9668         else
9669                 stack_trap "$LFS setdirstripe -D -i $default_lmv_index \
9670                         -c $default_lmv_count -H $default_lmv_hash $MOUNT" EXIT
9671         fi
9672
9673         $LFS setdirstripe -D -c 2 $MOUNT ||
9674                 error "setdirstripe -D -c 2 failed"
9675         mkdir $MOUNT/$tdir-6 || error "mkdir $tdir-6 failed"
9676         local lmv_count=$($LFS getdirstripe -c $MOUNT/$tdir-6)
9677         [ $lmv_count -eq 2 ] || error "$tdir-6 stripe count $lmv_count"
9678
9679         # $dir4 layout includes pool
9680         $LFS setstripe -S $((new_def_stripe_size * 2)) $dir4
9681         [[ "$pool" = $($LFS getstripe -p -d $dir4) ]] ||
9682                 error "pool lost on setstripe"
9683         $LFS setstripe -E -1 -S $new_def_stripe_size $dir4
9684         [[ "$pool" = $($LFS getstripe -p -d $dir4) ]] ||
9685                 error "pool lost on compound layout setstripe"
9686 }
9687 run_test 65n "don't inherit default layout from root for new subdirectories"
9688
9689 test_65o() {
9690         (( $MDS1_VERSION >= $(version_code 2.14.57) )) ||
9691                 skip "need MDS version at least 2.14.57"
9692
9693         # set OST pool on root directory
9694         local pool=$TESTNAME
9695
9696         pool_add $pool || error "add $pool failed"
9697         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
9698                 error "add targets to $pool failed"
9699
9700         local dir1=$MOUNT/$tdir
9701
9702         mkdir $dir1 || error "mkdir $dir1 failed"
9703
9704         # set a new striping pattern on root directory
9705         local def_stripe_size=$($LFS getstripe -S $MOUNT)
9706
9707         $LFS setstripe -p $pool $dir1 ||
9708                 error "set directory layout on $dir1 failed"
9709
9710         # $dir1 layout includes pool
9711         $LFS setstripe -S $((def_stripe_size * 2)) $dir1
9712         [[ "$pool" = $($LFS getstripe -p -d $dir1) ]] ||
9713                 error "pool lost on setstripe"
9714         $LFS setstripe -E 1M -L mdt -E -1 -c 1 $dir1
9715         $LFS getstripe $dir1
9716         [[ "$pool" = $($LFS getstripe -p -d $dir1) ]] ||
9717                 error "pool lost on compound layout setstripe"
9718
9719         $LFS setdirstripe -i 0 -c 2 $dir1/dir2 ||
9720                 error "setdirstripe failed on sub-dir with inherited pool"
9721         $LFS getstripe $dir1/dir2
9722         [[ "$pool" = $($LFS getstripe -p -d $dir1/dir2) ]] ||
9723                 error "pool lost on compound layout setdirstripe"
9724
9725         $LFS setstripe -E -1 -c 1 $dir1
9726         $LFS getstripe -d $dir1
9727         [[ "$pool" = $($LFS getstripe -p -d $dir1) ]] ||
9728                 error "pool lost on setstripe"
9729 }
9730 run_test 65o "pool inheritance for mdt component"
9731
9732 test_65p () { # LU-16152
9733         local src_dir=$DIR/$tdir/src_dir
9734         local dst_dir=$DIR/$tdir/dst_dir
9735         local yaml_file=$DIR/$tdir/layout.yaml
9736         local border
9737
9738         (( $CLIENT_VERSION >= $(version_code 2.15.51) )) ||
9739                 skip "Need at least version 2.15.51"
9740
9741         test_mkdir -p $src_dir
9742         $LFS setstripe -E 2048M -c 4 -E EOF -c 8 $src_dir ||
9743                 error "failed to setstripe"
9744         $LFS getstripe --yaml -d $src_dir > $yaml_file ||
9745                 error "failed to getstripe"
9746
9747         test_mkdir -p $dst_dir
9748         $LFS setstripe --yaml $yaml_file $dst_dir ||
9749                 error "failed to setstripe with yaml file"
9750         border=$($LFS getstripe -d $dst_dir |
9751                 awk '/lcme_extent.e_end:/ { print $2; exit; }') ||
9752                 error "failed to getstripe"
9753
9754         # 2048M is 0x80000000, or 2147483648
9755         (( $border == 2147483648 )) ||
9756                 error "failed to handle huge number in yaml layout"
9757 }
9758 run_test 65p "setstripe with yaml file and huge number"
9759
9760 # bug 2543 - update blocks count on client
9761 test_66() {
9762         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9763
9764         local COUNT=${COUNT:-8}
9765         dd if=/dev/zero of=$DIR/f66 bs=1k count=$COUNT
9766         sync; sync_all_data; sync; sync_all_data
9767         cancel_lru_locks osc
9768         local BLOCKS=$(ls -s --block-size=1k $DIR/f66 | awk '{ print $1 }')
9769         (( BLOCKS >= COUNT )) || error "$DIR/f66 blocks $BLOCKS < $COUNT"
9770 }
9771 run_test 66 "update inode blocks count on client ==============="
9772
9773 meminfo() {
9774         awk '($1 == "'$1':") { print $2 }' /proc/meminfo
9775 }
9776
9777 swap_used() {
9778         swapon -s | awk '($1 == "'$1'") { print $4 }'
9779 }
9780
9781 # bug5265, obdfilter oa2dentry return -ENOENT
9782 # #define OBD_FAIL_SRV_ENOENT 0x217
9783 test_69() {
9784         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9785         remote_ost_nodsh && skip "remote OST with nodsh"
9786
9787         f="$DIR/$tfile"
9788         $LFS setstripe -c 1 -i 0 $f
9789
9790         $DIRECTIO write ${f}.2 0 1 || error "directio write error"
9791
9792         do_facet ost1 lctl set_param fail_loc=0x217
9793         $TRUNCATE $f 1 # vmtruncate() will ignore truncate() error.
9794         $DIRECTIO write $f 0 2 && error "write succeeded, expect -ENOENT"
9795
9796         do_facet ost1 lctl set_param fail_loc=0
9797         $DIRECTIO write $f 0 2 || error "write error"
9798
9799         cancel_lru_locks osc
9800         $DIRECTIO read $f 0 1 || error "read error"
9801
9802         do_facet ost1 lctl set_param fail_loc=0x217
9803         $DIRECTIO read $f 1 1 && error "read succeeded, expect -ENOENT"
9804
9805         do_facet ost1 lctl set_param fail_loc=0
9806         rm -f $f
9807 }
9808 run_test 69 "verify oa2dentry return -ENOENT doesn't LBUG ======"
9809
9810 test_71() {
9811         test_mkdir $DIR/$tdir
9812         $LFS setdirstripe -D -c$MDSCOUNT $DIR/$tdir
9813         bash rundbench -C -D $DIR/$tdir 2 || error "dbench failed!"
9814 }
9815 run_test 71 "Running dbench on lustre (don't segment fault) ===="
9816
9817 test_72a() { # bug 5695 - Test that on 2.6 remove_suid works properly
9818         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9819         [ "$RUNAS_ID" = "$UID" ] &&
9820                 skip_env "RUNAS_ID = UID = $UID -- skipping"
9821         # Check that testing environment is properly set up. Skip if not
9822         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_GID $RUNAS ||
9823                 skip_env "User $RUNAS_ID does not exist - skipping"
9824
9825         touch $DIR/$tfile
9826         chmod 777 $DIR/$tfile
9827         chmod ug+s $DIR/$tfile
9828         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=512 count=1 ||
9829                 error "$RUNAS dd $DIR/$tfile failed"
9830         # See if we are still setuid/sgid
9831         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
9832                 error "S/gid is not dropped on write"
9833         # Now test that MDS is updated too
9834         cancel_lru_locks mdc
9835         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
9836                 error "S/gid is not dropped on MDS"
9837         rm -f $DIR/$tfile
9838 }
9839 run_test 72a "Test that remove suid works properly (bug5695) ===="
9840
9841 test_72b() { # bug 24226 -- keep mode setting when size is not changing
9842         local perm
9843
9844         [ "$RUNAS_ID" = "$UID" ] &&
9845                 skip_env "RUNAS_ID = UID = $UID -- skipping"
9846         [ "$RUNAS_ID" -eq 0 ] &&
9847                 skip_env "RUNAS_ID = 0 -- skipping"
9848         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9849         # Check that testing environment is properly set up. Skip if not
9850         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_ID $RUNAS ||
9851                 skip_env "User $RUNAS_ID does not exist - skipping"
9852
9853         touch $DIR/${tfile}-f{g,u}
9854         test_mkdir $DIR/${tfile}-dg
9855         test_mkdir $DIR/${tfile}-du
9856         chmod 770 $DIR/${tfile}-{f,d}{g,u}
9857         chmod g+s $DIR/${tfile}-{f,d}g
9858         chmod u+s $DIR/${tfile}-{f,d}u
9859         for perm in 777 2777 4777; do
9860                 $RUNAS chmod $perm $DIR/${tfile}-fg && error "S/gid file allowed improper chmod to $perm"
9861                 $RUNAS chmod $perm $DIR/${tfile}-fu && error "S/uid file allowed improper chmod to $perm"
9862                 $RUNAS chmod $perm $DIR/${tfile}-dg && error "S/gid dir allowed improper chmod to $perm"
9863                 $RUNAS chmod $perm $DIR/${tfile}-du && error "S/uid dir allowed improper chmod to $perm"
9864         done
9865         true
9866 }
9867 run_test 72b "Test that we keep mode setting if without file data changed (bug 24226)"
9868
9869 # bug 3462 - multiple simultaneous MDC requests
9870 test_73() {
9871         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9872
9873         test_mkdir $DIR/d73-1
9874         test_mkdir $DIR/d73-2
9875         multiop_bg_pause $DIR/d73-1/f73-1 O_c || return 1
9876         pid1=$!
9877
9878         lctl set_param fail_loc=0x80000129
9879         $MULTIOP $DIR/d73-1/f73-2 Oc &
9880         sleep 1
9881         lctl set_param fail_loc=0
9882
9883         $MULTIOP $DIR/d73-2/f73-3 Oc &
9884         pid3=$!
9885
9886         kill -USR1 $pid1
9887         wait $pid1 || return 1
9888
9889         sleep 25
9890
9891         $CHECKSTAT -t file $DIR/d73-1/f73-1 || return 4
9892         $CHECKSTAT -t file $DIR/d73-1/f73-2 || return 5
9893         $CHECKSTAT -t file $DIR/d73-2/f73-3 || return 6
9894
9895         rm -rf $DIR/d73-*
9896 }
9897 run_test 73 "multiple MDC requests (should not deadlock)"
9898
9899 test_74a() { # bug 6149, 6184
9900         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9901
9902         touch $DIR/f74a
9903         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
9904         #
9905         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
9906         # will spin in a tight reconnection loop
9907         $LCTL set_param fail_loc=0x8000030e
9908         # get any lock that won't be difficult - lookup works.
9909         ls $DIR/f74a
9910         $LCTL set_param fail_loc=0
9911         rm -f $DIR/f74a
9912         true
9913 }
9914 run_test 74a "ldlm_enqueue freed-export error path, ls (shouldn't LBUG)"
9915
9916 test_74b() { # bug 13310
9917         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9918
9919         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
9920         #
9921         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
9922         # will spin in a tight reconnection loop
9923         $LCTL set_param fail_loc=0x8000030e
9924         # get a "difficult" lock
9925         touch $DIR/f74b
9926         $LCTL set_param fail_loc=0
9927         rm -f $DIR/f74b
9928         true
9929 }
9930 run_test 74b "ldlm_enqueue freed-export error path, touch (shouldn't LBUG)"
9931
9932 test_74c() {
9933         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9934
9935         #define OBD_FAIL_LDLM_NEW_LOCK
9936         $LCTL set_param fail_loc=0x319
9937         touch $DIR/$tfile && error "touch successful"
9938         $LCTL set_param fail_loc=0
9939         true
9940 }
9941 run_test 74c "ldlm_lock_create error path, (shouldn't LBUG)"
9942
9943 slab_lic=/sys/kernel/slab/lustre_inode_cache
9944 num_objects() {
9945         [ -f $slab_lic/shrink ] && echo 1 > $slab_lic/shrink
9946         [ -f $slab_lic/objects ] && awk '{ print $1 }' $slab_lic/objects ||
9947                 awk '/lustre_inode_cache/ { print $2; exit }' /proc/slabinfo
9948 }
9949
9950 test_76a() { # Now for b=20433, added originally in b=1443
9951         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9952
9953         cancel_lru_locks osc
9954         # there may be some slab objects cached per core
9955         local cpus=$(getconf _NPROCESSORS_ONLN 2>/dev/null)
9956         local before=$(num_objects)
9957         local count=$((512 * cpus))
9958         [ "$SLOW" = "no" ] && count=$((128 * cpus))
9959         local margin=$((count / 10))
9960         if [[ -f $slab_lic/aliases ]]; then
9961                 local aliases=$(cat $slab_lic/aliases)
9962                 (( aliases > 0 )) && margin=$((margin * aliases))
9963         fi
9964
9965         echo "before slab objects: $before"
9966         for i in $(seq $count); do
9967                 touch $DIR/$tfile
9968                 rm -f $DIR/$tfile
9969         done
9970         cancel_lru_locks osc
9971         local after=$(num_objects)
9972         echo "created: $count, after slab objects: $after"
9973         # shared slab counts are not very accurate, allow significant margin
9974         # the main goal is that the cache growth is not permanently > $count
9975         while (( after > before + margin )); do
9976                 sleep 1
9977                 after=$(num_objects)
9978                 wait=$((wait + 1))
9979                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
9980                 if (( wait > 60 )); then
9981                         error "inode slab grew from $before+$margin to $after"
9982                 fi
9983         done
9984 }
9985 run_test 76a "confirm clients recycle inodes properly ===="
9986
9987 test_76b() {
9988         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9989         [ $CLIENT_VERSION -ge $(version_code 2.13.55) ] || skip "not supported"
9990
9991         local count=512
9992         local before=$(num_objects)
9993
9994         for i in $(seq $count); do
9995                 mkdir $DIR/$tdir
9996                 rmdir $DIR/$tdir
9997         done
9998
9999         local after=$(num_objects)
10000         local wait=0
10001
10002         while (( after > before )); do
10003                 sleep 1
10004                 after=$(num_objects)
10005                 wait=$((wait + 1))
10006                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
10007                 if (( wait > 60 )); then
10008                         error "inode slab grew from $before to $after"
10009                 fi
10010         done
10011
10012         echo "slab objects before: $before, after: $after"
10013 }
10014 run_test 76b "confirm clients recycle directory inodes properly ===="
10015
10016 export ORIG_CSUM=""
10017 set_checksums()
10018 {
10019         # Note: in sptlrpc modes which enable its own bulk checksum, the
10020         # original crc32_le bulk checksum will be automatically disabled,
10021         # and the OBD_FAIL_OSC_CHECKSUM_SEND/OBD_FAIL_OSC_CHECKSUM_RECEIVE
10022         # will be checked by sptlrpc code against sptlrpc bulk checksum.
10023         # In this case set_checksums() will not be no-op, because sptlrpc
10024         # bulk checksum will be enabled all through the test.
10025
10026         [ "$ORIG_CSUM" ] || ORIG_CSUM=`lctl get_param -n osc.*.checksums | head -n1`
10027         lctl set_param -n osc.*.checksums $1
10028         return 0
10029 }
10030
10031 export ORIG_CSUM_TYPE="`lctl get_param -n osc.*osc-[^mM]*.checksum_type |
10032                         sed 's/.*\[\(.*\)\].*/\1/g' | head -n1`"
10033 CKSUM_TYPES=${CKSUM_TYPES:-$(lctl get_param -n osc.*osc-[^mM]*.checksum_type |
10034                              tr -d [] | head -n1)}
10035 set_checksum_type()
10036 {
10037         lctl set_param -n osc.*osc-[^mM]*.checksum_type $1
10038         rc=$?
10039         log "set checksum type to $1, rc = $rc"
10040         return $rc
10041 }
10042
10043 get_osc_checksum_type()
10044 {
10045         # arugment 1: OST name, like OST0000
10046         ost=$1
10047         checksum_type=$(lctl get_param -n osc.*${ost}-osc-[^mM]*.checksum_type |
10048                         sed 's/.*\[\(.*\)\].*/\1/g')
10049         rc=$?
10050         [ $rc -ne 0 ] && error "failed to get checksum type of $ost, rc = $rc, output = $checksum_type"
10051         echo $checksum_type
10052 }
10053
10054 F77_TMP=$TMP/f77-temp
10055 F77SZ=8
10056 setup_f77() {
10057         dd if=/dev/urandom of=$F77_TMP bs=1M count=$F77SZ || \
10058                 error "error writing to $F77_TMP"
10059 }
10060
10061 test_77a() { # bug 10889
10062         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10063         $GSS && skip_env "could not run with gss"
10064
10065         [ ! -f $F77_TMP ] && setup_f77
10066         set_checksums 1
10067         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ || error "dd error"
10068         set_checksums 0
10069         rm -f $DIR/$tfile
10070 }
10071 run_test 77a "normal checksum read/write operation"
10072
10073 test_77b() { # bug 10889
10074         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10075         $GSS && skip_env "could not run with gss"
10076
10077         [ ! -f $F77_TMP ] && setup_f77
10078         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
10079         $LCTL set_param fail_loc=0x80000409
10080         set_checksums 1
10081
10082         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
10083                 error "dd error: $?"
10084         $LCTL set_param fail_loc=0
10085
10086         for algo in $CKSUM_TYPES; do
10087                 cancel_lru_locks osc
10088                 set_checksum_type $algo
10089                 #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
10090                 $LCTL set_param fail_loc=0x80000408
10091                 cmp $F77_TMP $DIR/$tfile || error "file compare failed"
10092                 $LCTL set_param fail_loc=0
10093         done
10094         set_checksums 0
10095         set_checksum_type $ORIG_CSUM_TYPE
10096         rm -f $DIR/$tfile
10097 }
10098 run_test 77b "checksum error on client write, read"
10099
10100 cleanup_77c() {
10101         trap 0
10102         set_checksums 0
10103         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=0
10104         $check_ost &&
10105                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=0
10106         [ -n "$osc_file_prefix" ] && rm -f ${osc_file_prefix}*
10107         $check_ost && [ -n "$ost_file_prefix" ] &&
10108                 do_facet ost1 rm -f ${ost_file_prefix}\*
10109 }
10110
10111 test_77c() {
10112         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10113         $GSS && skip_env "could not run with gss"
10114         remote_ost_nodsh && skip "remote OST with nodsh"
10115
10116         local bad1
10117         local osc_file_prefix
10118         local osc_file
10119         local check_ost=false
10120         local ost_file_prefix
10121         local ost_file
10122         local orig_cksum
10123         local dump_cksum
10124         local fid
10125
10126         # ensure corruption will occur on first OSS/OST
10127         $LFS setstripe -i 0 $DIR/$tfile
10128
10129         [ ! -f $F77_TMP ] && setup_f77
10130         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
10131                 error "dd write error: $?"
10132         fid=$($LFS path2fid $DIR/$tfile)
10133
10134         if [ $OST1_VERSION -ge $(version_code 2.9.57) ]
10135         then
10136                 check_ost=true
10137                 ost_file_prefix=$(do_facet ost1 $LCTL get_param -n debug_path)
10138                 ost_file_prefix=${ost_file_prefix}-checksum_dump-ost-\\${fid}
10139         else
10140                 echo "OSS do not support bulk pages dump upon error"
10141         fi
10142
10143         osc_file_prefix=$($LCTL get_param -n debug_path)
10144         osc_file_prefix=${osc_file_prefix}-checksum_dump-osc-\\${fid}
10145
10146         trap cleanup_77c EXIT
10147
10148         set_checksums 1
10149         # enable bulk pages dump upon error on Client
10150         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=1
10151         # enable bulk pages dump upon error on OSS
10152         $check_ost &&
10153                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=1
10154
10155         # flush Client cache to allow next read to reach OSS
10156         cancel_lru_locks osc
10157
10158         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE       0x408
10159         $LCTL set_param fail_loc=0x80000408
10160         dd if=$DIR/$tfile of=/dev/null bs=1M || error "dd read error: $?"
10161         $LCTL set_param fail_loc=0
10162
10163         rm -f $DIR/$tfile
10164
10165         # check cksum dump on Client
10166         osc_file=$(ls ${osc_file_prefix}*)
10167         [ -n "$osc_file" ] || error "no checksum dump file on Client"
10168         # OBD_FAIL_OSC_CHECKSUM_RECEIVE corrupts with "bad1" at start of file
10169         bad1=$(dd if=$osc_file bs=1 count=4 2>/dev/null) || error "dd error: $?"
10170         [ $bad1 == "bad1" ] || error "unexpected corrupt pattern"
10171         orig_cksum=$(dd if=$F77_TMP bs=1 skip=4 count=1048572 2>/dev/null |
10172                      cksum)
10173         dump_cksum=$(dd if=$osc_file bs=1 skip=4 2>/dev/null | cksum)
10174         [[ "$orig_cksum" == "$dump_cksum" ]] ||
10175                 error "dump content does not match on Client"
10176
10177         $check_ost || skip "No need to check cksum dump on OSS"
10178
10179         # check cksum dump on OSS
10180         ost_file=$(do_facet ost1 ls ${ost_file_prefix}\*)
10181         [ -n "$ost_file" ] || error "no checksum dump file on OSS"
10182         orig_cksum=$(dd if=$F77_TMP bs=1048576 count=1 2>/dev/null | cksum)
10183         dump_cksum=$(do_facet ost1 dd if=$ost_file 2>/dev/null \| cksum)
10184         [[ "$orig_cksum" == "$dump_cksum" ]] ||
10185                 error "dump content does not match on OSS"
10186
10187         cleanup_77c
10188 }
10189 run_test 77c "checksum error on client read with debug"
10190
10191 test_77d() { # bug 10889
10192         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10193         $GSS && skip_env "could not run with gss"
10194
10195         stack_trap "rm -f $DIR/$tfile"
10196         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
10197         $LCTL set_param fail_loc=0x80000409
10198         set_checksums 1
10199         $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
10200                 error "direct write: rc=$?"
10201         $LCTL set_param fail_loc=0
10202         set_checksums 0
10203
10204         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
10205         $LCTL set_param fail_loc=0x80000408
10206         set_checksums 1
10207         cancel_lru_locks osc
10208         $DIRECTIO read $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
10209                 error "direct read: rc=$?"
10210         $LCTL set_param fail_loc=0
10211         set_checksums 0
10212 }
10213 run_test 77d "checksum error on OST direct write, read"
10214
10215 test_77f() { # bug 10889
10216         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10217         $GSS && skip_env "could not run with gss"
10218
10219         set_checksums 1
10220         stack_trap "rm -f $DIR/$tfile"
10221         for algo in $CKSUM_TYPES; do
10222                 cancel_lru_locks osc
10223                 set_checksum_type $algo
10224                 #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
10225                 $LCTL set_param fail_loc=0x409
10226                 $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) &&
10227                         error "direct write succeeded"
10228                 $LCTL set_param fail_loc=0
10229         done
10230         set_checksum_type $ORIG_CSUM_TYPE
10231         set_checksums 0
10232 }
10233 run_test 77f "repeat checksum error on write (expect error)"
10234
10235 test_77g() { # bug 10889
10236         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10237         $GSS && skip_env "could not run with gss"
10238         remote_ost_nodsh && skip "remote OST with nodsh"
10239
10240         [ ! -f $F77_TMP ] && setup_f77
10241
10242         local file=$DIR/$tfile
10243         stack_trap "rm -f $file" EXIT
10244
10245         $LFS setstripe -c 1 -i 0 $file
10246         #define OBD_FAIL_OST_CHECKSUM_RECEIVE       0x21a
10247         do_facet ost1 lctl set_param fail_loc=0x8000021a
10248         set_checksums 1
10249         dd if=$F77_TMP of=$file bs=1M count=$F77SZ ||
10250                 error "write error: rc=$?"
10251         do_facet ost1 lctl set_param fail_loc=0
10252         set_checksums 0
10253
10254         cancel_lru_locks osc
10255         #define OBD_FAIL_OST_CHECKSUM_SEND          0x21b
10256         do_facet ost1 lctl set_param fail_loc=0x8000021b
10257         set_checksums 1
10258         cmp $F77_TMP $file || error "file compare failed"
10259         do_facet ost1 lctl set_param fail_loc=0
10260         set_checksums 0
10261 }
10262 run_test 77g "checksum error on OST write, read"
10263
10264 test_77k() { # LU-10906
10265         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10266         $GSS && skip_env "could not run with gss"
10267
10268         local cksum_param="osc.$FSNAME*.checksums"
10269         local get_checksum="$LCTL get_param -n $cksum_param | head -n1"
10270         local checksum
10271         local i
10272
10273         [ "$ORIG_CSUM" ] || ORIG_CSUM=$(eval $get_checksum)
10274         stack_trap "wait_update $HOSTNAME '$get_checksum' $ORIG_CSUM || true"
10275         stack_trap "do_facet mgs $LCTL set_param -P $cksum_param=$ORIG_CSUM"
10276
10277         for i in 0 1; do
10278                 do_facet mgs $LCTL set_param -P $cksum_param=$i ||
10279                         error "failed to set checksum=$i on MGS"
10280                 wait_update $HOSTNAME "$get_checksum" $i
10281                 #remount
10282                 echo "remount client, checksum should be $i"
10283                 remount_client $MOUNT || error "failed to remount client"
10284                 checksum=$(eval $get_checksum)
10285                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
10286         done
10287         # remove persistent param to avoid races with checksum mountopt below
10288         do_facet mgs $LCTL set_param -P -d $cksum_param ||
10289                 error "failed to delete checksum on MGS"
10290
10291         for opt in "checksum" "nochecksum"; do
10292                 #remount with mount option
10293                 echo "remount client with option $opt, checksum should be $i"
10294                 umount_client $MOUNT || error "failed to umount client"
10295                 mount_client $MOUNT "$MOUNT_OPTS,$opt" ||
10296                         error "failed to mount client with option '$opt'"
10297                 checksum=$(eval $get_checksum)
10298                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
10299                 i=$((i - 1))
10300         done
10301
10302         remount_client $MOUNT || error "failed to remount client"
10303 }
10304 run_test 77k "enable/disable checksum correctly"
10305
10306 test_77l() {
10307         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10308         $GSS && skip_env "could not run with gss"
10309
10310         set_checksums 1
10311         stack_trap "set_checksums $ORIG_CSUM" EXIT
10312         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
10313
10314         set_checksum_type invalid && error "unexpected success of invalid checksum type"
10315
10316         $LFS setstripe -c 1 -i 0 $DIR/$tfile
10317         for algo in $CKSUM_TYPES; do
10318                 set_checksum_type $algo || error "fail to set checksum type $algo"
10319                 osc_algo=$(get_osc_checksum_type OST0000)
10320                 [ "$osc_algo" != "$algo" ] && error "checksum type is $osc_algo after setting it to $algo"
10321
10322                 # no locks, no reqs to let the connection idle
10323                 cancel_lru_locks osc
10324                 lru_resize_disable osc
10325                 wait_osc_import_state client ost1 IDLE
10326
10327                 # ensure ost1 is connected
10328                 stat $DIR/$tfile >/dev/null || error "can't stat"
10329                 wait_osc_import_state client ost1 FULL
10330
10331                 osc_algo=$(get_osc_checksum_type OST0000)
10332                 [ "$osc_algo" != "$algo" ] && error "checksum type changed from $algo to $osc_algo after reconnection"
10333         done
10334         return 0
10335 }
10336 run_test 77l "preferred checksum type is remembered after reconnected"
10337
10338 [ "$ORIG_CSUM" ] && set_checksums $ORIG_CSUM || true
10339 rm -f $F77_TMP
10340 unset F77_TMP
10341
10342 test_77m() {
10343         (( $CLIENT_VERSION >= $(version_code 2.14.52) )) ||
10344                 skip "Need at least version 2.14.52"
10345         local param=checksum_speed
10346
10347         $LCTL get_param $param || error "reading $param failed"
10348
10349         csum_speeds=$($LCTL get_param -n $param)
10350
10351         [[ "$csum_speeds" =~ "adler32" && "$csum_speeds" =~ "crc32" ]] ||
10352                 error "known checksum types are missing"
10353 }
10354 run_test 77m "Verify checksum_speed is correctly read"
10355
10356 check_filefrag_77n() {
10357         local nr_ext=0
10358         local starts=()
10359         local ends=()
10360
10361         while read extidx a b start end rest; do
10362                 if [[ "${extidx}" =~ ^[0-9]+: ]]; then
10363                         nr_ext=$(( $nr_ext + 1 ))
10364                         starts+=( ${start%..} )
10365                         ends+=( ${end%:} )
10366                 fi
10367         done < <( filefrag -sv $1 )
10368
10369         [[ $nr_ext -eq 2 ]] && [[ "${starts[-1]}" == $(( ${ends[0]} + 1 )) ]] && return 0
10370         return 1
10371 }
10372
10373 test_77n() {
10374         [[ "$CKSUM_TYPES" =~ t10 ]] || skip "no T10 checksum support on osc"
10375
10376         touch $DIR/$tfile
10377         $TRUNCATE $DIR/$tfile 0
10378         dd if=/dev/urandom of=$DIR/$tfile bs=4k conv=notrunc count=1 seek=0
10379         dd if=/dev/urandom of=$DIR/$tfile bs=4k conv=notrunc count=1 seek=2
10380         check_filefrag_77n $DIR/$tfile ||
10381                 skip "$tfile blocks not contiguous around hole"
10382
10383         set_checksums 1
10384         stack_trap "set_checksums $ORIG_CSUM" EXIT
10385         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
10386         stack_trap "rm -f $DIR/$tfile"
10387
10388         for algo in $CKSUM_TYPES; do
10389                 if [[ "$algo" =~ ^t10 ]]; then
10390                         set_checksum_type $algo ||
10391                                 error "fail to set checksum type $algo"
10392                         dd if=$DIR/$tfile of=/dev/null bs=12k count=1 iflag=direct ||
10393                                 error "fail to read $tfile with $algo"
10394                 fi
10395         done
10396         rm -f $DIR/$tfile
10397         return 0
10398 }
10399 run_test 77n "Verify read from a hole inside contiguous blocks with T10PI"
10400
10401 test_77o() {
10402         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
10403                 skip "Need MDS version at least 2.14.55"
10404         (( $OST1_VERSION >= $(version_code 2.14.55) )) ||
10405                 skip "Need OST version at least 2.14.55"
10406         local ofd=obdfilter
10407         local mdt=mdt
10408
10409         # print OST checksum_type
10410         echo "$ofd.$FSNAME-*.checksum_type:"
10411         do_nodes $(comma_list $(osts_nodes)) \
10412                 $LCTL get_param -n $ofd.$FSNAME-*.checksum_type
10413
10414         # print MDT checksum_type
10415         echo "$mdt.$FSNAME-*.checksum_type:"
10416         do_nodes $(comma_list $(mdts_nodes)) \
10417                 $LCTL get_param -n $mdt.$FSNAME-*.checksum_type
10418
10419         local o_count=$(do_nodes $(comma_list $(osts_nodes)) \
10420                    $LCTL get_param -n $ofd.$FSNAME-*.checksum_type | wc -l)
10421
10422         (( $o_count == $OSTCOUNT )) ||
10423                 error "found $o_count checksums, not \$MDSCOUNT=$OSTCOUNT"
10424
10425         local m_count=$(do_nodes $(comma_list $(mdts_nodes)) \
10426                    $LCTL get_param -n $mdt.$FSNAME-*.checksum_type | wc -l)
10427
10428         (( $m_count == $MDSCOUNT )) ||
10429                 error "found $m_count checksums, not \$MDSCOUNT=$MDSCOUNT"
10430 }
10431 run_test 77o "Verify checksum_type for server (mdt and ofd(obdfilter))"
10432
10433 cleanup_test_78() {
10434         trap 0
10435         rm -f $DIR/$tfile
10436 }
10437
10438 test_78() { # bug 10901
10439         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10440         remote_ost || skip_env "local OST"
10441
10442         NSEQ=5
10443         F78SIZE=$(($(awk '/MemFree:/ { print $2 }' /proc/meminfo) / 1024))
10444         echo "MemFree: $F78SIZE, Max file size: $MAXFREE"
10445         MEMTOTAL=$(($(awk '/MemTotal:/ { print $2 }' /proc/meminfo) / 1024))
10446         echo "MemTotal: $MEMTOTAL"
10447
10448         # reserve 256MB of memory for the kernel and other running processes,
10449         # and then take 1/2 of the remaining memory for the read/write buffers.
10450         if [ $MEMTOTAL -gt 512 ] ;then
10451                 MEMTOTAL=$(((MEMTOTAL - 256 ) / 2))
10452         else
10453                 # for those poor memory-starved high-end clusters...
10454                 MEMTOTAL=$((MEMTOTAL / 2))
10455         fi
10456         echo "Mem to use for directio: $MEMTOTAL"
10457
10458         [[ $F78SIZE -gt $MEMTOTAL ]] && F78SIZE=$MEMTOTAL
10459         [[ $F78SIZE -gt 512 ]] && F78SIZE=512
10460         [[ $F78SIZE -gt $((MAXFREE / 1024)) ]] && F78SIZE=$((MAXFREE / 1024))
10461         SMALLESTOST=$($LFS df $DIR | grep OST | awk '{ print $4 }' | sort -n |
10462                 head -n1)
10463         echo "Smallest OST: $SMALLESTOST"
10464         [[ $SMALLESTOST -lt 10240 ]] &&
10465                 skip "too small OSTSIZE, useless to run large O_DIRECT test"
10466
10467         trap cleanup_test_78 EXIT
10468
10469         [[ $F78SIZE -gt $((SMALLESTOST * $OSTCOUNT / 1024 - 80)) ]] &&
10470                 F78SIZE=$((SMALLESTOST * $OSTCOUNT / 1024 - 80))
10471
10472         [ "$SLOW" = "no" ] && NSEQ=1 && [ $F78SIZE -gt 32 ] && F78SIZE=32
10473         echo "File size: $F78SIZE"
10474         $LFS setstripe -c $OSTCOUNT $DIR/$tfile || error "setstripe failed"
10475         for i in $(seq 1 $NSEQ); do
10476                 FSIZE=$(($F78SIZE / ($NSEQ - $i + 1)))
10477                 echo directIO rdwr round $i of $NSEQ
10478                 $DIRECTIO rdwr $DIR/$tfile 0 $FSIZE 1048576||error "rdwr failed"
10479         done
10480
10481         cleanup_test_78
10482 }
10483 run_test 78 "handle large O_DIRECT writes correctly ============"
10484
10485 test_79() { # bug 12743
10486         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10487
10488         wait_delete_completed
10489
10490         BKTOTAL=$(calc_osc_kbytes kbytestotal)
10491         BKFREE=$(calc_osc_kbytes kbytesfree)
10492         BKAVAIL=$(calc_osc_kbytes kbytesavail)
10493
10494         STRING=`df -P $MOUNT | tail -n 1 | awk '{print $2","$3","$4}'`
10495         DFTOTAL=`echo $STRING | cut -d, -f1`
10496         DFUSED=`echo $STRING  | cut -d, -f2`
10497         DFAVAIL=`echo $STRING | cut -d, -f3`
10498         DFFREE=$(($DFTOTAL - $DFUSED))
10499
10500         ALLOWANCE=$((64 * $OSTCOUNT))
10501
10502         if [ $DFTOTAL -lt $(($BKTOTAL - $ALLOWANCE)) ] ||
10503            [ $DFTOTAL -gt $(($BKTOTAL + $ALLOWANCE)) ] ; then
10504                 error "df total($DFTOTAL) mismatch OST total($BKTOTAL)"
10505         fi
10506         if [ $DFFREE -lt $(($BKFREE - $ALLOWANCE)) ] ||
10507            [ $DFFREE -gt $(($BKFREE + $ALLOWANCE)) ] ; then
10508                 error "df free($DFFREE) mismatch OST free($BKFREE)"
10509         fi
10510         if [ $DFAVAIL -lt $(($BKAVAIL - $ALLOWANCE)) ] ||
10511            [ $DFAVAIL -gt $(($BKAVAIL + $ALLOWANCE)) ] ; then
10512                 error "df avail($DFAVAIL) mismatch OST avail($BKAVAIL)"
10513         fi
10514 }
10515 run_test 79 "df report consistency check ======================="
10516
10517 test_80() { # bug 10718
10518         remote_ost_nodsh && skip "remote OST with nodsh"
10519         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10520
10521         # relax strong synchronous semantics for slow backends like ZFS
10522         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
10523                 local soc="obdfilter.*.sync_lock_cancel"
10524                 local save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
10525
10526                 # "sync_on_lock_cancel" was broken by v2_11_55_0-26-g7059644e9a
10527                 if [ -z "$save" ]; then
10528                         soc="obdfilter.*.sync_on_lock_cancel"
10529                         save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
10530                 fi
10531
10532                 if [ "$save" != "never" ]; then
10533                         local hosts=$(comma_list $(osts_nodes))
10534
10535                         do_nodes $hosts $LCTL set_param $soc=never
10536                         stack_trap "do_nodes $hosts $LCTL set_param $soc=$save"
10537                 fi
10538         fi
10539
10540         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1M
10541         sync; sleep 1; sync
10542         local before=$(date +%s)
10543         cancel_lru_locks osc
10544         local after=$(date +%s)
10545         local diff=$((after - before))
10546         [ $diff -le 1 ] || error "elapsed for 1M@1T = $diff"
10547
10548         rm -f $DIR/$tfile
10549 }
10550 run_test 80 "Page eviction is equally fast at high offsets too"
10551
10552 test_81a() { # LU-456
10553         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10554         remote_ost_nodsh && skip "remote OST with nodsh"
10555
10556         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
10557         # MUST OR with the OBD_FAIL_ONCE (0x80000000)
10558         do_facet ost1 lctl set_param fail_loc=0x80000228
10559
10560         # write should trigger a retry and success
10561         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10562         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10563         RC=$?
10564         if [ $RC -ne 0 ] ; then
10565                 error "write should success, but failed for $RC"
10566         fi
10567 }
10568 run_test 81a "OST should retry write when get -ENOSPC ==============="
10569
10570 test_81b() { # LU-456
10571         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10572         remote_ost_nodsh && skip "remote OST with nodsh"
10573
10574         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
10575         # Don't OR with the OBD_FAIL_ONCE (0x80000000)
10576         do_facet ost1 lctl set_param fail_loc=0x228
10577
10578         # write should retry several times and return -ENOSPC finally
10579         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10580         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10581         RC=$?
10582         ENOSPC=28
10583         if [ $RC -ne $ENOSPC ] ; then
10584                 error "dd should fail for -ENOSPC, but succeed."
10585         fi
10586 }
10587 run_test 81b "OST should return -ENOSPC when retry still fails ======="
10588
10589 test_99() {
10590         [ -z "$(which cvs 2>/dev/null)" ] && skip_env "could not find cvs"
10591
10592         test_mkdir $DIR/$tdir.cvsroot
10593         chown $RUNAS_ID $DIR/$tdir.cvsroot
10594
10595         cd $TMP
10596         $RUNAS cvs -d $DIR/$tdir.cvsroot init || error "cvs init failed"
10597
10598         cd /etc/init.d
10599         # some versions of cvs import exit(1) when asked to import links or
10600         # files they can't read.  ignore those files.
10601         local toignore=$(find . -type l -printf '-I %f\n' -o \
10602                          ! -perm /4 -printf '-I %f\n')
10603         $RUNAS cvs -d $DIR/$tdir.cvsroot import -m "nomesg" $toignore \
10604                 $tdir.reposname vtag rtag
10605
10606         cd $DIR
10607         test_mkdir $DIR/$tdir.reposname
10608         chown $RUNAS_ID $DIR/$tdir.reposname
10609         $RUNAS cvs -d $DIR/$tdir.cvsroot co $tdir.reposname
10610
10611         cd $DIR/$tdir.reposname
10612         $RUNAS touch foo99
10613         $RUNAS cvs add -m 'addmsg' foo99
10614         $RUNAS cvs update
10615         $RUNAS cvs commit -m 'nomsg' foo99
10616         rm -fr $DIR/$tdir.cvsroot
10617 }
10618 run_test 99 "cvs strange file/directory operations"
10619
10620 test_100() {
10621         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10622         [[ "$NETTYPE" =~ tcp ]] ||
10623                 skip_env "TCP secure port test, not useful for NETTYPE=$NETTYPE"
10624         remote_ost_nodsh && skip "remote OST with nodsh"
10625         remote_mds_nodsh && skip "remote MDS with nodsh"
10626         remote_servers ||
10627                 skip "useless for local single node setup"
10628
10629         netstat -tna | ( rc=1; while read PROT SND RCV LOCAL REMOTE STAT; do
10630                 [ "$PROT" != "tcp" ] && continue
10631                 RPORT=$(echo $REMOTE | cut -d: -f2)
10632                 [ "$RPORT" != "$ACCEPTOR_PORT" ] && continue
10633
10634                 rc=0
10635                 LPORT=`echo $LOCAL | cut -d: -f2`
10636                 if [ $LPORT -ge 1024 ]; then
10637                         echo "bad: $PROT $SND $RCV $LOCAL $REMOTE $STAT"
10638                         netstat -tna
10639                         error_exit "local: $LPORT > 1024, remote: $RPORT"
10640                 fi
10641         done
10642         [ "$rc" = 0 ] || error_exit "privileged port not found" )
10643 }
10644 run_test 100 "check local port using privileged port ==========="
10645
10646 function get_named_value()
10647 {
10648     local tag=$1
10649
10650     grep -w "$tag" | sed "s/^$tag  *\([0-9]*\)  *.*/\1/"
10651 }
10652
10653 export CACHE_MAX=$($LCTL get_param -n llite.*.max_cached_mb |
10654                    awk '/^max_cached_mb/ { print $2 }')
10655
10656 cleanup_101a() {
10657         $LCTL set_param -n llite.*.max_cached_mb $CACHE_MAX
10658         trap 0
10659 }
10660
10661 test_101a() {
10662         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10663
10664         local s
10665         local discard
10666         local nreads=10000
10667         local cache_limit=32
10668
10669         $LCTL set_param -n osc.*-osc*.rpc_stats=0
10670         trap cleanup_101a EXIT
10671         $LCTL set_param -n llite.*.read_ahead_stats=0
10672         $LCTL set_param -n llite.*.max_cached_mb=$cache_limit
10673
10674         #
10675         # randomly read 10000 of 64K chunks from file 3x 32MB in size
10676         #
10677         echo "nreads: $nreads file size: $((cache_limit * 3))MB"
10678         $READS -f $DIR/$tfile -s$((cache_limit * 3192 * 1024)) -b65536 -C -n$nreads -t 180
10679
10680         discard=0
10681         for s in $($LCTL get_param -n llite.*.read_ahead_stats |
10682                    get_named_value 'read.but.discarded'); do
10683                         discard=$(($discard + $s))
10684         done
10685         cleanup_101a
10686
10687         $LCTL get_param osc.*-osc*.rpc_stats
10688         $LCTL get_param llite.*.read_ahead_stats
10689
10690         # Discard is generally zero, but sometimes a few random reads line up
10691         # and trigger larger readahead, which is wasted & leads to discards.
10692         if [[ $(($discard)) -gt $nreads ]]; then
10693                 error "too many ($discard) discarded pages"
10694         fi
10695         rm -f $DIR/$tfile || true
10696 }
10697 run_test 101a "check read-ahead for random reads"
10698
10699 setup_test101bc() {
10700         test_mkdir $DIR/$tdir
10701         local ssize=$1
10702         local FILE_LENGTH=$2
10703         STRIPE_OFFSET=0
10704
10705         local FILE_SIZE_MB=$((FILE_LENGTH / ssize))
10706
10707         local list=$(comma_list $(osts_nodes))
10708         set_osd_param $list '' read_cache_enable 0
10709         set_osd_param $list '' writethrough_cache_enable 0
10710
10711         trap cleanup_test101bc EXIT
10712         # prepare the read-ahead file
10713         $LFS setstripe -S $ssize -i $STRIPE_OFFSET -c $OSTCOUNT $DIR/$tfile
10714
10715         dd if=/dev/zero of=$DIR/$tfile bs=$ssize \
10716                                 count=$FILE_SIZE_MB 2> /dev/null
10717
10718 }
10719
10720 cleanup_test101bc() {
10721         trap 0
10722         rm -rf $DIR/$tdir
10723         rm -f $DIR/$tfile
10724
10725         local list=$(comma_list $(osts_nodes))
10726         set_osd_param $list '' read_cache_enable 1
10727         set_osd_param $list '' writethrough_cache_enable 1
10728 }
10729
10730 calc_total() {
10731         awk 'BEGIN{total=0}; {total+=$1}; END{print total}'
10732 }
10733
10734 ra_check_101() {
10735         local read_size=$1
10736         local stripe_size=$2
10737         local stride_length=$((stripe_size / read_size))
10738         local stride_width=$((stride_length * OSTCOUNT))
10739         local discard_limit=$(( ((stride_length - 1) * 3 / stride_width) *
10740                                 (stride_width - stride_length) ))
10741         local discard=$($LCTL get_param -n llite.*.read_ahead_stats |
10742                   get_named_value 'read.but.discarded' | calc_total)
10743
10744         if [[ $discard -gt $discard_limit ]]; then
10745                 $LCTL get_param llite.*.read_ahead_stats
10746                 error "($discard limit ${discard_limit}) discarded pages with size (${read_size})"
10747         else
10748                 echo "Read-ahead success for size ${read_size}"
10749         fi
10750 }
10751
10752 test_101b() {
10753         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10754         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10755
10756         local STRIPE_SIZE=1048576
10757         local STRIDE_SIZE=$((STRIPE_SIZE*OSTCOUNT))
10758
10759         if [ $SLOW == "yes" ]; then
10760                 local FILE_LENGTH=$((STRIDE_SIZE * 64))
10761         else
10762                 local FILE_LENGTH=$((STRIDE_SIZE * 8))
10763         fi
10764
10765         local ITERATION=$((FILE_LENGTH / STRIDE_SIZE))
10766
10767         # prepare the read-ahead file
10768         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
10769         cancel_lru_locks osc
10770         for BIDX in 2 4 8 16 32 64 128 256
10771         do
10772                 local BSIZE=$((BIDX*4096))
10773                 local READ_COUNT=$((STRIPE_SIZE/BSIZE))
10774                 local STRIDE_LENGTH=$((STRIDE_SIZE/BSIZE))
10775                 local OFFSET=$((STRIPE_SIZE/BSIZE*(OSTCOUNT - 1)))
10776                 $LCTL set_param -n llite.*.read_ahead_stats=0
10777                 $READS -f $DIR/$tfile  -l $STRIDE_LENGTH -o $OFFSET \
10778                               -s $FILE_LENGTH -b $STRIPE_SIZE -a $READ_COUNT -n $ITERATION
10779                 cancel_lru_locks osc
10780                 ra_check_101 $BSIZE $STRIPE_SIZE $FILE_LENGTH
10781         done
10782         cleanup_test101bc
10783         true
10784 }
10785 run_test 101b "check stride-io mode read-ahead ================="
10786
10787 test_101c() {
10788         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10789
10790         local STRIPE_SIZE=1048576
10791         local FILE_LENGTH=$((STRIPE_SIZE*100))
10792         local nreads=10000
10793         local rsize=65536
10794         local osc_rpc_stats
10795
10796         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
10797
10798         cancel_lru_locks osc
10799         $LCTL set_param osc.*.rpc_stats=0
10800         $READS -f $DIR/$tfile -s$FILE_LENGTH -b$rsize -n$nreads -t 180
10801         $LCTL get_param osc.*.rpc_stats
10802         for osc_rpc_stats in $($LCTL get_param -N osc.*.rpc_stats); do
10803                 local stats=$($LCTL get_param -n $osc_rpc_stats)
10804                 local lines=$(echo "$stats" | awk 'END {print NR;}')
10805                 local size
10806
10807                 if [ $lines -le 20 ]; then
10808                         echo "continue debug"
10809                         continue
10810                 fi
10811                 for size in 1 2 4 8; do
10812                         local rpc=$(echo "$stats" |
10813                                     awk '($1 == "'$size':") {print $2; exit; }')
10814                         [ $rpc != 0 ] && ((size * PAGE_SIZE < rsize)) &&
10815                                 error "Small $((size*PAGE_SIZE)) read IO $rpc!"
10816                 done
10817                 echo "$osc_rpc_stats check passed!"
10818         done
10819         cleanup_test101bc
10820         true
10821 }
10822 run_test 101c "check stripe_size aligned read-ahead"
10823
10824 test_101d() {
10825         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10826
10827         local file=$DIR/$tfile
10828         local sz_MB=${FILESIZE_101d:-80}
10829         local ra_MB=${READAHEAD_MB:-40}
10830
10831         local free_MB=$(($(df -P $DIR | tail -n 1 | awk '{ print $4 }') / 1024))
10832         [ $free_MB -lt $sz_MB ] &&
10833                 skip "Need free space ${sz_MB}M, have ${free_MB}M"
10834
10835         echo "Create test file $file size ${sz_MB}M, ${free_MB}M free"
10836         $LFS setstripe -c -1 $file || error "setstripe failed"
10837
10838         dd if=/dev/zero of=$file bs=1M count=$sz_MB || error "dd failed"
10839         echo Cancel LRU locks on lustre client to flush the client cache
10840         cancel_lru_locks osc
10841
10842         echo Disable read-ahead
10843         local old_RA=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
10844         $LCTL set_param -n llite.*.max_read_ahead_mb=0
10845         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb=$old_RA" EXIT
10846         $LCTL get_param -n llite.*.max_read_ahead_mb
10847
10848         echo "Reading the test file $file with read-ahead disabled"
10849         local sz_KB=$((sz_MB * 1024 / 4))
10850         # 10485760 bytes transferred in 0.000938 secs (11179579337 bytes/sec)
10851         # 104857600 bytes (105 MB) copied, 0.00876352 s, 12.0 GB/s
10852         local raOFF=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
10853                       sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
10854
10855         echo "Cancel LRU locks on lustre client to flush the client cache"
10856         cancel_lru_locks osc
10857         echo Enable read-ahead with ${ra_MB}MB
10858         $LCTL set_param -n llite.*.max_read_ahead_mb=$ra_MB
10859
10860         echo "Reading the test file $file with read-ahead enabled"
10861         local raON=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
10862                      sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
10863
10864         echo "read-ahead disabled time read $raOFF"
10865         echo "read-ahead enabled time read $raON"
10866
10867         rm -f $file
10868         wait_delete_completed
10869
10870         # use awk for this check instead of bash because it handles decimals
10871         awk "{ exit !($raOFF < 1.0 || $raOFF > $raON) }" <<<"ignore_me" ||
10872                 error "readahead ${raON}s > no-readahead ${raOFF}s ${sz_MB}M"
10873 }
10874 run_test 101d "file read with and without read-ahead enabled"
10875
10876 test_101e() {
10877         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10878
10879         local file=$DIR/$tfile
10880         local size_KB=500  #KB
10881         local count=100
10882         local bsize=1024
10883
10884         local free_KB=$(df -P $DIR | tail -n 1 | awk '{ print $4 }')
10885         local need_KB=$((count * size_KB))
10886         [[ $free_KB -le $need_KB ]] &&
10887                 skip_env "Need free space $need_KB, have $free_KB"
10888
10889         echo "Creating $count ${size_KB}K test files"
10890         for ((i = 0; i < $count; i++)); do
10891                 dd if=/dev/zero of=$file.$i bs=$bsize count=$size_KB 2>/dev/null
10892         done
10893
10894         echo "Cancel LRU locks on lustre client to flush the client cache"
10895         cancel_lru_locks $OSC
10896
10897         echo "Reset readahead stats"
10898         $LCTL set_param -n llite.*.read_ahead_stats=0
10899
10900         for ((i = 0; i < $count; i++)); do
10901                 dd if=$file.$i of=/dev/null bs=$bsize count=$size_KB 2>/dev/null
10902         done
10903
10904         $LCTL get_param llite.*.max_cached_mb
10905         $LCTL get_param llite.*.read_ahead_stats
10906         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10907                      get_named_value 'misses' | calc_total)
10908
10909         for ((i = 0; i < $count; i++)); do
10910                 rm -rf $file.$i 2>/dev/null
10911         done
10912
10913         #10000 means 20% reads are missing in readahead
10914         [[ $miss -lt 10000 ]] ||  error "misses too much for small reads"
10915 }
10916 run_test 101e "check read-ahead for small read(1k) for small files(500k)"
10917
10918 test_101f() {
10919         which iozone || skip_env "no iozone installed"
10920
10921         local old_debug=$($LCTL get_param debug)
10922         old_debug=${old_debug#*=}
10923         $LCTL set_param debug="reada mmap"
10924
10925         # create a test file
10926         iozone -i 0 -+n -r 1m -s 128m -w -f $DIR/$tfile > /dev/null 2>&1
10927
10928         echo Cancel LRU locks on lustre client to flush the client cache
10929         cancel_lru_locks osc
10930
10931         echo Reset readahead stats
10932         $LCTL set_param -n llite.*.read_ahead_stats=0
10933
10934         echo mmap read the file with small block size
10935         iozone -i 1 -u 1 -l 1 -+n -r 32k -s 128m -B -f $DIR/$tfile \
10936                 > /dev/null 2>&1
10937
10938         echo checking missing pages
10939         $LCTL get_param llite.*.read_ahead_stats
10940         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10941                         get_named_value 'misses' | calc_total)
10942
10943         $LCTL set_param debug="$old_debug"
10944         [ $miss -lt 3 ] || error "misses too much pages ('$miss')!"
10945         rm -f $DIR/$tfile
10946 }
10947 run_test 101f "check mmap read performance"
10948
10949 test_101g_brw_size_test() {
10950         local mb=$1
10951         local pages=$((mb * 1048576 / PAGE_SIZE))
10952         local file=$DIR/$tfile
10953
10954         $LCTL set_param osc.*.max_pages_per_rpc=${mb}M ||
10955                 { error "unable to set max_pages_per_rpc=${mb}M"; return 1; }
10956         for mp in $($LCTL get_param -n osc.*.max_pages_per_rpc); do
10957                 [ $mp -ne $pages ] && error "max_pages_per_rpc $mp != $pages" &&
10958                         return 2
10959         done
10960
10961         stack_trap "rm -f $file" EXIT
10962         $LCTL set_param -n osc.*.rpc_stats=0
10963
10964         # 10 RPCs should be enough for the test
10965         local count=10
10966         dd if=/dev/zero of=$file bs=${mb}M count=$count ||
10967                 { error "dd write ${mb} MB blocks failed"; return 3; }
10968         cancel_lru_locks osc
10969         dd of=/dev/null if=$file bs=${mb}M count=$count ||
10970                 { error "dd write ${mb} MB blocks failed"; return 4; }
10971
10972         # calculate number of full-sized read and write RPCs
10973         rpcs=($($LCTL get_param -n 'osc.*.rpc_stats' |
10974                 sed -n '/pages per rpc/,/^$/p' |
10975                 awk '/'$pages':/ { reads += $2; writes += $6 }; \
10976                 END { print reads,writes }'))
10977         # allow one extra full-sized read RPC for async readahead
10978         [[ ${rpcs[0]} == $count || ${rpcs[0]} == $((count + 1)) ]] ||
10979                 { error "${rpcs[0]} != $count read RPCs"; return 5; }
10980         [[ ${rpcs[1]} == $count ]] ||
10981                 { error "${rpcs[1]} != $count write RPCs"; return 6; }
10982 }
10983
10984 test_101g() {
10985         remote_ost_nodsh && skip "remote OST with nodsh"
10986
10987         local rpcs
10988         local osts=$(get_facets OST)
10989         local list=$(comma_list $(osts_nodes))
10990         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
10991         local brw_size="obdfilter.*.brw_size"
10992
10993         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10994
10995         local orig_mb=$(do_facet ost1 $LCTL get_param -n $brw_size | head -n 1)
10996
10997         if { [ $OST1_VERSION -ge $(version_code 2.8.52) ] ||
10998                 { [ $OST1_VERSION -ge $(version_code 2.7.17) ] &&
10999                   [ $OST1_VERSION -lt $(version_code 2.7.50) ]; }; } &&
11000            { [ $CLIENT_VERSION -ge $(version_code 2.8.52) ] ||
11001                 { [ $CLIENT_VERSION -ge $(version_code 2.7.17) ] &&
11002                   [ $CLIENT_VERSION -lt $(version_code 2.7.50) ]; }; }; then
11003
11004                 [ $OST1_VERSION -ge $(version_code 2.9.52) ] &&
11005                         suffix="M"
11006
11007                 if [[ $orig_mb -lt 16 ]]; then
11008                         save_lustre_params $osts "$brw_size" > $p
11009                         do_nodes $list $LCTL set_param -n $brw_size=16$suffix ||
11010                                 error "set 16MB RPC size failed"
11011
11012                         echo "remount client to enable new RPC size"
11013                         remount_client $MOUNT || error "remount_client failed"
11014                 fi
11015
11016                 test_101g_brw_size_test 16 || error "16MB RPC test failed"
11017                 # should be able to set brw_size=12, but no rpc_stats for that
11018                 test_101g_brw_size_test 8 || error "8MB RPC test failed"
11019         fi
11020
11021         test_101g_brw_size_test 4 || error "4MB RPC test failed"
11022
11023         if [[ $orig_mb -lt 16 ]]; then
11024                 restore_lustre_params < $p
11025                 remount_client $MOUNT || error "remount_client restore failed"
11026         fi
11027
11028         rm -f $p $DIR/$tfile
11029 }
11030 run_test 101g "Big bulk(4/16 MiB) readahead"
11031
11032 test_101h() {
11033         $LFS setstripe -i 0 -c 1 $DIR/$tfile
11034
11035         dd if=/dev/zero of=$DIR/$tfile bs=1M count=70 ||
11036                 error "dd 70M file failed"
11037         echo Cancel LRU locks on lustre client to flush the client cache
11038         cancel_lru_locks osc
11039
11040         echo "Reset readahead stats"
11041         $LCTL set_param -n llite.*.read_ahead_stats 0
11042
11043         echo "Read 10M of data but cross 64M bundary"
11044         dd if=$DIR/$tfile of=/dev/null bs=10M skip=6 count=1
11045         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11046                      get_named_value 'misses' | calc_total)
11047         [ $miss -eq 1 ] || error "expected miss 1 but got $miss"
11048         rm -f $p $DIR/$tfile
11049 }
11050 run_test 101h "Readahead should cover current read window"
11051
11052 test_101i() {
11053         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 ||
11054                 error "dd 10M file failed"
11055
11056         local max_per_file_mb=$($LCTL get_param -n \
11057                 llite.*.max_read_ahead_per_file_mb 2>/dev/null)
11058         cancel_lru_locks osc
11059         stack_trap "$LCTL set_param llite.*.max_read_ahead_per_file_mb=$max_per_file_mb"
11060         $LCTL set_param llite.*.max_read_ahead_per_file_mb=1 ||
11061                 error "set max_read_ahead_per_file_mb to 1 failed"
11062
11063         echo "Reset readahead stats"
11064         $LCTL set_param llite.*.read_ahead_stats=0
11065
11066         dd if=$DIR/$tfile of=/dev/null bs=2M
11067
11068         $LCTL get_param llite.*.read_ahead_stats
11069         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11070                      awk '/misses/ { print $2 }')
11071         [ $miss -eq 5 ] || error "expected misses 5 but got $miss"
11072         rm -f $DIR/$tfile
11073 }
11074 run_test 101i "allow current readahead to exceed reservation"
11075
11076 test_101j() {
11077         $LFS setstripe -i 0 -c 1 $DIR/$tfile ||
11078                 error "setstripe $DIR/$tfile failed"
11079         local file_size=$((1048576 * 16))
11080         local old_ra=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
11081         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb $old_ra" EXIT
11082
11083         echo Disable read-ahead
11084         $LCTL set_param -n llite.*.max_read_ahead_mb=0
11085
11086         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$(($file_size / 1048576))
11087         for blk in $PAGE_SIZE 1048576 $file_size; do
11088                 cancel_lru_locks osc
11089                 echo "Reset readahead stats"
11090                 $LCTL set_param -n llite.*.read_ahead_stats=0
11091                 local count=$(($file_size / $blk))
11092                 dd if=$DIR/$tfile bs=$blk count=$count of=/dev/null
11093                 local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11094                              get_named_value 'failed.to.fast.read' | calc_total)
11095                 $LCTL get_param -n llite.*.read_ahead_stats
11096                 [ $miss -eq $count ] || error "expected $count got $miss"
11097         done
11098
11099         rm -f $p $DIR/$tfile
11100 }
11101 run_test 101j "A complete read block should be submitted when no RA"
11102
11103 setup_test102() {
11104         test_mkdir $DIR/$tdir
11105         chown $RUNAS_ID $DIR/$tdir
11106         STRIPE_SIZE=65536
11107         STRIPE_OFFSET=1
11108         STRIPE_COUNT=$OSTCOUNT
11109         [[ $OSTCOUNT -gt 4 ]] && STRIPE_COUNT=4
11110
11111         trap cleanup_test102 EXIT
11112         cd $DIR
11113         $1 $LFS setstripe -S $STRIPE_SIZE -i $STRIPE_OFFSET -c $STRIPE_COUNT $tdir
11114         cd $DIR/$tdir
11115         for num in 1 2 3 4; do
11116                 for count in $(seq 1 $STRIPE_COUNT); do
11117                         for idx in $(seq 0 $[$STRIPE_COUNT - 1]); do
11118                                 local size=`expr $STRIPE_SIZE \* $num`
11119                                 local file=file"$num-$idx-$count"
11120                                 $1 $LFS setstripe -S $size -i $idx -c $count $file
11121                         done
11122                 done
11123         done
11124
11125         cd $DIR
11126         $1 tar cf $TMP/f102.tar $tdir --xattrs
11127 }
11128
11129 cleanup_test102() {
11130         trap 0
11131         rm -f $TMP/f102.tar
11132         rm -rf $DIR/d0.sanity/d102
11133 }
11134
11135 test_102a() {
11136         [ "$UID" != 0 ] && skip "must run as root"
11137         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep xattr)" ] &&
11138                 skip_env "must have user_xattr"
11139
11140         [ -z "$(which setfattr 2>/dev/null)" ] &&
11141                 skip_env "could not find setfattr"
11142
11143         local testfile=$DIR/$tfile
11144
11145         touch $testfile
11146         echo "set/get xattr..."
11147         setfattr -n trusted.name1 -v value1 $testfile ||
11148                 error "setfattr -n trusted.name1=value1 $testfile failed"
11149         getfattr -n trusted.name1 $testfile 2> /dev/null |
11150           grep "trusted.name1=.value1" ||
11151                 error "$testfile missing trusted.name1=value1"
11152
11153         setfattr -n user.author1 -v author1 $testfile ||
11154                 error "setfattr -n user.author1=author1 $testfile failed"
11155         getfattr -n user.author1 $testfile 2> /dev/null |
11156           grep "user.author1=.author1" ||
11157                 error "$testfile missing trusted.author1=author1"
11158
11159         echo "listxattr..."
11160         setfattr -n trusted.name2 -v value2 $testfile ||
11161                 error "$testfile unable to set trusted.name2"
11162         setfattr -n trusted.name3 -v value3 $testfile ||
11163                 error "$testfile unable to set trusted.name3"
11164         [ $(getfattr -d -m "^trusted" $testfile 2> /dev/null |
11165             grep "trusted.name" | wc -l) -eq 3 ] ||
11166                 error "$testfile missing 3 trusted.name xattrs"
11167
11168         setfattr -n user.author2 -v author2 $testfile ||
11169                 error "$testfile unable to set user.author2"
11170         setfattr -n user.author3 -v author3 $testfile ||
11171                 error "$testfile unable to set user.author3"
11172         [ $(getfattr -d -m "^user" $testfile 2> /dev/null |
11173             grep "user.author" | wc -l) -eq 3 ] ||
11174                 error "$testfile missing 3 user.author xattrs"
11175
11176         echo "remove xattr..."
11177         setfattr -x trusted.name1 $testfile ||
11178                 error "$testfile error deleting trusted.name1"
11179         getfattr -d -m trusted $testfile 2> /dev/null | grep "trusted.name1" &&
11180                 error "$testfile did not delete trusted.name1 xattr"
11181
11182         setfattr -x user.author1 $testfile ||
11183                 error "$testfile error deleting user.author1"
11184         echo "set lustre special xattr ..."
11185         $LFS setstripe -c1 $testfile
11186         local lovea=$(getfattr -n "trusted.lov" -e hex $testfile |
11187                 awk -F "=" '/trusted.lov/ { print $2 }' )
11188         setfattr -n "trusted.lov" -v $lovea $testfile ||
11189                 error "$testfile doesn't ignore setting trusted.lov again"
11190         setfattr -n "trusted.lov" -v "invalid_value" $testfile &&
11191                 error "$testfile allow setting invalid trusted.lov"
11192         rm -f $testfile
11193 }
11194 run_test 102a "user xattr test =================================="
11195
11196 check_102b_layout() {
11197         local layout="$*"
11198         local testfile=$DIR/$tfile
11199
11200         echo "test layout '$layout'"
11201         $LFS setstripe $layout $testfile || error "setstripe failed"
11202         $LFS getstripe -y $testfile
11203
11204         echo "get/set/list trusted.lov xattr ..." # b=10930
11205         local value=$(getfattr -n trusted.lov -e hex $testfile | grep trusted)
11206         [[ "$value" =~ "trusted.lov" ]] ||
11207                 error "can't get trusted.lov from $testfile"
11208         local stripe_count_orig=$($LFS getstripe -c $testfile) ||
11209                 error "getstripe failed"
11210
11211         $MCREATE $testfile.2 || error "mcreate $testfile.2 failed"
11212
11213         value=$(cut -d= -f2 <<<$value)
11214         # LU-13168: truncated xattr should fail if short lov_user_md header
11215         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
11216                 lens="${#value}" || lens="$(seq 4 2 ${#value})"
11217         for len in $lens; do
11218                 echo "setfattr $len $testfile.2"
11219                 setfattr -n trusted.lov -v ${value:0:$len} $testfile.2 &&
11220                         [ $len -lt 66 ] && error "short xattr len=$len worked"
11221         done
11222         local stripe_size=$($LFS getstripe -S $testfile.2)
11223         local stripe_count=$($LFS getstripe -c $testfile.2)
11224         [[ $stripe_size -eq 65536 ]] ||
11225                 error "stripe size $stripe_size != 65536"
11226         [[ $stripe_count -eq $stripe_count_orig ]] ||
11227                 error "stripe count $stripe_count != $stripe_count_orig"
11228         rm $testfile $testfile.2
11229 }
11230
11231 test_102b() {
11232         [ -z "$(which setfattr 2>/dev/null)" ] &&
11233                 skip_env "could not find setfattr"
11234         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11235
11236         # check plain layout
11237         check_102b_layout -S 65536 -i 1 -c $OSTCOUNT
11238
11239         # and also check composite layout
11240         check_102b_layout -E 1M -S 65536 -i 1 -c $OSTCOUNT -Eeof -S4M
11241
11242 }
11243 run_test 102b "getfattr/setfattr for trusted.lov EAs"
11244
11245 test_102c() {
11246         [ -z "$(which setfattr 2>/dev/null)" ] &&
11247                 skip_env "could not find setfattr"
11248         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11249
11250         # b10930: get/set/list lustre.lov xattr
11251         echo "get/set/list lustre.lov xattr ..."
11252         test_mkdir $DIR/$tdir
11253         chown $RUNAS_ID $DIR/$tdir
11254         local testfile=$DIR/$tdir/$tfile
11255         $RUNAS $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
11256                 error "setstripe failed"
11257         local STRIPECOUNT=$($RUNAS $LFS getstripe -c $testfile) ||
11258                 error "getstripe failed"
11259         $RUNAS getfattr -d -m "^lustre" $testfile 2> /dev/null | \
11260         grep "lustre.lov" || error "can't get lustre.lov from $testfile"
11261
11262         local testfile2=${testfile}2
11263         local value=`getfattr -n lustre.lov $testfile 2> /dev/null | \
11264                      grep "lustre.lov" |sed -e 's/[^=]\+=//'  `
11265
11266         $RUNAS $MCREATE $testfile2
11267         $RUNAS setfattr -n lustre.lov -v $value $testfile2
11268         local stripe_size=$($RUNAS $LFS getstripe -S $testfile2)
11269         local stripe_count=$($RUNAS $LFS getstripe -c $testfile2)
11270         [ $stripe_size -eq 65536 ] || error "stripe size $stripe_size != 65536"
11271         [ $stripe_count -eq $STRIPECOUNT ] ||
11272                 error "stripe count $stripe_count != $STRIPECOUNT"
11273 }
11274 run_test 102c "non-root getfattr/setfattr for lustre.lov EAs ==========="
11275
11276 compare_stripe_info1() {
11277         local stripe_index_all_zero=true
11278
11279         for num in 1 2 3 4; do
11280                 for count in $(seq 1 $STRIPE_COUNT); do
11281                         for offset in $(seq 0 $[$STRIPE_COUNT - 1]); do
11282                                 local size=$((STRIPE_SIZE * num))
11283                                 local file=file"$num-$offset-$count"
11284                                 stripe_size=$($LFS getstripe -S $PWD/$file)
11285                                 [[ $stripe_size -ne $size ]] &&
11286                                     error "$file: size $stripe_size != $size"
11287                                 stripe_count=$($LFS getstripe -c $PWD/$file)
11288                                 # allow fewer stripes to be created, ORI-601
11289                                 [[ $stripe_count -lt $(((3 * count + 3) / 4)) ]] &&
11290                                     error "$file: count $stripe_count != $count"
11291                                 stripe_index=$($LFS getstripe -i $PWD/$file)
11292                                 [[ $stripe_index -ne 0 ]] &&
11293                                         stripe_index_all_zero=false
11294                         done
11295                 done
11296         done
11297         $stripe_index_all_zero &&
11298                 error "all files are being extracted starting from OST index 0"
11299         return 0
11300 }
11301
11302 have_xattrs_include() {
11303         tar --help | grep -q xattrs-include &&
11304                 echo --xattrs-include="lustre.*"
11305 }
11306
11307 test_102d() {
11308         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11309         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11310
11311         XINC=$(have_xattrs_include)
11312         setup_test102
11313         tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
11314         cd $DIR/$tdir/$tdir
11315         compare_stripe_info1
11316 }
11317 run_test 102d "tar restore stripe info from tarfile,not keep osts"
11318
11319 test_102f() {
11320         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11321         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11322
11323         XINC=$(have_xattrs_include)
11324         setup_test102
11325         test_mkdir $DIR/$tdir.restore
11326         cd $DIR
11327         tar cf - --xattrs $tdir | tar xf - \
11328                 -C $DIR/$tdir.restore --xattrs $XINC
11329         cd $DIR/$tdir.restore/$tdir
11330         compare_stripe_info1
11331 }
11332 run_test 102f "tar copy files, not keep osts"
11333
11334 grow_xattr() {
11335         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep xattr)" ] &&
11336                 skip "must have user_xattr"
11337         [ -z "$(which setfattr 2>/dev/null)" ] &&
11338                 skip_env "could not find setfattr"
11339         [ -z "$(which getfattr 2>/dev/null)" ] &&
11340                 skip_env "could not find getfattr"
11341
11342         local xsize=${1:-1024}  # in bytes
11343         local file=$DIR/$tfile
11344         local value="$(generate_string $xsize)"
11345         local xbig=trusted.big
11346         local toobig=$2
11347
11348         touch $file
11349         log "save $xbig on $file"
11350         if [ -z "$toobig" ]
11351         then
11352                 setfattr -n $xbig -v $value $file ||
11353                         error "saving $xbig on $file failed"
11354         else
11355                 setfattr -n $xbig -v $value $file &&
11356                         error "saving $xbig on $file succeeded"
11357                 return 0
11358         fi
11359
11360         local orig=$(get_xattr_value $xbig $file)
11361         [[ "$orig" != "$value" ]] && error "$xbig different after saving $xbig"
11362
11363         local xsml=trusted.sml
11364         log "save $xsml on $file"
11365         setfattr -n $xsml -v val $file || error "saving $xsml on $file failed"
11366
11367         local new=$(get_xattr_value $xbig $file)
11368         [[ "$new" != "$orig" ]] && error "$xbig different after saving $xsml"
11369
11370         log "grow $xsml on $file"
11371         setfattr -n $xsml -v "$value" $file ||
11372                 error "growing $xsml on $file failed"
11373
11374         new=$(get_xattr_value $xbig $file)
11375         [[ "$new" != "$orig" ]] && error "$xbig different after growing $xsml"
11376         log "$xbig still valid after growing $xsml"
11377
11378         rm -f $file
11379 }
11380
11381 test_102h() { # bug 15777
11382         grow_xattr 1024
11383 }
11384 run_test 102h "grow xattr from inside inode to external block"
11385
11386 test_102ha() {
11387         large_xattr_enabled || skip_env "ea_inode feature disabled"
11388
11389         echo "setting xattr of max xattr size: $(max_xattr_size)"
11390         grow_xattr $(max_xattr_size)
11391
11392         echo "setting xattr of > max xattr size: $(max_xattr_size) + 10"
11393         echo "This should fail:"
11394         grow_xattr $(($(max_xattr_size) + 10)) 1
11395 }
11396 run_test 102ha "grow xattr from inside inode to external inode"
11397
11398 test_102i() { # bug 17038
11399         [ -z "$(which getfattr 2>/dev/null)" ] &&
11400                 skip "could not find getfattr"
11401
11402         touch $DIR/$tfile
11403         ln -s $DIR/$tfile $DIR/${tfile}link
11404         getfattr -n trusted.lov $DIR/$tfile ||
11405                 error "lgetxattr on $DIR/$tfile failed"
11406         getfattr -h -n trusted.lov $DIR/${tfile}link 2>&1 |
11407                 grep -i "no such attr" ||
11408                 error "error for lgetxattr on $DIR/${tfile}link is not ENODATA"
11409         rm -f $DIR/$tfile $DIR/${tfile}link
11410 }
11411 run_test 102i "lgetxattr test on symbolic link ============"
11412
11413 test_102j() {
11414         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11415         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11416
11417         XINC=$(have_xattrs_include)
11418         setup_test102 "$RUNAS"
11419         chown $RUNAS_ID $DIR/$tdir
11420         $RUNAS tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
11421         cd $DIR/$tdir/$tdir
11422         compare_stripe_info1 "$RUNAS"
11423 }
11424 run_test 102j "non-root tar restore stripe info from tarfile, not keep osts ==="
11425
11426 test_102k() {
11427         [ -z "$(which setfattr 2>/dev/null)" ] &&
11428                 skip "could not find setfattr"
11429
11430         touch $DIR/$tfile
11431         # b22187 just check that does not crash for regular file.
11432         setfattr -n trusted.lov $DIR/$tfile
11433         # b22187 'setfattr -n trusted.lov' should remove LOV EA for directories
11434         local test_kdir=$DIR/$tdir
11435         test_mkdir $test_kdir
11436         local default_size=$($LFS getstripe -S $test_kdir)
11437         local default_count=$($LFS getstripe -c $test_kdir)
11438         local default_offset=$($LFS getstripe -i $test_kdir)
11439         $LFS setstripe -S 65536 -i 0 -c $OSTCOUNT $test_kdir ||
11440                 error 'dir setstripe failed'
11441         setfattr -n trusted.lov $test_kdir
11442         local stripe_size=$($LFS getstripe -S $test_kdir)
11443         local stripe_count=$($LFS getstripe -c $test_kdir)
11444         local stripe_offset=$($LFS getstripe -i $test_kdir)
11445         [ $stripe_size -eq $default_size ] ||
11446                 error "stripe size $stripe_size != $default_size"
11447         [ $stripe_count -eq $default_count ] ||
11448                 error "stripe count $stripe_count != $default_count"
11449         [ $stripe_offset -eq $default_offset ] ||
11450                 error "stripe offset $stripe_offset != $default_offset"
11451         rm -rf $DIR/$tfile $test_kdir
11452 }
11453 run_test 102k "setfattr without parameter of value shouldn't cause a crash"
11454
11455 test_102l() {
11456         [ -z "$(which getfattr 2>/dev/null)" ] &&
11457                 skip "could not find getfattr"
11458
11459         # LU-532 trusted. xattr is invisible to non-root
11460         local testfile=$DIR/$tfile
11461
11462         touch $testfile
11463
11464         echo "listxattr as user..."
11465         chown $RUNAS_ID $testfile
11466         $RUNAS getfattr -d -m '.*' $testfile 2>&1 |
11467             grep -q "trusted" &&
11468                 error "$testfile trusted xattrs are user visible"
11469
11470         return 0;
11471 }
11472 run_test 102l "listxattr size test =================================="
11473
11474 test_102m() { # LU-3403 llite: error of listxattr when buffer is small
11475         local path=$DIR/$tfile
11476         touch $path
11477
11478         listxattr_size_check $path || error "listattr_size_check $path failed"
11479 }
11480 run_test 102m "Ensure listxattr fails on small bufffer ========"
11481
11482 cleanup_test102
11483
11484 getxattr() { # getxattr path name
11485         # Return the base64 encoding of the value of xattr name on path.
11486         local path=$1
11487         local name=$2
11488
11489         # # getfattr --absolute-names --encoding=base64 --name=trusted.lov $path
11490         # file: $path
11491         # trusted.lov=0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
11492         #
11493         # We print just 0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
11494
11495         getfattr --absolute-names --encoding=base64 --name=$name $path |
11496                 awk -F= -v name=$name '$1 == name {
11497                         print substr($0, index($0, "=") + 1);
11498         }'
11499 }
11500
11501 test_102n() { # LU-4101 mdt: protect internal xattrs
11502         [ -z "$(which setfattr 2>/dev/null)" ] &&
11503                 skip "could not find setfattr"
11504         if [ $MDS1_VERSION -lt $(version_code 2.5.50) ]
11505         then
11506                 skip "MDT < 2.5.50 allows setxattr on internal trusted xattrs"
11507         fi
11508
11509         local file0=$DIR/$tfile.0
11510         local file1=$DIR/$tfile.1
11511         local xattr0=$TMP/$tfile.0
11512         local xattr1=$TMP/$tfile.1
11513         local namelist="lov lma lmv link fid version som hsm"
11514         local name
11515         local value
11516
11517         rm -rf $file0 $file1 $xattr0 $xattr1
11518         touch $file0 $file1
11519
11520         # Get 'before' xattrs of $file1.
11521         getfattr --absolute-names --dump --match=- $file1 > $xattr0
11522
11523         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
11524                 namelist+=" lfsck_namespace"
11525         for name in $namelist; do
11526                 # Try to copy xattr from $file0 to $file1.
11527                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
11528
11529                 setfattr --name=trusted.$name --value="$value" $file1 ||
11530                         error "setxattr 'trusted.$name' failed"
11531
11532                 # Try to set a garbage xattr.
11533                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
11534
11535                 if [[ x$name == "xlov" ]]; then
11536                         setfattr --name=trusted.lov --value="$value" $file1 &&
11537                         error "setxattr invalid 'trusted.lov' success"
11538                 else
11539                         setfattr --name=trusted.$name --value="$value" $file1 ||
11540                                 error "setxattr invalid 'trusted.$name' failed"
11541                 fi
11542
11543                 # Try to remove the xattr from $file1. We don't care if this
11544                 # appears to succeed or fail, we just don't want there to be
11545                 # any changes or crashes.
11546                 setfattr --remove=$trusted.$name $file1 2> /dev/null
11547         done
11548
11549         if [ $MDS1_VERSION -gt $(version_code 2.6.50) ]
11550         then
11551                 name="lfsck_ns"
11552                 # Try to copy xattr from $file0 to $file1.
11553                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
11554
11555                 setfattr --name=trusted.$name --value="$value" $file1 ||
11556                         error "setxattr 'trusted.$name' failed"
11557
11558                 # Try to set a garbage xattr.
11559                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
11560
11561                 setfattr --name=trusted.$name --value="$value" $file1 ||
11562                         error "setxattr 'trusted.$name' failed"
11563
11564                 # Try to remove the xattr from $file1. We don't care if this
11565                 # appears to succeed or fail, we just don't want there to be
11566                 # any changes or crashes.
11567                 setfattr --remove=$trusted.$name $file1 2> /dev/null
11568         fi
11569
11570         # Get 'after' xattrs of file1.
11571         getfattr --absolute-names --dump --match=- $file1 > $xattr1
11572
11573         if ! diff $xattr0 $xattr1; then
11574                 error "before and after xattrs of '$file1' differ"
11575         fi
11576
11577         rm -rf $file0 $file1 $xattr0 $xattr1
11578
11579         return 0
11580 }
11581 run_test 102n "silently ignore setxattr on internal trusted xattrs"
11582
11583 test_102p() { # LU-4703 setxattr did not check ownership
11584         [ $MDS1_VERSION -lt $(version_code 2.5.56) ] &&
11585                 skip "MDS needs to be at least 2.5.56"
11586
11587         local testfile=$DIR/$tfile
11588
11589         touch $testfile
11590
11591         echo "setfacl as user..."
11592         $RUNAS setfacl -m "u:$RUNAS_ID:rwx" $testfile
11593         [ $? -ne 0 ] || error "setfacl by $RUNAS_ID was allowed on $testfile"
11594
11595         echo "setfattr as user..."
11596         setfacl -m "u:$RUNAS_ID:---" $testfile
11597         $RUNAS setfattr -x system.posix_acl_access $testfile
11598         [ $? -ne 0 ] || error "setfattr by $RUNAS_ID was allowed on $testfile"
11599 }
11600 run_test 102p "check setxattr(2) correctly fails without permission"
11601
11602 test_102q() {
11603         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] &&
11604                 skip "MDS needs to be at least 2.6.92"
11605
11606         orphan_linkea_check $DIR/$tfile || error "orphan_linkea_check"
11607 }
11608 run_test 102q "flistxattr should not return trusted.link EAs for orphans"
11609
11610 test_102r() {
11611         [ $MDS1_VERSION -lt $(version_code 2.6.93) ] &&
11612                 skip "MDS needs to be at least 2.6.93"
11613
11614         touch $DIR/$tfile || error "touch"
11615         setfattr -n user.$(basename $tfile) $DIR/$tfile || error "setfattr"
11616         getfattr -n user.$(basename $tfile) $DIR/$tfile || error "getfattr"
11617         rm $DIR/$tfile || error "rm"
11618
11619         #normal directory
11620         mkdir -p $DIR/$tdir || error "mkdir"
11621         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
11622         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
11623         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
11624                 error "$testfile error deleting user.author1"
11625         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
11626                 grep "user.$(basename $tdir)" &&
11627                 error "$tdir did not delete user.$(basename $tdir)"
11628         rmdir $DIR/$tdir || error "rmdir"
11629
11630         #striped directory
11631         test_mkdir $DIR/$tdir
11632         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
11633         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
11634         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
11635                 error "$testfile error deleting user.author1"
11636         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
11637                 grep "user.$(basename $tdir)" &&
11638                 error "$tdir did not delete user.$(basename $tdir)"
11639         rmdir $DIR/$tdir || error "rm striped dir"
11640 }
11641 run_test 102r "set EAs with empty values"
11642
11643 test_102s() {
11644         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
11645                 skip "MDS needs to be at least 2.11.52"
11646
11647         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
11648
11649         save_lustre_params client "llite.*.xattr_cache" > $save
11650
11651         for cache in 0 1; do
11652                 lctl set_param llite.*.xattr_cache=$cache
11653
11654                 rm -f $DIR/$tfile
11655                 touch $DIR/$tfile || error "touch"
11656                 for prefix in lustre security system trusted user; do
11657                         # Note getxattr() may fail with 'Operation not
11658                         # supported' or 'No such attribute' depending
11659                         # on prefix and cache.
11660                         getfattr -n $prefix.n102s $DIR/$tfile &&
11661                                 error "getxattr '$prefix.n102s' should fail (cache = $cache)"
11662                 done
11663         done
11664
11665         restore_lustre_params < $save
11666 }
11667 run_test 102s "getting nonexistent xattrs should fail"
11668
11669 test_102t() {
11670         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
11671                 skip "MDS needs to be at least 2.11.52"
11672
11673         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
11674
11675         save_lustre_params client "llite.*.xattr_cache" > $save
11676
11677         for cache in 0 1; do
11678                 lctl set_param llite.*.xattr_cache=$cache
11679
11680                 for buf_size in 0 256; do
11681                         rm -f $DIR/$tfile
11682                         touch $DIR/$tfile || error "touch"
11683                         setfattr -n user.multiop $DIR/$tfile
11684                         $MULTIOP $DIR/$tfile oa$buf_size ||
11685                                 error "cannot get zero length xattr value (buf_size = $buf_size)"
11686                 done
11687         done
11688
11689         restore_lustre_params < $save
11690 }
11691 run_test 102t "zero length xattr values handled correctly"
11692
11693 run_acl_subtest()
11694 {
11695         local test=$LUSTRE/tests/acl/$1.test
11696         local tmp=$(mktemp -t $1-XXXXXX).test
11697         local bin=$2
11698         local dmn=$3
11699         local grp=$4
11700         local nbd=$5
11701         export LANG=C
11702
11703
11704         local sedusers="-e s/bin/$bin/g -e s/daemon/$dmn/g"
11705         local sedgroups="-e s/:users/:$grp/g"
11706         [[ -z "$nbd" ]] || sedusers+=" -e s/nobody/$nbd/g"
11707
11708         sed $sedusers $sedgroups < $test > $tmp
11709         stack_trap "rm -f $tmp"
11710         [[ -s $tmp ]] || error "sed failed to create test script"
11711
11712         echo "performing $1 with bin='$bin' daemon='$dmn' users='$grp'..."
11713         $LUSTRE/tests/acl/run $tmp || error "run_acl_subtest '$1' failed"
11714 }
11715
11716 test_103a() {
11717         [ "$UID" != 0 ] && skip "must run as root"
11718         $GSS && skip_env "could not run under gss"
11719         [[ "$(lctl get_param -n mdc.*-mdc-*.connect_flags)" =~ "acl" ]] ||
11720                 skip_env "must have acl enabled"
11721         which setfacl || skip_env "could not find setfacl"
11722         remote_mds_nodsh && skip "remote MDS with nodsh"
11723
11724         ACLBIN=${ACLBIN:-"bin"}
11725         ACLDMN=${ACLDMN:-"daemon"}
11726         ACLGRP=${ACLGRP:-"users"}
11727         ACLNBD=${ACLNBD:-"nobody"}
11728
11729         if ! id $ACLBIN ||
11730            [[ "$(id -u $ACLBIN)" != "$(do_facet mds1 id -u $ACLBIN)" ]]; then
11731                 echo "bad 'bin' user '$ACLBIN', using '$USER0'"
11732                 ACLBIN=$USER0
11733                 if ! id $ACLBIN ; then
11734                         cat /etc/passwd
11735                         skip_env "can't find suitable ACL 'bin' $ACLBIN"
11736                 fi
11737         fi
11738         if ! id $ACLDMN || (( $(id -u $ACLDMN) < $(id -u $ACLBIN) )) ||
11739            [[ "$(id -u $ACLDMN)" != "$(do_facet mds1 id -u $ACLDMN)" ]]; then
11740                 echo "bad 'daemon' user '$ACLDMN', using '$USER1'"
11741                 ACLDMN=$USER1
11742                 if ! id $ACLDMN ; then
11743                         cat /etc/passwd
11744                         skip_env "can't find suitable ACL 'daemon' $ACLDMN"
11745                 fi
11746         fi
11747         if ! getent group $ACLGRP; then
11748                 echo "missing 'users' group '$ACLGRP', using '$TSTUSR'"
11749                 ACLGRP="$TSTUSR"
11750                 if ! getent group $ACLGRP; then
11751                         echo "cannot find group '$ACLGRP', adding it"
11752                         cat /etc/group
11753                         add_group 60000 $ACLGRP
11754                 fi
11755         fi
11756
11757         local bingid=$(getent group $ACLBIN | cut -d: -f 3)
11758         local dmngid=$(getent group $ACLDMN | cut -d: -f 3)
11759         local grpgid=$(getent group $ACLGRP | cut -d: -f 3)
11760
11761         if (( $bingid > $grpgid || $dmngid > $grpgid )); then
11762                 echo "group '$ACLGRP' has low gid=$grpgid, use '$TSTUSR'"
11763                 ACLGRP="$TSTUSR"
11764                 if ! getent group $ACLGRP; then
11765                         echo "cannot find group '$ACLGRP', adding it"
11766                         cat /etc/group
11767                         add_group 60000 $ACLGRP
11768                 fi
11769                 grpgid=$(getent group $ACLGRP | cut -d: -f 3)
11770                 if (( $bingid > $grpgid || $dmngid > $grpgid )); then
11771                         cat /etc/group
11772                         skip_env "$ACLGRP gid=$grpgid less than $bingid|$dmngid"
11773                 fi
11774         fi
11775
11776         gpasswd -a $ACLDMN $ACLBIN ||
11777                 error "setting client group failed"             # LU-5641
11778         do_facet mds1 gpasswd -a $ACLDMN $ACLBIN ||
11779                 error "setting MDS group failed"                # LU-5641
11780
11781         declare -a identity_old
11782
11783         for num in $(seq $MDSCOUNT); do
11784                 switch_identity $num true || identity_old[$num]=$?
11785         done
11786
11787         SAVE_UMASK=$(umask)
11788         umask 0022
11789         mkdir -p $DIR/$tdir
11790         cd $DIR/$tdir
11791
11792         run_acl_subtest cp $ACLBIN $ACLDMN $ACLGRP
11793         run_acl_subtest getfacl-noacl $ACLBIN $ACLDMN $ACLGRP
11794         run_acl_subtest misc $ACLBIN $ACLDMN $ACLGRP
11795         run_acl_subtest permissions $ACLBIN $ACLDMN $ACLGRP
11796         # LU-1482 mdd: Setting xattr are properly checked with and without ACLs
11797         # CentOS7- uses nobody=99, while newer distros use nobody=65534
11798         if ! id -u $ACLNBD ||
11799            (( $(id -u nobody) != $(do_facet mds1 id -u nobody) )); then
11800                 ACLNBD="nfsnobody"
11801                 if ! id -u $ACLNBD; then
11802                         ACLNBD=""
11803                 fi
11804         fi
11805         if [[ -n "$ACLNBD" ]] && ! getent group $ACLNBD; then
11806                 add_group $(id -u $ACLNBD) $ACLNBD
11807                 if ! getent group $ACLNBD; then
11808                         ACLNBD=""
11809                 fi
11810         fi
11811         if (( $MDS1_VERSION > $(version_code 2.8.55) )) &&
11812            [[ -n "$ACLNBD" ]] && which setfattr; then
11813                 run_acl_subtest permissions_xattr \
11814                         $ACLBIN $ACLDMN $ACLGRP $ACLNBD
11815         elif [[ -z "$ACLNBD" ]]; then
11816                 echo "skip 'permission_xattr' test - missing 'nobody' user/grp"
11817         else
11818                 echo "skip 'permission_xattr' test - missing setfattr command"
11819         fi
11820         run_acl_subtest setfacl $ACLBIN $ACLDMN $ACLGRP
11821
11822         # inheritance test got from HP
11823         cp $LUSTRE/tests/acl/make-tree . || error "cannot copy make-tree"
11824         chmod +x make-tree || error "chmod +x failed"
11825         run_acl_subtest inheritance $ACLBIN $ACLDMN $ACLGRP
11826         rm -f make-tree
11827
11828         echo "LU-974 ignore umask when acl is enabled..."
11829         run_acl_subtest 974 $ACLBIN $ACLDMN $ACLGRP
11830         if [ $MDSCOUNT -ge 2 ]; then
11831                 run_acl_subtest 974_remote $ACLBIN $ACLDMN $ACLGRP
11832         fi
11833
11834         echo "LU-2561 newly created file is same size as directory..."
11835         if [ "$mds1_FSTYPE" != "zfs" ]; then
11836                 run_acl_subtest 2561 $ACLBIN $ACLDMN $ACLGRP
11837         else
11838                 run_acl_subtest 2561_zfs $ACLBIN $ACLDMN $ACLGRP
11839         fi
11840
11841         run_acl_subtest 4924 $ACLBIN $ACLDMN $ACLGRP
11842
11843         cd $SAVE_PWD
11844         umask $SAVE_UMASK
11845
11846         for num in $(seq $MDSCOUNT); do
11847                 if [ "${identity_old[$num]}" = 1 ]; then
11848                         switch_identity $num false || identity_old[$num]=$?
11849                 fi
11850         done
11851 }
11852 run_test 103a "acl test"
11853
11854 test_103b() {
11855         declare -a pids
11856         local U
11857
11858         for U in {0..511}; do
11859                 {
11860                 local O=$(printf "%04o" $U)
11861
11862                 umask $(printf "%04o" $((511 ^ $O)))
11863                 $LFS setstripe -c 1 $DIR/$tfile.s$O
11864                 local S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.s$O))
11865
11866                 (( $S == ($O & 0666) )) ||
11867                         error "lfs setstripe $DIR/$tfile.s$O '$S' != '$O'"
11868
11869                 $LFS setstripe -E16M -c 1 -E1G -S4M $DIR/$tfile.p$O
11870                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.p$O))
11871                 (( $S == ($O & 0666) )) ||
11872                         error "lfs setstripe -E $DIR/$tfile.p$O '$S' != '$O'"
11873
11874                 $LFS setstripe -N2 -c 1 $DIR/$tfile.m$O
11875                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.m$O))
11876                 (( $S == ($O & 0666) )) ||
11877                         error "lfs setstripe -N2 $DIR/$tfile.m$O '$S' != '$O'"
11878                 rm -f $DIR/$tfile.[smp]$0
11879                 } &
11880                 local pid=$!
11881
11882                 # limit the concurrently running threads to 64. LU-11878
11883                 local idx=$((U % 64))
11884                 [ -z "${pids[idx]}" ] || wait ${pids[idx]}
11885                 pids[idx]=$pid
11886         done
11887         wait
11888 }
11889 run_test 103b "umask lfs setstripe"
11890
11891 test_103c() {
11892         mkdir -p $DIR/$tdir
11893         cp -rp $DIR/$tdir $DIR/$tdir.bak
11894
11895         [ -n "$(getfattr -d -m. $DIR/$tdir | grep posix_acl_default)" ] &&
11896                 error "$DIR/$tdir shouldn't contain default ACL"
11897         [ -n "$(getfattr -d -m. $DIR/$tdir.bak | grep posix_acl_default)" ] &&
11898                 error "$DIR/$tdir.bak shouldn't contain default ACL"
11899         true
11900 }
11901 run_test 103c "'cp -rp' won't set empty acl"
11902
11903 test_103e() {
11904         local numacl
11905         local fileacl
11906         local saved_debug=$($LCTL get_param -n debug)
11907
11908         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
11909                 skip "MDS needs to be at least 2.14.52"
11910
11911         large_xattr_enabled || skip_env "ea_inode feature disabled"
11912
11913         mkdir -p $DIR/$tdir
11914         # add big LOV EA to cause reply buffer overflow earlier
11915         $LFS setstripe -C 1000 $DIR/$tdir
11916         lctl set_param mdc.*-mdc*.stats=clear
11917
11918         $LCTL set_param debug=0
11919         stack_trap "$LCTL set_param debug=\"$saved_debug\"" EXIT
11920         stack_trap "$LCTL get_param mdc.*-mdc*.stats" EXIT
11921
11922         # add a large number of default ACLs (expect 8000+ for 2.13+)
11923         for U in {2..7000}; do
11924                 setfacl -d -m user:$U:rwx $DIR/$tdir ||
11925                         error "Able to add just $U default ACLs"
11926         done
11927         numacl=$(getfacl $DIR/$tdir |& grep -c "default:user")
11928         echo "$numacl default ACLs created"
11929
11930         stat $DIR/$tdir || error "Cannot stat directory"
11931         # check file creation
11932         touch $DIR/$tdir/$tfile ||
11933                 error "failed to create $tfile with $numacl default ACLs"
11934         stat $DIR/$tdir/$tfile  || error "Cannot stat file"
11935         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
11936         echo "$fileacl ACLs were inherited"
11937         (( $fileacl == $numacl )) ||
11938                 error "Not all default ACLs were inherited: $numacl != $fileacl"
11939         # check that new ACLs creation adds new ACLs to inherited ACLs
11940         setfacl -m user:19000:rwx $DIR/$tdir/$tfile ||
11941                 error "Cannot set new ACL"
11942         numacl=$((numacl + 1))
11943         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
11944         (( $fileacl == $numacl )) ||
11945                 error "failed to add new ACL: $fileacl != $numacl as expected"
11946         # adds more ACLs to a file to reach their maximum at 8000+
11947         numacl=0
11948         for U in {20000..25000}; do
11949                 setfacl -m user:$U:rwx $DIR/$tdir/$tfile || break
11950                 numacl=$((numacl + 1))
11951         done
11952         echo "Added $numacl more ACLs to the file"
11953         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
11954         echo "Total $fileacl ACLs in file"
11955         stat $DIR/$tdir/$tfile > /dev/null || error "Cannot stat file"
11956         rm -f $DIR/$tdir/$tfile || error "Cannot remove file"
11957         rmdir $DIR/$tdir || error "Cannot remove directory"
11958 }
11959 run_test 103e "inheritance of big amount of default ACLs"
11960
11961 test_103f() {
11962         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
11963                 skip "MDS needs to be at least 2.14.51"
11964
11965         large_xattr_enabled || skip_env "ea_inode feature disabled"
11966
11967         # enable changelog to consume more internal MDD buffers
11968         changelog_register
11969
11970         mkdir -p $DIR/$tdir
11971         # add big LOV EA
11972         $LFS setstripe -C 1000 $DIR/$tdir
11973         setfacl -d -m user:$U:rwx $DIR/$tdir || error "Cannot add default ACLs"
11974         mkdir $DIR/$tdir/inherited || error "failed to create subdirectory"
11975         rmdir $DIR/$tdir/inherited || error "Cannot remove subdirectory"
11976         rmdir $DIR/$tdir || error "Cannot remove directory"
11977 }
11978 run_test 103f "changelog doesn't interfere with default ACLs buffers"
11979
11980 test_104a() {
11981         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11982
11983         touch $DIR/$tfile
11984         lfs df || error "lfs df failed"
11985         lfs df -ih || error "lfs df -ih failed"
11986         lfs df -h $DIR || error "lfs df -h $DIR failed"
11987         lfs df -i $DIR || error "lfs df -i $DIR failed"
11988         lfs df $DIR/$tfile || error "lfs df $DIR/$tfile failed"
11989         lfs df -ih $DIR/$tfile || error "lfs df -ih $DIR/$tfile failed"
11990
11991         local OSC=$(lctl dl | grep OST0000-osc-[^M] | awk '{ print $4 }')
11992         lctl --device %$OSC deactivate
11993         lfs df || error "lfs df with deactivated OSC failed"
11994         lctl --device %$OSC activate
11995         # wait the osc back to normal
11996         wait_osc_import_ready client ost
11997
11998         lfs df || error "lfs df with reactivated OSC failed"
11999         rm -f $DIR/$tfile
12000 }
12001 run_test 104a "lfs df [-ih] [path] test ========================="
12002
12003 test_104b() {
12004         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12005         [ $RUNAS_ID -eq $UID ] &&
12006                 skip_env "RUNAS_ID = UID = $UID -- skipping"
12007
12008         denied_cnt=$(($($RUNAS $LFS check servers 2>&1 |
12009                         grep "Permission denied" | wc -l)))
12010         if [ $denied_cnt -ne 0 ]; then
12011                 error "lfs check servers test failed"
12012         fi
12013 }
12014 run_test 104b "$RUNAS lfs check servers test ===================="
12015
12016 #
12017 # Verify $1 is within range of $2.
12018 # Success when $1 is within range. That is, when $1 is >= 2% of $2 and
12019 # $1 is <= 2% of $2. Else Fail.
12020 #
12021 value_in_range() {
12022         # Strip all units (M, G, T)
12023         actual=$(echo $1 | tr -d A-Z)
12024         expect=$(echo $2 | tr -d A-Z)
12025
12026         expect_lo=$(($expect * 98 / 100)) # 2% below
12027         expect_hi=$(($expect * 102 / 100)) # 2% above
12028
12029         # permit 2% drift above and below
12030         (( $actual >= $expect_lo && $actual <= $expect_hi ))
12031 }
12032
12033 test_104c() {
12034         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12035         [ "$ost1_FSTYPE" == "zfs" ] || skip "zfs only test"
12036
12037         local ost_param="osd-zfs.$FSNAME-OST0000."
12038         local mdt_param="osd-zfs.$FSNAME-MDT0000."
12039         local ofacets=$(get_facets OST)
12040         local mfacets=$(get_facets MDS)
12041         local saved_ost_blocks=
12042         local saved_mdt_blocks=
12043
12044         echo "Before recordsize change"
12045         lfs_df=($($LFS df -h | grep "filesystem_summary:"))
12046         df=($(df -h | grep "$MOUNT"$))
12047
12048         # For checking.
12049         echo "lfs output : ${lfs_df[*]}"
12050         echo "df  output : ${df[*]}"
12051
12052         for facet in ${ofacets//,/ }; do
12053                 if [ -z $saved_ost_blocks ]; then
12054                         saved_ost_blocks=$(do_facet $facet \
12055                                 lctl get_param -n $ost_param.blocksize)
12056                         echo "OST Blocksize: $saved_ost_blocks"
12057                 fi
12058                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
12059                 do_facet $facet zfs set recordsize=32768 $ost
12060         done
12061
12062         # BS too small. Sufficient for functional testing.
12063         for facet in ${mfacets//,/ }; do
12064                 if [ -z $saved_mdt_blocks ]; then
12065                         saved_mdt_blocks=$(do_facet $facet \
12066                                 lctl get_param -n $mdt_param.blocksize)
12067                         echo "MDT Blocksize: $saved_mdt_blocks"
12068                 fi
12069                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
12070                 do_facet $facet zfs set recordsize=32768 $mdt
12071         done
12072
12073         # Give new values chance to reflect change
12074         sleep 2
12075
12076         echo "After recordsize change"
12077         lfs_df_after=($($LFS df -h | grep "filesystem_summary:"))
12078         df_after=($(df -h | grep "$MOUNT"$))
12079
12080         # For checking.
12081         echo "lfs output : ${lfs_df_after[*]}"
12082         echo "df  output : ${df_after[*]}"
12083
12084         # Verify lfs df
12085         value_in_range ${lfs_df_after[1]%.*} ${lfs_df[1]%.*} ||
12086                 error "lfs_df bytes: ${lfs_df_after[1]%.*} != ${lfs_df[1]%.*}"
12087         value_in_range ${lfs_df_after[2]%.*} ${lfs_df[2]%.*} ||
12088                 error "lfs_df used: ${lfs_df_after[2]%.*} != ${lfs_df[2]%.*}"
12089         value_in_range ${lfs_df_after[3]%.*} ${lfs_df[3]%.*} ||
12090                 error "lfs_df avail: ${lfs_df_after[3]%.*} != ${lfs_df[3]%.*}"
12091
12092         # Verify df
12093         value_in_range ${df_after[1]%.*} ${df[1]%.*} ||
12094                 error "df bytes: ${df_after[1]%.*} != ${df[1]%.*}"
12095         value_in_range ${df_after[2]%.*} ${df[2]%.*} ||
12096                 error "df used: ${df_after[2]%.*} != ${df[2]%.*}"
12097         value_in_range ${df_after[3]%.*} ${df[3]%.*} ||
12098                 error "df avail: ${df_after[3]%.*} != ${df[3]%.*}"
12099
12100         # Restore MDT recordize back to original
12101         for facet in ${mfacets//,/ }; do
12102                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
12103                 do_facet $facet zfs set recordsize=$saved_mdt_blocks $mdt
12104         done
12105
12106         # Restore OST recordize back to original
12107         for facet in ${ofacets//,/ }; do
12108                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
12109                 do_facet $facet zfs set recordsize=$saved_ost_blocks $ost
12110         done
12111
12112         return 0
12113 }
12114 run_test 104c "Verify df vs lfs_df stays same after recordsize change"
12115
12116 test_104d() {
12117         (( $RUNAS_ID != $UID )) ||
12118                 skip_env "RUNAS_ID = UID = $UID -- skipping"
12119
12120         (( $CLIENT_VERSION >= $(version_code 2.15.51) )) ||
12121                 skip "lustre version doesn't support lctl dl with non-root"
12122
12123         # debugfs only allows root users to access files, so the
12124         # previous move of the "devices" file to debugfs broke
12125         # "lctl dl" for non-root users. The LU-9680 Netlink
12126         # interface again allows non-root users to list devices.
12127         [ "$($RUNAS $LCTL dl | wc -l)" -ge 3 ] ||
12128                 error "lctl dl doesn't work for non root"
12129
12130         ost_count="$($RUNAS $LCTL dl | grep $FSNAME-OST* | wc -l)"
12131         [ "$ost_count" -eq $OSTCOUNT ]  ||
12132                 error "lctl dl reports wrong number of OST devices"
12133
12134         mdt_count="$($RUNAS $LCTL dl | grep $FSNAME-MDT* | wc -l)"
12135         [ "$mdt_count" -eq $MDSCOUNT ]  ||
12136                 error "lctl dl reports wrong number of MDT devices"
12137 }
12138 run_test 104d "$RUNAS lctl dl test"
12139
12140 test_105a() {
12141         # doesn't work on 2.4 kernels
12142         touch $DIR/$tfile
12143         if $(flock_is_enabled); then
12144                 flocks_test 1 on -f $DIR/$tfile || error "fail flock on"
12145         else
12146                 flocks_test 1 off -f $DIR/$tfile || error "fail flock off"
12147         fi
12148         rm -f $DIR/$tfile
12149 }
12150 run_test 105a "flock when mounted without -o flock test ========"
12151
12152 test_105b() {
12153         touch $DIR/$tfile
12154         if $(flock_is_enabled); then
12155                 flocks_test 1 on -c $DIR/$tfile || error "fail flock on"
12156         else
12157                 flocks_test 1 off -c $DIR/$tfile || error "fail flock off"
12158         fi
12159         rm -f $DIR/$tfile
12160 }
12161 run_test 105b "fcntl when mounted without -o flock test ========"
12162
12163 test_105c() {
12164         touch $DIR/$tfile
12165         if $(flock_is_enabled); then
12166                 flocks_test 1 on -l $DIR/$tfile || error "fail flock on"
12167         else
12168                 flocks_test 1 off -l $DIR/$tfile || error "fail flock off"
12169         fi
12170         rm -f $DIR/$tfile
12171 }
12172 run_test 105c "lockf when mounted without -o flock test"
12173
12174 test_105d() { # bug 15924
12175         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12176
12177         test_mkdir $DIR/$tdir
12178         flock_is_enabled || skip_env "mount w/o flock enabled"
12179         #define OBD_FAIL_LDLM_CP_CB_WAIT  0x315
12180         $LCTL set_param fail_loc=0x80000315
12181         flocks_test 2 $DIR/$tdir
12182 }
12183 run_test 105d "flock race (should not freeze) ========"
12184
12185 test_105e() { # bug 22660 && 22040
12186         flock_is_enabled || skip_env "mount w/o flock enabled"
12187
12188         touch $DIR/$tfile
12189         flocks_test 3 $DIR/$tfile
12190 }
12191 run_test 105e "Two conflicting flocks from same process"
12192
12193 test_106() { #bug 10921
12194         test_mkdir $DIR/$tdir
12195         $DIR/$tdir && error "exec $DIR/$tdir succeeded"
12196         chmod 777 $DIR/$tdir || error "chmod $DIR/$tdir failed"
12197 }
12198 run_test 106 "attempt exec of dir followed by chown of that dir"
12199
12200 test_107() {
12201         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12202
12203         CDIR=`pwd`
12204         local file=core
12205
12206         cd $DIR
12207         rm -f $file
12208
12209         local save_pattern=$(sysctl -n kernel.core_pattern)
12210         local save_uses_pid=$(sysctl -n kernel.core_uses_pid)
12211         sysctl -w kernel.core_pattern=$file
12212         sysctl -w kernel.core_uses_pid=0
12213
12214         ulimit -c unlimited
12215         sleep 60 &
12216         SLEEPPID=$!
12217
12218         sleep 1
12219
12220         kill -s 11 $SLEEPPID
12221         wait $SLEEPPID
12222         if [ -e $file ]; then
12223                 size=`stat -c%s $file`
12224                 [ $size -eq 0 ] && error "Fail to create core file $file"
12225         else
12226                 error "Fail to create core file $file"
12227         fi
12228         rm -f $file
12229         sysctl -w kernel.core_pattern=$save_pattern
12230         sysctl -w kernel.core_uses_pid=$save_uses_pid
12231         cd $CDIR
12232 }
12233 run_test 107 "Coredump on SIG"
12234
12235 test_110() {
12236         test_mkdir $DIR/$tdir
12237         test_mkdir $DIR/$tdir/$(str_repeat 'a' 255)
12238         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/$(str_repeat 'b' 256) &&
12239                 error "mkdir with 256 char should fail, but did not"
12240         touch $DIR/$tdir/$(str_repeat 'x' 255) ||
12241                 error "create with 255 char failed"
12242         touch $DIR/$tdir/$(str_repeat 'y' 256) &&
12243                 error "create with 256 char should fail, but did not"
12244
12245         ls -l $DIR/$tdir
12246         rm -rf $DIR/$tdir
12247 }
12248 run_test 110 "filename length checking"
12249
12250 test_116a() { # was previously test_116()
12251         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12252         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12253         remote_mds_nodsh && skip "remote MDS with nodsh"
12254
12255         echo -n "Free space priority "
12256         do_facet $SINGLEMDS lctl get_param -n lo[vd].*-mdtlov.qos_prio_free |
12257                 head -n1
12258         declare -a AVAIL
12259         free_min_max
12260
12261         [ $MINV -eq 0 ] && skip "no free space in OST$MINI, skip"
12262         [ $MINV -gt 10000000 ] && skip "too much free space in OST$MINI, skip"
12263         stack_trap simple_cleanup_common
12264
12265         # Check if we need to generate uneven OSTs
12266         test_mkdir -p $DIR/$tdir/OST${MINI}
12267         local FILL=$((MINV / 4))
12268         local DIFF=$((MAXV - MINV))
12269         local DIFF2=$((DIFF * 100 / MINV))
12270
12271         local threshold=$(do_facet $SINGLEMDS \
12272                 lctl get_param -n *.*MDT0000-mdtlov.qos_threshold_rr | head -n1)
12273         threshold=${threshold%%%}
12274         echo -n "Check for uneven OSTs: "
12275         echo -n "diff=${DIFF}KB (${DIFF2}%) must be > ${threshold}% ..."
12276
12277         if [[ $DIFF2 -gt $threshold ]]; then
12278                 echo "ok"
12279                 echo "Don't need to fill OST$MINI"
12280         else
12281                 # generate uneven OSTs. Write 2% over the QOS threshold value
12282                 echo "no"
12283                 DIFF=$((threshold - DIFF2 + 2))
12284                 DIFF2=$((MINV * DIFF / 100))
12285                 echo "Fill $DIFF% remaining space in OST$MINI with ${DIFF2}KB"
12286                 $LFS setstripe -i $MINI -c 1 $DIR/$tdir/OST${MINI} ||
12287                         error "setstripe failed"
12288                 DIFF=$((DIFF2 / 2048))
12289                 i=0
12290                 while [ $i -lt $DIFF ]; do
12291                         i=$((i + 1))
12292                         dd if=/dev/zero of=$DIR/$tdir/OST${MINI}/$tfile-$i \
12293                                 bs=2M count=1 2>/dev/null
12294                         echo -n .
12295                 done
12296                 echo .
12297                 sync
12298                 sleep_maxage
12299                 free_min_max
12300         fi
12301
12302         DIFF=$((MAXV - MINV))
12303         DIFF2=$((DIFF * 100 / MINV))
12304         echo -n "diff=$DIFF=$DIFF2% must be > $threshold% for QOS mode..."
12305         if [ $DIFF2 -gt $threshold ]; then
12306                 echo "ok"
12307         else
12308                 skip "QOS imbalance criteria not met"
12309         fi
12310
12311         MINI1=$MINI
12312         MINV1=$MINV
12313         MAXI1=$MAXI
12314         MAXV1=$MAXV
12315
12316         # now fill using QOS
12317         $LFS setstripe -c 1 $DIR/$tdir
12318         FILL=$((FILL / 200))
12319         if [ $FILL -gt 600 ]; then
12320                 FILL=600
12321         fi
12322         echo "writing $FILL files to QOS-assigned OSTs"
12323         i=0
12324         while [ $i -lt $FILL ]; do
12325                 i=$((i + 1))
12326                 dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=200k \
12327                         count=1 2>/dev/null
12328                 echo -n .
12329         done
12330         echo "wrote $i 200k files"
12331         sync
12332         sleep_maxage
12333
12334         echo "Note: free space may not be updated, so measurements might be off"
12335         free_min_max
12336         DIFF2=$((MAXV - MINV))
12337         echo "free space delta: orig $DIFF final $DIFF2"
12338         [ $DIFF2 -gt $DIFF ] && echo "delta got worse!"
12339         DIFF=$((MINV1 - ${AVAIL[$MINI1]}))
12340         echo "Wrote ${DIFF}KB to smaller OST $MINI1"
12341         DIFF2=$((MAXV1 - ${AVAIL[$MAXI1]}))
12342         echo "Wrote ${DIFF2}KB to larger OST $MAXI1"
12343         if [[ $DIFF -gt 0 ]]; then
12344                 FILL=$((DIFF2 * 100 / DIFF - 100))
12345                 echo "Wrote ${FILL}% more data to larger OST $MAXI1"
12346         fi
12347
12348         # Figure out which files were written where
12349         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
12350                awk '/'$MINI1': / {print $2; exit}')
12351         echo $UUID
12352         MINC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
12353         echo "$MINC files created on smaller OST $MINI1"
12354         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
12355                awk '/'$MAXI1': / {print $2; exit}')
12356         echo $UUID
12357         MAXC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
12358         echo "$MAXC files created on larger OST $MAXI1"
12359         if [[ $MINC -gt 0 ]]; then
12360                 FILL=$((MAXC * 100 / MINC - 100))
12361                 echo "Wrote ${FILL}% more files to larger OST $MAXI1"
12362         fi
12363         [[ $MAXC -gt $MINC ]] ||
12364                 error_ignore LU-9 "stripe QOS didn't balance free space"
12365 }
12366 run_test 116a "stripe QOS: free space balance ==================="
12367
12368 test_116b() { # LU-2093
12369         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12370         remote_mds_nodsh && skip "remote MDS with nodsh"
12371
12372 #define OBD_FAIL_MDS_OSC_CREATE_FAIL     0x147
12373         local old_rr=$(do_facet $SINGLEMDS lctl get_param -n \
12374                        lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr | head -1)
12375         [ -z "$old_rr" ] && skip "no QOS"
12376         do_facet $SINGLEMDS lctl set_param \
12377                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=0
12378         mkdir -p $DIR/$tdir
12379         do_facet $SINGLEMDS lctl set_param fail_loc=0x147
12380         createmany -o $DIR/$tdir/f- 20 || error "can't create"
12381         do_facet $SINGLEMDS lctl set_param fail_loc=0
12382         rm -rf $DIR/$tdir
12383         do_facet $SINGLEMDS lctl set_param \
12384                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=$old_rr
12385 }
12386 run_test 116b "QoS shouldn't LBUG if not enough OSTs found on the 2nd pass"
12387
12388 test_117() # bug 10891
12389 {
12390         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12391
12392         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
12393         #define OBD_FAIL_OST_SETATTR_CREDITS 0x21e
12394         lctl set_param fail_loc=0x21e
12395         > $DIR/$tfile || error "truncate failed"
12396         lctl set_param fail_loc=0
12397         echo "Truncate succeeded."
12398         rm -f $DIR/$tfile
12399 }
12400 run_test 117 "verify osd extend =========="
12401
12402 NO_SLOW_RESENDCOUNT=4
12403 export OLD_RESENDCOUNT=""
12404 set_resend_count () {
12405         local PROC_RESENDCOUNT="osc.${FSNAME}-OST*-osc-*.resend_count"
12406         OLD_RESENDCOUNT=$(lctl get_param -n $PROC_RESENDCOUNT | head -n1)
12407         lctl set_param -n $PROC_RESENDCOUNT $1
12408         echo resend_count is set to $(lctl get_param -n $PROC_RESENDCOUNT)
12409 }
12410
12411 # for reduce test_118* time (b=14842)
12412 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
12413
12414 # Reset async IO behavior after error case
12415 reset_async() {
12416         FILE=$DIR/reset_async
12417
12418         # Ensure all OSCs are cleared
12419         $LFS setstripe -c -1 $FILE
12420         dd if=/dev/zero of=$FILE bs=64k count=$OSTCOUNT
12421         sync
12422         rm $FILE
12423 }
12424
12425 test_118a() #bug 11710
12426 {
12427         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12428
12429         reset_async
12430
12431         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12432         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12433         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
12434
12435         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12436                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12437                 return 1;
12438         fi
12439         rm -f $DIR/$tfile
12440 }
12441 run_test 118a "verify O_SYNC works =========="
12442
12443 test_118b()
12444 {
12445         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12446         remote_ost_nodsh && skip "remote OST with nodsh"
12447
12448         reset_async
12449
12450         #define OBD_FAIL_SRV_ENOENT 0x217
12451         set_nodes_failloc "$(osts_nodes)" 0x217
12452         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12453         RC=$?
12454         set_nodes_failloc "$(osts_nodes)" 0
12455         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12456         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12457                     grep -c writeback)
12458
12459         if [[ $RC -eq 0 ]]; then
12460                 error "Must return error due to dropped pages, rc=$RC"
12461                 return 1;
12462         fi
12463
12464         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12465                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12466                 return 1;
12467         fi
12468
12469         echo "Dirty pages not leaked on ENOENT"
12470
12471         # Due to the above error the OSC will issue all RPCs syncronously
12472         # until a subsequent RPC completes successfully without error.
12473         $MULTIOP $DIR/$tfile Ow4096yc
12474         rm -f $DIR/$tfile
12475
12476         return 0
12477 }
12478 run_test 118b "Reclaim dirty pages on fatal error =========="
12479
12480 test_118c()
12481 {
12482         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12483
12484         # for 118c, restore the original resend count, LU-1940
12485         [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] &&
12486                                 set_resend_count $OLD_RESENDCOUNT
12487         remote_ost_nodsh && skip "remote OST with nodsh"
12488
12489         reset_async
12490
12491         #define OBD_FAIL_OST_EROFS               0x216
12492         set_nodes_failloc "$(osts_nodes)" 0x216
12493
12494         # multiop should block due to fsync until pages are written
12495         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
12496         MULTIPID=$!
12497         sleep 1
12498
12499         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
12500                 error "Multiop failed to block on fsync, pid=$MULTIPID"
12501         fi
12502
12503         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12504                     grep -c writeback)
12505         if [[ $WRITEBACK -eq 0 ]]; then
12506                 error "No page in writeback, writeback=$WRITEBACK"
12507         fi
12508
12509         set_nodes_failloc "$(osts_nodes)" 0
12510         wait $MULTIPID
12511         RC=$?
12512         if [[ $RC -ne 0 ]]; then
12513                 error "Multiop fsync failed, rc=$RC"
12514         fi
12515
12516         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12517         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12518                     grep -c writeback)
12519         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12520                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12521         fi
12522
12523         rm -f $DIR/$tfile
12524         echo "Dirty pages flushed via fsync on EROFS"
12525         return 0
12526 }
12527 run_test 118c "Fsync blocks on EROFS until dirty pages are flushed =========="
12528
12529 # continue to use small resend count to reduce test_118* time (b=14842)
12530 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
12531
12532 test_118d()
12533 {
12534         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12535         remote_ost_nodsh && skip "remote OST with nodsh"
12536
12537         reset_async
12538
12539         #define OBD_FAIL_OST_BRW_PAUSE_BULK
12540         set_nodes_failloc "$(osts_nodes)" 0x214
12541         # multiop should block due to fsync until pages are written
12542         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
12543         MULTIPID=$!
12544         sleep 1
12545
12546         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
12547                 error "Multiop failed to block on fsync, pid=$MULTIPID"
12548         fi
12549
12550         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12551                     grep -c writeback)
12552         if [[ $WRITEBACK -eq 0 ]]; then
12553                 error "No page in writeback, writeback=$WRITEBACK"
12554         fi
12555
12556         wait $MULTIPID || error "Multiop fsync failed, rc=$?"
12557         set_nodes_failloc "$(osts_nodes)" 0
12558
12559         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12560         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12561                     grep -c writeback)
12562         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12563                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12564         fi
12565
12566         rm -f $DIR/$tfile
12567         echo "Dirty pages gaurenteed flushed via fsync"
12568         return 0
12569 }
12570 run_test 118d "Fsync validation inject a delay of the bulk =========="
12571
12572 test_118f() {
12573         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12574
12575         reset_async
12576
12577         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
12578         lctl set_param fail_loc=0x8000040a
12579
12580         # Should simulate EINVAL error which is fatal
12581         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12582         RC=$?
12583         if [[ $RC -eq 0 ]]; then
12584                 error "Must return error due to dropped pages, rc=$RC"
12585         fi
12586
12587         lctl set_param fail_loc=0x0
12588
12589         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12590         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12591         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12592                     grep -c writeback)
12593         if [[ $LOCKED -ne 0 ]]; then
12594                 error "Locked pages remain in cache, locked=$LOCKED"
12595         fi
12596
12597         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12598                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12599         fi
12600
12601         rm -f $DIR/$tfile
12602         echo "No pages locked after fsync"
12603
12604         reset_async
12605         return 0
12606 }
12607 run_test 118f "Simulate unrecoverable OSC side error =========="
12608
12609 test_118g() {
12610         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12611
12612         reset_async
12613
12614         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
12615         lctl set_param fail_loc=0x406
12616
12617         # simulate local -ENOMEM
12618         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12619         RC=$?
12620
12621         lctl set_param fail_loc=0
12622         if [[ $RC -eq 0 ]]; then
12623                 error "Must return error due to dropped pages, rc=$RC"
12624         fi
12625
12626         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12627         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12628         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12629                         grep -c writeback)
12630         if [[ $LOCKED -ne 0 ]]; then
12631                 error "Locked pages remain in cache, locked=$LOCKED"
12632         fi
12633
12634         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12635                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12636         fi
12637
12638         rm -f $DIR/$tfile
12639         echo "No pages locked after fsync"
12640
12641         reset_async
12642         return 0
12643 }
12644 run_test 118g "Don't stay in wait if we got local -ENOMEM  =========="
12645
12646 test_118h() {
12647         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12648         remote_ost_nodsh && skip "remote OST with nodsh"
12649
12650         reset_async
12651
12652         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
12653         set_nodes_failloc "$(osts_nodes)" 0x20e
12654         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
12655         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12656         RC=$?
12657
12658         set_nodes_failloc "$(osts_nodes)" 0
12659         if [[ $RC -eq 0 ]]; then
12660                 error "Must return error due to dropped pages, rc=$RC"
12661         fi
12662
12663         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12664         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12665         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12666                     grep -c writeback)
12667         if [[ $LOCKED -ne 0 ]]; then
12668                 error "Locked pages remain in cache, locked=$LOCKED"
12669         fi
12670
12671         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12672                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12673         fi
12674
12675         rm -f $DIR/$tfile
12676         echo "No pages locked after fsync"
12677
12678         return 0
12679 }
12680 run_test 118h "Verify timeout in handling recoverables errors  =========="
12681
12682 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
12683
12684 test_118i() {
12685         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12686         remote_ost_nodsh && skip "remote OST with nodsh"
12687
12688         reset_async
12689
12690         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
12691         set_nodes_failloc "$(osts_nodes)" 0x20e
12692
12693         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
12694         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
12695         PID=$!
12696         sleep 5
12697         set_nodes_failloc "$(osts_nodes)" 0
12698
12699         wait $PID
12700         RC=$?
12701         if [[ $RC -ne 0 ]]; then
12702                 error "got error, but should be not, rc=$RC"
12703         fi
12704
12705         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12706         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12707         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
12708         if [[ $LOCKED -ne 0 ]]; then
12709                 error "Locked pages remain in cache, locked=$LOCKED"
12710         fi
12711
12712         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12713                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12714         fi
12715
12716         rm -f $DIR/$tfile
12717         echo "No pages locked after fsync"
12718
12719         return 0
12720 }
12721 run_test 118i "Fix error before timeout in recoverable error  =========="
12722
12723 [ "$SLOW" = "no" ] && set_resend_count 4
12724
12725 test_118j() {
12726         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12727         remote_ost_nodsh && skip "remote OST with nodsh"
12728
12729         reset_async
12730
12731         #define OBD_FAIL_OST_BRW_WRITE_BULK2     0x220
12732         set_nodes_failloc "$(osts_nodes)" 0x220
12733
12734         # return -EIO from OST
12735         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12736         RC=$?
12737         set_nodes_failloc "$(osts_nodes)" 0x0
12738         if [[ $RC -eq 0 ]]; then
12739                 error "Must return error due to dropped pages, rc=$RC"
12740         fi
12741
12742         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12743         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12744         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
12745         if [[ $LOCKED -ne 0 ]]; then
12746                 error "Locked pages remain in cache, locked=$LOCKED"
12747         fi
12748
12749         # in recoverable error on OST we want resend and stay until it finished
12750         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12751                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12752         fi
12753
12754         rm -f $DIR/$tfile
12755         echo "No pages locked after fsync"
12756
12757         return 0
12758 }
12759 run_test 118j "Simulate unrecoverable OST side error =========="
12760
12761 test_118k()
12762 {
12763         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12764         remote_ost_nodsh && skip "remote OSTs with nodsh"
12765
12766         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
12767         set_nodes_failloc "$(osts_nodes)" 0x20e
12768         test_mkdir $DIR/$tdir
12769
12770         for ((i=0;i<10;i++)); do
12771                 (dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=1M count=10 || \
12772                         error "dd to $DIR/$tdir/$tfile-$i failed" )&
12773                 SLEEPPID=$!
12774                 sleep 0.500s
12775                 kill $SLEEPPID
12776                 wait $SLEEPPID
12777         done
12778
12779         set_nodes_failloc "$(osts_nodes)" 0
12780         rm -rf $DIR/$tdir
12781 }
12782 run_test 118k "bio alloc -ENOMEM and IO TERM handling ========="
12783
12784 test_118l() # LU-646
12785 {
12786         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12787
12788         test_mkdir $DIR/$tdir
12789         $MULTIOP $DIR/$tdir Dy || error "fsync dir failed"
12790         rm -rf $DIR/$tdir
12791 }
12792 run_test 118l "fsync dir"
12793
12794 test_118m() # LU-3066
12795 {
12796         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12797
12798         test_mkdir $DIR/$tdir
12799         $MULTIOP $DIR/$tdir DY || error "fdatasync dir failed"
12800         rm -rf $DIR/$tdir
12801 }
12802 run_test 118m "fdatasync dir ========="
12803
12804 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
12805
12806 test_118n()
12807 {
12808         local begin
12809         local end
12810
12811         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12812         remote_ost_nodsh && skip "remote OSTs with nodsh"
12813
12814         # Sleep to avoid a cached response.
12815         #define OBD_STATFS_CACHE_SECONDS 1
12816         sleep 2
12817
12818         # Inject a 10 second delay in the OST_STATFS handler.
12819         #define OBD_FAIL_OST_STATFS_DELAY 0x242
12820         set_nodes_failloc "$(osts_nodes)" 0x242
12821
12822         begin=$SECONDS
12823         stat --file-system $MOUNT > /dev/null
12824         end=$SECONDS
12825
12826         set_nodes_failloc "$(osts_nodes)" 0
12827
12828         if ((end - begin > 20)); then
12829             error "statfs took $((end - begin)) seconds, expected 10"
12830         fi
12831 }
12832 run_test 118n "statfs() sends OST_STATFS requests in parallel"
12833
12834 test_119a() # bug 11737
12835 {
12836         BSIZE=$((512 * 1024))
12837         directio write $DIR/$tfile 0 1 $BSIZE
12838         # We ask to read two blocks, which is more than a file size.
12839         # directio will indicate an error when requested and actual
12840         # sizes aren't equeal (a normal situation in this case) and
12841         # print actual read amount.
12842         NOB=`directio read $DIR/$tfile 0 2 $BSIZE | awk '/error/ {print $6}'`
12843         if [ "$NOB" != "$BSIZE" ]; then
12844                 error "read $NOB bytes instead of $BSIZE"
12845         fi
12846         rm -f $DIR/$tfile
12847 }
12848 run_test 119a "Short directIO read must return actual read amount"
12849
12850 test_119b() # bug 11737
12851 {
12852         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12853
12854         $LFS setstripe -c 2 $DIR/$tfile || error "setstripe failed"
12855         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1 || error "dd failed"
12856         sync
12857         $MULTIOP $DIR/$tfile oO_RDONLY:O_DIRECT:r$((2048 * 1024)) ||
12858                 error "direct read failed"
12859         rm -f $DIR/$tfile
12860 }
12861 run_test 119b "Sparse directIO read must return actual read amount"
12862
12863 test_119c() # bug 13099
12864 {
12865         BSIZE=1048576
12866         directio write $DIR/$tfile 3 1 $BSIZE || error "direct write failed"
12867         directio readhole $DIR/$tfile 0 2 $BSIZE || error "reading hole failed"
12868         rm -f $DIR/$tfile
12869 }
12870 run_test 119c "Testing for direct read hitting hole"
12871
12872 test_119d() # bug 15950
12873 {
12874         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12875
12876         MAX_RPCS_IN_FLIGHT=`$LCTL get_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight`
12877         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight 1
12878         BSIZE=1048576
12879         $LFS setstripe $DIR/$tfile -i 0 -c 1 || error "setstripe failed"
12880         $DIRECTIO write $DIR/$tfile 0 1 $BSIZE || error "first directio failed"
12881         #define OBD_FAIL_OSC_DIO_PAUSE           0x40d
12882         lctl set_param fail_loc=0x40d
12883         $DIRECTIO write $DIR/$tfile 1 4 $BSIZE &
12884         pid_dio=$!
12885         sleep 1
12886         cat $DIR/$tfile > /dev/null &
12887         lctl set_param fail_loc=0
12888         pid_reads=$!
12889         wait $pid_dio
12890         log "the DIO writes have completed, now wait for the reads (should not block very long)"
12891         sleep 2
12892         [ -n "`ps h -p $pid_reads -o comm`" ] && \
12893         error "the read rpcs have not completed in 2s"
12894         rm -f $DIR/$tfile
12895         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight $MAX_RPCS_IN_FLIGHT
12896 }
12897 run_test 119d "The DIO path should try to send a new rpc once one is completed"
12898
12899 test_120a() {
12900         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12901         remote_mds_nodsh && skip "remote MDS with nodsh"
12902         test_mkdir -i0 -c1 $DIR/$tdir
12903         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12904                 skip_env "no early lock cancel on server"
12905
12906         lru_resize_disable mdc
12907         lru_resize_disable osc
12908         cancel_lru_locks mdc
12909         # asynchronous object destroy at MDT could cause bl ast to client
12910         cancel_lru_locks osc
12911
12912         stat $DIR/$tdir > /dev/null
12913         can1=$(do_facet mds1 \
12914                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12915                awk '/ldlm_cancel/ {print $2}')
12916         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12917                awk '/ldlm_bl_callback/ {print $2}')
12918         test_mkdir -i0 -c1 $DIR/$tdir/d1
12919         can2=$(do_facet mds1 \
12920                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12921                awk '/ldlm_cancel/ {print $2}')
12922         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12923                awk '/ldlm_bl_callback/ {print $2}')
12924         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12925         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12926         lru_resize_enable mdc
12927         lru_resize_enable osc
12928 }
12929 run_test 120a "Early Lock Cancel: mkdir test"
12930
12931 test_120b() {
12932         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12933         remote_mds_nodsh && skip "remote MDS with nodsh"
12934         test_mkdir $DIR/$tdir
12935         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12936                 skip_env "no early lock cancel on server"
12937
12938         lru_resize_disable mdc
12939         lru_resize_disable osc
12940         cancel_lru_locks mdc
12941         stat $DIR/$tdir > /dev/null
12942         can1=$(do_facet $SINGLEMDS \
12943                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12944                awk '/ldlm_cancel/ {print $2}')
12945         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12946                awk '/ldlm_bl_callback/ {print $2}')
12947         touch $DIR/$tdir/f1
12948         can2=$(do_facet $SINGLEMDS \
12949                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12950                awk '/ldlm_cancel/ {print $2}')
12951         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12952                awk '/ldlm_bl_callback/ {print $2}')
12953         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12954         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12955         lru_resize_enable mdc
12956         lru_resize_enable osc
12957 }
12958 run_test 120b "Early Lock Cancel: create test"
12959
12960 test_120c() {
12961         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12962         remote_mds_nodsh && skip "remote MDS with nodsh"
12963         test_mkdir -i0 -c1 $DIR/$tdir
12964         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12965                 skip "no early lock cancel on server"
12966
12967         lru_resize_disable mdc
12968         lru_resize_disable osc
12969         test_mkdir -i0 -c1 $DIR/$tdir/d1
12970         test_mkdir -i0 -c1 $DIR/$tdir/d2
12971         touch $DIR/$tdir/d1/f1
12972         cancel_lru_locks mdc
12973         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 > /dev/null
12974         can1=$(do_facet mds1 \
12975                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12976                awk '/ldlm_cancel/ {print $2}')
12977         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12978                awk '/ldlm_bl_callback/ {print $2}')
12979         ln $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
12980         can2=$(do_facet mds1 \
12981                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12982                awk '/ldlm_cancel/ {print $2}')
12983         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12984                awk '/ldlm_bl_callback/ {print $2}')
12985         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12986         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12987         lru_resize_enable mdc
12988         lru_resize_enable osc
12989 }
12990 run_test 120c "Early Lock Cancel: link test"
12991
12992 test_120d() {
12993         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12994         remote_mds_nodsh && skip "remote MDS with nodsh"
12995         test_mkdir -i0 -c1 $DIR/$tdir
12996         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12997                 skip_env "no early lock cancel on server"
12998
12999         lru_resize_disable mdc
13000         lru_resize_disable osc
13001         touch $DIR/$tdir
13002         cancel_lru_locks mdc
13003         stat $DIR/$tdir > /dev/null
13004         can1=$(do_facet mds1 \
13005                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13006                awk '/ldlm_cancel/ {print $2}')
13007         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13008                awk '/ldlm_bl_callback/ {print $2}')
13009         chmod a+x $DIR/$tdir
13010         can2=$(do_facet mds1 \
13011                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13012                awk '/ldlm_cancel/ {print $2}')
13013         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13014                awk '/ldlm_bl_callback/ {print $2}')
13015         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
13016         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
13017         lru_resize_enable mdc
13018         lru_resize_enable osc
13019 }
13020 run_test 120d "Early Lock Cancel: setattr test"
13021
13022 test_120e() {
13023         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13024         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13025                 skip_env "no early lock cancel on server"
13026         remote_mds_nodsh && skip "remote MDS with nodsh"
13027
13028         local dlmtrace_set=false
13029
13030         test_mkdir -i0 -c1 $DIR/$tdir
13031         lru_resize_disable mdc
13032         lru_resize_disable osc
13033         ! $LCTL get_param debug | grep -q dlmtrace &&
13034                 $LCTL set_param debug=+dlmtrace && dlmtrace_set=true
13035         dd if=/dev/zero of=$DIR/$tdir/f1 count=1
13036         cancel_lru_locks mdc
13037         cancel_lru_locks osc
13038         dd if=$DIR/$tdir/f1 of=/dev/null
13039         stat $DIR/$tdir $DIR/$tdir/f1 > /dev/null
13040         # XXX client can not do early lock cancel of OST lock
13041         # during unlink (LU-4206), so cancel osc lock now.
13042         sleep 2
13043         cancel_lru_locks osc
13044         can1=$(do_facet mds1 \
13045                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13046                awk '/ldlm_cancel/ {print $2}')
13047         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13048                awk '/ldlm_bl_callback/ {print $2}')
13049         unlink $DIR/$tdir/f1
13050         sleep 5
13051         can2=$(do_facet mds1 \
13052                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13053                awk '/ldlm_cancel/ {print $2}')
13054         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13055                awk '/ldlm_bl_callback/ {print $2}')
13056         [ $can1 -ne $can2 ] && error "$((can2 - can1)) cancel RPC occured" &&
13057                 $LCTL dk $TMP/cancel.debug.txt
13058         [ $blk1 -ne $blk2 ] && error "$((blk2 - blk1)) blocking RPC occured" &&
13059                 $LCTL dk $TMP/blocking.debug.txt
13060         $dlmtrace_set && $LCTL set_param debug=-dlmtrace
13061         lru_resize_enable mdc
13062         lru_resize_enable osc
13063 }
13064 run_test 120e "Early Lock Cancel: unlink test"
13065
13066 test_120f() {
13067         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13068         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13069                 skip_env "no early lock cancel on server"
13070         remote_mds_nodsh && skip "remote MDS with nodsh"
13071
13072         test_mkdir -i0 -c1 $DIR/$tdir
13073         lru_resize_disable mdc
13074         lru_resize_disable osc
13075         test_mkdir -i0 -c1 $DIR/$tdir/d1
13076         test_mkdir -i0 -c1 $DIR/$tdir/d2
13077         dd if=/dev/zero of=$DIR/$tdir/d1/f1 count=1
13078         dd if=/dev/zero of=$DIR/$tdir/d2/f2 count=1
13079         cancel_lru_locks mdc
13080         cancel_lru_locks osc
13081         dd if=$DIR/$tdir/d1/f1 of=/dev/null
13082         dd if=$DIR/$tdir/d2/f2 of=/dev/null
13083         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2 > /dev/null
13084         # XXX client can not do early lock cancel of OST lock
13085         # during rename (LU-4206), so cancel osc lock now.
13086         sleep 2
13087         cancel_lru_locks osc
13088         can1=$(do_facet mds1 \
13089                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13090                awk '/ldlm_cancel/ {print $2}')
13091         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13092                awk '/ldlm_bl_callback/ {print $2}')
13093         mrename $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
13094         sleep 5
13095         can2=$(do_facet mds1 \
13096                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13097                awk '/ldlm_cancel/ {print $2}')
13098         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13099                awk '/ldlm_bl_callback/ {print $2}')
13100         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
13101         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
13102         lru_resize_enable mdc
13103         lru_resize_enable osc
13104 }
13105 run_test 120f "Early Lock Cancel: rename test"
13106
13107 test_120g() {
13108         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13109         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13110                 skip_env "no early lock cancel on server"
13111         remote_mds_nodsh && skip "remote MDS with nodsh"
13112
13113         lru_resize_disable mdc
13114         lru_resize_disable osc
13115         count=10000
13116         echo create $count files
13117         test_mkdir $DIR/$tdir
13118         cancel_lru_locks mdc
13119         cancel_lru_locks osc
13120         t0=$(date +%s)
13121
13122         can0=$(do_facet $SINGLEMDS \
13123                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13124                awk '/ldlm_cancel/ {print $2}')
13125         blk0=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13126                awk '/ldlm_bl_callback/ {print $2}')
13127         createmany -o $DIR/$tdir/f $count
13128         sync
13129         can1=$(do_facet $SINGLEMDS \
13130                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13131                awk '/ldlm_cancel/ {print $2}')
13132         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13133                awk '/ldlm_bl_callback/ {print $2}')
13134         t1=$(date +%s)
13135         echo total: $((can1-can0)) cancels, $((blk1-blk0)) blockings
13136         echo rm $count files
13137         rm -r $DIR/$tdir
13138         sync
13139         can2=$(do_facet $SINGLEMDS \
13140                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13141                awk '/ldlm_cancel/ {print $2}')
13142         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13143                awk '/ldlm_bl_callback/ {print $2}')
13144         t2=$(date +%s)
13145         echo total: $count removes in $((t2-t1))
13146         echo total: $((can2-can1)) cancels, $((blk2-blk1)) blockings
13147         sleep 2
13148         # wait for commitment of removal
13149         lru_resize_enable mdc
13150         lru_resize_enable osc
13151 }
13152 run_test 120g "Early Lock Cancel: performance test"
13153
13154 test_121() { #bug #10589
13155         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13156
13157         rm -rf $DIR/$tfile
13158         writes=$(LANG=C dd if=/dev/zero of=$DIR/$tfile count=1 2>&1 | awk -F '+' '/out$/ {print $1}')
13159 #define OBD_FAIL_LDLM_CANCEL_RACE        0x310
13160         lctl set_param fail_loc=0x310
13161         cancel_lru_locks osc > /dev/null
13162         reads=$(LANG=C dd if=$DIR/$tfile of=/dev/null 2>&1 | awk -F '+' '/in$/ {print $1}')
13163         lctl set_param fail_loc=0
13164         [[ $reads -eq $writes ]] ||
13165                 error "read $reads blocks, must be $writes blocks"
13166 }
13167 run_test 121 "read cancel race ========="
13168
13169 test_123a_base() { # was test 123, statahead(bug 11401)
13170         local lsx="$1"
13171
13172         SLOWOK=0
13173         if ! grep -q "processor.*: 1" /proc/cpuinfo; then
13174                 log "testing UP system. Performance may be lower than expected."
13175                 SLOWOK=1
13176         fi
13177         running_in_vm && SLOWOK=1
13178
13179         rm -rf $DIR/$tdir
13180         test_mkdir $DIR/$tdir
13181         NUMFREE=$(df -i -P $DIR | tail -n 1 | awk '{ print $4 }')
13182         [[ $NUMFREE -gt 100000 ]] && NUMFREE=100000 || NUMFREE=$((NUMFREE-1000))
13183         MULT=10
13184         for ((i=100, j=0; i<=$NUMFREE; j=$i, i=$((i * MULT)) )); do
13185                 createmany -o $DIR/$tdir/$tfile $j $((i - j))
13186
13187                 max=$(lctl get_param -n llite.*.statahead_max | head -n 1)
13188                 lctl set_param -n llite.*.statahead_max 0
13189                 lctl get_param llite.*.statahead_max
13190                 cancel_lru_locks mdc
13191                 cancel_lru_locks osc
13192                 stime=$(date +%s)
13193                 time $lsx $DIR/$tdir | wc -l
13194                 etime=$(date +%s)
13195                 delta=$((etime - stime))
13196                 log "$lsx $i files without statahead: $delta sec"
13197                 lctl set_param llite.*.statahead_max=$max
13198
13199                 swrong=$(lctl get_param -n llite.*.statahead_stats |
13200                          awk '/statahead.wrong:/ { print $NF }')
13201                 lctl get_param -n llite.*.statahead_max | grep '[0-9]'
13202                 cancel_lru_locks mdc
13203                 cancel_lru_locks osc
13204                 stime=$(date +%s)
13205                 time $lsx $DIR/$tdir | wc -l
13206                 etime=$(date +%s)
13207                 delta_sa=$((etime - stime))
13208                 log "$lsx $i files with statahead: $delta_sa sec"
13209                 lctl get_param -n llite.*.statahead_stats
13210                 ewrong=$(lctl get_param -n llite.*.statahead_stats |
13211                          awk '/statahead.wrong:/ { print $NF }')
13212
13213                 [[ $swrong -lt $ewrong ]] &&
13214                         log "statahead was stopped, maybe too many locks held!"
13215                 [[ $delta -eq 0 || $delta_sa -eq 0 ]] && continue
13216
13217                 if (( $delta_sa*100 > $delta*105 && $delta_sa > $delta+2)); then
13218                         max=$(lctl get_param -n llite.*.statahead_max |
13219                                 head -n 1)
13220                         lctl set_param -n llite.*.statahead_max 0
13221                         lctl get_param llite.*.statahead_max
13222                         cancel_lru_locks mdc
13223                         cancel_lru_locks osc
13224                         stime=$(date +%s)
13225                         time $lsx $DIR/$tdir | wc -l
13226                         etime=$(date +%s)
13227                         delta=$((etime - stime))
13228                         log "$lsx $i files again without statahead: $delta sec"
13229                         lctl set_param llite.*.statahead_max=$max
13230                         if (( $delta_sa*100 > delta*105 && delta_sa > delta+2 )); then
13231                                 if [ $SLOWOK -eq 0 ]; then
13232                                         error "$lsx $i files is slower with statahead!"
13233                                 else
13234                                         log "$lsx $i files is slower with statahead!"
13235                                 fi
13236                                 break
13237                         fi
13238                 fi
13239
13240                 [ $delta -gt 20 ] && break
13241                 [ $delta -gt 8 ] && MULT=$((50 / delta))
13242                 [ "$SLOW" = "no" -a $delta -gt 5 ] && break
13243         done
13244         log "$lsx done"
13245
13246         stime=$(date +%s)
13247         rm -r $DIR/$tdir
13248         sync
13249         etime=$(date +%s)
13250         delta=$((etime - stime))
13251         log "rm -r $DIR/$tdir/: $delta seconds"
13252         log "rm done"
13253         lctl get_param -n llite.*.statahead_stats
13254 }
13255
13256 test_123aa() {
13257         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13258
13259         test_123a_base "ls -l"
13260 }
13261 run_test 123aa "verify statahead work"
13262
13263 test_123ab() {
13264         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13265
13266         statx_supported || skip_env "Test must be statx() syscall supported"
13267
13268         test_123a_base "$STATX -l"
13269 }
13270 run_test 123ab "verify statahead work by using statx"
13271
13272 test_123ac() {
13273         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13274
13275         statx_supported || skip_env "Test must be statx() syscall supported"
13276
13277         local rpcs_before
13278         local rpcs_after
13279         local agl_before
13280         local agl_after
13281
13282         cancel_lru_locks $OSC
13283         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
13284         agl_before=$($LCTL get_param -n llite.*.statahead_stats |
13285                      awk '/agl.total:/ { print $NF }')
13286         test_123a_base "$STATX -c \"%n %i %A %h %u %g %W %X %Z\" -D"
13287         test_123a_base "$STATX --cached=always -D"
13288         agl_after=$($LCTL get_param -n llite.*.statahead_stats |
13289                     awk '/agl.total:/ { print $NF }')
13290         [ $agl_before -eq $agl_after ] ||
13291                 error "Should not trigger AGL thread - $agl_before:$agl_after"
13292         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
13293         [ $rpcs_after -eq $rpcs_before ] ||
13294                 error "$STATX should not send glimpse RPCs to $OSC"
13295 }
13296 run_test 123ac "verify statahead work by using statx without glimpse RPCs"
13297
13298 test_123b () { # statahead(bug 15027)
13299         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13300
13301         test_mkdir $DIR/$tdir
13302         createmany -o $DIR/$tdir/$tfile-%d 1000
13303
13304         cancel_lru_locks mdc
13305         cancel_lru_locks osc
13306
13307 #define OBD_FAIL_MDC_GETATTR_ENQUEUE     0x803
13308         lctl set_param fail_loc=0x80000803
13309         ls -lR $DIR/$tdir > /dev/null
13310         log "ls done"
13311         lctl set_param fail_loc=0x0
13312         lctl get_param -n llite.*.statahead_stats
13313         rm -r $DIR/$tdir
13314         sync
13315
13316 }
13317 run_test 123b "not panic with network error in statahead enqueue (bug 15027)"
13318
13319 test_123c() {
13320         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
13321
13322         test_mkdir -i 0 -c 1 $DIR/$tdir.0
13323         test_mkdir -i 1 -c 1 $DIR/$tdir.1
13324         touch $DIR/$tdir.1/{1..3}
13325         mv $DIR/$tdir.1/{1..3} $DIR/$tdir.0
13326
13327         remount_client $MOUNT
13328
13329         $MULTIOP $DIR/$tdir.0 Q
13330
13331         # let statahead to complete
13332         ls -l $DIR/$tdir.0 > /dev/null
13333
13334         testid=$(echo $TESTNAME | tr '_' ' ')
13335         dmesg | tac | sed "/$testid/,$ d" | grep "Can not initialize inode" &&
13336                 error "statahead warning" || true
13337 }
13338 run_test 123c "Can not initialize inode warning on DNE statahead"
13339
13340 test_123d() {
13341         local num=100
13342         local swrong
13343         local ewrong
13344
13345         test_mkdir -c -1 $DIR/$tdir || error "test_mkdir $DIR/$tdir failed"
13346         $LFS setdirstripe -D -c $MDSCOUNT $DIR/$tdir ||
13347                 error "setdirstripe $DIR/$tdir failed"
13348         createmany -d $DIR/$tdir/$tfile $num || error "createmany $num failed"
13349         remount_client $MOUNT
13350         $LCTL get_param llite.*.statahead_max
13351         $LCTL set_param llite.*.statahead_stats=0 ||
13352                 error "clear statahead_stats failed"
13353         swrong=$(lctl get_param -n llite.*.statahead_stats |
13354                  awk '/statahead.wrong:/ { print $NF }')
13355         ls -l $DIR/$tdir || error "ls -l $DIR/$tdir failed"
13356         # wait for statahead thread finished to update hit/miss stats.
13357         sleep 1
13358         $LCTL get_param -n llite.*.statahead_stats
13359         ewrong=$(lctl get_param -n llite.*.statahead_stats |
13360                  awk '/statahead.wrong:/ { print $NF }')
13361         (( $swrong == $ewrong )) ||
13362                 log "statahead was stopped, maybe too many locks held!"
13363 }
13364 run_test 123d "Statahead on striped directories works correctly"
13365
13366 test_124a() {
13367         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13368         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13369                 skip_env "no lru resize on server"
13370
13371         local NR=2000
13372
13373         test_mkdir $DIR/$tdir
13374
13375         log "create $NR files at $DIR/$tdir"
13376         createmany -o $DIR/$tdir/f $NR ||
13377                 error "failed to create $NR files in $DIR/$tdir"
13378
13379         cancel_lru_locks mdc
13380         ls -l $DIR/$tdir > /dev/null
13381
13382         local NSDIR=""
13383         local LRU_SIZE=0
13384         for VALUE in $($LCTL get_param ldlm.namespaces.*mdc-*.lru_size); do
13385                 local PARAM=$(echo ${VALUE[0]} | cut -d "=" -f1)
13386                 LRU_SIZE=$($LCTL get_param -n $PARAM)
13387                 if [[ $LRU_SIZE -gt $(default_lru_size) ]]; then
13388                         NSDIR=$(echo $PARAM | cut -d "." -f1-3)
13389                         log "NSDIR=$NSDIR"
13390                         log "NS=$(basename $NSDIR)"
13391                         break
13392                 fi
13393         done
13394
13395         if [[ -z "$NSDIR" || $LRU_SIZE -lt $(default_lru_size) ]]; then
13396                 skip "Not enough cached locks created!"
13397         fi
13398         log "LRU=$LRU_SIZE"
13399
13400         local SLEEP=30
13401
13402         # We know that lru resize allows one client to hold $LIMIT locks
13403         # for 10h. After that locks begin to be killed by client.
13404         local MAX_HRS=10
13405         local LIMIT=$($LCTL get_param -n $NSDIR.pool.limit)
13406         log "LIMIT=$LIMIT"
13407         if [ $LIMIT -lt $LRU_SIZE ]; then
13408                 skip "Limit is too small $LIMIT"
13409         fi
13410
13411         # Make LVF so higher that sleeping for $SLEEP is enough to _start_
13412         # killing locks. Some time was spent for creating locks. This means
13413         # that up to the moment of sleep finish we must have killed some of
13414         # them (10-100 locks). This depends on how fast ther were created.
13415         # Many of them were touched in almost the same moment and thus will
13416         # be killed in groups.
13417         local LVF=$(($MAX_HRS * 60 * 60 / $SLEEP * $LIMIT / $LRU_SIZE * 100))
13418
13419         # Use $LRU_SIZE_B here to take into account real number of locks
13420         # created in the case of CMD, LRU_SIZE_B != $NR in most of cases
13421         local LRU_SIZE_B=$LRU_SIZE
13422         log "LVF=$LVF"
13423         local OLD_LVF=$($LCTL get_param -n $NSDIR.pool.lock_volume_factor)
13424         log "OLD_LVF=$OLD_LVF"
13425         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $LVF
13426
13427         # Let's make sure that we really have some margin. Client checks
13428         # cached locks every 10 sec.
13429         SLEEP=$((SLEEP+20))
13430         log "Sleep ${SLEEP} sec"
13431         local SEC=0
13432         while ((SEC<$SLEEP)); do
13433                 echo -n "..."
13434                 sleep 5
13435                 SEC=$((SEC+5))
13436                 LRU_SIZE=$($LCTL get_param -n $NSDIR/lru_size)
13437                 echo -n "$LRU_SIZE"
13438         done
13439         echo ""
13440         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $OLD_LVF
13441         local LRU_SIZE_A=$($LCTL get_param -n $NSDIR.lru_size)
13442
13443         [[ $LRU_SIZE_B -gt $LRU_SIZE_A ]] || {
13444                 error "No locks dropped in ${SLEEP}s. LRU size: $LRU_SIZE_A"
13445                 unlinkmany $DIR/$tdir/f $NR
13446                 return
13447         }
13448
13449         log "Dropped "$((LRU_SIZE_B-LRU_SIZE_A))" locks in ${SLEEP}s"
13450         log "unlink $NR files at $DIR/$tdir"
13451         unlinkmany $DIR/$tdir/f $NR
13452 }
13453 run_test 124a "lru resize ======================================="
13454
13455 get_max_pool_limit()
13456 {
13457         local limit=$($LCTL get_param \
13458                       -n ldlm.namespaces.*-MDT0000-mdc-*.pool.limit)
13459         local max=0
13460         for l in $limit; do
13461                 if [[ $l -gt $max ]]; then
13462                         max=$l
13463                 fi
13464         done
13465         echo $max
13466 }
13467
13468 test_124b() {
13469         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13470         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13471                 skip_env "no lru resize on server"
13472
13473         LIMIT=$(get_max_pool_limit)
13474
13475         NR=$(($(default_lru_size)*20))
13476         if [[ $NR -gt $LIMIT ]]; then
13477                 log "Limit lock number by $LIMIT locks"
13478                 NR=$LIMIT
13479         fi
13480
13481         IFree=$(mdsrate_inodes_available)
13482         if [ $IFree -lt $NR ]; then
13483                 log "Limit lock number by $IFree inodes"
13484                 NR=$IFree
13485         fi
13486
13487         lru_resize_disable mdc
13488         test_mkdir -p $DIR/$tdir/disable_lru_resize
13489
13490         createmany -o $DIR/$tdir/disable_lru_resize/f $NR
13491         log "doing ls -la $DIR/$tdir/disable_lru_resize 3 times"
13492         cancel_lru_locks mdc
13493         stime=`date +%s`
13494         PID=""
13495         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
13496         PID="$PID $!"
13497         sleep 2
13498         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
13499         PID="$PID $!"
13500         sleep 2
13501         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
13502         PID="$PID $!"
13503         wait $PID
13504         etime=`date +%s`
13505         nolruresize_delta=$((etime-stime))
13506         log "ls -la time: $nolruresize_delta seconds"
13507         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
13508         unlinkmany $DIR/$tdir/disable_lru_resize/f $NR
13509
13510         lru_resize_enable mdc
13511         test_mkdir -p $DIR/$tdir/enable_lru_resize
13512
13513         createmany -o $DIR/$tdir/enable_lru_resize/f $NR
13514         log "doing ls -la $DIR/$tdir/enable_lru_resize 3 times"
13515         cancel_lru_locks mdc
13516         stime=`date +%s`
13517         PID=""
13518         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
13519         PID="$PID $!"
13520         sleep 2
13521         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
13522         PID="$PID $!"
13523         sleep 2
13524         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
13525         PID="$PID $!"
13526         wait $PID
13527         etime=`date +%s`
13528         lruresize_delta=$((etime-stime))
13529         log "ls -la time: $lruresize_delta seconds"
13530         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
13531
13532         if [ $lruresize_delta -gt $nolruresize_delta ]; then
13533                 log "ls -la is $(((lruresize_delta - $nolruresize_delta) * 100 / $nolruresize_delta))% slower with lru resize enabled"
13534         elif [ $nolruresize_delta -gt $lruresize_delta ]; then
13535                 log "ls -la is $(((nolruresize_delta - $lruresize_delta) * 100 / $nolruresize_delta))% faster with lru resize enabled"
13536         else
13537                 log "lru resize performs the same with no lru resize"
13538         fi
13539         unlinkmany $DIR/$tdir/enable_lru_resize/f $NR
13540 }
13541 run_test 124b "lru resize (performance test) ======================="
13542
13543 test_124c() {
13544         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13545         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13546                 skip_env "no lru resize on server"
13547
13548         # cache ununsed locks on client
13549         local nr=100
13550         cancel_lru_locks mdc
13551         test_mkdir $DIR/$tdir
13552         createmany -o $DIR/$tdir/f $nr ||
13553                 error "failed to create $nr files in $DIR/$tdir"
13554         ls -l $DIR/$tdir > /dev/null
13555
13556         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
13557         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
13558         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
13559         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
13560         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
13561
13562         # set lru_max_age to 1 sec
13563         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
13564         echo "sleep $((recalc_p * 2)) seconds..."
13565         sleep $((recalc_p * 2))
13566
13567         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
13568         # restore lru_max_age
13569         $LCTL set_param -n $nsdir.lru_max_age $max_age
13570         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
13571         unlinkmany $DIR/$tdir/f $nr
13572 }
13573 run_test 124c "LRUR cancel very aged locks"
13574
13575 test_124d() {
13576         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13577         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13578                 skip_env "no lru resize on server"
13579
13580         # cache ununsed locks on client
13581         local nr=100
13582
13583         lru_resize_disable mdc
13584         stack_trap "lru_resize_enable mdc" EXIT
13585
13586         cancel_lru_locks mdc
13587
13588         # asynchronous object destroy at MDT could cause bl ast to client
13589         test_mkdir $DIR/$tdir
13590         createmany -o $DIR/$tdir/f $nr ||
13591                 error "failed to create $nr files in $DIR/$tdir"
13592         stack_trap "unlinkmany $DIR/$tdir/f $nr" EXIT
13593
13594         ls -l $DIR/$tdir > /dev/null
13595
13596         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
13597         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
13598         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
13599         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
13600
13601         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
13602
13603         # set lru_max_age to 1 sec
13604         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
13605         stack_trap "$LCTL set_param -n $nsdir.lru_max_age $max_age" EXIT
13606
13607         echo "sleep $((recalc_p * 2)) seconds..."
13608         sleep $((recalc_p * 2))
13609
13610         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
13611
13612         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
13613 }
13614 run_test 124d "cancel very aged locks if lru-resize diasbaled"
13615
13616 test_125() { # 13358
13617         $LCTL get_param -n llite.*.client_type | grep -q local ||
13618                 skip "must run as local client"
13619         $LCTL get_param -n mdc.*-mdc-*.connect_flags | grep -q acl ||
13620                 skip_env "must have acl enabled"
13621         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
13622
13623         test_mkdir $DIR/$tdir
13624         $LFS setstripe -S 65536 -c -1 $DIR/$tdir || error "setstripe failed"
13625         setfacl -R -m u:$USER0:rwx $DIR/$tdir ||
13626                 error "setfacl $DIR/$tdir failed"
13627         ls -ld $DIR/$tdir || error "cannot access $DIR/$tdir"
13628 }
13629 run_test 125 "don't return EPROTO when a dir has a non-default striping and ACLs"
13630
13631 test_126() { # bug 12829/13455
13632         $GSS && skip_env "must run as gss disabled"
13633         $LCTL get_param -n llite.*.client_type | grep -q local ||
13634                 skip "must run as local client"
13635         [ "$UID" != 0 ] && skip "must run as root, not UID $UID"
13636
13637         $RUNAS -u 0 -g 1 touch $DIR/$tfile || error "touch failed"
13638         gid=`ls -n $DIR/$tfile | awk '{print $4}'`
13639         rm -f $DIR/$tfile
13640         [ $gid -eq "1" ] || error "gid is set to" $gid "instead of 1"
13641 }
13642 run_test 126 "check that the fsgid provided by the client is taken into account"
13643
13644 test_127a() { # bug 15521
13645         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13646         local name count samp unit min max sum sumsq
13647         local tmpfile=$TMP/$tfile.tmp
13648
13649         $LFS setstripe -i 0 -c 1 $DIR/$tfile || error "setstripe failed"
13650         echo "stats before reset"
13651         stack_trap "rm -f $tmpfile"
13652         local now=$(date +%s)
13653
13654         $LCTL get_param osc.*.stats | tee $tmpfile
13655
13656         local snapshot_time=$(awk '/snapshot_time/ { print $2; exit }' $tmpfile)
13657         local start_time=$(awk '/start_time/ { print $2; exit }' $tmpfile)
13658         local elapsed=$(awk '/elapsed_time/ { print $2; exit }' $tmpfile)
13659         local uptime=$(awk '{ print $1 }' /proc/uptime)
13660
13661         # snapshot_time should match POSIX epoch time, allow some delta for VMs
13662         (( ${snapshot_time%\.*} >= $now - 5 &&
13663            ${snapshot_time%\.*} <= $now + 5 )) ||
13664                 error "snapshot_time=$snapshot_time != now=$now"
13665         # elapsed _should_ be from mount, but at least less than uptime
13666         (( ${elapsed%\.*} < ${uptime%\.*} )) ||
13667                 error "elapsed=$elapsed > uptime=$uptime"
13668         (( ${snapshot_time%\.*} - ${start_time%\.*} >= ${elapsed%\.*} - 2 &&
13669            ${snapshot_time%\.*} - ${start_time%\.*} <= ${elapsed%\.*} + 2 )) ||
13670                 error "elapsed=$elapsed != $snapshot_time - $start_time"
13671
13672         $LCTL set_param osc.*.stats=0
13673         local reset=$(date +%s)
13674         local fsize=$((2048 * 1024))
13675
13676         dd if=/dev/zero of=$DIR/$tfile bs=$fsize count=1
13677         cancel_lru_locks osc
13678         dd if=$DIR/$tfile of=/dev/null bs=$fsize
13679
13680         now=$(date +%s)
13681         $LCTL get_param osc.*0000-osc-*.stats > $tmpfile
13682         while read name count samp unit min max sum sumsq; do
13683                 [[ "$samp" == "samples" ]] || continue
13684
13685                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
13686                 [ ! $min ] && error "Missing min value for $name proc entry"
13687                 eval $name=$count || error "Wrong proc format"
13688
13689                 case $name in
13690                 read_bytes|write_bytes)
13691                         [[ "$unit" =~ "bytes" ]] ||
13692                                 error "unit is not 'bytes': $unit"
13693                         (( $min >= 4096 )) || error "min is too small: $min"
13694                         (( $min <= $fsize )) || error "min is too big: $min"
13695                         (( $max >= 4096 )) || error "max is too small: $max"
13696                         (( $max <= $fsize )) || error "max is too big: $max"
13697                         (( $sum == $fsize )) || error "sum is wrong: $sum"
13698                         (( $sumsq >= ($fsize / 4096) * (4096 * 4096) )) ||
13699                                 error "sumsquare is too small: $sumsq"
13700                         (( $sumsq <= $fsize * $fsize )) ||
13701                                 error "sumsquare is too big: $sumsq"
13702                         ;;
13703                 ost_read|ost_write)
13704                         [[ "$unit" =~ "usec" ]] ||
13705                                 error "unit is not 'usec': $unit"
13706                         ;;
13707                 *)      ;;
13708                 esac
13709         done < $tmpfile
13710
13711         #check that we actually got some stats
13712         [ "$read_bytes" ] || error "Missing read_bytes stats"
13713         [ "$write_bytes" ] || error "Missing write_bytes stats"
13714         [ "$read_bytes" != 0 ] || error "no read done"
13715         [ "$write_bytes" != 0 ] || error "no write done"
13716
13717         snapshot_time=$(awk '/snapshot_time/ { print $2; exit }' $tmpfile)
13718         start_time=$(awk '/start_time/ { print $2; exit }' $tmpfile)
13719         elapsed=$(awk '/elapsed_time/ { print $2; exit }' $tmpfile)
13720
13721         # snapshot_time should match POSIX epoch time, allow some delta for VMs
13722         (( ${snapshot_time%\.*} >= $now - 5 &&
13723            ${snapshot_time%\.*} <= $now + 5 )) ||
13724                 error "reset snapshot_time=$snapshot_time != now=$now"
13725         # elapsed should be from time of stats reset
13726         (( ${elapsed%\.*} >= $now - $reset - 2 &&
13727            ${elapsed%\.*} <= $now - $reset + 2 )) ||
13728                 error "reset elapsed=$elapsed > $now - $reset"
13729         (( ${snapshot_time%\.*} - ${start_time%\.*} >= ${elapsed%\.*} - 2 &&
13730            ${snapshot_time%\.*} - ${start_time%\.*} <= ${elapsed%\.*} + 2 )) ||
13731                 error "reset elapsed=$elapsed != $snapshot_time - $start_time"
13732 }
13733 run_test 127a "verify the client stats are sane"
13734
13735 test_127b() { # bug LU-333
13736         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13737         local name count samp unit min max sum sumsq
13738
13739         echo "stats before reset"
13740         $LCTL get_param llite.*.stats
13741         $LCTL set_param llite.*.stats=0
13742
13743         # perform 2 reads and writes so MAX is different from SUM.
13744         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
13745         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
13746         cancel_lru_locks osc
13747         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
13748         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
13749
13750         $LCTL get_param llite.*.stats | grep samples > $TMP/$tfile.tmp
13751         stack_trap "rm -f $TMP/$tfile.tmp"
13752         while read name count samp unit min max sum sumsq; do
13753                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
13754                 eval $name=$count || error "Wrong proc format"
13755
13756                 case $name in
13757                 read_bytes|write_bytes)
13758                         [[ "$unit" =~ "bytes" ]] ||
13759                                 error "unit is not 'bytes': $unit"
13760                         (( $count == 2 )) || error "count is not 2: $count"
13761                         (( $min == $PAGE_SIZE )) ||
13762                                 error "min is not $PAGE_SIZE: $min"
13763                         (( $max == $PAGE_SIZE )) ||
13764                                 error "max is not $PAGE_SIZE: $max"
13765                         (( $sum == $PAGE_SIZE * 2 )) ||
13766                                 error "sum is not $((PAGE_SIZE * 2)): $sum"
13767                         ;;
13768                 read|write)
13769                         [[ "$unit" =~ "usec" ]] ||
13770                                 error "unit is not 'usec': $unit"
13771                         ;;
13772                 *)      ;;
13773                 esac
13774         done < $TMP/$tfile.tmp
13775
13776         #check that we actually got some stats
13777         [ "$read_bytes" ] || error "Missing read_bytes stats"
13778         [ "$write_bytes" ] || error "Missing write_bytes stats"
13779         [ "$read_bytes" != 0 ] || error "no read done"
13780         [ "$write_bytes" != 0 ] || error "no write done"
13781 }
13782 run_test 127b "verify the llite client stats are sane"
13783
13784 test_127c() { # LU-12394
13785         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
13786         local size
13787         local bsize
13788         local reads
13789         local writes
13790         local count
13791
13792         $LCTL set_param llite.*.extents_stats=1
13793         stack_trap "$LCTL set_param llite.*.extents_stats=0" EXIT
13794
13795         # Use two stripes so there is enough space in default config
13796         $LFS setstripe -c 2 $DIR/$tfile
13797
13798         # Extent stats start at 0-4K and go in power of two buckets
13799         # LL_HIST_START = 12 --> 2^12 = 4K
13800         # We do 3K*2^i, so 3K, 6K, 12K, 24K... hitting each bucket.
13801         # We do not do buckets larger than 64 MiB to avoid ENOSPC issues on
13802         # small configs
13803         for size in 3K 6K 12K 24K 48K 96K 192K 384K 768K 1536K 3M 6M 12M 24M 48M;
13804                 do
13805                 # Write and read, 2x each, second time at a non-zero offset
13806                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1
13807                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1 seek=10
13808                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1
13809                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1 seek=10
13810                 rm -f $DIR/$tfile
13811         done
13812
13813         $LCTL get_param llite.*.extents_stats
13814
13815         count=2
13816         for bsize in 4K 8K 16K 32K 64K 128K 256K 512K 1M 2M 4M 8M 16M 32M 64M;
13817                 do
13818                 local bucket=$($LCTL get_param -n llite.*.extents_stats |
13819                                 grep -m 1 $bsize)
13820                 reads=$(echo $bucket | awk '{print $5}')
13821                 writes=$(echo $bucket | awk '{print $9}')
13822                 [ "$reads" -eq $count ] ||
13823                         error "$reads reads in < $bsize bucket, expect $count"
13824                 [ "$writes" -eq $count ] ||
13825                         error "$writes writes in < $bsize bucket, expect $count"
13826         done
13827
13828         # Test mmap write and read
13829         $LCTL set_param llite.*.extents_stats=c
13830         size=512
13831         dd if=/dev/zero of=$DIR/$tfile bs=${size}K count=1
13832         $MULTIOP $DIR/$tfile OSMRUc || error "$MULTIOP $DIR/$tfile failed"
13833         $MULTIOP $DIR/$tfile OSMWUc || error "$MULTIOP $DIR/$tfile failed"
13834
13835         $LCTL get_param llite.*.extents_stats
13836
13837         count=$(((size*1024) / PAGE_SIZE))
13838
13839         bsize=$((2 * PAGE_SIZE / 1024))K
13840
13841         bucket=$($LCTL get_param -n llite.*.extents_stats |
13842                         grep -m 1 $bsize)
13843         reads=$(echo $bucket | awk '{print $5}')
13844         writes=$(echo $bucket | awk '{print $9}')
13845         # mmap writes fault in the page first, creating an additonal read
13846         [ "$reads" -eq $((2 * count)) ] ||
13847                 error "$reads reads in < $bsize bucket, expect $count"
13848         [ "$writes" -eq $count ] ||
13849                 error "$writes writes in < $bsize bucket, expect $count"
13850 }
13851 run_test 127c "test llite extent stats with regular & mmap i/o"
13852
13853 test_128() { # bug 15212
13854         touch $DIR/$tfile
13855         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
13856                 find $DIR/$tfile
13857                 find $DIR/$tfile
13858         EOF
13859
13860         result=$(grep error $TMP/$tfile.log)
13861         rm -f $DIR/$tfile $TMP/$tfile.log
13862         [ -z "$result" ] ||
13863                 error "consecutive find's under interactive lfs failed"
13864 }
13865 run_test 128 "interactive lfs for 2 consecutive find's"
13866
13867 set_dir_limits () {
13868         local mntdev
13869         local canondev
13870         local node
13871
13872         local ldproc=/proc/fs/ldiskfs
13873         local facets=$(get_facets MDS)
13874
13875         for facet in ${facets//,/ }; do
13876                 canondev=$(ldiskfs_canon \
13877                            *.$(convert_facet2label $facet).mntdev $facet)
13878                 do_facet $facet "test -e $ldproc/$canondev/max_dir_size" ||
13879                         ldproc=/sys/fs/ldiskfs
13880                 do_facet $facet "echo $1 >$ldproc/$canondev/max_dir_size"
13881                 do_facet $facet "echo $2 >$ldproc/$canondev/warning_dir_size"
13882         done
13883 }
13884
13885 check_mds_dmesg() {
13886         local facets=$(get_facets MDS)
13887         for facet in ${facets//,/ }; do
13888                 do_facet $facet "dmesg | tail -3 | grep $1" && return 0
13889         done
13890         return 1
13891 }
13892
13893 test_129() {
13894         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13895         [[ $MDS1_VERSION -ge $(version_code 2.5.56) ]] ||
13896                 skip "Need MDS version with at least 2.5.56"
13897         if [ "$mds1_FSTYPE" != ldiskfs ]; then
13898                 skip_env "ldiskfs only test"
13899         fi
13900         remote_mds_nodsh && skip "remote MDS with nodsh"
13901
13902         local ENOSPC=28
13903         local has_warning=false
13904
13905         rm -rf $DIR/$tdir
13906         mkdir -p $DIR/$tdir
13907
13908         # block size of mds1
13909         local maxsize=$(($($LCTL get_param -n mdc.*MDT0000*.blocksize) * 8))
13910         set_dir_limits $maxsize $((maxsize * 6 / 8))
13911         stack_trap "set_dir_limits 0 0"
13912         stack_trap "unlinkmany $DIR/$tdir/file_base_ 2000 || true"
13913         local dirsize=$(stat -c%s "$DIR/$tdir")
13914         local nfiles=0
13915         while (( $dirsize <= $maxsize )); do
13916                 $MCREATE $DIR/$tdir/file_base_$nfiles
13917                 rc=$?
13918                 # check two errors:
13919                 # ENOSPC for ext4 max_dir_size, which has been used since
13920                 # kernel v3.6-rc1-8-gdf981d03ee, lustre v2_4_50_0-79-gaed82035c0
13921                 if (( rc == ENOSPC )); then
13922                         set_dir_limits 0 0
13923                         echo "rc=$rc returned as expected after $nfiles files"
13924
13925                         createmany -o $DIR/$tdir/file_extra_$nfiles. 5 ||
13926                                 error "create failed w/o dir size limit"
13927
13928                         # messages may be rate limited if test is run repeatedly
13929                         check_mds_dmesg '"is approaching max"' ||
13930                                 echo "warning message should be output"
13931                         check_mds_dmesg '"has reached max"' ||
13932                                 echo "reached message should be output"
13933
13934                         dirsize=$(stat -c%s "$DIR/$tdir")
13935
13936                         [[ $dirsize -ge $maxsize ]] && return 0
13937                         error "dirsize $dirsize < $maxsize after $nfiles files"
13938                 elif (( rc != 0 )); then
13939                         break
13940                 fi
13941                 nfiles=$((nfiles + 1))
13942                 dirsize=$(stat -c%s "$DIR/$tdir")
13943         done
13944
13945         error "rc=$rc, size=$dirsize/$maxsize, mdt=$MDSCOUNT, nfiles=$nfiles"
13946 }
13947 run_test 129 "test directory size limit ========================"
13948
13949 OLDIFS="$IFS"
13950 cleanup_130() {
13951         trap 0
13952         IFS="$OLDIFS"
13953 }
13954
13955 test_130a() {
13956         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13957         [[ -z "$filefrag_op" ]] || skip_env "filefrag does not support FIEMAP"
13958
13959         trap cleanup_130 EXIT RETURN
13960
13961         local fm_file=$DIR/$tfile
13962         $LFS setstripe -S 65536 -c 1 $fm_file || error "setstripe on $fm_file"
13963         dd if=/dev/zero of=$fm_file bs=65536 count=1 ||
13964                 error "dd failed for $fm_file"
13965
13966         # LU-1795: test filefrag/FIEMAP once, even if unsupported on ZFS
13967         filefrag -ves $fm_file
13968         local rc=$?
13969         [[ "$ost1_FSTYPE" != "zfs" ]] ||
13970                 skip "LU-1941: FIEMAP unimplemented on ZFS"
13971         (( $rc == 0 )) || error "filefrag $fm_file failed"
13972
13973         filefrag_op=$(filefrag -ve -k $fm_file |
13974                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13975         local lun=$($LFS getstripe -i $fm_file)
13976
13977         local start_blk=$(echo $filefrag_op | cut -d: -f2 | cut -d. -f1)
13978         IFS=$'\n'
13979         local tot_len=0
13980         for line in $filefrag_op; do
13981                 local frag_lun=$(echo $line | cut -d: -f5)
13982                 local ext_len=$(echo $line | cut -d: -f4)
13983
13984                 if (( $frag_lun != $lun )); then
13985                         error "FIEMAP on 1-stripe file($fm_file) failed"
13986                         return
13987                 fi
13988                 (( tot_len += ext_len ))
13989         done
13990
13991         if (( lun != frag_lun || start_blk != 0 || tot_len != 64 )); then
13992                 error "FIEMAP on 1-stripe file($fm_file) failed"
13993                 return
13994         fi
13995
13996         echo "FIEMAP on single striped file succeeded"
13997 }
13998 run_test 130a "FIEMAP (1-stripe file)"
13999
14000 test_130b() {
14001         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
14002
14003         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
14004         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
14005         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14006                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14007
14008         trap cleanup_130 EXIT RETURN
14009
14010         local fm_file=$DIR/$tfile
14011         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
14012                 error "setstripe on $fm_file"
14013
14014         dd if=/dev/zero of=$fm_file bs=1M count=$OSTCOUNT ||
14015                 error "dd failed on $fm_file"
14016
14017         filefrag -ves $fm_file || error "filefrag $fm_file failed"
14018         filefrag_op=$(filefrag -ve -k $fm_file |
14019                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
14020
14021         local last_lun=$(echo $filefrag_op | cut -d: -f5 |
14022                          sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14023
14024         IFS=$'\n'
14025         local tot_len=0
14026         local num_luns=1
14027
14028         for line in $filefrag_op; do
14029                 local frag_lun=$(echo $line | cut -d: -f5 |
14030                                  sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14031                 local ext_len=$(echo $line | cut -d: -f4)
14032                 if (( $frag_lun != $last_lun )); then
14033                         if (( tot_len != 1024 )); then
14034                                 error "FIEMAP on $fm_file failed; returned len $tot_len for OST $last_lun instead of 1024"
14035                                 return
14036                         else
14037                                 (( num_luns += 1 ))
14038                                 tot_len=0
14039                         fi
14040                 fi
14041                 (( tot_len += ext_len ))
14042                 last_lun=$frag_lun
14043         done
14044         if (( num_luns != $OSTCOUNT || tot_len != 1024 )); then
14045                 error "FIEMAP on $fm_file failed; returned wrong number of luns or wrong len for OST $last_lun"
14046                 return
14047         fi
14048
14049         echo "FIEMAP on $OSTCOUNT-stripe file succeeded"
14050 }
14051 run_test 130b "FIEMAP ($OSTCOUNT-stripe file)"
14052
14053 test_130c() {
14054         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
14055
14056         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
14057         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
14058         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14059                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14060
14061         trap cleanup_130 EXIT RETURN
14062
14063         local fm_file=$DIR/$tfile
14064         $LFS setstripe -S 65536 -c 2 $fm_file || error "setstripe on $fm_file"
14065
14066         dd if=/dev/zero of=$fm_file seek=1 bs=1M count=1 ||
14067                 error "dd failed on $fm_file"
14068
14069         filefrag -ves $fm_file || error "filefrag $fm_file failed"
14070         filefrag_op=$(filefrag -ve -k $fm_file |
14071                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
14072
14073         local last_lun=$(echo $filefrag_op | cut -d: -f5 |
14074                          sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14075
14076         IFS=$'\n'
14077         local tot_len=0
14078         local num_luns=1
14079         for line in $filefrag_op; do
14080                 local frag_lun=$(echo $line | cut -d: -f5 |
14081                                  sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14082                 local ext_len=$(echo $line | cut -d: -f4)
14083                 if (( $frag_lun != $last_lun )); then
14084                         local logical=$(echo $line | cut -d: -f2 | cut -d. -f1)
14085                         if (( logical != 512 )); then
14086                                 error "FIEMAP on $fm_file failed; returned logical start for lun $logical instead of 512"
14087                                 return
14088                         fi
14089                         if (( tot_len != 512 )); then
14090                                 error "FIEMAP on $fm_file failed; returned len $tot_len for OST $last_lun instead of 1024"
14091                                 return
14092                         else
14093                                 (( num_luns += 1 ))
14094                                 tot_len=0
14095                         fi
14096                 fi
14097                 (( tot_len += ext_len ))
14098                 last_lun=$frag_lun
14099         done
14100         if (( num_luns != 2 || tot_len != 512 )); then
14101                 error "FIEMAP on $fm_file failed; returned wrong number of luns or wrong len for OST $last_lun"
14102                 return
14103         fi
14104
14105         echo "FIEMAP on 2-stripe file with hole succeeded"
14106 }
14107 run_test 130c "FIEMAP (2-stripe file with hole)"
14108
14109 test_130d() {
14110         (( $OSTCOUNT >= 3 )) || skip "needs >= 3 OSTs"
14111
14112         filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
14113         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
14114         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14115                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14116
14117         trap cleanup_130 EXIT RETURN
14118
14119         local fm_file=$DIR/$tfile
14120         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
14121                         error "setstripe on $fm_file"
14122
14123         local actual_stripe_count=$($LFS getstripe -c $fm_file)
14124         dd if=/dev/zero of=$fm_file bs=1M count=$actual_stripe_count ||
14125                 error "dd failed on $fm_file"
14126
14127         filefrag -ves $fm_file || error "filefrag $fm_file failed"
14128         filefrag_op=$(filefrag -ve -k $fm_file |
14129                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
14130
14131         local last_lun=$(echo $filefrag_op | cut -d: -f5 |
14132                          sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14133
14134         IFS=$'\n'
14135         local tot_len=0
14136         local num_luns=1
14137         for line in $filefrag_op; do
14138                 local frag_lun=$(echo $line | cut -d: -f5 |
14139                                  sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14140                 local ext_len=$(echo $line | cut -d: -f4)
14141                 if (( $frag_lun != $last_lun )); then
14142                         if (( tot_len != 1024 )); then
14143                                 error "FIEMAP on $fm_file failed; returned len $tot_len for OST $last_lun instead of 1024"
14144                                 return
14145                         else
14146                                 (( num_luns += 1 ))
14147                                 local tot_len=0
14148                         fi
14149                 fi
14150                 (( tot_len += ext_len ))
14151                 last_lun=$frag_lun
14152         done
14153         if (( num_luns != actual_stripe_count || tot_len != 1024 )); then
14154                 error "FIEMAP on $fm_file failed; returned wrong number of luns or wrong len for OST $last_lun"
14155                 return
14156         fi
14157
14158         echo "FIEMAP on N-stripe file succeeded"
14159 }
14160 run_test 130d "FIEMAP (N-stripe file)"
14161
14162 test_130e() {
14163         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
14164
14165         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
14166         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
14167         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14168                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14169
14170         trap cleanup_130 EXIT RETURN
14171
14172         local fm_file=$DIR/$tfile
14173         $LFS setstripe -S 131072 -c 2 $fm_file || error "setstripe on $fm_file"
14174
14175         local num_blks=512
14176         local expected_len=$(( (num_blks / 2) * 64 ))
14177         for ((i = 0; i < $num_blks; i++)); do
14178                 dd if=/dev/zero of=$fm_file count=1 bs=64k seek=$((2*$i)) \
14179                         conv=notrunc > /dev/null 2>&1
14180         done
14181
14182         filefrag -ves $fm_file || error "filefrag $fm_file failed"
14183         filefrag_op=$(filefrag -ve -k $fm_file |
14184                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
14185
14186         local last_lun=$(echo $filefrag_op | cut -d: -f5)
14187
14188         IFS=$'\n'
14189         local tot_len=0
14190         local num_luns=1
14191         for line in $filefrag_op; do
14192                 local frag_lun=$(echo $line | cut -d: -f5)
14193                 local ext_len=$(echo $line | cut -d: -f4)
14194                 if (( $frag_lun != $last_lun )); then
14195                         if (( tot_len != $expected_len )); then
14196                                 error "OST$last_lun $tot_len != $expected_len"
14197                         else
14198                                 (( num_luns += 1 ))
14199                                 tot_len=0
14200                         fi
14201                 fi
14202                 (( tot_len += ext_len ))
14203                 last_lun=$frag_lun
14204         done
14205         if (( num_luns != 2 || tot_len != $expected_len )); then
14206                 error "OST$last_lun $num_luns != 2, $tot_len != $expected_len"
14207         fi
14208
14209         echo "FIEMAP with continuation calls succeeded"
14210 }
14211 run_test 130e "FIEMAP (test continuation FIEMAP calls)"
14212
14213 test_130f() {
14214         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
14215         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
14216         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14217                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14218
14219         local fm_file=$DIR/$tfile
14220         $MULTIOP $fm_file oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T33554432c ||
14221                 error "multiop create with lov_delay_create on $fm_file"
14222
14223         filefrag -ves $fm_file || error "filefrag $fm_file failed"
14224         filefrag_extents=$(filefrag -vek $fm_file |
14225                            awk '/extents? found/ { print $2 }')
14226         if (( $filefrag_extents != 0 )); then
14227                 error "$fm_file: filefrag_extents=$filefrag_extents != 0"
14228         fi
14229
14230         rm -f $fm_file
14231 }
14232 run_test 130f "FIEMAP (unstriped file)"
14233
14234 test_130g() {
14235         (( $MDS1_VERSION >= $(version_code 2.12.53) )) ||
14236                 skip "Need MDS version with at least 2.12.53 for overstriping"
14237         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
14238         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
14239         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14240                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14241
14242         local file=$DIR/$tfile
14243         local nr=$((OSTCOUNT * 100))
14244
14245         $LFS setstripe -C $nr $file || error "failed to setstripe -C $nr $file"
14246
14247         stack_trap "rm -f $file"
14248         dd if=/dev/zero of=$file count=$nr bs=1M
14249         sync
14250         nr=$($LFS getstripe -c $file)
14251
14252         local extents=$(filefrag -v $file |
14253                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}' | wc -l)
14254
14255         echo "filefrag list $extents extents in file with stripecount $nr"
14256         if (( extents < nr )); then
14257                 $LFS getstripe $file
14258                 filefrag -v $file
14259                 error "filefrag printed $extents < $nr extents"
14260         fi
14261 }
14262 run_test 130g "FIEMAP (overstripe file)"
14263
14264 # Test for writev/readv
14265 test_131a() {
14266         rwv -f $DIR/$tfile -w -n 3 524288 1048576 1572864 ||
14267                 error "writev test failed"
14268         rwv -f $DIR/$tfile -r -v -n 2 1572864 1048576 ||
14269                 error "readv failed"
14270         rm -f $DIR/$tfile
14271 }
14272 run_test 131a "test iov's crossing stripe boundary for writev/readv"
14273
14274 test_131b() {
14275         local fsize=$((524288 + 1048576 + 1572864))
14276         rwv -f $DIR/$tfile -w -a -n 3 524288 1048576 1572864 &&
14277                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
14278                         error "append writev test failed"
14279
14280         ((fsize += 1572864 + 1048576))
14281         rwv -f $DIR/$tfile -w -a -n 2 1572864 1048576 &&
14282                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
14283                         error "append writev test failed"
14284         rm -f $DIR/$tfile
14285 }
14286 run_test 131b "test append writev"
14287
14288 test_131c() {
14289         rwv -f $DIR/$tfile -w -d -n 1 1048576 || return 0
14290         error "NOT PASS"
14291 }
14292 run_test 131c "test read/write on file w/o objects"
14293
14294 test_131d() {
14295         rwv -f $DIR/$tfile -w -n 1 1572864
14296         NOB=`rwv -f $DIR/$tfile -r -n 3 524288 524288 1048576 | awk '/error/ {print $6}'`
14297         if [ "$NOB" != 1572864 ]; then
14298                 error "Short read filed: read $NOB bytes instead of 1572864"
14299         fi
14300         rm -f $DIR/$tfile
14301 }
14302 run_test 131d "test short read"
14303
14304 test_131e() {
14305         rwv -f $DIR/$tfile -w -s 1048576 -n 1 1048576
14306         rwv -f $DIR/$tfile -r -z -s 0 -n 1 524288 || \
14307         error "read hitting hole failed"
14308         rm -f $DIR/$tfile
14309 }
14310 run_test 131e "test read hitting hole"
14311
14312 check_stats() {
14313         local facet=$1
14314         local op=$2
14315         local want=${3:-0}
14316         local res
14317
14318         # open             11 samples [usecs] 468 4793 13658 35791898
14319         case $facet in
14320         mds*) res=($(do_facet $facet \
14321                    $LCTL get_param mdt.$FSNAME-MDT0000.md_stats | grep "$op"))
14322                  ;;
14323         ost*) res=($(do_facet $facet \
14324                   $LCTL get_param obdfilter.$FSNAME-OST0000.stats | grep "$op"))
14325                  ;;
14326         *) error "Wrong facet '$facet'" ;;
14327         esac
14328         [[ -n "$res" ]] || error "counter for $op on $facet not incremented"
14329         # if $want is zero, it means any stat increment is ok.
14330         if (( $want > 0 )); then
14331                 local count=${res[1]}
14332
14333                 if (( $count != $want )); then
14334                         if [[ $facet =~ "mds" ]]; then
14335                                 do_nodes $(comma_list $(mdts_nodes)) \
14336                                         $LCTL get_param mdt.*.md_stats
14337                         else
14338                                 do_nodes $(comma_list $(osts-nodes)) \
14339                                         $LCTL get_param obdfilter.*.stats
14340                         fi
14341                         error "The $op counter on $facet is $count, not $want"
14342                 fi
14343         fi
14344 }
14345
14346 test_133a() {
14347         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14348         remote_ost_nodsh && skip "remote OST with nodsh"
14349         remote_mds_nodsh && skip "remote MDS with nodsh"
14350         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
14351                 skip_env "MDS doesn't support rename stats"
14352
14353         local testdir=$DIR/${tdir}/stats_testdir
14354
14355         mkdir -p $DIR/${tdir}
14356
14357         # clear stats.
14358         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14359         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
14360
14361         # verify mdt stats first.
14362         mkdir_on_mdt0 ${testdir} || error "mkdir_on_mdt0 failed"
14363         check_stats $SINGLEMDS "mkdir" 1
14364
14365         # clear "open" from "lfs mkdir" above
14366         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14367         touch ${testdir}/${tfile} || error "touch failed"
14368         check_stats $SINGLEMDS "open" 1
14369         check_stats $SINGLEMDS "close" 1
14370         [ $MDS1_VERSION -ge $(version_code 2.8.54) ] && {
14371                 mknod ${testdir}/${tfile}-pipe p || error "mknod failed"
14372                 check_stats $SINGLEMDS "mknod" 2
14373         }
14374         rm -f ${testdir}/${tfile}-pipe || error "pipe remove failed"
14375         check_stats $SINGLEMDS "unlink" 1
14376         rm -f ${testdir}/${tfile} || error "file remove failed"
14377         check_stats $SINGLEMDS "unlink" 2
14378
14379         # remove working dir and check mdt stats again.
14380         rmdir ${testdir} || error "rmdir failed"
14381         check_stats $SINGLEMDS "rmdir" 1
14382
14383         local testdir1=$DIR/${tdir}/stats_testdir1
14384         mkdir -p ${testdir}
14385         mkdir -p ${testdir1}
14386         touch ${testdir1}/test1
14387         mv ${testdir1}/test1 ${testdir} || error "file crossdir rename"
14388         check_stats $SINGLEMDS "crossdir_rename" 1
14389
14390         mv ${testdir}/test1 ${testdir}/test0 || error "file samedir rename"
14391         check_stats $SINGLEMDS "samedir_rename" 1
14392
14393         rm -rf $DIR/${tdir}
14394 }
14395 run_test 133a "Verifying MDT stats ========================================"
14396
14397 test_133b() {
14398         local res
14399
14400         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14401         remote_ost_nodsh && skip "remote OST with nodsh"
14402         remote_mds_nodsh && skip "remote MDS with nodsh"
14403
14404         local testdir=$DIR/${tdir}/stats_testdir
14405
14406         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
14407         mkdir_on_mdt0 ${testdir} || error "mkdir_on_mdt0 failed"
14408         touch ${testdir}/${tfile} || error "touch failed"
14409         cancel_lru_locks mdc
14410
14411         # clear stats.
14412         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14413         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
14414
14415         # extra mdt stats verification.
14416         chmod 444 ${testdir}/${tfile} || error "chmod failed"
14417         check_stats $SINGLEMDS "setattr" 1
14418         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14419         if [ $MDS1_VERSION -ne $(version_code 2.2.0) ]
14420         then            # LU-1740
14421                 ls -l ${testdir}/${tfile} > /dev/null|| error "ls failed"
14422                 check_stats $SINGLEMDS "getattr" 1
14423         fi
14424         rm -rf $DIR/${tdir}
14425
14426         # when DNE is enabled, MDT uses STATFS RPC to ping other targets
14427         # so the check below is not reliable
14428         [ $MDSCOUNT -eq 1 ] || return 0
14429
14430         # Sleep to avoid a cached response.
14431         #define OBD_STATFS_CACHE_SECONDS 1
14432         sleep 2
14433         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14434         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
14435         $LFS df || error "lfs failed"
14436         check_stats $SINGLEMDS "statfs" 1
14437
14438         # check aggregated statfs (LU-10018)
14439         [ $MDS1_VERSION -lt $(version_code 2.11.54) ] &&
14440                 return 0
14441         [ $CLIENT_VERSION -lt $(version_code 2.11.54) ] &&
14442                 return 0
14443         sleep 2
14444         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14445         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
14446         df $DIR
14447         check_stats $SINGLEMDS "statfs" 1
14448
14449         # We want to check that the client didn't send OST_STATFS to
14450         # ost1 but the MDT also uses OST_STATFS for precreate. So some
14451         # extra care is needed here.
14452         if remote_mds; then
14453                 local nid=$($LCTL list_nids | head -1 | sed  "s/\./\\\./g")
14454                 local param="obdfilter.$FSNAME-OST0000.exports.'$nid'.stats"
14455
14456                 res=$(do_facet ost1 $LCTL get_param $param | grep statfs)
14457                 [ "$res" ] && error "OST got STATFS"
14458         fi
14459
14460         return 0
14461 }
14462 run_test 133b "Verifying extra MDT stats =================================="
14463
14464 test_133c() {
14465         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14466         remote_ost_nodsh && skip "remote OST with nodsh"
14467         remote_mds_nodsh && skip "remote MDS with nodsh"
14468
14469         local testdir=$DIR/$tdir/stats_testdir
14470
14471         test_mkdir -p $testdir
14472
14473         # verify obdfilter stats.
14474         $LFS setstripe -c 1 -i 0 $testdir/$tfile
14475         sync
14476         cancel_lru_locks osc
14477         wait_delete_completed
14478
14479         # clear stats.
14480         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14481         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
14482
14483         dd if=/dev/zero of=$testdir/$tfile conv=notrunc bs=512k count=1 ||
14484                 error "dd failed"
14485         sync
14486         cancel_lru_locks osc
14487         check_stats ost1 "write" 1
14488
14489         dd if=$testdir/$tfile of=/dev/null bs=1k count=1 || error "dd failed"
14490         check_stats ost1 "read" 1
14491
14492         > $testdir/$tfile || error "truncate failed"
14493         check_stats ost1 "punch" 1
14494
14495         rm -f $testdir/$tfile || error "file remove failed"
14496         wait_delete_completed
14497         check_stats ost1 "destroy" 1
14498
14499         rm -rf $DIR/$tdir
14500 }
14501 run_test 133c "Verifying OST stats ========================================"
14502
14503 order_2() {
14504         local value=$1
14505         local orig=$value
14506         local order=1
14507
14508         while [ $value -ge 2 ]; do
14509                 order=$((order*2))
14510                 value=$((value/2))
14511         done
14512
14513         if [ $orig -gt $order ]; then
14514                 order=$((order*2))
14515         fi
14516         echo $order
14517 }
14518
14519 size_in_KMGT() {
14520     local value=$1
14521     local size=('K' 'M' 'G' 'T');
14522     local i=0
14523     local size_string=$value
14524
14525     while [ $value -ge 1024 ]; do
14526         if [ $i -gt 3 ]; then
14527             #T is the biggest unit we get here, if that is bigger,
14528             #just return XXXT
14529             size_string=${value}T
14530             break
14531         fi
14532         value=$((value >> 10))
14533         if [ $value -lt 1024 ]; then
14534             size_string=${value}${size[$i]}
14535             break
14536         fi
14537         i=$((i + 1))
14538     done
14539
14540     echo $size_string
14541 }
14542
14543 get_rename_size() {
14544         local size=$1
14545         local context=${2:-.}
14546         local sample=$(do_facet $SINGLEMDS $LCTL \
14547                 get_param mdt.$FSNAME-MDT0000.rename_stats |
14548                 grep -A1 $context |
14549                 awk '/ '${size}'/ {print $4}' | sed -e "s/,//g")
14550         echo $sample
14551 }
14552
14553 test_133d() {
14554         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14555         remote_ost_nodsh && skip "remote OST with nodsh"
14556         remote_mds_nodsh && skip "remote MDS with nodsh"
14557         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
14558                 skip_env "MDS doesn't support rename stats"
14559
14560         local testdir1=$DIR/${tdir}/stats_testdir1
14561         local testdir2=$DIR/${tdir}/stats_testdir2
14562         mkdir -p $DIR/${tdir} || error "mkdir $tdir failed"
14563
14564         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
14565
14566         mkdir_on_mdt0 ${testdir1} || error "mkdir $testdir1 failed"
14567         mkdir_on_mdt0 ${testdir2} || error "mkdir $testdir2 failed"
14568
14569         createmany -o $testdir1/test 512 || error "createmany failed"
14570
14571         # check samedir rename size
14572         mv ${testdir1}/test0 ${testdir1}/test_0
14573
14574         local testdir1_size=$(ls -l $DIR/${tdir} |
14575                 awk '/stats_testdir1/ {print $5}')
14576         local testdir2_size=$(ls -l $DIR/${tdir} |
14577                 awk '/stats_testdir2/ {print $5}')
14578
14579         testdir1_size=$(order_2 $testdir1_size)
14580         testdir2_size=$(order_2 $testdir2_size)
14581
14582         testdir1_size=$(size_in_KMGT $testdir1_size)
14583         testdir2_size=$(size_in_KMGT $testdir2_size)
14584
14585         echo "source rename dir size: ${testdir1_size}"
14586         echo "target rename dir size: ${testdir2_size}"
14587
14588         local cmd="do_facet $SINGLEMDS $LCTL "
14589         cmd+="get_param mdt.$FSNAME-MDT0000.rename_stats"
14590
14591         eval $cmd || error "$cmd failed"
14592         local samedir=$($cmd | grep 'same_dir')
14593         local same_sample=$(get_rename_size $testdir1_size)
14594         [ -z "$samedir" ] && error "samedir_rename_size count error"
14595         [[ $same_sample -eq 1 ]] ||
14596                 error "samedir_rename_size error $same_sample"
14597         echo "Check same dir rename stats success"
14598
14599         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
14600
14601         # check crossdir rename size
14602         mv ${testdir1}/test_0 ${testdir2}/test_0
14603
14604         testdir1_size=$(ls -l $DIR/${tdir} |
14605                 awk '/stats_testdir1/ {print $5}')
14606         testdir2_size=$(ls -l $DIR/${tdir} |
14607                 awk '/stats_testdir2/ {print $5}')
14608
14609         testdir1_size=$(order_2 $testdir1_size)
14610         testdir2_size=$(order_2 $testdir2_size)
14611
14612         testdir1_size=$(size_in_KMGT $testdir1_size)
14613         testdir2_size=$(size_in_KMGT $testdir2_size)
14614
14615         echo "source rename dir size: ${testdir1_size}"
14616         echo "target rename dir size: ${testdir2_size}"
14617
14618         eval $cmd || error "$cmd failed"
14619         local crossdir=$($cmd | grep 'crossdir')
14620         local src_sample=$(get_rename_size $testdir1_size crossdir_src)
14621         local tgt_sample=$(get_rename_size $testdir2_size crossdir_tgt)
14622         [ -z "$crossdir" ] && error "crossdir_rename_size count error"
14623         [[ $src_sample -eq 1 ]] ||
14624                 error "crossdir_rename_size error $src_sample"
14625         [[ $tgt_sample -eq 1 ]] ||
14626                 error "crossdir_rename_size error $tgt_sample"
14627         echo "Check cross dir rename stats success"
14628         rm -rf $DIR/${tdir}
14629 }
14630 run_test 133d "Verifying rename_stats ========================================"
14631
14632 test_133e() {
14633         remote_mds_nodsh && skip "remote MDS with nodsh"
14634         remote_ost_nodsh && skip "remote OST with nodsh"
14635         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14636
14637         local testdir=$DIR/${tdir}/stats_testdir
14638         local ctr f0 f1 bs=32768 count=42 sum
14639
14640         mkdir -p ${testdir} || error "mkdir failed"
14641
14642         $LFS setstripe -c 1 -i 0 ${testdir}/${tfile}
14643
14644         for ctr in {write,read}_bytes; do
14645                 sync
14646                 cancel_lru_locks osc
14647
14648                 do_facet ost1 $LCTL set_param -n \
14649                         "obdfilter.*.exports.clear=clear"
14650
14651                 if [ $ctr = write_bytes ]; then
14652                         f0=/dev/zero
14653                         f1=${testdir}/${tfile}
14654                 else
14655                         f0=${testdir}/${tfile}
14656                         f1=/dev/null
14657                 fi
14658
14659                 dd if=$f0 of=$f1 conv=notrunc bs=$bs count=$count || \
14660                         error "dd failed"
14661                 sync
14662                 cancel_lru_locks osc
14663
14664                 sum=$(do_facet ost1 $LCTL get_param \
14665                         "obdfilter.*.exports.*.stats" |
14666                         awk -v ctr=$ctr 'BEGIN { sum = 0 }
14667                                 $1 == ctr { sum += $7 }
14668                                 END { printf("%0.0f", sum) }')
14669
14670                 if ((sum != bs * count)); then
14671                         error "Bad $ctr sum, expected $((bs * count)), got $sum"
14672                 fi
14673         done
14674
14675         rm -rf $DIR/${tdir}
14676 }
14677 run_test 133e "Verifying OST {read,write}_bytes nid stats ================="
14678
14679 test_133f() {
14680         [[ $(lustre_version_code $facet) -ge $(version_code 2.7.65) ]] ||
14681                 skip "too old lustre for get_param -R ($facet_ver)"
14682
14683         # verifying readability.
14684         $LCTL get_param -R '*' &> /dev/null
14685
14686         # Verifing writability with badarea_io.
14687         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
14688         local skipped_params='force_lbug|changelog_mask|daemon_file'
14689         $LCTL list_param -FR '*' | grep '=' | tr -d = |
14690                 egrep -v "$skipped_params" |
14691                 xargs -n 1 find $proc_dirs -name |
14692                 xargs -n 1 badarea_io ||
14693                 error "client badarea_io failed"
14694
14695         # remount the FS in case writes/reads /proc break the FS
14696         cleanup || error "failed to unmount"
14697         setup || error "failed to setup"
14698 }
14699 run_test 133f "Check reads/writes of client lustre proc files with bad area io"
14700
14701 test_133g() {
14702         remote_mds_nodsh && skip "remote MDS with nodsh"
14703         remote_ost_nodsh && skip "remote OST with nodsh"
14704
14705         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
14706         local skipped_params="'force_lbug|changelog_mask|daemon_file'"
14707         local facet
14708         for facet in mds1 ost1; do
14709                 local facet_ver=$(lustre_version_code $facet)
14710                 if [ $facet_ver -ge $(version_code 2.7.65) ]; then
14711                         do_facet $facet "$LCTL get_param -R '*'" &> /dev/null
14712                 else
14713                         log "$facet: too old lustre for get_param -R"
14714                 fi
14715                 if [ $facet_ver -ge $(version_code 2.5.54) ]; then
14716                         do_facet $facet "$LCTL list_param -FR '*' | grep '=' |
14717                                 tr -d = | egrep -v $skipped_params |
14718                                 xargs -n 1 find $proc_dirs -name |
14719                                 xargs -n 1 badarea_io" ||
14720                                         error "$facet badarea_io failed"
14721                 else
14722                         skip_noexit "$facet: too old lustre for get_param -R"
14723                 fi
14724         done
14725
14726         # remount the FS in case writes/reads /proc break the FS
14727         cleanup || error "failed to unmount"
14728         setup || error "failed to setup"
14729 }
14730 run_test 133g "Check reads/writes of server lustre proc files with bad area io"
14731
14732 test_133h() {
14733         remote_mds_nodsh && skip "remote MDS with nodsh"
14734         remote_ost_nodsh && skip "remote OST with nodsh"
14735         [[ $MDS1_VERSION -lt $(version_code 2.9.54) ]] &&
14736                 skip "Need MDS version at least 2.9.54"
14737
14738         local facet
14739         for facet in client mds1 ost1; do
14740                 # Get the list of files that are missing the terminating newline
14741                 local plist=$(do_facet $facet
14742                         $LCTL list_param -FR '*' | grep '=' | tr -d =)
14743                 local ent
14744                 for ent in $plist; do
14745                         local missing=$(do_facet $facet $LCTL get_param $ent \|\
14746                                 awk -v FS='\v' -v RS='\v\v' \
14747                                 "'END { if(NR>0 && \\\$NF !~ /.*\\\n\$/) \
14748                                         print FILENAME}'" 2>/dev/null)
14749                         [ -z $missing ] || {
14750                                 do_facet $facet $LCTL get_param $ent | od -An -tx1
14751                                 error "file does not end with newline: $facet-$ent"
14752                         }
14753                 done
14754         done
14755 }
14756 run_test 133h "Proc files should end with newlines"
14757
14758 test_134a() {
14759         remote_mds_nodsh && skip "remote MDS with nodsh"
14760         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
14761                 skip "Need MDS version at least 2.7.54"
14762
14763         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
14764         cancel_lru_locks mdc
14765
14766         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
14767         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
14768         [ $unused -eq 0 ] || error "$unused locks are not cleared"
14769
14770         local nr=1000
14771         createmany -o $DIR/$tdir/f $nr ||
14772                 error "failed to create $nr files in $DIR/$tdir"
14773         unused=$($LCTL get_param -n $nsdir.lock_unused_count)
14774
14775         #define OBD_FAIL_LDLM_WATERMARK_LOW     0x327
14776         do_facet mds1 $LCTL set_param fail_loc=0x327
14777         do_facet mds1 $LCTL set_param fail_val=500
14778         touch $DIR/$tdir/m
14779
14780         echo "sleep 10 seconds ..."
14781         sleep 10
14782         local lck_cnt=$($LCTL get_param -n $nsdir.lock_unused_count)
14783
14784         do_facet mds1 $LCTL set_param fail_loc=0
14785         do_facet mds1 $LCTL set_param fail_val=0
14786         [ $lck_cnt -lt $unused ] ||
14787                 error "No locks reclaimed, before:$unused, after:$lck_cnt"
14788
14789         rm $DIR/$tdir/m
14790         unlinkmany $DIR/$tdir/f $nr
14791 }
14792 run_test 134a "Server reclaims locks when reaching lock_reclaim_threshold"
14793
14794 test_134b() {
14795         remote_mds_nodsh && skip "remote MDS with nodsh"
14796         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
14797                 skip "Need MDS version at least 2.7.54"
14798
14799         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
14800         cancel_lru_locks mdc
14801
14802         local low_wm=$(do_facet mds1 $LCTL get_param -n \
14803                         ldlm.lock_reclaim_threshold_mb)
14804         # disable reclaim temporarily
14805         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=0
14806
14807         #define OBD_FAIL_LDLM_WATERMARK_HIGH     0x328
14808         do_facet mds1 $LCTL set_param fail_loc=0x328
14809         do_facet mds1 $LCTL set_param fail_val=500
14810
14811         $LCTL set_param debug=+trace
14812
14813         local nr=600
14814         createmany -o $DIR/$tdir/f $nr &
14815         local create_pid=$!
14816
14817         echo "Sleep $TIMEOUT seconds ..."
14818         sleep $TIMEOUT
14819         if ! ps -p $create_pid  > /dev/null 2>&1; then
14820                 do_facet mds1 $LCTL set_param fail_loc=0
14821                 do_facet mds1 $LCTL set_param fail_val=0
14822                 do_facet mds1 $LCTL set_param \
14823                         ldlm.lock_reclaim_threshold_mb=${low_wm}m
14824                 error "createmany finished incorrectly!"
14825         fi
14826         do_facet mds1 $LCTL set_param fail_loc=0
14827         do_facet mds1 $LCTL set_param fail_val=0
14828         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=${low_wm}m
14829         wait $create_pid || return 1
14830
14831         unlinkmany $DIR/$tdir/f $nr
14832 }
14833 run_test 134b "Server rejects lock request when reaching lock_limit_mb"
14834
14835 test_135() {
14836         remote_mds_nodsh && skip "remote MDS with nodsh"
14837         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
14838                 skip "Need MDS version at least 2.13.50"
14839         local fname
14840
14841         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
14842
14843 #define OBD_FAIL_PLAIN_RECORDS 0x1319
14844         #set only one record at plain llog
14845         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1319 fail_val=1
14846
14847         #fill already existed plain llog each 64767
14848         #wrapping whole catalog
14849         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
14850
14851         createmany -o $DIR/$tdir/$tfile_ 64700
14852         for (( i = 0; i < 64700; i = i + 2 ))
14853         do
14854                 rm $DIR/$tdir/$tfile_$i &
14855                 rm $DIR/$tdir/$tfile_$((i + 1)) &
14856                 local pid=$!
14857                 wait $pid
14858         done
14859
14860         #waiting osp synchronization
14861         wait_delete_completed
14862 }
14863 run_test 135 "Race catalog processing"
14864
14865 test_136() {
14866         remote_mds_nodsh && skip "remote MDS with nodsh"
14867         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
14868                 skip "Need MDS version at least 2.13.50"
14869         local fname
14870
14871         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
14872         $LFS setstripe -c 1 -i 0 $DIR/$tdir || error "failed to set striping"
14873         #set only one record at plain llog
14874 #define OBD_FAIL_CATALOG_FULL_CHECK                0x131a
14875         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x131a fail_val=1
14876
14877         #fill already existed 2 plain llogs each 64767
14878         #wrapping whole catalog
14879         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
14880         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 3 / 2))
14881         wait_delete_completed
14882
14883         createmany -o $DIR/$tdir/$tfile_ 10
14884         sleep 25
14885
14886         do_facet $SINGLEMDS $LCTL set_param fail_val=3
14887         for (( i = 0; i < 10; i = i + 3 ))
14888         do
14889                 rm $DIR/$tdir/$tfile_$i &
14890                 rm $DIR/$tdir/$tfile_$((i + 1)) &
14891                 local pid=$!
14892                 wait $pid
14893                 sleep 7
14894                 rm $DIR/$tdir/$tfile_$((i + 2)) &
14895         done
14896
14897         #waiting osp synchronization
14898         wait_delete_completed
14899 }
14900 run_test 136 "Race catalog processing 2"
14901
14902 test_140() { #bug-17379
14903         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14904
14905         test_mkdir $DIR/$tdir
14906         cd $DIR/$tdir || error "Changing to $DIR/$tdir"
14907         cp $(which stat) . || error "Copying stat to $DIR/$tdir"
14908
14909         # VFS limits max symlink depth to 5(4KSTACK) or 7(8KSTACK) or 8
14910         # For kernel > 3.5, bellow only tests consecutive symlink (MAX 40)
14911         local i=0
14912         while i=$((i + 1)); do
14913                 test_mkdir $i
14914                 cd $i || error "Changing to $i"
14915                 ln -s ../stat stat || error "Creating stat symlink"
14916                 # Read the symlink until ELOOP present,
14917                 # not LBUGing the system is considered success,
14918                 # we didn't overrun the stack.
14919                 $OPENFILE -f O_RDONLY stat >/dev/null 2>&1; ret=$?
14920                 if [ $ret -ne 0 ]; then
14921                         if [ $ret -eq 40 ]; then
14922                                 break  # -ELOOP
14923                         else
14924                                 error "Open stat symlink"
14925                                         return
14926                         fi
14927                 fi
14928         done
14929         i=$((i - 1))
14930         echo "The symlink depth = $i"
14931         [ $i -eq 5 ] || [ $i -eq 7 ] || [ $i -eq 8 ] || [ $i -eq 40 ] ||
14932                 error "Invalid symlink depth"
14933
14934         # Test recursive symlink
14935         ln -s symlink_self symlink_self
14936         $OPENFILE -f O_RDONLY symlink_self >/dev/null 2>&1; ret=$?
14937         echo "open symlink_self returns $ret"
14938         [ $ret -eq 40 ] || error "recursive symlink doesn't return -ELOOP"
14939 }
14940 run_test 140 "Check reasonable stack depth (shouldn't LBUG) ===="
14941
14942 test_150a() {
14943         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14944
14945         local TF="$TMP/$tfile"
14946
14947         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14948         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
14949         cp $TF $DIR/$tfile
14950         cancel_lru_locks $OSC
14951         cmp $TF $DIR/$tfile || error "$TMP/$tfile $DIR/$tfile differ"
14952         remount_client $MOUNT
14953         df -P $MOUNT
14954         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (remount)"
14955
14956         $TRUNCATE $TF 6000
14957         $TRUNCATE $DIR/$tfile 6000
14958         cancel_lru_locks $OSC
14959         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (truncate1)"
14960
14961         echo "12345" >>$TF
14962         echo "12345" >>$DIR/$tfile
14963         cancel_lru_locks $OSC
14964         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append1)"
14965
14966         echo "12345" >>$TF
14967         echo "12345" >>$DIR/$tfile
14968         cancel_lru_locks $OSC
14969         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append2)"
14970 }
14971 run_test 150a "truncate/append tests"
14972
14973 test_150b() {
14974         check_set_fallocate_or_skip
14975         local out
14976
14977         touch $DIR/$tfile
14978         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14979         out=$(check_fallocate $DIR/$tfile 2>&1) ||
14980                 skip_eopnotsupp "$out|check_fallocate failed"
14981 }
14982 run_test 150b "Verify fallocate (prealloc) functionality"
14983
14984 test_150bb() {
14985         check_set_fallocate_or_skip
14986
14987         touch $DIR/$tfile
14988         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14989         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=20 || error "dd failed"
14990         > $DIR/$tfile
14991         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
14992         # precomputed md5sum for 20MB of zeroes
14993         local expect="8f4e33f3dc3e414ff94e5fb6905cba8c"
14994         local sum=($(md5sum $DIR/$tfile))
14995
14996         [[ "${sum[0]}" == "$expect" ]] || error "fallocate unwritten is not zero"
14997
14998         check_set_fallocate 1
14999
15000         > $DIR/$tfile
15001         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
15002         sum=($(md5sum $DIR/$tfile))
15003
15004         [[ "${sum[0]}" == "$expect" ]] || error "fallocate zero is not zero"
15005 }
15006 run_test 150bb "Verify fallocate modes both zero space"
15007
15008 test_150c() {
15009         check_set_fallocate_or_skip
15010         local striping="-c2"
15011
15012         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15013         $LFS setstripe -c $OSTCOUNT -S1M $DIR/$tfile || error "setstripe failed"
15014         fallocate -l ${OSTCOUNT}m $DIR/$tfile || error "fallocate failed"
15015         local bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
15016         local want=$((OSTCOUNT * 1048576))
15017
15018         # Must allocate all requested space, not more than 5% extra
15019         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
15020                 error "bytes $bytes is not $want"
15021
15022         rm -f $DIR/$tfile
15023
15024         echo "verify fallocate on PFL file"
15025
15026         [[ "x$DOM" == "xyes" ]] && striping="-L mdt"
15027
15028         $LFS setstripe -E1M $striping -E16M -c3 -Eeof -c 4 $DIR/$tfile ||
15029                 error "Create $DIR/$tfile failed"
15030         fallocate -l $((1048576 * 512)) $DIR/$tfile || error "fallocate failed"
15031         bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
15032         want=$((512 * 1048576))
15033
15034         # Must allocate all requested space, not more than 5% extra
15035         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
15036                 error "bytes $bytes is not $want"
15037 }
15038 run_test 150c "Verify fallocate Size and Blocks"
15039
15040 test_150d() {
15041         check_set_fallocate_or_skip
15042         local striping="-c2"
15043
15044         [[ "x$DOM" == "xyes" ]] && striping="-L mdt"
15045
15046         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15047         $LFS setstripe -E1M $striping -E eof -c $OSTCOUNT -S1M $DIR/$tdir ||
15048                 error "setstripe failed"
15049         fallocate -o 1G -l ${OSTCOUNT}m $DIR/$tdir || error "fallocate failed"
15050         local bytes=$(($(stat -c '%b * %B' $DIR/$tdir)))
15051         local want=$((OSTCOUNT * 1048576))
15052
15053         # Must allocate all requested space, not more than 5% extra
15054         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
15055                 error "bytes $bytes is not $want"
15056 }
15057 run_test 150d "Verify fallocate Size and Blocks - Non zero start"
15058
15059 test_150e() {
15060         check_set_fallocate_or_skip
15061
15062         echo "df before:"
15063         $LFS df
15064         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15065         $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
15066                 error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
15067
15068         # Find OST with Minimum Size
15069         min_size_ost=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
15070                        sort -un | head -1)
15071
15072         # Get 100MB per OST of the available space to reduce run time
15073         # else 60% of the available space if we are running SLOW tests
15074         if [ $SLOW == "no" ]; then
15075                 local space=$((1024 * 100 * OSTCOUNT))
15076         else
15077                 local space=$(((min_size_ost * 60)/100 * OSTCOUNT))
15078         fi
15079
15080         fallocate -l${space}k $DIR/$tfile ||
15081                 error "fallocate ${space}k $DIR/$tfile failed"
15082         echo "'fallocate -l ${space}k $DIR/$tfile' succeeded"
15083
15084         # get size immediately after fallocate. This should be correctly
15085         # updated
15086         local size=$(stat -c '%s' $DIR/$tfile)
15087         local used=$(( $(stat -c '%b * %B' $DIR/$tfile) / 1024))
15088
15089         # Sleep for a while for statfs to get updated. And not pull from cache.
15090         sleep 2
15091
15092         echo "df after fallocate:"
15093         $LFS df
15094
15095         (( size / 1024 == space )) || error "size $size != requested $space"
15096         [ "$ost1_FSTYPE" != ldiskfs ] || (( used >= space )) ||
15097                 error "used $used < space $space"
15098
15099         rm $DIR/$tfile || error "rm failed"
15100         sync
15101         wait_delete_completed
15102
15103         echo "df after unlink:"
15104         $LFS df
15105 }
15106 run_test 150e "Verify 60% of available OST space consumed by fallocate"
15107
15108 test_150f() {
15109         local size
15110         local blocks
15111         local want_size_before=20480 # in bytes
15112         local want_blocks_before=40 # 512 sized blocks
15113         local want_blocks_after=24  # 512 sized blocks
15114         local length=$(((want_blocks_before - want_blocks_after) * 512))
15115
15116         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
15117                 skip "need at least 2.14.0 for fallocate punch"
15118
15119         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
15120                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
15121         fi
15122
15123         check_set_fallocate_or_skip
15124         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15125
15126         [[ "x$DOM" == "xyes" ]] &&
15127                 $LFS setstripe -E1M -L mdt -E eof $DIR/$tfile
15128
15129         echo "Verify fallocate punch: Range within the file range"
15130         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
15131                 error "dd failed for bs 4096 and count 5"
15132
15133         # Call fallocate with punch range which is within the file range
15134         out=$(fallocate -p --offset 4096 -l $length $DIR/$tfile 2>&1) ||
15135                 skip_eopnotsupp "$out|fallocate: offset 4096 and length $length"
15136         # client must see changes immediately after fallocate
15137         size=$(stat -c '%s' $DIR/$tfile)
15138         blocks=$(stat -c '%b' $DIR/$tfile)
15139
15140         # Verify punch worked.
15141         (( blocks == want_blocks_after )) ||
15142                 error "punch failed: blocks $blocks != $want_blocks_after"
15143
15144         (( size == want_size_before )) ||
15145                 error "punch failed: size $size != $want_size_before"
15146
15147         # Verify there is hole in file
15148         local data_off=$(lseek_test -d 4096 $DIR/$tfile)
15149         # precomputed md5sum
15150         local expect="4a9a834a2db02452929c0a348273b4aa"
15151
15152         cksum=($(md5sum $DIR/$tfile))
15153         [[ "${cksum[0]}" == "$expect" ]] ||
15154                 error "unexpected MD5SUM after punch: ${cksum[0]}"
15155
15156         # Start second sub-case for fallocate punch.
15157         echo "Verify fallocate punch: Range overlapping and less than blocksize"
15158         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
15159                 error "dd failed for bs 4096 and count 5"
15160
15161         # Punch range less than block size will have no change in block count
15162         want_blocks_after=40  # 512 sized blocks
15163
15164         # Punch overlaps two blocks and less than blocksize
15165         out=$(fallocate -p --offset 4000 -l 3000 $DIR/$tfile 2>&1) ||
15166                 skip_eopnotsupp "$out|fallocate: offset 4000 length 3000"
15167         size=$(stat -c '%s' $DIR/$tfile)
15168         blocks=$(stat -c '%b' $DIR/$tfile)
15169
15170         # Verify punch worked.
15171         (( blocks == want_blocks_after )) ||
15172                 error "punch failed: blocks $blocks != $want_blocks_after"
15173
15174         (( size == want_size_before )) ||
15175                 error "punch failed: size $size != $want_size_before"
15176
15177         # Verify if range is really zero'ed out. We expect Zeros.
15178         # precomputed md5sum
15179         expect="c57ec5d769c3dbe3426edc3f7d7e11d3"
15180         cksum=($(md5sum $DIR/$tfile))
15181         [[ "${cksum[0]}" == "$expect" ]] ||
15182                 error "unexpected MD5SUM after punch: ${cksum[0]}"
15183 }
15184 run_test 150f "Verify fallocate punch functionality"
15185
15186 test_150g() {
15187         local space
15188         local size
15189         local blocks
15190         local blocks_after
15191         local size_after
15192         local BS=4096 # Block size in bytes
15193
15194         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
15195                 skip "need at least 2.14.0 for fallocate punch"
15196
15197         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
15198                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
15199         fi
15200
15201         check_set_fallocate_or_skip
15202         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15203
15204         if [[ "x$DOM" == "xyes" ]]; then
15205                 $LFS setstripe -E2M -L mdt -E eof -c${OSTCOUNT} $DIR/$tfile ||
15206                         error "$LFS setstripe DoM + ${OSTCOUNT} OST failed"
15207         else
15208                 $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
15209                         error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
15210         fi
15211
15212         # Get 100MB per OST of the available space to reduce run time
15213         # else 60% of the available space if we are running SLOW tests
15214         if [ $SLOW == "no" ]; then
15215                 space=$((1024 * 100 * OSTCOUNT))
15216         else
15217                 # Find OST with Minimum Size
15218                 space=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
15219                         sort -un | head -1)
15220                 echo "min size OST: $space"
15221                 space=$(((space * 60)/100 * OSTCOUNT))
15222         fi
15223         # space in 1k units, round to 4k blocks
15224         local blkcount=$((space * 1024 / $BS))
15225
15226         echo "Verify fallocate punch: Very large Range"
15227         fallocate -l${space}k $DIR/$tfile ||
15228                 error "fallocate ${space}k $DIR/$tfile failed"
15229         # write 1M at the end, start and in the middle
15230         yes 'A' | dd of=$DIR/$tfile bs=$BS count=256 ||
15231                 error "dd failed: bs $BS count 256"
15232         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount - 256)) count=256 ||
15233                 error "dd failed: bs $BS count 256 seek $((blkcount - 256))"
15234         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount / 2)) count=1024 ||
15235                 error "dd failed: bs $BS count 256 seek $((blkcount / 2))"
15236
15237         # Gather stats.
15238         size=$(stat -c '%s' $DIR/$tfile)
15239
15240         # gather punch length.
15241         local punch_size=$((size - (BS * 2)))
15242
15243         echo "punch_size = $punch_size"
15244         echo "size - punch_size: $((size - punch_size))"
15245         echo "size - punch_size in blocks: $(((size - punch_size)/BS))"
15246
15247         # Call fallocate to punch all except 2 blocks. We leave the
15248         # first and the last block
15249         echo "fallocate -p --offset $BS -l $punch_size $DIR/$tfile"
15250         out=$(fallocate -p --offset $BS -l $punch_size $DIR/$tfile 2>&1) ||
15251                 skip_eopnotsupp "$out|fallocate: offset $BS length $punch_size"
15252
15253         size_after=$(stat -c '%s' $DIR/$tfile)
15254         blocks_after=$(stat -c '%b' $DIR/$tfile)
15255
15256         # Verify punch worked.
15257         # Size should be kept
15258         (( size == size_after )) ||
15259                 error "punch failed: size $size != $size_after"
15260
15261         # two 4k data blocks to remain plus possible 1 extra extent block
15262         (( blocks_after <= ((BS / 512) * 3) )) ||
15263                 error "too many blocks remains: $blocks_after"
15264
15265         # Verify that file has hole between the first and the last blocks
15266         local hole_start=$(lseek_test -l 0 $DIR/$tfile)
15267         local hole_end=$(lseek_test -d $BS $DIR/$tfile)
15268
15269         echo "Hole at [$hole_start, $hole_end)"
15270         (( hole_start == BS )) ||
15271                 error "no hole at offset $BS after punch"
15272
15273         (( hole_end == BS + punch_size )) ||
15274                 error "data at offset $hole_end < $((BS + punch_size))"
15275 }
15276 run_test 150g "Verify fallocate punch on large range"
15277
15278 test_150h() {
15279         local file=$DIR/$tfile
15280         local size
15281
15282         check_set_fallocate_or_skip
15283         statx_supported || skip_env "Test must be statx() syscall supported"
15284
15285         # fallocate() does not update the size information on the MDT
15286         fallocate -l 16K $file || error "failed to fallocate $file"
15287         cancel_lru_locks $OSC
15288         # STATX with cached-always mode will not send glimpse RPCs to OST,
15289         # it uses the caching attrs on the client side as much as possible.
15290         size=$($STATX --cached=always -c %s $file)
15291         [ $size == 16384 ] ||
15292                 error "size after fallocate() is $size, expected 16384"
15293 }
15294 run_test 150h "Verify extend fallocate updates the file size"
15295
15296 #LU-2902 roc_hit was not able to read all values from lproc
15297 function roc_hit_init() {
15298         local list=$(comma_list $(osts_nodes))
15299         local dir=$DIR/$tdir-check
15300         local file=$dir/$tfile
15301         local BEFORE
15302         local AFTER
15303         local idx
15304
15305         test_mkdir $dir
15306         #use setstripe to do a write to every ost
15307         for i in $(seq 0 $((OSTCOUNT-1))); do
15308                 $LFS setstripe -c 1 -i $i $dir || error "$LFS setstripe $file failed"
15309                 dd if=/dev/urandom of=$file bs=4k count=4 2>&1 > /dev/null
15310                 idx=$(printf %04x $i)
15311                 BEFORE=$(get_osd_param $list *OST*$idx stats |
15312                         awk '$1 == "cache_access" {sum += $7}
15313                                 END { printf("%0.0f", sum) }')
15314
15315                 cancel_lru_locks osc
15316                 cat $file >/dev/null
15317
15318                 AFTER=$(get_osd_param $list *OST*$idx stats |
15319                         awk '$1 == "cache_access" {sum += $7}
15320                                 END { printf("%0.0f", sum) }')
15321
15322                 echo BEFORE:$BEFORE AFTER:$AFTER
15323                 if ! let "AFTER - BEFORE == 4"; then
15324                         rm -rf $dir
15325                         error "roc_hit is not safe to use"
15326                 fi
15327                 rm $file
15328         done
15329
15330         rm -rf $dir
15331 }
15332
15333 function roc_hit() {
15334         local list=$(comma_list $(osts_nodes))
15335         echo $(get_osd_param $list '' stats |
15336                 awk '$1 == "cache_hit" {sum += $7}
15337                         END { printf("%0.0f", sum) }')
15338 }
15339
15340 function set_cache() {
15341         local on=1
15342
15343         if [ "$2" == "off" ]; then
15344                 on=0;
15345         fi
15346         local list=$(comma_list $(osts_nodes))
15347         set_osd_param $list '' $1_cache_enable $on
15348
15349         cancel_lru_locks osc
15350 }
15351
15352 test_151() {
15353         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15354         remote_ost_nodsh && skip "remote OST with nodsh"
15355
15356         local CPAGES=3
15357         local list=$(comma_list $(osts_nodes))
15358
15359         # check whether obdfilter is cache capable at all
15360         if ! get_osd_param $list '' read_cache_enable >/dev/null; then
15361                 skip "not cache-capable obdfilter"
15362         fi
15363
15364         # check cache is enabled on all obdfilters
15365         if get_osd_param $list '' read_cache_enable | grep 0; then
15366                 skip "oss cache is disabled"
15367         fi
15368
15369         set_osd_param $list '' writethrough_cache_enable 1
15370
15371         # check write cache is enabled on all obdfilters
15372         if get_osd_param $list '' writethrough_cache_enable | grep 0; then
15373                 skip "oss write cache is NOT enabled"
15374         fi
15375
15376         roc_hit_init
15377
15378         #define OBD_FAIL_OBD_NO_LRU  0x609
15379         do_nodes $list $LCTL set_param fail_loc=0x609
15380
15381         # pages should be in the case right after write
15382         dd if=/dev/urandom of=$DIR/$tfile bs=4k count=$CPAGES ||
15383                 error "dd failed"
15384
15385         local BEFORE=$(roc_hit)
15386         cancel_lru_locks osc
15387         cat $DIR/$tfile >/dev/null
15388         local AFTER=$(roc_hit)
15389
15390         do_nodes $list $LCTL set_param fail_loc=0
15391
15392         if ! let "AFTER - BEFORE == CPAGES"; then
15393                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
15394         fi
15395
15396         cancel_lru_locks osc
15397         # invalidates OST cache
15398         do_nodes $list "echo 1 > /proc/sys/vm/drop_caches"
15399         set_osd_param $list '' read_cache_enable 0
15400         cat $DIR/$tfile >/dev/null
15401
15402         # now data shouldn't be found in the cache
15403         BEFORE=$(roc_hit)
15404         cancel_lru_locks osc
15405         cat $DIR/$tfile >/dev/null
15406         AFTER=$(roc_hit)
15407         if let "AFTER - BEFORE != 0"; then
15408                 error "IN CACHE: before: $BEFORE, after: $AFTER"
15409         fi
15410
15411         set_osd_param $list '' read_cache_enable 1
15412         rm -f $DIR/$tfile
15413 }
15414 run_test 151 "test cache on oss and controls ==============================="
15415
15416 test_152() {
15417         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15418
15419         local TF="$TMP/$tfile"
15420
15421         # simulate ENOMEM during write
15422 #define OBD_FAIL_OST_NOMEM      0x226
15423         lctl set_param fail_loc=0x80000226
15424         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
15425         cp $TF $DIR/$tfile
15426         sync || error "sync failed"
15427         lctl set_param fail_loc=0
15428
15429         # discard client's cache
15430         cancel_lru_locks osc
15431
15432         # simulate ENOMEM during read
15433         lctl set_param fail_loc=0x80000226
15434         cmp $TF $DIR/$tfile || error "cmp failed"
15435         lctl set_param fail_loc=0
15436
15437         rm -f $TF
15438 }
15439 run_test 152 "test read/write with enomem ============================"
15440
15441 test_153() {
15442         $MULTIOP $DIR/$tfile Ow4096Ycu || error "multiop failed"
15443 }
15444 run_test 153 "test if fdatasync does not crash ======================="
15445
15446 dot_lustre_fid_permission_check() {
15447         local fid=$1
15448         local ffid=$MOUNT/.lustre/fid/$fid
15449         local test_dir=$2
15450
15451         echo "stat fid $fid"
15452         stat $ffid || error "stat $ffid failed."
15453         echo "touch fid $fid"
15454         touch $ffid || error "touch $ffid failed."
15455         echo "write to fid $fid"
15456         cat /etc/hosts > $ffid || error "write $ffid failed."
15457         echo "read fid $fid"
15458         diff /etc/hosts $ffid || error "read $ffid failed."
15459         echo "append write to fid $fid"
15460         cat /etc/hosts >> $ffid || error "append write $ffid failed."
15461         echo "rename fid $fid"
15462         mv $ffid $test_dir/$tfile.1 &&
15463                 error "rename $ffid to $tfile.1 should fail."
15464         touch $test_dir/$tfile.1
15465         mv $test_dir/$tfile.1 $ffid &&
15466                 error "rename $tfile.1 to $ffid should fail."
15467         rm -f $test_dir/$tfile.1
15468         echo "truncate fid $fid"
15469         $TRUNCATE $ffid 777 || error "truncate $ffid failed."
15470         echo "link fid $fid"
15471         ln -f $ffid $test_dir/tfile.lnk || error "link $ffid failed."
15472         if [[ $($LCTL get_param -n mdc.*-mdc-*.connect_flags) =~ acl ]]; then
15473                 echo "setfacl fid $fid"
15474                 setfacl -R -m u:$USER0:rwx $ffid ||
15475                         error "setfacl $ffid failed"
15476                 echo "getfacl fid $fid"
15477                 getfacl $ffid || error "getfacl $ffid failed."
15478         fi
15479         echo "unlink fid $fid"
15480         unlink $MOUNT/.lustre/fid/$fid && error "unlink $ffid should fail."
15481         echo "mknod fid $fid"
15482         mknod $ffid c 1 3 && error "mknod $ffid should fail."
15483
15484         fid=[0xf00000400:0x1:0x0]
15485         ffid=$MOUNT/.lustre/fid/$fid
15486
15487         echo "stat non-exist fid $fid"
15488         stat $ffid > /dev/null && error "stat non-exist $ffid should fail."
15489         echo "write to non-exist fid $fid"
15490         cat /etc/hosts > $ffid && error "write non-exist $ffid should fail."
15491         echo "link new fid $fid"
15492         ln $test_dir/$tfile $ffid && error "link $ffid should fail."
15493
15494         mkdir -p $test_dir/$tdir
15495         touch $test_dir/$tdir/$tfile
15496         fid=$($LFS path2fid $test_dir/$tdir)
15497         rc=$?
15498         [ $rc -ne 0 ] &&
15499                 error "error: could not get fid for $test_dir/$dir/$tfile."
15500
15501         ffid=$MOUNT/.lustre/fid/$fid
15502
15503         echo "ls $fid"
15504         ls $ffid || error "ls $ffid failed."
15505         echo "touch $fid/$tfile.1"
15506         touch $ffid/$tfile.1 || error "touch $ffid/$tfile.1 failed."
15507
15508         echo "touch $MOUNT/.lustre/fid/$tfile"
15509         touch $MOUNT/.lustre/fid/$tfile && \
15510                 error "touch $MOUNT/.lustre/fid/$tfile should fail."
15511
15512         echo "setxattr to $MOUNT/.lustre/fid"
15513         setfattr -n trusted.name1 -v value1 $MOUNT/.lustre/fid
15514
15515         echo "listxattr for $MOUNT/.lustre/fid"
15516         getfattr -d -m "^trusted" $MOUNT/.lustre/fid
15517
15518         echo "delxattr from $MOUNT/.lustre/fid"
15519         setfattr -x trusted.name1 $MOUNT/.lustre/fid
15520
15521         echo "touch invalid fid: $MOUNT/.lustre/fid/[0x200000400:0x2:0x3]"
15522         touch $MOUNT/.lustre/fid/[0x200000400:0x2:0x3] &&
15523                 error "touch invalid fid should fail."
15524
15525         echo "touch non-normal fid: $MOUNT/.lustre/fid/[0x1:0x2:0x0]"
15526         touch $MOUNT/.lustre/fid/[0x1:0x2:0x0] &&
15527                 error "touch non-normal fid should fail."
15528
15529         echo "rename $tdir to $MOUNT/.lustre/fid"
15530         mrename $test_dir/$tdir $MOUNT/.lustre/fid &&
15531                 error "rename to $MOUNT/.lustre/fid should fail."
15532
15533         if [ $MDS1_VERSION -ge $(version_code 2.3.51) ]
15534         then            # LU-3547
15535                 local old_obf_mode=$(stat --format="%a" $DIR/.lustre/fid)
15536                 local new_obf_mode=777
15537
15538                 echo "change mode of $DIR/.lustre/fid to $new_obf_mode"
15539                 chmod $new_obf_mode $DIR/.lustre/fid ||
15540                         error "chmod $new_obf_mode $DIR/.lustre/fid failed"
15541
15542                 local obf_mode=$(stat --format=%a $DIR/.lustre/fid)
15543                 [ $obf_mode -eq $new_obf_mode ] ||
15544                         error "stat $DIR/.lustre/fid returned wrong mode $obf_mode"
15545
15546                 echo "restore mode of $DIR/.lustre/fid to $old_obf_mode"
15547                 chmod $old_obf_mode $DIR/.lustre/fid ||
15548                         error "chmod $old_obf_mode $DIR/.lustre/fid failed"
15549         fi
15550
15551         $OPENFILE -f O_LOV_DELAY_CREATE:O_CREAT $test_dir/$tfile-2
15552         fid=$($LFS path2fid $test_dir/$tfile-2)
15553
15554         if [ $MDS1_VERSION -ge $(version_code 2.6.50) ]
15555         then # LU-5424
15556                 echo "cp /etc/passwd $MOUNT/.lustre/fid/$fid"
15557                 cp /etc/passwd $MOUNT/.lustre/fid/$fid ||
15558                         error "create lov data thru .lustre failed"
15559         fi
15560         echo "cp /etc/passwd $test_dir/$tfile-2"
15561         cp /etc/passwd $test_dir/$tfile-2 ||
15562                 error "copy to $test_dir/$tfile-2 failed."
15563         echo "diff /etc/passwd $MOUNT/.lustre/fid/$fid"
15564         diff /etc/passwd $MOUNT/.lustre/fid/$fid ||
15565                 error "diff /etc/passwd $MOUNT/.lustre/fid/$fid failed."
15566
15567         rm -rf $test_dir/tfile.lnk
15568         rm -rf $test_dir/$tfile-2
15569 }
15570
15571 test_154A() {
15572         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
15573                 skip "Need MDS version at least 2.4.1"
15574
15575         local tf=$DIR/$tfile
15576         touch $tf
15577
15578         local fid=$($LFS path2fid $tf)
15579         [ -z "$fid" ] && error "path2fid unable to get $tf FID"
15580
15581         # check that we get the same pathname back
15582         local rootpath
15583         local found
15584         for rootpath in "$MOUNT" "$MOUNT///" "$MOUNT/$tfile"; do
15585                 echo "$rootpath $fid"
15586                 found=$($LFS fid2path $rootpath "$fid")
15587                 [ -z "$found" ] && error "fid2path unable to get '$fid' path"
15588                 [ "$found" == "$tf" ] || error "fid2path $found != $tf"
15589         done
15590
15591         # check wrong root path format
15592         rootpath=$MOUNT"_wrong"
15593         found=$($LFS fid2path $rootpath "$fid")
15594         [ -z "$found" ] || error "should fail ($rootpath != $MOUNT)"
15595 }
15596 run_test 154A "lfs path2fid and fid2path basic checks"
15597
15598 test_154B() {
15599         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
15600                 skip "Need MDS version at least 2.4.1"
15601
15602         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
15603         touch $DIR/$tdir/$tfile || error "touch $DIR/$tdir/$tfile failed"
15604         local linkea=$($LL_DECODE_LINKEA $DIR/$tdir/$tfile | grep 'pfid')
15605         [ -z "$linkea" ] && error "decode linkea $DIR/$tdir/$tfile failed"
15606
15607         local name=$(echo $linkea | awk '/pfid/ {print $5}' | sed -e "s/'//g")
15608         local PFID=$(echo $linkea | awk '/pfid/ {print $3}' | sed -e "s/,//g")
15609
15610         # check that we get the same pathname
15611         echo "PFID: $PFID, name: $name"
15612         local FOUND=$($LFS fid2path $MOUNT "$PFID")
15613         [ -z "$FOUND" ] && error "fid2path unable to get $PFID path"
15614         [ "$FOUND/$name" != "$DIR/$tdir/$tfile" ] &&
15615                 error "ll_decode_linkea has $FOUND/$name != $DIR/$tdir/$tfile"
15616
15617         rm -rf $DIR/$tdir || error "Can not delete directory $DIR/$tdir"
15618 }
15619 run_test 154B "verify the ll_decode_linkea tool"
15620
15621 test_154a() {
15622         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15623         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15624         (( $MDS1_VERSION >= $(version_code 2.2.51) )) ||
15625                 skip "Need MDS version at least 2.2.51"
15626         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
15627
15628         cp /etc/hosts $DIR/$tfile
15629
15630         fid=$($LFS path2fid $DIR/$tfile)
15631         rc=$?
15632         [ $rc -ne 0 ] && error "error: could not get fid for $DIR/$tfile."
15633
15634         dot_lustre_fid_permission_check "$fid" $DIR ||
15635                 error "dot lustre permission check $fid failed"
15636
15637         ls -a $MOUNT | grep "\.lustre" && error ".lustre should not be listed"
15638
15639         rm -rf $MOUNT/.lustre && error ".lustre is not allowed to be unlinked"
15640
15641         touch $MOUNT/.lustre/file &&
15642                 error "creation is not allowed under .lustre"
15643
15644         mkdir $MOUNT/.lustre/dir &&
15645                 error "mkdir is not allowed under .lustre"
15646
15647         rm -rf $DIR/$tfile
15648 }
15649 run_test 154a "Open-by-FID"
15650
15651 test_154b() {
15652         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15653         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15654         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15655         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
15656                 skip "Need MDS version at least 2.2.51"
15657
15658         local remote_dir=$DIR/$tdir/remote_dir
15659         local MDTIDX=1
15660         local rc=0
15661
15662         mkdir -p $DIR/$tdir
15663         $LFS mkdir -i $MDTIDX $remote_dir ||
15664                 error "create remote directory failed"
15665
15666         cp /etc/hosts $remote_dir/$tfile
15667
15668         fid=$($LFS path2fid $remote_dir/$tfile)
15669         rc=$?
15670         [ $rc -ne 0 ] && error "error: could not get fid for $remote_dir/$tfile"
15671
15672         dot_lustre_fid_permission_check "$fid" $remote_dir ||
15673                 error "dot lustre permission check $fid failed"
15674         rm -rf $DIR/$tdir
15675 }
15676 run_test 154b "Open-by-FID for remote directory"
15677
15678 test_154c() {
15679         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
15680                 skip "Need MDS version at least 2.4.1"
15681
15682         touch $DIR/$tfile.1 $DIR/$tfile.2 $DIR/$tfile.3
15683         local FID1=$($LFS path2fid $DIR/$tfile.1)
15684         local FID2=$($LFS path2fid $DIR/$tfile.2)
15685         local FID3=$($LFS path2fid $DIR/$tfile.3)
15686
15687         local N=1
15688         $LFS path2fid $DIR/$tfile.[123] | while read PATHNAME FID; do
15689                 [ "$PATHNAME" = "$DIR/$tfile.$N:" ] ||
15690                         error "path2fid pathname $PATHNAME != $DIR/$tfile.$N:"
15691                 local want=FID$N
15692                 [ "$FID" = "${!want}" ] ||
15693                         error "path2fid $PATHNAME FID $FID != FID$N ${!want}"
15694                 N=$((N + 1))
15695         done
15696
15697         $LFS fid2path $MOUNT "$FID1" "$FID2" "$FID3" | while read PATHNAME;
15698         do
15699                 [ "$PATHNAME" = "$DIR/$tfile.$N" ] ||
15700                         error "fid2path pathname $PATHNAME != $DIR/$tfile.$N:"
15701                 N=$((N + 1))
15702         done
15703 }
15704 run_test 154c "lfs path2fid and fid2path multiple arguments"
15705
15706 test_154d() {
15707         remote_mds_nodsh && skip "remote MDS with nodsh"
15708         [[ $MDS1_VERSION -lt $(version_code 2.5.53) ]] &&
15709                 skip "Need MDS version at least 2.5.53"
15710
15711         if remote_mds; then
15712                 nid=$($LCTL list_nids | sed  "s/\./\\\./g")
15713         else
15714                 nid="0@lo"
15715         fi
15716         local proc_ofile="mdt.*.exports.'$nid'.open_files"
15717         local fd
15718         local cmd
15719
15720         rm -f $DIR/$tfile
15721         touch $DIR/$tfile
15722
15723         local fid=$($LFS path2fid $DIR/$tfile)
15724         # Open the file
15725         fd=$(free_fd)
15726         cmd="exec $fd<$DIR/$tfile"
15727         eval $cmd
15728         local fid_list=$(do_facet $SINGLEMDS $LCTL get_param $proc_ofile)
15729         echo "$fid_list" | grep "$fid"
15730         rc=$?
15731
15732         cmd="exec $fd>/dev/null"
15733         eval $cmd
15734         if [ $rc -ne 0 ]; then
15735                 error "FID $fid not found in open files list $fid_list"
15736         fi
15737 }
15738 run_test 154d "Verify open file fid"
15739
15740 test_154e()
15741 {
15742         [[ $MDS1_VERSION -lt $(version_code 2.6.50) ]] &&
15743                 skip "Need MDS version at least 2.6.50"
15744
15745         if ls -a $MOUNT | grep -q '^\.lustre$'; then
15746                 error ".lustre returned by readdir"
15747         fi
15748 }
15749 run_test 154e ".lustre is not returned by readdir"
15750
15751 test_154f() {
15752         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15753
15754         # create parent directory on a single MDT to avoid cross-MDT hardlinks
15755         mkdir_on_mdt0 $DIR/$tdir
15756         # test dirs inherit from its stripe
15757         mkdir -p $DIR/$tdir/foo1 || error "mkdir error"
15758         mkdir -p $DIR/$tdir/foo2 || error "mkdir error"
15759         cp /etc/hosts $DIR/$tdir/foo1/$tfile
15760         ln $DIR/$tdir/foo1/$tfile $DIR/$tdir/foo2/link
15761         touch $DIR/f
15762
15763         # get fid of parents
15764         local FID0=$($LFS path2fid $DIR/$tdir)
15765         local FID1=$($LFS path2fid $DIR/$tdir/foo1)
15766         local FID2=$($LFS path2fid $DIR/$tdir/foo2)
15767         local FID3=$($LFS path2fid $DIR)
15768
15769         # check that path2fid --parents returns expected <parent_fid>/name
15770         # 1) test for a directory (single parent)
15771         local parent=$($LFS path2fid --parents $DIR/$tdir/foo1)
15772         [ "$parent" == "$FID0/foo1" ] ||
15773                 error "expected parent: $FID0/foo1, got: $parent"
15774
15775         # 2) test for a file with nlink > 1 (multiple parents)
15776         parent=$($LFS path2fid --parents $DIR/$tdir/foo1/$tfile)
15777         echo "$parent" | grep -F "$FID1/$tfile" ||
15778                 error "$FID1/$tfile not returned in parent list"
15779         echo "$parent" | grep -F "$FID2/link" ||
15780                 error "$FID2/link not returned in parent list"
15781
15782         # 3) get parent by fid
15783         local file_fid=$($LFS path2fid $DIR/$tdir/foo1/$tfile)
15784         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
15785         echo "$parent" | grep -F "$FID1/$tfile" ||
15786                 error "$FID1/$tfile not returned in parent list (by fid)"
15787         echo "$parent" | grep -F "$FID2/link" ||
15788                 error "$FID2/link not returned in parent list (by fid)"
15789
15790         # 4) test for entry in root directory
15791         parent=$($LFS path2fid --parents $DIR/f)
15792         echo "$parent" | grep -F "$FID3/f" ||
15793                 error "$FID3/f not returned in parent list"
15794
15795         # 5) test it on root directory
15796         [ -z "$($LFS path2fid --parents $MOUNT 2>/dev/null)" ] ||
15797                 error "$MOUNT should not have parents"
15798
15799         # enable xattr caching and check that linkea is correctly updated
15800         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
15801         save_lustre_params client "llite.*.xattr_cache" > $save
15802         lctl set_param llite.*.xattr_cache 1
15803
15804         # 6.1) linkea update on rename
15805         mv $DIR/$tdir/foo1/$tfile $DIR/$tdir/foo2/$tfile.moved
15806
15807         # get parents by fid
15808         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
15809         # foo1 should no longer be returned in parent list
15810         echo "$parent" | grep -F "$FID1" &&
15811                 error "$FID1 should no longer be in parent list"
15812         # the new path should appear
15813         echo "$parent" | grep -F "$FID2/$tfile.moved" ||
15814                 error "$FID2/$tfile.moved is not in parent list"
15815
15816         # 6.2) linkea update on unlink
15817         rm -f $DIR/$tdir/foo2/link
15818         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
15819         # foo2/link should no longer be returned in parent list
15820         echo "$parent" | grep -F "$FID2/link" &&
15821                 error "$FID2/link should no longer be in parent list"
15822         true
15823
15824         rm -f $DIR/f
15825         restore_lustre_params < $save
15826         rm -f $save
15827 }
15828 run_test 154f "get parent fids by reading link ea"
15829
15830 test_154g()
15831 {
15832         [[ $MDS1_VERSION -ge $(version_code 2.6.92) &&
15833            $CLIENT_VERSION -gt $(version_code 2.6.99) ]] ||
15834                 skip "Need MDS version at least 2.6.92"
15835
15836         mkdir_on_mdt0 $DIR/$tdir
15837         llapi_fid_test -d $DIR/$tdir
15838 }
15839 run_test 154g "various llapi FID tests"
15840
15841 test_155_small_load() {
15842     local temp=$TMP/$tfile
15843     local file=$DIR/$tfile
15844
15845     dd if=/dev/urandom of=$temp bs=6096 count=1 || \
15846         error "dd of=$temp bs=6096 count=1 failed"
15847     cp $temp $file
15848     cancel_lru_locks $OSC
15849     cmp $temp $file || error "$temp $file differ"
15850
15851     $TRUNCATE $temp 6000
15852     $TRUNCATE $file 6000
15853     cmp $temp $file || error "$temp $file differ (truncate1)"
15854
15855     echo "12345" >>$temp
15856     echo "12345" >>$file
15857     cmp $temp $file || error "$temp $file differ (append1)"
15858
15859     echo "12345" >>$temp
15860     echo "12345" >>$file
15861     cmp $temp $file || error "$temp $file differ (append2)"
15862
15863     rm -f $temp $file
15864     true
15865 }
15866
15867 test_155_big_load() {
15868         remote_ost_nodsh && skip "remote OST with nodsh"
15869
15870         local temp=$TMP/$tfile
15871         local file=$DIR/$tfile
15872
15873         free_min_max
15874         local cache_size=$(do_facet ost$((MAXI+1)) \
15875                 "awk '/cache/ {sum+=\\\$4} END {print sum}' /proc/cpuinfo")
15876
15877         # LU-16042: can not get the cache size on Arm64 VM here, fallback to a
15878         # pre-set value
15879         if [ -z "$cache_size" ]; then
15880                 cache_size=256
15881         fi
15882         local large_file_size=$((cache_size * 2))
15883
15884         echo "OSS cache size: $cache_size KB"
15885         echo "Large file size: $large_file_size KB"
15886
15887         [ $MAXV -le $large_file_size ] &&
15888                 skip_env "max available OST size needs > $large_file_size KB"
15889
15890         $LFS setstripe $file -c 1 -i $MAXI || error "$LFS setstripe $file failed"
15891
15892         dd if=/dev/urandom of=$temp bs=$large_file_size count=1k ||
15893                 error "dd of=$temp bs=$large_file_size count=1k failed"
15894         cp $temp $file
15895         ls -lh $temp $file
15896         cancel_lru_locks osc
15897         cmp $temp $file || error "$temp $file differ"
15898
15899         rm -f $temp $file
15900         true
15901 }
15902
15903 save_writethrough() {
15904         local facets=$(get_facets OST)
15905
15906         save_lustre_params $facets "osd-*.*.writethrough_cache_enable" > $1
15907 }
15908
15909 test_155a() {
15910         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15911
15912         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15913
15914         save_writethrough $p
15915
15916         set_cache read on
15917         set_cache writethrough on
15918         test_155_small_load
15919         restore_lustre_params < $p
15920         rm -f $p
15921 }
15922 run_test 155a "Verify small file correctness: read cache:on write_cache:on"
15923
15924 test_155b() {
15925         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15926
15927         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15928
15929         save_writethrough $p
15930
15931         set_cache read on
15932         set_cache writethrough off
15933         test_155_small_load
15934         restore_lustre_params < $p
15935         rm -f $p
15936 }
15937 run_test 155b "Verify small file correctness: read cache:on write_cache:off"
15938
15939 test_155c() {
15940         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15941
15942         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15943
15944         save_writethrough $p
15945
15946         set_cache read off
15947         set_cache writethrough on
15948         test_155_small_load
15949         restore_lustre_params < $p
15950         rm -f $p
15951 }
15952 run_test 155c "Verify small file correctness: read cache:off write_cache:on"
15953
15954 test_155d() {
15955         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15956
15957         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15958
15959         save_writethrough $p
15960
15961         set_cache read off
15962         set_cache writethrough off
15963         test_155_small_load
15964         restore_lustre_params < $p
15965         rm -f $p
15966 }
15967 run_test 155d "Verify small file correctness: read cache:off write_cache:off"
15968
15969 test_155e() {
15970         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15971
15972         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15973
15974         save_writethrough $p
15975
15976         set_cache read on
15977         set_cache writethrough on
15978         test_155_big_load
15979         restore_lustre_params < $p
15980         rm -f $p
15981 }
15982 run_test 155e "Verify big file correctness: read cache:on write_cache:on"
15983
15984 test_155f() {
15985         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15986
15987         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15988
15989         save_writethrough $p
15990
15991         set_cache read on
15992         set_cache writethrough off
15993         test_155_big_load
15994         restore_lustre_params < $p
15995         rm -f $p
15996 }
15997 run_test 155f "Verify big file correctness: read cache:on write_cache:off"
15998
15999 test_155g() {
16000         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16001
16002         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16003
16004         save_writethrough $p
16005
16006         set_cache read off
16007         set_cache writethrough on
16008         test_155_big_load
16009         restore_lustre_params < $p
16010         rm -f $p
16011 }
16012 run_test 155g "Verify big file correctness: read cache:off write_cache:on"
16013
16014 test_155h() {
16015         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16016
16017         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16018
16019         save_writethrough $p
16020
16021         set_cache read off
16022         set_cache writethrough off
16023         test_155_big_load
16024         restore_lustre_params < $p
16025         rm -f $p
16026 }
16027 run_test 155h "Verify big file correctness: read cache:off write_cache:off"
16028
16029 test_156() {
16030         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16031         remote_ost_nodsh && skip "remote OST with nodsh"
16032         [ $OST1_VERSION -lt $(version_code 2.6.93) ] &&
16033                 skip "stats not implemented on old servers"
16034         [ "$ost1_FSTYPE" = "zfs" ] &&
16035                 skip "LU-1956/LU-2261: stats not implemented on OSD ZFS"
16036
16037         local CPAGES=3
16038         local BEFORE
16039         local AFTER
16040         local file="$DIR/$tfile"
16041         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16042
16043         save_writethrough $p
16044         roc_hit_init
16045
16046         log "Turn on read and write cache"
16047         set_cache read on
16048         set_cache writethrough on
16049
16050         log "Write data and read it back."
16051         log "Read should be satisfied from the cache."
16052         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
16053         BEFORE=$(roc_hit)
16054         cancel_lru_locks osc
16055         cat $file >/dev/null
16056         AFTER=$(roc_hit)
16057         if ! let "AFTER - BEFORE == CPAGES"; then
16058                 error "NOT IN CACHE (2): before: $BEFORE, after: $AFTER"
16059         else
16060                 log "cache hits: before: $BEFORE, after: $AFTER"
16061         fi
16062
16063         log "Read again; it should be satisfied from the cache."
16064         BEFORE=$AFTER
16065         cancel_lru_locks osc
16066         cat $file >/dev/null
16067         AFTER=$(roc_hit)
16068         if ! let "AFTER - BEFORE == CPAGES"; then
16069                 error "NOT IN CACHE (3): before: $BEFORE, after: $AFTER"
16070         else
16071                 log "cache hits:: before: $BEFORE, after: $AFTER"
16072         fi
16073
16074         log "Turn off the read cache and turn on the write cache"
16075         set_cache read off
16076         set_cache writethrough on
16077
16078         log "Read again; it should be satisfied from the cache."
16079         BEFORE=$(roc_hit)
16080         cancel_lru_locks osc
16081         cat $file >/dev/null
16082         AFTER=$(roc_hit)
16083         if ! let "AFTER - BEFORE == CPAGES"; then
16084                 error "NOT IN CACHE (4): before: $BEFORE, after: $AFTER"
16085         else
16086                 log "cache hits:: before: $BEFORE, after: $AFTER"
16087         fi
16088
16089         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
16090                 # > 2.12.56 uses pagecache if cached
16091                 log "Read again; it should not be satisfied from the cache."
16092                 BEFORE=$AFTER
16093                 cancel_lru_locks osc
16094                 cat $file >/dev/null
16095                 AFTER=$(roc_hit)
16096                 if ! let "AFTER - BEFORE == 0"; then
16097                         error "IN CACHE (5): before: $BEFORE, after: $AFTER"
16098                 else
16099                         log "cache hits:: before: $BEFORE, after: $AFTER"
16100                 fi
16101         fi
16102
16103         log "Write data and read it back."
16104         log "Read should be satisfied from the cache."
16105         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
16106         BEFORE=$(roc_hit)
16107         cancel_lru_locks osc
16108         cat $file >/dev/null
16109         AFTER=$(roc_hit)
16110         if ! let "AFTER - BEFORE == CPAGES"; then
16111                 error "NOT IN CACHE (6): before: $BEFORE, after: $AFTER"
16112         else
16113                 log "cache hits:: before: $BEFORE, after: $AFTER"
16114         fi
16115
16116         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
16117                 # > 2.12.56 uses pagecache if cached
16118                 log "Read again; it should not be satisfied from the cache."
16119                 BEFORE=$AFTER
16120                 cancel_lru_locks osc
16121                 cat $file >/dev/null
16122                 AFTER=$(roc_hit)
16123                 if ! let "AFTER - BEFORE == 0"; then
16124                         error "IN CACHE (7): before: $BEFORE, after: $AFTER"
16125                 else
16126                         log "cache hits:: before: $BEFORE, after: $AFTER"
16127                 fi
16128         fi
16129
16130         log "Turn off read and write cache"
16131         set_cache read off
16132         set_cache writethrough off
16133
16134         log "Write data and read it back"
16135         log "It should not be satisfied from the cache."
16136         rm -f $file
16137         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
16138         cancel_lru_locks osc
16139         BEFORE=$(roc_hit)
16140         cat $file >/dev/null
16141         AFTER=$(roc_hit)
16142         if ! let "AFTER - BEFORE == 0"; then
16143                 error_ignore bz20762 "IN CACHE (8):before:$BEFORE,after:$AFTER"
16144         else
16145                 log "cache hits:: before: $BEFORE, after: $AFTER"
16146         fi
16147
16148         log "Turn on the read cache and turn off the write cache"
16149         set_cache read on
16150         set_cache writethrough off
16151
16152         log "Write data and read it back"
16153         log "It should not be satisfied from the cache."
16154         rm -f $file
16155         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
16156         BEFORE=$(roc_hit)
16157         cancel_lru_locks osc
16158         cat $file >/dev/null
16159         AFTER=$(roc_hit)
16160         if ! let "AFTER - BEFORE == 0"; then
16161                 error_ignore bz20762 "IN CACHE (9):before:$BEFORE,after:$AFTER"
16162         else
16163                 log "cache hits:: before: $BEFORE, after: $AFTER"
16164         fi
16165
16166         log "Read again; it should be satisfied from the cache."
16167         BEFORE=$(roc_hit)
16168         cancel_lru_locks osc
16169         cat $file >/dev/null
16170         AFTER=$(roc_hit)
16171         if ! let "AFTER - BEFORE == CPAGES"; then
16172                 error "NOT IN CACHE (1): before: $BEFORE, after: $AFTER"
16173         else
16174                 log "cache hits:: before: $BEFORE, after: $AFTER"
16175         fi
16176
16177         restore_lustre_params < $p
16178         rm -f $p $file
16179 }
16180 run_test 156 "Verification of tunables"
16181
16182 test_160a() {
16183         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16184         remote_mds_nodsh && skip "remote MDS with nodsh"
16185         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
16186                 skip "Need MDS version at least 2.2.0"
16187
16188         changelog_register || error "changelog_register failed"
16189         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16190         changelog_users $SINGLEMDS | grep -q $cl_user ||
16191                 error "User $cl_user not found in changelog_users"
16192
16193         mkdir_on_mdt0 $DIR/$tdir
16194
16195         # change something
16196         test_mkdir -p $DIR/$tdir/pics/2008/zachy
16197         changelog_clear 0 || error "changelog_clear failed"
16198         touch $DIR/$tdir/pics/2008/zachy/$tfile                 # open 1
16199         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg       # open 2
16200         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
16201         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
16202         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
16203         rm $DIR/$tdir/pics/desktop.jpg
16204
16205         echo "verifying changelog mask"
16206         changelog_chmask "-MKDIR"
16207         changelog_chmask "-CLOSE"
16208
16209         test_mkdir -p $DIR/$tdir/pics/zach/sofia                # not logged
16210         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # not logged
16211
16212         changelog_chmask "+MKDIR"
16213         changelog_chmask "+CLOSE"
16214
16215         test_mkdir -p $DIR/$tdir/pics/2008/sofia                # mkdir 1
16216         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # open 3
16217
16218         MKDIRS=$(changelog_dump | grep -c "MKDIR")
16219         CLOSES=$(changelog_dump | grep -c "CLOSE")
16220         [ $MKDIRS -eq 1 ] || error "MKDIR changelog mask count $MKDIRS != 1"
16221         [ $CLOSES -eq 3 ] || error "CLOSE changelog mask count $CLOSES != 3"
16222
16223         # verify contents
16224         echo "verifying target fid"
16225         local fidc=$(changelog_extract_field "CREAT" "$tfile" "t=")
16226         local fidf=$($LFS path2fid $DIR/$tdir/pics/zach/$tfile)
16227         [ "$fidc" == "$fidf" ] ||
16228                 error "changelog '$tfile' fid $fidc != file fid $fidf"
16229         echo "verifying parent fid"
16230         # The FID returned from the Changelog may be the directory shard on
16231         # a different MDT, and not the FID returned by path2fid on the parent.
16232         # Instead of comparing FIDs, verify that fid2path(fidp) is correct,
16233         # since this is what will matter when recreating this file in the tree.
16234         local fidp=$(changelog_extract_field "CREAT" "$tfile" "p=")
16235         local pathp=$($LFS fid2path $MOUNT "$fidp")
16236         [ "${pathp%/}" == "$DIR/$tdir/pics/zach" ] ||
16237                 error "changelog fid2path($fidc) $pathp != $DIR/$tdir/pics/zach"
16238
16239         echo "getting records for $cl_user"
16240         changelog_users $SINGLEMDS
16241         local user_rec1=$(changelog_user_rec $SINGLEMDS $cl_user)
16242         local nclr=3
16243         __changelog_clear $SINGLEMDS $cl_user +$nclr ||
16244                 error "changelog_clear failed"
16245         local user_rec2=$(changelog_user_rec $SINGLEMDS $cl_user)
16246         echo "verifying user clear: $user_rec1 + $nclr == $user_rec2"
16247         [ $user_rec2 == $((user_rec1 + nclr)) ] ||
16248                 error "user index expect $user_rec1 + $nclr != $user_rec2"
16249
16250         local min0_rec=$(changelog_users $SINGLEMDS |
16251                 awk 'min == "" || $2 < min { min = $2 }; END { print min }')
16252         local first_rec=$($LFS changelog $(facet_svc $SINGLEMDS) |
16253                           awk '{ print $1; exit; }')
16254
16255         changelog_dump | tail -n 5
16256         echo "verifying user min purge: $min0_rec + 1 == $first_rec"
16257         [ $first_rec == $((min0_rec + 1)) ] ||
16258                 error "first index should be $min0_rec + 1 not $first_rec"
16259
16260         # LU-3446 changelog index reset on MDT restart
16261         local cur_rec1=$(changelog_users $SINGLEMDS |
16262                          awk '/^current.index:/ { print $NF }')
16263         changelog_clear 0 ||
16264                 error "clear all changelog records for $cl_user failed"
16265         stop $SINGLEMDS || error "Fail to stop $SINGLEMDS"
16266         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
16267                 error "Fail to start $SINGLEMDS"
16268         local cur_rec2=$(changelog_users $SINGLEMDS |
16269                          awk '/^current.index:/ { print $NF }')
16270         echo "verifying index survives MDT restart: $cur_rec1 == $cur_rec2"
16271         [ $cur_rec1 == $cur_rec2 ] ||
16272                 error "current index should be $cur_rec1 not $cur_rec2"
16273
16274         echo "verifying users from this test are deregistered"
16275         changelog_deregister || error "changelog_deregister failed"
16276         changelog_users $SINGLEMDS | grep -q $cl_user &&
16277                 error "User '$cl_user' still in changelog_users"
16278
16279         # lctl get_param -n mdd.*.changelog_users
16280         # current_index: 144
16281         # ID    index (idle seconds)
16282         # cl3   144   (2) mask=<list>
16283         if [ -z "$(changelog_users $SINGLEMDS | grep -v current.index)" ]; then
16284                 # this is the normal case where all users were deregistered
16285                 # make sure no new records are added when no users are present
16286                 local last_rec1=$(changelog_users $SINGLEMDS |
16287                                   awk '/^current.index:/ { print $NF }')
16288                 touch $DIR/$tdir/chloe
16289                 local last_rec2=$(changelog_users $SINGLEMDS |
16290                                   awk '/^current.index:/ { print $NF }')
16291                 echo "verify changelogs are off: $last_rec1 == $last_rec2"
16292                 [ $last_rec1 == $last_rec2 ] || error "changelogs not off"
16293         else
16294                 # any changelog users must be leftovers from a previous test
16295                 changelog_users $SINGLEMDS
16296                 echo "other changelog users; can't verify off"
16297         fi
16298 }
16299 run_test 160a "changelog sanity"
16300
16301 test_160b() { # LU-3587
16302         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16303         remote_mds_nodsh && skip "remote MDS with nodsh"
16304         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
16305                 skip "Need MDS version at least 2.2.0"
16306
16307         changelog_register || error "changelog_register failed"
16308         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16309         changelog_users $SINGLEMDS | grep -q $cl_user ||
16310                 error "User '$cl_user' not found in changelog_users"
16311
16312         local longname1=$(str_repeat a 255)
16313         local longname2=$(str_repeat b 255)
16314
16315         cd $DIR
16316         echo "creating very long named file"
16317         touch $longname1 || error "create of '$longname1' failed"
16318         echo "renaming very long named file"
16319         mv $longname1 $longname2
16320
16321         changelog_dump | grep RENME | tail -n 5
16322         rm -f $longname2
16323 }
16324 run_test 160b "Verify that very long rename doesn't crash in changelog"
16325
16326 test_160c() {
16327         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16328         remote_mds_nodsh && skip "remote MDS with nodsh"
16329
16330         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
16331                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
16332                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
16333                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
16334
16335         local rc=0
16336
16337         # Registration step
16338         changelog_register || error "changelog_register failed"
16339
16340         rm -rf $DIR/$tdir
16341         mkdir -p $DIR/$tdir
16342         $MCREATE $DIR/$tdir/foo_160c
16343         changelog_chmask "-TRUNC"
16344         $TRUNCATE $DIR/$tdir/foo_160c 200
16345         changelog_chmask "+TRUNC"
16346         $TRUNCATE $DIR/$tdir/foo_160c 199
16347         changelog_dump | tail -n 5
16348         local truncs=$(changelog_dump | tail -n 5 | grep -c TRUNC)
16349         [ $truncs -eq 1 ] || error "TRUNC changelog mask count $truncs != 1"
16350 }
16351 run_test 160c "verify that changelog log catch the truncate event"
16352
16353 test_160d() {
16354         remote_mds_nodsh && skip "remote MDS with nodsh"
16355         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16356         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16357         [[ $MDS1_VERSION -ge $(version_code 2.7.60) ]] ||
16358                 skip "Need MDS version at least 2.7.60"
16359
16360         # Registration step
16361         changelog_register || error "changelog_register failed"
16362
16363         mkdir -p $DIR/$tdir/migrate_dir
16364         changelog_clear 0 || error "changelog_clear failed"
16365
16366         $LFS migrate -m 1 $DIR/$tdir/migrate_dir || error "migrate fails"
16367         changelog_dump | tail -n 5
16368         local migrates=$(changelog_dump | grep -c "MIGRT")
16369         [ $migrates -eq 1 ] || error "MIGRATE changelog count $migrates != 1"
16370 }
16371 run_test 160d "verify that changelog log catch the migrate event"
16372
16373 test_160e() {
16374         remote_mds_nodsh && skip "remote MDS with nodsh"
16375
16376         # Create a user
16377         changelog_register || error "changelog_register failed"
16378
16379         local MDT0=$(facet_svc $SINGLEMDS)
16380         local rc
16381
16382         # No user (expect fail)
16383         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister
16384         rc=$?
16385         if [ $rc -eq 0 ]; then
16386                 error "Should fail without user"
16387         elif [ $rc -ne 4 ]; then
16388                 error "changelog_deregister failed with $rc, expect 4(CMD_HELP)"
16389         fi
16390
16391         # Delete a future user (expect fail)
16392         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister "cl77"
16393         rc=$?
16394         if [ $rc -eq 0 ]; then
16395                 error "Deleted non-existant user cl77"
16396         elif [ $rc -ne 2 ]; then
16397                 error "changelog_deregister failed with $rc, expect 2 (ENOENT)"
16398         fi
16399
16400         # Clear to a bad index (1 billion should be safe)
16401         $LFS changelog_clear $MDT0 "${CL_USERS[$SINGLEMDS]%% *}" 1000000000
16402         rc=$?
16403
16404         if [ $rc -eq 0 ]; then
16405                 error "Successfully cleared to invalid CL index"
16406         elif [ $rc -ne 22 ]; then
16407                 error "changelog_clear failed with $rc, expected 22 (EINVAL)"
16408         fi
16409 }
16410 run_test 160e "changelog negative testing (should return errors)"
16411
16412 test_160f() {
16413         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16414         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
16415                 skip "Need MDS version at least 2.10.56"
16416
16417         local mdts=$(comma_list $(mdts_nodes))
16418
16419         # Create a user
16420         changelog_register || error "first changelog_register failed"
16421         changelog_register || error "second changelog_register failed"
16422         local cl_users
16423         declare -A cl_user1
16424         declare -A cl_user2
16425         local user_rec1
16426         local user_rec2
16427         local i
16428
16429         # generate some changelog records to accumulate on each MDT
16430         # use all_char because created files should be evenly distributed
16431         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16432                 error "test_mkdir $tdir failed"
16433         log "$(date +%s): creating first files"
16434         for ((i = 0; i < MDSCOUNT * 2; i++)); do
16435                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT)) ||
16436                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT)) failed"
16437         done
16438
16439         # check changelogs have been generated
16440         local start=$SECONDS
16441         local idle_time=$((MDSCOUNT * 5 + 5))
16442         local nbcl=$(changelog_dump | wc -l)
16443         [[ $nbcl -eq 0 ]] && error "no changelogs found"
16444
16445         for param in "changelog_max_idle_time=$idle_time" \
16446                      "changelog_gc=1" \
16447                      "changelog_min_gc_interval=2" \
16448                      "changelog_min_free_cat_entries=3"; do
16449                 local MDT0=$(facet_svc $SINGLEMDS)
16450                 local var="${param%=*}"
16451                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
16452
16453                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
16454                 do_nodes $mdts $LCTL set_param mdd.*.$param
16455         done
16456
16457         # force cl_user2 to be idle (1st part), but also cancel the
16458         # cl_user1 records so that it is not evicted later in the test.
16459         local sleep1=$((idle_time / 2))
16460         echo "$(date +%s): sleep1 $sleep1/${idle_time}s"
16461         sleep $sleep1
16462
16463         # simulate changelog catalog almost full
16464         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
16465         do_nodes $mdts "$LCTL set_param fail_loc=0x1313 fail_val=3"
16466
16467         for i in $(seq $MDSCOUNT); do
16468                 cl_users=(${CL_USERS[mds$i]})
16469                 cl_user1[mds$i]="${cl_users[0]}"
16470                 cl_user2[mds$i]="${cl_users[1]}"
16471
16472                 [ -n "${cl_user1[mds$i]}" ] ||
16473                         error "mds$i: no user registered"
16474                 [ -n "${cl_user2[mds$i]}" ] ||
16475                         error "mds$i: only ${cl_user2[mds$i]} is registered"
16476
16477                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16478                 [ -n "$user_rec1" ] ||
16479                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16480                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
16481                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16482                 [ -n "$user_rec2" ] ||
16483                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16484                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
16485                      "$user_rec1 + 2 == $user_rec2"
16486                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
16487                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
16488                               "$user_rec1 + 2, but is $user_rec2"
16489                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
16490                 [ -n "$user_rec2" ] ||
16491                         error "mds$i: User ${cl_user2[mds$i]} not registered"
16492                 [ $user_rec1 == $user_rec2 ] ||
16493                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
16494                               "$user_rec1, but is $user_rec2"
16495         done
16496
16497         # force cl_user2 idle (2nd part) to just exceed changelog_max_idle_time
16498         local sleep2=$((idle_time - (SECONDS - start) + 1))
16499         echo "$(date +%s): sleep2 $sleep2/${idle_time}s"
16500         sleep $sleep2
16501
16502         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
16503         # cl_user1 should be OK because it recently processed records.
16504         echo "$(date +%s): creating $((MDSCOUNT * 2)) files"
16505         for ((i = 0; i < MDSCOUNT * 2; i++)); do
16506                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT+2))||
16507                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT+2)) failed"
16508         done
16509
16510         # ensure gc thread is done
16511         for i in $(mdts_nodes); do
16512                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
16513                         error "$i: GC-thread not done"
16514         done
16515
16516         local first_rec
16517         for (( i = 1; i <= MDSCOUNT; i++ )); do
16518                 # check cl_user1 still registered
16519                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
16520                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16521                 # check cl_user2 unregistered
16522                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
16523                         error "mds$i: User ${cl_user2[mds$i]} still registered"
16524
16525                 # check changelogs are present and starting at $user_rec1 + 1
16526                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16527                 [ -n "$user_rec1" ] ||
16528                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16529                 first_rec=$($LFS changelog $(facet_svc mds$i) |
16530                             awk '{ print $1; exit; }')
16531
16532                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
16533                 [ $((user_rec1 + 1)) == $first_rec ] ||
16534                         error "mds$i: rec $first_rec != $user_rec1 + 1"
16535         done
16536 }
16537 run_test 160f "changelog garbage collect (timestamped users)"
16538
16539 test_160g() {
16540         remote_mds_nodsh && skip "remote MDS with nodsh"
16541         [[ $MDS1_VERSION -ge $(version_code 2.14.55) ]] ||
16542                 skip "Need MDS version at least 2.14.55"
16543
16544         local mdts=$(comma_list $(mdts_nodes))
16545
16546         # Create a user
16547         changelog_register || error "first changelog_register failed"
16548         changelog_register || error "second changelog_register failed"
16549         local cl_users
16550         declare -A cl_user1
16551         declare -A cl_user2
16552         local user_rec1
16553         local user_rec2
16554         local i
16555
16556         # generate some changelog records to accumulate on each MDT
16557         # use all_char because created files should be evenly distributed
16558         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16559                 error "test_mkdir $tdir failed"
16560         for ((i = 0; i < MDSCOUNT; i++)); do
16561                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16562                         error "create $DIR/$tdir/d$i.1 failed"
16563         done
16564
16565         # check changelogs have been generated
16566         local nbcl=$(changelog_dump | wc -l)
16567         (( $nbcl > 0 )) || error "no changelogs found"
16568
16569         # reduce the max_idle_indexes value to make sure we exceed it
16570         for param in "changelog_max_idle_indexes=2" \
16571                      "changelog_gc=1" \
16572                      "changelog_min_gc_interval=2"; do
16573                 local MDT0=$(facet_svc $SINGLEMDS)
16574                 local var="${param%=*}"
16575                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
16576
16577                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
16578                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
16579                         error "unable to set mdd.*.$param"
16580         done
16581
16582         local start=$SECONDS
16583         for i in $(seq $MDSCOUNT); do
16584                 cl_users=(${CL_USERS[mds$i]})
16585                 cl_user1[mds$i]="${cl_users[0]}"
16586                 cl_user2[mds$i]="${cl_users[1]}"
16587
16588                 [ -n "${cl_user1[mds$i]}" ] ||
16589                         error "mds$i: user1 is not registered"
16590                 [ -n "${cl_user2[mds$i]}" ] ||
16591                         error "mds$i: only ${cl_user1[mds$i]} is registered"
16592
16593                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16594                 [ -n "$user_rec1" ] ||
16595                         error "mds$i: user1 ${cl_user1[mds$i]} not found"
16596                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
16597                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16598                 [ -n "$user_rec2" ] ||
16599                         error "mds$i: user1 ${cl_user1[mds$i]} not found (2)"
16600                 echo "mds$i: verifying user1 ${cl_user1[mds$i]} clear: " \
16601                      "$user_rec1 + 2 == $user_rec2"
16602                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
16603                         error "mds$i: user1 ${cl_user1[mds$i]} index " \
16604                               "expected $user_rec1 + 2, but is $user_rec2"
16605                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
16606                 [ -n "$user_rec2" ] ||
16607                         error "mds$i: user2 ${cl_user2[mds$i]} not found"
16608                 [ $user_rec1 == $user_rec2 ] ||
16609                         error "mds$i: user2 ${cl_user2[mds$i]} index " \
16610                               "expected $user_rec1, but is $user_rec2"
16611         done
16612
16613         # ensure we are past the previous changelog_min_gc_interval set above
16614         local sleep2=$((start + 2 - SECONDS))
16615         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
16616         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
16617         # cl_user1 should be OK because it recently processed records.
16618         for ((i = 0; i < MDSCOUNT; i++)); do
16619                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 ||
16620                         error "create $DIR/$tdir/d$i.3 failed"
16621         done
16622
16623         # ensure gc thread is done
16624         for i in $(mdts_nodes); do
16625                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
16626                         error "$i: GC-thread not done"
16627         done
16628
16629         local first_rec
16630         for (( i = 1; i <= MDSCOUNT; i++ )); do
16631                 # check cl_user1 still registered
16632                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
16633                         error "mds$i: user1 ${cl_user1[mds$i]} not found (3)"
16634                 # check cl_user2 unregistered
16635                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
16636                         error "mds$i: user2 ${cl_user2[mds$i]} is registered"
16637
16638                 # check changelogs are present and starting at $user_rec1 + 1
16639                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16640                 [ -n "$user_rec1" ] ||
16641                         error "mds$i: user1 ${cl_user1[mds$i]} not found (4)"
16642                 first_rec=$($LFS changelog $(facet_svc mds$i) |
16643                             awk '{ print $1; exit; }')
16644
16645                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
16646                 [ $((user_rec1 + 1)) == $first_rec ] ||
16647                         error "mds$i: rec $first_rec != $user_rec1 + 1"
16648         done
16649 }
16650 run_test 160g "changelog garbage collect on idle records"
16651
16652 test_160h() {
16653         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16654         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
16655                 skip "Need MDS version at least 2.10.56"
16656
16657         local mdts=$(comma_list $(mdts_nodes))
16658
16659         # Create a user
16660         changelog_register || error "first changelog_register failed"
16661         changelog_register || error "second changelog_register failed"
16662         local cl_users
16663         declare -A cl_user1
16664         declare -A cl_user2
16665         local user_rec1
16666         local user_rec2
16667         local i
16668
16669         # generate some changelog records to accumulate on each MDT
16670         # use all_char because created files should be evenly distributed
16671         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16672                 error "test_mkdir $tdir failed"
16673         for ((i = 0; i < MDSCOUNT; i++)); do
16674                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16675                         error "create $DIR/$tdir/d$i.1 failed"
16676         done
16677
16678         # check changelogs have been generated
16679         local nbcl=$(changelog_dump | wc -l)
16680         [[ $nbcl -eq 0 ]] && error "no changelogs found"
16681
16682         for param in "changelog_max_idle_time=10" \
16683                      "changelog_gc=1" \
16684                      "changelog_min_gc_interval=2"; do
16685                 local MDT0=$(facet_svc $SINGLEMDS)
16686                 local var="${param%=*}"
16687                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
16688
16689                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
16690                 do_nodes $mdts $LCTL set_param mdd.*.$param
16691         done
16692
16693         # force cl_user2 to be idle (1st part)
16694         sleep 9
16695
16696         for i in $(seq $MDSCOUNT); do
16697                 cl_users=(${CL_USERS[mds$i]})
16698                 cl_user1[mds$i]="${cl_users[0]}"
16699                 cl_user2[mds$i]="${cl_users[1]}"
16700
16701                 [ -n "${cl_user1[mds$i]}" ] ||
16702                         error "mds$i: no user registered"
16703                 [ -n "${cl_user2[mds$i]}" ] ||
16704                         error "mds$i: only ${cl_user2[mds$i]} is registered"
16705
16706                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16707                 [ -n "$user_rec1" ] ||
16708                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16709                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
16710                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16711                 [ -n "$user_rec2" ] ||
16712                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16713                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
16714                      "$user_rec1 + 2 == $user_rec2"
16715                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
16716                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
16717                               "$user_rec1 + 2, but is $user_rec2"
16718                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
16719                 [ -n "$user_rec2" ] ||
16720                         error "mds$i: User ${cl_user2[mds$i]} not registered"
16721                 [ $user_rec1 == $user_rec2 ] ||
16722                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
16723                               "$user_rec1, but is $user_rec2"
16724         done
16725
16726         # force cl_user2 to be idle (2nd part) and to reach
16727         # changelog_max_idle_time
16728         sleep 2
16729
16730         # force each GC-thread start and block then
16731         # one per MDT/MDD, set fail_val accordingly
16732         #define OBD_FAIL_FORCE_GC_THREAD 0x1316
16733         do_nodes $mdts $LCTL set_param fail_loc=0x1316
16734
16735         # generate more changelogs to trigger fail_loc
16736         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
16737                 error "create $DIR/$tdir/${tfile}bis failed"
16738
16739         # stop MDT to stop GC-thread, should be done in back-ground as it will
16740         # block waiting for the thread to be released and exit
16741         declare -A stop_pids
16742         for i in $(seq $MDSCOUNT); do
16743                 stop mds$i &
16744                 stop_pids[mds$i]=$!
16745         done
16746
16747         for i in $(mdts_nodes); do
16748                 local facet
16749                 local nb=0
16750                 local facets=$(facets_up_on_host $i)
16751
16752                 for facet in ${facets//,/ }; do
16753                         if [[ $facet == mds* ]]; then
16754                                 nb=$((nb + 1))
16755                         fi
16756                 done
16757                 # ensure each MDS's gc threads are still present and all in "R"
16758                 # state (OBD_FAIL_FORCE_GC_THREAD effect!)
16759                 [[ $(do_node $i pgrep chlg_gc_thread | wc -l) -eq $nb ]] ||
16760                         error "$i: expected $nb GC-thread"
16761                 wait_update $i \
16762                         "ps -C chlg_gc_thread -o state --no-headers | uniq" \
16763                         "R" 20 ||
16764                         error "$i: GC-thread not found in R-state"
16765                 # check umounts of each MDT on MDS have reached kthread_stop()
16766                 [[ $(do_node $i pgrep umount | wc -l) -eq $nb ]] ||
16767                         error "$i: expected $nb umount"
16768                 wait_update $i \
16769                         "ps -C umount -o state --no-headers | uniq" "D" 20 ||
16770                         error "$i: umount not found in D-state"
16771         done
16772
16773         # release all GC-threads
16774         do_nodes $mdts $LCTL set_param fail_loc=0
16775
16776         # wait for MDT stop to complete
16777         for i in $(seq $MDSCOUNT); do
16778                 wait ${stop_pids[mds$i]} || error "mds$i: stop failed"
16779         done
16780
16781         # XXX
16782         # may try to check if any orphan changelog records are present
16783         # via ldiskfs/zfs and llog_reader...
16784
16785         # re-start/mount MDTs
16786         for i in $(seq $MDSCOUNT); do
16787                 start mds$i $(mdsdevname $i) $MDS_MOUNT_OPTS ||
16788                         error "Fail to start mds$i"
16789         done
16790
16791         local first_rec
16792         for i in $(seq $MDSCOUNT); do
16793                 # check cl_user1 still registered
16794                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
16795                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16796                 # check cl_user2 unregistered
16797                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
16798                         error "mds$i: User ${cl_user2[mds$i]} still registered"
16799
16800                 # check changelogs are present and starting at $user_rec1 + 1
16801                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16802                 [ -n "$user_rec1" ] ||
16803                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16804                 first_rec=$($LFS changelog $(facet_svc mds$i) |
16805                             awk '{ print $1; exit; }')
16806
16807                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
16808                 [ $((user_rec1 + 1)) == $first_rec ] ||
16809                         error "mds$i: first index should be $user_rec1 + 1, " \
16810                               "but is $first_rec"
16811         done
16812 }
16813 run_test 160h "changelog gc thread stop upon umount, orphan records delete " \
16814               "during mount"
16815
16816 test_160i() {
16817
16818         local mdts=$(comma_list $(mdts_nodes))
16819
16820         changelog_register || error "first changelog_register failed"
16821
16822         # generate some changelog records to accumulate on each MDT
16823         # use all_char because created files should be evenly distributed
16824         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16825                 error "test_mkdir $tdir failed"
16826         for ((i = 0; i < MDSCOUNT; i++)); do
16827                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16828                         error "create $DIR/$tdir/d$i.1 failed"
16829         done
16830
16831         # check changelogs have been generated
16832         local nbcl=$(changelog_dump | wc -l)
16833         [[ $nbcl -eq 0 ]] && error "no changelogs found"
16834
16835         # simulate race between register and unregister
16836         # XXX as fail_loc is set per-MDS, with DNE configs the race
16837         # simulation will only occur for one MDT per MDS and for the
16838         # others the normal race scenario will take place
16839         #define CFS_FAIL_CHLOG_USER_REG_UNREG_RACE          0x1315
16840         do_nodes $mdts $LCTL set_param fail_loc=0x10001315
16841         do_nodes $mdts $LCTL set_param fail_val=1
16842
16843         # unregister 1st user
16844         changelog_deregister &
16845         local pid1=$!
16846         # wait some time for deregister work to reach race rdv
16847         sleep 2
16848         # register 2nd user
16849         changelog_register || error "2nd user register failed"
16850
16851         wait $pid1 || error "1st user deregister failed"
16852
16853         local i
16854         local last_rec
16855         declare -A LAST_REC
16856         for i in $(seq $MDSCOUNT); do
16857                 if changelog_users mds$i | grep "^cl"; then
16858                         # make sure new records are added with one user present
16859                         LAST_REC[mds$i]=$(changelog_users $SINGLEMDS |
16860                                           awk '/^current.index:/ { print $NF }')
16861                 else
16862                         error "mds$i has no user registered"
16863                 fi
16864         done
16865
16866         # generate more changelog records to accumulate on each MDT
16867         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
16868                 error "create $DIR/$tdir/${tfile}bis failed"
16869
16870         for i in $(seq $MDSCOUNT); do
16871                 last_rec=$(changelog_users $SINGLEMDS |
16872                            awk '/^current.index:/ { print $NF }')
16873                 echo "verify changelogs are on: $last_rec != ${LAST_REC[mds$i]}"
16874                 [ $last_rec != ${LAST_REC[mds$i]} ] ||
16875                         error "changelogs are off on mds$i"
16876         done
16877 }
16878 run_test 160i "changelog user register/unregister race"
16879
16880 test_160j() {
16881         remote_mds_nodsh && skip "remote MDS with nodsh"
16882         [[ $MDS1_VERSION -lt $(version_code 2.12.56) ]] &&
16883                 skip "Need MDS version at least 2.12.56"
16884
16885         mount_client $MOUNT2 || error "mount_client on $MOUNT2 failed"
16886         stack_trap "umount $MOUNT2" EXIT
16887
16888         changelog_register || error "first changelog_register failed"
16889         stack_trap "changelog_deregister" EXIT
16890
16891         # generate some changelog
16892         # use all_char because created files should be evenly distributed
16893         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16894                 error "mkdir $tdir failed"
16895         for ((i = 0; i < MDSCOUNT; i++)); do
16896                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16897                         error "create $DIR/$tdir/d$i.1 failed"
16898         done
16899
16900         # open the changelog device
16901         exec 3>/dev/changelog-$FSNAME-MDT0000
16902         stack_trap "exec 3>&-" EXIT
16903         exec 4</dev/changelog-$FSNAME-MDT0000
16904         stack_trap "exec 4<&-" EXIT
16905
16906         # umount the first lustre mount
16907         umount $MOUNT
16908         stack_trap "mount_client $MOUNT" EXIT
16909
16910         # read changelog, which may or may not fail, but should not crash
16911         cat <&4 >/dev/null
16912
16913         # clear changelog
16914         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16915         changelog_users $SINGLEMDS | grep -q $cl_user ||
16916                 error "User $cl_user not found in changelog_users"
16917
16918         printf 'clear:'$cl_user':0' >&3
16919 }
16920 run_test 160j "client can be umounted while its chanangelog is being used"
16921
16922 test_160k() {
16923         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16924         remote_mds_nodsh && skip "remote MDS with nodsh"
16925
16926         mkdir -p $DIR/$tdir/1/1
16927
16928         changelog_register || error "changelog_register failed"
16929         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16930
16931         changelog_users $SINGLEMDS | grep -q $cl_user ||
16932                 error "User '$cl_user' not found in changelog_users"
16933 #define OBD_FAIL_MDS_CHANGELOG_REORDER 0x15d
16934         do_facet mds1 $LCTL set_param fail_loc=0x8000015d fail_val=3
16935         rmdir $DIR/$tdir/1/1 & sleep 1
16936         mkdir $DIR/$tdir/2
16937         touch $DIR/$tdir/2/2
16938         rm -rf $DIR/$tdir/2
16939
16940         wait
16941         sleep 4
16942
16943         changelog_dump | grep rmdir || error "rmdir not recorded"
16944 }
16945 run_test 160k "Verify that changelog records are not lost"
16946
16947 # Verifies that a file passed as a parameter has recently had an operation
16948 # performed on it that has generated an MTIME changelog which contains the
16949 # correct parent FID. As files might reside on a different MDT from the
16950 # parent directory in DNE configurations, the FIDs are translated to paths
16951 # before being compared, which should be identical
16952 compare_mtime_changelog() {
16953         local file="${1}"
16954         local mdtidx
16955         local mtime
16956         local cl_fid
16957         local pdir
16958         local dir
16959
16960         mdtidx=$($LFS getstripe --mdt-index $file)
16961         mdtidx=$(printf "%04x" $mdtidx)
16962
16963         # Obtain the parent FID from the MTIME changelog
16964         mtime=$($LFS changelog $FSNAME-MDT$mdtidx | tail -n 1 | grep MTIME)
16965         [ -z "$mtime" ] && error "MTIME changelog not recorded"
16966
16967         cl_fid=$(sed -e 's/.* p=//' -e 's/ .*//' <<<$mtime)
16968         [ -z "$cl_fid" ] && error "parent FID not present"
16969
16970         # Verify that the path for the parent FID is the same as the path for
16971         # the test directory
16972         pdir=$($LFS fid2path $MOUNT "$cl_fid")
16973
16974         dir=$(dirname $1)
16975
16976         [[ "${pdir%/}" == "$dir" ]] ||
16977                 error "MTIME changelog parent FID is wrong, expected $dir, got $pdir"
16978 }
16979
16980 test_160l() {
16981         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16982
16983         remote_mds_nodsh && skip "remote MDS with nodsh"
16984         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
16985                 skip "Need MDS version at least 2.13.55"
16986
16987         local cl_user
16988
16989         changelog_register || error "changelog_register failed"
16990         cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16991
16992         changelog_users $SINGLEMDS | grep -q $cl_user ||
16993                 error "User '$cl_user' not found in changelog_users"
16994
16995         # Clear some types so that MTIME changelogs are generated
16996         changelog_chmask "-CREAT"
16997         changelog_chmask "-CLOSE"
16998
16999         test_mkdir $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
17000
17001         # Test CL_MTIME during setattr
17002         touch $DIR/$tdir/$tfile
17003         compare_mtime_changelog $DIR/$tdir/$tfile
17004
17005         # Test CL_MTIME during close
17006         $MULTIOP $DIR/$tdir/${tfile}_2 O_2w4096c || error "multiop failed"
17007         compare_mtime_changelog $DIR/$tdir/${tfile}_2
17008 }
17009 run_test 160l "Verify that MTIME changelog records contain the parent FID"
17010
17011 test_160m() {
17012         remote_mds_nodsh && skip "remote MDS with nodsh" && return
17013         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
17014                 skip "Need MDS version at least 2.14.51"
17015         local cl_users
17016         local cl_user1
17017         local cl_user2
17018         local pid1
17019
17020         # Create a user
17021         changelog_register || error "first changelog_register failed"
17022         changelog_register || error "second changelog_register failed"
17023
17024         cl_users=(${CL_USERS[mds1]})
17025         cl_user1="${cl_users[0]}"
17026         cl_user2="${cl_users[1]}"
17027         # generate some changelog records to accumulate on MDT0
17028         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
17029         createmany -m $DIR/$tdir/$tfile 50 ||
17030                 error "create $DIR/$tdir/$tfile failed"
17031         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
17032         rm -f $DIR/$tdir
17033
17034         # check changelogs have been generated
17035         local nbcl=$(changelog_dump | wc -l)
17036         [[ $nbcl -eq 0 ]] && error "no changelogs found"
17037
17038 #define OBD_FAIL_MDS_CHANGELOG_RACE      0x15f
17039         do_facet mds1 $LCTL set_param fail_loc=0x8000015f fail_val=0
17040
17041         __changelog_clear mds1 $cl_user1 +10
17042         __changelog_clear mds1 $cl_user2 0 &
17043         pid1=$!
17044         sleep 2
17045         __changelog_clear mds1 $cl_user1 0 ||
17046                 error "fail to cancel record for $cl_user1"
17047         wait $pid1
17048         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
17049 }
17050 run_test 160m "Changelog clear race"
17051
17052 test_160n() {
17053         remote_mds_nodsh && skip "remote MDS with nodsh" && return
17054         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
17055                 skip "Need MDS version at least 2.14.51"
17056         local cl_users
17057         local cl_user1
17058         local cl_user2
17059         local pid1
17060         local first_rec
17061         local last_rec=0
17062
17063         # Create a user
17064         changelog_register || error "first changelog_register failed"
17065
17066         cl_users=(${CL_USERS[mds1]})
17067         cl_user1="${cl_users[0]}"
17068
17069         # generate some changelog records to accumulate on MDT0
17070         test_mkdir -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
17071         first_rec=$(changelog_users $SINGLEMDS |
17072                         awk '/^current.index:/ { print $NF }')
17073         while (( last_rec < (( first_rec + 65000)) )); do
17074                 createmany -m $DIR/$tdir/$tfile 10000 ||
17075                         error "create $DIR/$tdir/$tfile failed"
17076
17077                 for i in $(seq 0 10000); do
17078                         mrename $DIR/$tdir/$tfile$i $DIR/$tdir/$tfile-new$i \
17079                                 > /dev/null
17080                 done
17081
17082                 unlinkmany $DIR/$tdir/$tfile-new 10000 ||
17083                         error "unlinkmany failed unlink"
17084                 last_rec=$(changelog_users $SINGLEMDS |
17085                         awk '/^current.index:/ { print $NF }')
17086                 echo last record $last_rec
17087                 (( last_rec == 0 )) && error "no changelog found"
17088         done
17089
17090 #define OBD_FAIL_MDS_CHANGELOG_DEL       0x16c
17091         do_facet mds1 $LCTL set_param fail_loc=0x8000016c fail_val=0
17092
17093         __changelog_clear mds1 $cl_user1 0 &
17094         pid1=$!
17095         sleep 2
17096         __changelog_clear mds1 $cl_user1 0 ||
17097                 error "fail to cancel record for $cl_user1"
17098         wait $pid1
17099         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
17100 }
17101 run_test 160n "Changelog destroy race"
17102
17103 test_160o() {
17104         local mdt="$(facet_svc $SINGLEMDS)"
17105
17106         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
17107         remote_mds_nodsh && skip "remote MDS with nodsh"
17108         [ $MDS1_VERSION -ge $(version_code 2.14.52) ] ||
17109                 skip "Need MDS version at least 2.14.52"
17110
17111         changelog_register --user test_160o -m unlnk+close+open ||
17112                 error "changelog_register failed"
17113
17114         do_facet $SINGLEMDS $LCTL --device $mdt \
17115                                 changelog_register -u "Tt3_-#" &&
17116                 error "bad symbols in name should fail"
17117
17118         do_facet $SINGLEMDS $LCTL --device $mdt \
17119                                 changelog_register -u test_160o &&
17120                 error "the same name registration should fail"
17121
17122         do_facet $SINGLEMDS $LCTL --device $mdt \
17123                         changelog_register -u test_160toolongname &&
17124                 error "too long name registration should fail"
17125
17126         changelog_chmask "MARK+HSM"
17127         lctl get_param mdd.*.changelog*mask
17128         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
17129         changelog_users $SINGLEMDS | grep -q $cl_user ||
17130                 error "User $cl_user not found in changelog_users"
17131         #verify username
17132         echo $cl_user | grep -q test_160o ||
17133                 error "User $cl_user has no specific name 'test160o'"
17134
17135         # change something
17136         changelog_clear 0 || error "changelog_clear failed"
17137         # generate some changelog records to accumulate on MDT0
17138         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
17139         touch $DIR/$tdir/$tfile                 # open 1
17140
17141         OPENS=$(changelog_dump | grep -c "OPEN")
17142         [[ $OPENS -eq 1 ]] || error "OPEN changelog mask count $OPENS != 1"
17143
17144         # must be no MKDIR it wasn't set as user mask
17145         MKDIR=$(changelog_dump | grep -c "MKDIR")
17146         [[ $MKDIR -eq 0 ]] || error "MKDIR changelog mask found $MKDIR > 0"
17147
17148         oldmask=$(do_facet $SINGLEMDS $LCTL get_param \
17149                                 mdd.$mdt.changelog_current_mask -n)
17150         # register maskless user
17151         changelog_register || error "changelog_register failed"
17152         # effective mask should be not changed because it is not minimal
17153         mask=$(do_facet $SINGLEMDS $LCTL get_param \
17154                                 mdd.$mdt.changelog_current_mask -n)
17155         [[ $mask == $oldmask ]] || error "mask was changed: $mask vs $oldmask"
17156         # set server mask to minimal value
17157         changelog_chmask "MARK"
17158         # check effective mask again, should be treated as DEFMASK now
17159         mask=$(do_facet $SINGLEMDS $LCTL get_param \
17160                                 mdd.$mdt.changelog_current_mask -n)
17161         [[ $mask == *"HLINK"* ]] || error "mask is not DEFMASK as expected"
17162
17163         do_facet $SINGLEMDS $LCTL --device $mdt \
17164                                 changelog_deregister -u test_160o ||
17165                 error "cannot deregister by name"
17166 }
17167 run_test 160o "changelog user name and mask"
17168
17169 test_160p() {
17170         remote_mds_nodsh && skip "remote MDS with nodsh" && return
17171         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
17172                 skip "Need MDS version at least 2.14.51"
17173         [[ "$mds1_FSTYPE" == "ldiskfs" ]] || skip "ldiskfs only test"
17174         local cl_users
17175         local cl_user1
17176         local entry_count
17177
17178         # Create a user
17179         changelog_register || error "first changelog_register failed"
17180
17181         cl_users=(${CL_USERS[mds1]})
17182         cl_user1="${cl_users[0]}"
17183
17184         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
17185         createmany -m $DIR/$tdir/$tfile 50 ||
17186                 error "create $DIR/$tdir/$tfile failed"
17187         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
17188         rm -rf $DIR/$tdir
17189
17190         # check changelogs have been generated
17191         entry_count=$(changelog_dump | wc -l)
17192         ((entry_count != 0)) || error "no changelog entries found"
17193
17194         # remove changelog_users and check that orphan entries are removed
17195         stop mds1
17196         local dev=$(mdsdevname 1)
17197         do_facet mds1 "$DEBUGFS -w -R 'rm changelog_users' $dev"
17198         start mds1 $dev $MDS_MOUNT_OPTS || error "cannot start mds1"
17199         entry_count=$(changelog_dump | wc -l)
17200         ((entry_count == 0)) ||
17201                 error "found $entry_count changelog entries, expected none"
17202 }
17203 run_test 160p "Changelog orphan cleanup with no users"
17204
17205 test_160q() {
17206         local mdt="$(facet_svc $SINGLEMDS)"
17207         local clu
17208
17209         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
17210         remote_mds_nodsh && skip "remote MDS with nodsh"
17211         [ $MDS1_VERSION -ge $(version_code 2.14.54) ] ||
17212                 skip "Need MDS version at least 2.14.54"
17213
17214         # set server mask to minimal value like server init does
17215         changelog_chmask "MARK"
17216         clu=$(do_facet $SINGLEMDS $LCTL --device $mdt changelog_register -n) ||
17217                 error "changelog_register failed"
17218         # check effective mask again, should be treated as DEFMASK now
17219         mask=$(do_facet $SINGLEMDS $LCTL get_param \
17220                                 mdd.$mdt.changelog_current_mask -n)
17221         do_facet $SINGLEMDS $LCTL --device $mdt changelog_deregister $clu ||
17222                 error "changelog_deregister failed"
17223         [[ $mask == *"HLINK"* ]] || error "mask is not DEFMASK as expected"
17224 }
17225 run_test 160q "changelog effective mask is DEFMASK if not set"
17226
17227 test_160s() {
17228         remote_mds_nodsh && skip "remote MDS with nodsh"
17229         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
17230                 skip "Need MDS version at least 2.14.55"
17231
17232         local mdts=$(comma_list $(mdts_nodes))
17233
17234         #define OBD_FAIL_TIME_IN_CHLOG_USER     0x1314
17235         do_nodes $mdts $LCTL set_param fail_loc=0x1314 \
17236                                        fail_val=$((24 * 3600 * 10))
17237
17238         # Create a user which is 10 days old
17239         changelog_register || error "first changelog_register failed"
17240         local cl_users
17241         declare -A cl_user1
17242         local i
17243
17244         # generate some changelog records to accumulate on each MDT
17245         # use all_char because created files should be evenly distributed
17246         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
17247                 error "test_mkdir $tdir failed"
17248         for ((i = 0; i < MDSCOUNT; i++)); do
17249                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
17250                         error "create $DIR/$tdir/d$i.1 failed"
17251         done
17252
17253         # check changelogs have been generated
17254         local nbcl=$(changelog_dump | wc -l)
17255         (( nbcl > 0 )) || error "no changelogs found"
17256
17257         # reduce the max_idle_indexes value to make sure we exceed it
17258         for param in "changelog_max_idle_indexes=2097446912" \
17259                      "changelog_max_idle_time=2592000" \
17260                      "changelog_gc=1" \
17261                      "changelog_min_gc_interval=2"; do
17262                 local MDT0=$(facet_svc $SINGLEMDS)
17263                 local var="${param%=*}"
17264                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
17265
17266                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
17267                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
17268                         error "unable to set mdd.*.$param"
17269         done
17270
17271         local start=$SECONDS
17272         for i in $(seq $MDSCOUNT); do
17273                 cl_users=(${CL_USERS[mds$i]})
17274                 cl_user1[mds$i]="${cl_users[0]}"
17275
17276                 [[ -n "${cl_user1[mds$i]}" ]] ||
17277                         error "mds$i: no user registered"
17278         done
17279
17280         #define OBD_FAIL_MDS_CHANGELOG_IDX_PUMP   0x16d
17281         do_nodes $mdts $LCTL set_param fail_loc=0x16d fail_val=500000000
17282
17283         # ensure we are past the previous changelog_min_gc_interval set above
17284         local sleep2=$((start + 2 - SECONDS))
17285         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
17286
17287         # Generate one more changelog to trigger GC
17288         for ((i = 0; i < MDSCOUNT; i++)); do
17289                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 $DIR/$tdir/d$i.4 ||
17290                         error "create $DIR/$tdir/d$i.3 failed"
17291         done
17292
17293         # ensure gc thread is done
17294         for node in $(mdts_nodes); do
17295                 wait_update $node "pgrep chlg_gc_thread" "" 20 ||
17296                         error "$node: GC-thread not done"
17297         done
17298
17299         do_nodes $mdts $LCTL set_param fail_loc=0
17300
17301         for (( i = 1; i <= MDSCOUNT; i++ )); do
17302                 # check cl_user1 is purged
17303                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" &&
17304                         error "mds$i: User ${cl_user1[mds$i]} is registered"
17305         done
17306         return 0
17307 }
17308 run_test 160s "changelog garbage collect on idle records * time"
17309
17310 test_160t() {
17311         remote_mds_nodsh && skip "remote MDS with nodsh"
17312         (( $MDS1_VERSION >= $(version_code 2.15.50) )) ||
17313                 skip "Need MDS version at least 2.15.50"
17314
17315         local MDT0=$(facet_svc $SINGLEMDS)
17316         local cl_users
17317         local cl_user1
17318         local cl_user2
17319         local start
17320
17321         changelog_register --user user1 -m all ||
17322                 error "user1 failed to register"
17323
17324         mkdir_on_mdt0 $DIR/$tdir
17325         # create default overstripe to maximize changelog size
17326         $LFS setstripe  -C 8 $DIR/$tdir || error "setstripe failed"
17327         createmany -o $DIR/$tdir/u1_ 2000 || error "createmany for user1 failed"
17328         llog_size1=$(do_facet mds1 $LCTL get_param -n mdd.$MDT0.changelog_size)
17329
17330         # user2 consumes less records so less space
17331         changelog_register --user user2 || error "user2 failed to register"
17332         createmany -o $DIR/$tdir/u2_ 500 || error "createmany for user2 failed"
17333         llog_size2=$(do_facet mds1 $LCTL get_param -n mdd.$MDT0.changelog_size)
17334
17335         # check changelogs have been generated
17336         local nbcl=$(changelog_dump | wc -l)
17337         (( nbcl > 0 )) || error "no changelogs found"
17338
17339         # reduce the changelog_min_gc_interval to force check
17340         for param in "changelog_gc=1" "changelog_min_gc_interval=2"; do
17341                 local var="${param%=*}"
17342                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
17343
17344                 stack_trap "do_facet mds1 $LCTL set_param mdd.$MDT0.$var=$old"
17345                 do_facet mds1 $LCTL set_param mdd.$MDT0.$param ||
17346                         error "unable to set mdd.*.$param"
17347         done
17348
17349         start=$SECONDS
17350         cl_users=(${CL_USERS[mds1]})
17351         cl_user1="${cl_users[0]}"
17352         cl_user2="${cl_users[1]}"
17353
17354         [[ -n $cl_user1 ]] ||
17355                 error "mds1: user #1 isn't registered"
17356         [[ -n $cl_user2 ]] ||
17357                 error "mds1: user #2 isn't registered"
17358
17359         # ensure we are past the previous changelog_min_gc_interval set above
17360         local sleep2=$((start + 2 - SECONDS))
17361         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
17362
17363         #define OBD_FAIL_MDS_CHANGELOG_ENOSPC 0x018c
17364         do_facet mds1 $LCTL set_param fail_loc=0x018c \
17365                         fail_val=$(((llog_size1 + llog_size2) / 2))
17366
17367         # Generate more changelog to trigger GC
17368         createmany -o $DIR/$tdir/u3_ 4 ||
17369                 error "create failed for more files"
17370
17371         # ensure gc thread is done
17372         wait_update_facet mds1 "pgrep chlg_gc_thread" "" 20 ||
17373                 error "mds1: GC-thread not done"
17374
17375         do_facet mds1 $LCTL set_param fail_loc=0
17376
17377         # check cl_user1 is purged
17378         changelog_users mds1 | grep -q "$cl_user1" &&
17379                 error "User $cl_user1 is registered"
17380         # check cl_user2 is not purged
17381         changelog_users mds1 | grep -q "$cl_user2" ||
17382                 error "User $cl_user2 is not registered"
17383 }
17384 run_test 160t "changelog garbage collect on lack of space"
17385
17386 test_161a() {
17387         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17388
17389         test_mkdir -c1 $DIR/$tdir
17390         cp /etc/hosts $DIR/$tdir/$tfile
17391         test_mkdir -c1 $DIR/$tdir/foo1
17392         test_mkdir -c1 $DIR/$tdir/foo2
17393         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/sofia
17394         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/zachary
17395         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/luna
17396         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/thor
17397         local FID=$($LFS path2fid $DIR/$tdir/$tfile | tr -d '[]')
17398         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
17399                 $LFS fid2path $DIR $FID
17400                 error "bad link ea"
17401         fi
17402         # middle
17403         rm $DIR/$tdir/foo2/zachary
17404         # last
17405         rm $DIR/$tdir/foo2/thor
17406         # first
17407         rm $DIR/$tdir/$tfile
17408         # rename
17409         mv $DIR/$tdir/foo1/sofia $DIR/$tdir/foo2/maggie
17410         [ "$($LFS fid2path $FSNAME --link 1 $FID)" != "$tdir/foo2/maggie" ] &&
17411                 { $LFS fid2path $DIR $FID; error "bad link rename"; }
17412         rm $DIR/$tdir/foo2/maggie
17413
17414         # overflow the EA
17415         local longname=$tfile.avg_len_is_thirty_two_
17416         stack_trap "unlinkmany $DIR/$tdir/foo2/$longname 1000 || \
17417                 error_noexit 'failed to unlink many hardlinks'" EXIT
17418         createmany -l$DIR/$tdir/foo1/luna $DIR/$tdir/foo2/$longname 1000 ||
17419                 error "failed to hardlink many files"
17420         links=$($LFS fid2path $DIR $FID | wc -l)
17421         echo -n "${links}/1000 links in link EA"
17422         [[ $links -gt 60 ]] || error "expected at least 60 links in link EA"
17423 }
17424 run_test 161a "link ea sanity"
17425
17426 test_161b() {
17427         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17428         [ $MDSCOUNT -lt 2 ] && skip_env "skipping remote directory test"
17429
17430         local MDTIDX=1
17431         local remote_dir=$DIR/$tdir/remote_dir
17432
17433         mkdir -p $DIR/$tdir
17434         $LFS mkdir -i $MDTIDX $remote_dir ||
17435                 error "create remote directory failed"
17436
17437         cp /etc/hosts $remote_dir/$tfile
17438         mkdir -p $remote_dir/foo1
17439         mkdir -p $remote_dir/foo2
17440         ln $remote_dir/$tfile $remote_dir/foo1/sofia
17441         ln $remote_dir/$tfile $remote_dir/foo2/zachary
17442         ln $remote_dir/$tfile $remote_dir/foo1/luna
17443         ln $remote_dir/$tfile $remote_dir/foo2/thor
17444
17445         local FID=$($LFS path2fid $remote_dir/$tfile | tr -d '[' |
17446                      tr -d ']')
17447         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
17448                 $LFS fid2path $DIR $FID
17449                 error "bad link ea"
17450         fi
17451         # middle
17452         rm $remote_dir/foo2/zachary
17453         # last
17454         rm $remote_dir/foo2/thor
17455         # first
17456         rm $remote_dir/$tfile
17457         # rename
17458         mv $remote_dir/foo1/sofia $remote_dir/foo2/maggie
17459         local link_path=$($LFS fid2path $FSNAME --link 1 $FID)
17460         if [ "$DIR/$link_path" != "$remote_dir/foo2/maggie" ]; then
17461                 $LFS fid2path $DIR $FID
17462                 error "bad link rename"
17463         fi
17464         rm $remote_dir/foo2/maggie
17465
17466         # overflow the EA
17467         local longname=filename_avg_len_is_thirty_two_
17468         createmany -l$remote_dir/foo1/luna $remote_dir/foo2/$longname 1000 ||
17469                 error "failed to hardlink many files"
17470         links=$($LFS fid2path $DIR $FID | wc -l)
17471         echo -n "${links}/1000 links in link EA"
17472         [[ ${links} -gt 60 ]] ||
17473                 error "expected at least 60 links in link EA"
17474         unlinkmany $remote_dir/foo2/$longname 1000 ||
17475         error "failed to unlink many hardlinks"
17476 }
17477 run_test 161b "link ea sanity under remote directory"
17478
17479 test_161c() {
17480         remote_mds_nodsh && skip "remote MDS with nodsh"
17481         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17482         [[ $MDS1_VERSION -lt $(version_code 2.1.5) ]] &&
17483                 skip "Need MDS version at least 2.1.5"
17484
17485         # define CLF_RENAME_LAST 0x0001
17486         # rename overwrite a target having nlink = 1 (changelog flag 0x1)
17487         changelog_register || error "changelog_register failed"
17488
17489         rm -rf $DIR/$tdir
17490         test_mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir
17491         touch $DIR/$tdir/foo_161c
17492         touch $DIR/$tdir/bar_161c
17493         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
17494         changelog_dump | grep RENME | tail -n 5
17495         local flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
17496         changelog_clear 0 || error "changelog_clear failed"
17497         if [ x$flags != "x0x1" ]; then
17498                 error "flag $flags is not 0x1"
17499         fi
17500
17501         echo "rename overwrite target with nlink = 1, changelog flags=$flags"
17502         # rename overwrite a target having nlink > 1 (changelog flag 0x0)
17503         touch $DIR/$tdir/foo_161c
17504         touch $DIR/$tdir/bar_161c
17505         ln $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
17506         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
17507         changelog_dump | grep RENME | tail -n 5
17508         flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
17509         changelog_clear 0 || error "changelog_clear failed"
17510         if [ x$flags != "x0x0" ]; then
17511                 error "flag $flags is not 0x0"
17512         fi
17513         echo "rename overwrite a target having nlink > 1," \
17514                 "changelog record has flags of $flags"
17515
17516         # rename doesn't overwrite a target (changelog flag 0x0)
17517         touch $DIR/$tdir/foo_161c
17518         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/foo2_161c
17519         changelog_dump | grep RENME | tail -n 5
17520         flags=$(changelog_dump | grep RENME | tail -1 | cut -f5 -d' ')
17521         changelog_clear 0 || error "changelog_clear failed"
17522         if [ x$flags != "x0x0" ]; then
17523                 error "flag $flags is not 0x0"
17524         fi
17525         echo "rename doesn't overwrite a target," \
17526                 "changelog record has flags of $flags"
17527
17528         # define CLF_UNLINK_LAST 0x0001
17529         # unlink a file having nlink = 1 (changelog flag 0x1)
17530         rm -f $DIR/$tdir/foo2_161c
17531         changelog_dump | grep UNLNK | tail -n 5
17532         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
17533         changelog_clear 0 || error "changelog_clear failed"
17534         if [ x$flags != "x0x1" ]; then
17535                 error "flag $flags is not 0x1"
17536         fi
17537         echo "unlink a file having nlink = 1," \
17538                 "changelog record has flags of $flags"
17539
17540         # unlink a file having nlink > 1 (changelog flag 0x0)
17541         ln -f $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
17542         rm -f $DIR/$tdir/foobar_161c
17543         changelog_dump | grep UNLNK | tail -n 5
17544         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
17545         changelog_clear 0 || error "changelog_clear failed"
17546         if [ x$flags != "x0x0" ]; then
17547                 error "flag $flags is not 0x0"
17548         fi
17549         echo "unlink a file having nlink > 1, changelog record flags '$flags'"
17550 }
17551 run_test 161c "check CL_RENME[UNLINK] changelog record flags"
17552
17553 test_161d() {
17554         remote_mds_nodsh && skip "remote MDS with nodsh"
17555         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
17556
17557         local pid
17558         local fid
17559
17560         changelog_register || error "changelog_register failed"
17561
17562         # work in a standalone dir to avoid locking on $DIR/$MOUNT to
17563         # interfer with $MOUNT/.lustre/fid/ access
17564         mkdir $DIR/$tdir
17565         [[ $? -eq 0 ]] || error "mkdir failed"
17566
17567         #define OBD_FAIL_LLITE_CREATE_NODE_PAUSE 0x140c | OBD_FAIL_ONCE
17568         $LCTL set_param fail_loc=0x8000140c
17569         # 5s pause
17570         $LCTL set_param fail_val=5
17571
17572         # create file
17573         echo foofoo > $DIR/$tdir/$tfile &
17574         pid=$!
17575
17576         # wait for create to be delayed
17577         sleep 2
17578
17579         ps -p $pid
17580         [[ $? -eq 0 ]] || error "create should be blocked"
17581
17582         local tempfile="$(mktemp --tmpdir $tfile.XXXXXX)"
17583         stack_trap "rm -f $tempfile"
17584         fid=$(changelog_extract_field "CREAT" "$tfile" "t=")
17585         cat $MOUNT/.lustre/fid/$fid 2>/dev/null >$tempfile || error "cat failed"
17586         # some delay may occur during ChangeLog publishing and file read just
17587         # above, that could allow file write to happen finally
17588         [[ -s $tempfile ]] && echo "file should be empty"
17589
17590         $LCTL set_param fail_loc=0
17591
17592         wait $pid
17593         [[ $? -eq 0 ]] || error "create failed"
17594 }
17595 run_test 161d "create with concurrent .lustre/fid access"
17596
17597 check_path() {
17598         local expected="$1"
17599         shift
17600         local fid="$2"
17601
17602         local path
17603         path=$($LFS fid2path "$@")
17604         local rc=$?
17605
17606         if [ $rc -ne 0 ]; then
17607                 error "path looked up of '$expected' failed: rc=$rc"
17608         elif [ "$path" != "$expected" ]; then
17609                 error "path looked up '$path' instead of '$expected'"
17610         else
17611                 echo "FID '$fid' resolves to path '$path' as expected"
17612         fi
17613 }
17614
17615 test_162a() { # was test_162
17616         test_mkdir -p -c1 $DIR/$tdir/d2
17617         touch $DIR/$tdir/d2/$tfile
17618         touch $DIR/$tdir/d2/x1
17619         touch $DIR/$tdir/d2/x2
17620         test_mkdir -p -c1 $DIR/$tdir/d2/a/b/c
17621         test_mkdir -p -c1 $DIR/$tdir/d2/p/q/r
17622         # regular file
17623         local fid=$($LFS path2fid $DIR/$tdir/d2/$tfile | tr -d '[]')
17624         check_path "$tdir/d2/$tfile" $FSNAME "$fid" --link 0
17625
17626         # softlink
17627         ln -s $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/slink
17628         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink | tr -d '[]')
17629         check_path "$tdir/d2/p/q/r/slink" $FSNAME "$fid" --link 0
17630
17631         # softlink to wrong file
17632         ln -s /this/is/garbage $DIR/$tdir/d2/p/q/r/slink.wrong
17633         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink.wrong | tr -d '[]')
17634         check_path "$tdir/d2/p/q/r/slink.wrong" $FSNAME "$fid" --link 0
17635
17636         # hardlink
17637         ln $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/hlink
17638         mv $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/a/b/c/new_file
17639         fid=$($LFS path2fid $DIR/$tdir/d2/a/b/c/new_file | tr -d '[]')
17640         # fid2path dir/fsname should both work
17641         check_path "$tdir/d2/a/b/c/new_file" $FSNAME "$fid" --link 1
17642         check_path "$DIR/$tdir/d2/p/q/r/hlink" $DIR "$fid" --link 0
17643
17644         # hardlink count: check that there are 2 links
17645         local nlinks=$($LFS fid2path $DIR "$fid" | wc -l)
17646         [ $nlinks -eq 2 ] || error "expect 2 links, found $nlinks"
17647
17648         # hardlink indexing: remove the first link
17649         rm $DIR/$tdir/d2/p/q/r/hlink
17650         check_path "$tdir/d2/a/b/c/new_file" $FSNAME $fid --link 0
17651 }
17652 run_test 162a "path lookup sanity"
17653
17654 test_162b() {
17655         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17656         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17657
17658         mkdir $DIR/$tdir
17659         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
17660                                 error "create striped dir failed"
17661
17662         local FID=$($LFS getdirstripe $DIR/$tdir/striped_dir |
17663                                         tail -n 1 | awk '{print $2}')
17664         stat $MOUNT/.lustre/fid/$FID && error "sub_stripe can be accessed"
17665
17666         touch $DIR/$tdir/striped_dir/f{0..4} || error "touch f0..4 failed"
17667         mkdir $DIR/$tdir/striped_dir/d{0..4} || error "mkdir d0..4 failed"
17668
17669         # regular file
17670         for ((i=0;i<5;i++)); do
17671                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/f$i | tr -d '[]') ||
17672                         error "get fid for f$i failed"
17673                 check_path "$tdir/striped_dir/f$i" $FSNAME $FID --link 0
17674
17675                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/d$i | tr -d '[]') ||
17676                         error "get fid for d$i failed"
17677                 check_path "$tdir/striped_dir/d$i" $FSNAME $FID --link 0
17678         done
17679
17680         return 0
17681 }
17682 run_test 162b "striped directory path lookup sanity"
17683
17684 # LU-4239: Verify fid2path works with paths 100 or more directories deep
17685 test_162c() {
17686         [[ $MDS1_VERSION -lt $(version_code 2.7.51) ]] &&
17687                 skip "Need MDS version at least 2.7.51"
17688
17689         local lpath=$tdir.local
17690         local rpath=$tdir.remote
17691
17692         test_mkdir $DIR/$lpath
17693         test_mkdir $DIR/$rpath
17694
17695         for ((i = 0; i <= 101; i++)); do
17696                 lpath="$lpath/$i"
17697                 mkdir $DIR/$lpath
17698                 FID=$($LFS path2fid $DIR/$lpath | tr -d '[]') ||
17699                         error "get fid for local directory $DIR/$lpath failed"
17700                 check_path "$DIR/$lpath" $MOUNT $FID --link 0
17701
17702                 rpath="$rpath/$i"
17703                 test_mkdir $DIR/$rpath
17704                 FID=$($LFS path2fid $DIR/$rpath | tr -d '[]') ||
17705                         error "get fid for remote directory $DIR/$rpath failed"
17706                 check_path "$DIR/$rpath" $MOUNT $FID --link 0
17707         done
17708
17709         return 0
17710 }
17711 run_test 162c "fid2path works with paths 100 or more directories deep"
17712
17713 oalr_event_count() {
17714         local event="${1}"
17715         local trace="${2}"
17716
17717         awk -v name="${FSNAME}-OST0000" \
17718             -v event="${event}" \
17719             '$1 == "TRACE" && $2 == event && $3 == name' \
17720             "${trace}" |
17721         wc -l
17722 }
17723
17724 oalr_expect_event_count() {
17725         local event="${1}"
17726         local trace="${2}"
17727         local expect="${3}"
17728         local count
17729
17730         count=$(oalr_event_count "${event}" "${trace}")
17731         if ((count == expect)); then
17732                 return 0
17733         fi
17734
17735         error_noexit "${event} event count was '${count}', expected ${expect}"
17736         cat "${trace}" >&2
17737         exit 1
17738 }
17739
17740 cleanup_165() {
17741         do_facet ost1 killall --quiet -KILL ofd_access_log_reader || true
17742         stop ost1
17743         start ost1 "$(ostdevname 1)" $OST_MOUNT_OPTS
17744 }
17745
17746 setup_165() {
17747         sync # Flush previous IOs so we can count log entries.
17748         do_facet ost1 $LCTL set_param "obdfilter.${FSNAME}-OST0000.access_log_size=4096"
17749         stack_trap cleanup_165 EXIT
17750 }
17751
17752 test_165a() {
17753         local trace="/tmp/${tfile}.trace"
17754         local rc
17755         local count
17756
17757         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17758                 skip "OFD access log unsupported"
17759
17760         setup_165
17761         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
17762         sleep 5
17763
17764         do_facet ost1 ofd_access_log_reader --list
17765         stop ost1
17766
17767         do_facet ost1 killall -TERM ofd_access_log_reader
17768         wait
17769         rc=$?
17770
17771         if ((rc != 0)); then
17772                 error "ofd_access_log_reader exited with rc = '${rc}'"
17773         fi
17774
17775         # Parse trace file for discovery events:
17776         oalr_expect_event_count alr_log_add "${trace}" 1
17777         oalr_expect_event_count alr_log_eof "${trace}" 1
17778         oalr_expect_event_count alr_log_free "${trace}" 1
17779 }
17780 run_test 165a "ofd access log discovery"
17781
17782 test_165b() {
17783         local trace="/tmp/${tfile}.trace"
17784         local file="${DIR}/${tfile}"
17785         local pfid1
17786         local pfid2
17787         local -a entry
17788         local rc
17789         local count
17790         local size
17791         local flags
17792
17793         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17794                 skip "OFD access log unsupported"
17795
17796         setup_165
17797         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
17798         sleep 5
17799
17800         do_facet ost1 ofd_access_log_reader --list
17801
17802         lfs setstripe -c 1 -i 0 "${file}"
17803         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17804                 error "cannot create '${file}'"
17805
17806         sleep 5
17807         do_facet ost1 killall -TERM ofd_access_log_reader
17808         wait
17809         rc=$?
17810
17811         if ((rc != 0)); then
17812                 error "ofd_access_log_reader exited with rc = '${rc}'"
17813         fi
17814
17815         oalr_expect_event_count alr_log_entry "${trace}" 1
17816
17817         pfid1=$($LFS path2fid "${file}")
17818
17819         # 1     2             3   4    5     6   7    8    9     10
17820         # TRACE alr_log_entry OST PFID BEGIN END TIME SIZE COUNT FLAGS
17821         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
17822
17823         echo "entry = '${entry[*]}'" >&2
17824
17825         pfid2=${entry[4]}
17826         if [[ "${pfid1}" != "${pfid2}" ]]; then
17827                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
17828         fi
17829
17830         size=${entry[8]}
17831         if ((size != 1048576)); then
17832                 error "entry '${entry[*]}' has invalid io size '${size}', expected 1048576"
17833         fi
17834
17835         flags=${entry[10]}
17836         if [[ "${flags}" != "w" ]]; then
17837                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'w'"
17838         fi
17839
17840         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
17841         sleep 5
17842
17843         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r524288c ||
17844                 error "cannot read '${file}'"
17845         sleep 5
17846
17847         do_facet ost1 killall -TERM ofd_access_log_reader
17848         wait
17849         rc=$?
17850
17851         if ((rc != 0)); then
17852                 error "ofd_access_log_reader exited with rc = '${rc}'"
17853         fi
17854
17855         oalr_expect_event_count alr_log_entry "${trace}" 1
17856
17857         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
17858         echo "entry = '${entry[*]}'" >&2
17859
17860         pfid2=${entry[4]}
17861         if [[ "${pfid1}" != "${pfid2}" ]]; then
17862                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
17863         fi
17864
17865         size=${entry[8]}
17866         if ((size != 524288)); then
17867                 error "entry '${entry[*]}' has invalid io size '${size}', 524288"
17868         fi
17869
17870         flags=${entry[10]}
17871         if [[ "${flags}" != "r" ]]; then
17872                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'r'"
17873         fi
17874 }
17875 run_test 165b "ofd access log entries are produced and consumed"
17876
17877 test_165c() {
17878         local trace="/tmp/${tfile}.trace"
17879         local file="${DIR}/${tdir}/${tfile}"
17880
17881         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17882                 skip "OFD access log unsupported"
17883
17884         test_mkdir "${DIR}/${tdir}"
17885
17886         setup_165
17887         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
17888         sleep 5
17889
17890         lfs setstripe -c 1 -i 0 "${DIR}/${tdir}"
17891
17892         # 4096 / 64 = 64. Create twice as many entries.
17893         for ((i = 0; i < 128; i++)); do
17894                 $MULTIOP "${file}-${i}" oO_CREAT:O_WRONLY:w512c ||
17895                         error "cannot create file"
17896         done
17897
17898         sync
17899
17900         do_facet ost1 killall -TERM ofd_access_log_reader
17901         wait
17902         rc=$?
17903         if ((rc != 0)); then
17904                 error "ofd_access_log_reader exited with rc = '${rc}'"
17905         fi
17906
17907         unlinkmany  "${file}-%d" 128
17908 }
17909 run_test 165c "full ofd access logs do not block IOs"
17910
17911 oal_get_read_count() {
17912         local stats="$1"
17913
17914         # STATS lustre-OST0001 alr_read_count 1
17915
17916         do_facet ost1 cat "${stats}" |
17917         awk '$1 == "STATS" && $3 == "alr_read_count" { count = $4; }
17918              END { print count; }'
17919 }
17920
17921 oal_expect_read_count() {
17922         local stats="$1"
17923         local count
17924         local expect="$2"
17925
17926         # Ask ofd_access_log_reader to write stats.
17927         do_facet ost1 killall -USR1 ofd_access_log_reader
17928
17929         # Allow some time for things to happen.
17930         sleep 1
17931
17932         count=$(oal_get_read_count "${stats}")
17933         if ((count == expect)); then
17934                 return 0
17935         fi
17936
17937         error_noexit "bad read count, got ${count}, expected ${expect}"
17938         do_facet ost1 cat "${stats}" >&2
17939         exit 1
17940 }
17941
17942 test_165d() {
17943         local stats="/tmp/${tfile}.stats"
17944         local file="${DIR}/${tdir}/${tfile}"
17945         local param="obdfilter.${FSNAME}-OST0000.access_log_mask"
17946
17947         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17948                 skip "OFD access log unsupported"
17949
17950         test_mkdir "${DIR}/${tdir}"
17951
17952         setup_165
17953         do_facet ost1 ofd_access_log_reader --stats="${stats}" &
17954         sleep 5
17955
17956         lfs setstripe -c 1 -i 0 "${file}"
17957
17958         do_facet ost1 lctl set_param "${param}=rw"
17959         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17960                 error "cannot create '${file}'"
17961         oal_expect_read_count "${stats}" 1
17962
17963         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
17964                 error "cannot read '${file}'"
17965         oal_expect_read_count "${stats}" 2
17966
17967         do_facet ost1 lctl set_param "${param}=r"
17968         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17969                 error "cannot create '${file}'"
17970         oal_expect_read_count "${stats}" 2
17971
17972         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
17973                 error "cannot read '${file}'"
17974         oal_expect_read_count "${stats}" 3
17975
17976         do_facet ost1 lctl set_param "${param}=w"
17977         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17978                 error "cannot create '${file}'"
17979         oal_expect_read_count "${stats}" 4
17980
17981         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
17982                 error "cannot read '${file}'"
17983         oal_expect_read_count "${stats}" 4
17984
17985         do_facet ost1 lctl set_param "${param}=0"
17986         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17987                 error "cannot create '${file}'"
17988         oal_expect_read_count "${stats}" 4
17989
17990         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
17991                 error "cannot read '${file}'"
17992         oal_expect_read_count "${stats}" 4
17993
17994         do_facet ost1 killall -TERM ofd_access_log_reader
17995         wait
17996         rc=$?
17997         if ((rc != 0)); then
17998                 error "ofd_access_log_reader exited with rc = '${rc}'"
17999         fi
18000 }
18001 run_test 165d "ofd_access_log mask works"
18002
18003 test_165e() {
18004         local stats="/tmp/${tfile}.stats"
18005         local file0="${DIR}/${tdir}-0/${tfile}"
18006         local file1="${DIR}/${tdir}-1/${tfile}"
18007
18008         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
18009                 skip "OFD access log unsupported"
18010
18011         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
18012
18013         test_mkdir -c 1 -i 0 "${DIR}/${tdir}-0"
18014         test_mkdir -c 1 -i 1 "${DIR}/${tdir}-1"
18015
18016         lfs setstripe -c 1 -i 0 "${file0}"
18017         lfs setstripe -c 1 -i 0 "${file1}"
18018
18019         setup_165
18020         do_facet ost1 ofd_access_log_reader -I 1 --stats="${stats}" &
18021         sleep 5
18022
18023         $MULTIOP "${file0}" oO_CREAT:O_WRONLY:w512c ||
18024                 error "cannot create '${file0}'"
18025         sync
18026         oal_expect_read_count "${stats}" 0
18027
18028         $MULTIOP "${file1}" oO_CREAT:O_WRONLY:w512c ||
18029                 error "cannot create '${file1}'"
18030         sync
18031         oal_expect_read_count "${stats}" 1
18032
18033         do_facet ost1 killall -TERM ofd_access_log_reader
18034         wait
18035         rc=$?
18036         if ((rc != 0)); then
18037                 error "ofd_access_log_reader exited with rc = '${rc}'"
18038         fi
18039 }
18040 run_test 165e "ofd_access_log MDT index filter works"
18041
18042 test_165f() {
18043         local trace="/tmp/${tfile}.trace"
18044         local rc
18045         local count
18046
18047         setup_165
18048         do_facet ost1 timeout 60 ofd_access_log_reader \
18049                 --exit-on-close --debug=- --trace=- > "${trace}" &
18050         sleep 5
18051         stop ost1
18052
18053         wait
18054         rc=$?
18055
18056         if ((rc != 0)); then
18057                 error_noexit "ofd_access_log_reader exited with rc = '${rc}'"
18058                 cat "${trace}"
18059                 exit 1
18060         fi
18061 }
18062 run_test 165f "ofd_access_log_reader --exit-on-close works"
18063
18064 test_169() {
18065         # do directio so as not to populate the page cache
18066         log "creating a 10 Mb file"
18067         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c ||
18068                 error "multiop failed while creating a file"
18069         log "starting reads"
18070         dd if=$DIR/$tfile of=/dev/null bs=4096 &
18071         log "truncating the file"
18072         $MULTIOP $DIR/$tfile oO_TRUNC:c ||
18073                 error "multiop failed while truncating the file"
18074         log "killing dd"
18075         kill %+ || true # reads might have finished
18076         echo "wait until dd is finished"
18077         wait
18078         log "removing the temporary file"
18079         rm -rf $DIR/$tfile || error "tmp file removal failed"
18080 }
18081 run_test 169 "parallel read and truncate should not deadlock"
18082
18083 test_170() {
18084         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18085
18086         $LCTL clear     # bug 18514
18087         $LCTL debug_daemon start $TMP/${tfile}_log_good
18088         touch $DIR/$tfile
18089         $LCTL debug_daemon stop
18090         sed -e "s/^...../a/g" $TMP/${tfile}_log_good > $TMP/${tfile}_log_bad ||
18091                 error "sed failed to read log_good"
18092
18093         $LCTL debug_daemon start $TMP/${tfile}_log_good
18094         rm -rf $DIR/$tfile
18095         $LCTL debug_daemon stop
18096
18097         $LCTL df $TMP/${tfile}_log_bad > $TMP/${tfile}_log_bad.out 2>&1 ||
18098                error "lctl df log_bad failed"
18099
18100         local bad_line=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
18101         local good_line1=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
18102
18103         $LCTL df $TMP/${tfile}_log_good > $TMP/${tfile}_log_good.out 2>&1
18104         local good_line2=$(tail -n 1 $TMP/${tfile}_log_good.out | awk '{print $5}')
18105
18106         [ "$bad_line" ] && [ "$good_line1" ] && [ "$good_line2" ] ||
18107                 error "bad_line good_line1 good_line2 are empty"
18108
18109         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
18110         cat $TMP/${tfile}_log_bad >> $TMP/${tfile}_logs_corrupt
18111         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
18112
18113         $LCTL df $TMP/${tfile}_logs_corrupt > $TMP/${tfile}_log_bad.out 2>&1
18114         local bad_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
18115         local good_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
18116
18117         [ "$bad_line_new" ] && [ "$good_line_new" ] ||
18118                 error "bad_line_new good_line_new are empty"
18119
18120         local expected_good=$((good_line1 + good_line2*2))
18121
18122         rm -f $TMP/${tfile}*
18123         # LU-231, short malformed line may not be counted into bad lines
18124         if [ $bad_line -ne $bad_line_new ] &&
18125                    [ $bad_line -ne $((bad_line_new - 1)) ]; then
18126                 error "expected $bad_line bad lines, but got $bad_line_new"
18127                 return 1
18128         fi
18129
18130         if [ $expected_good -ne $good_line_new ]; then
18131                 error "expected $expected_good good lines, but got $good_line_new"
18132                 return 2
18133         fi
18134         true
18135 }
18136 run_test 170 "test lctl df to handle corrupted log ====================="
18137
18138 test_171() { # bug20592
18139         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18140
18141         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
18142         $LCTL set_param fail_loc=0x50e
18143         $LCTL set_param fail_val=3000
18144         multiop_bg_pause $DIR/$tfile O_s || true
18145         local MULTIPID=$!
18146         kill -USR1 $MULTIPID
18147         # cause log dump
18148         sleep 3
18149         wait $MULTIPID
18150         if dmesg | grep "recursive fault"; then
18151                 error "caught a recursive fault"
18152         fi
18153         $LCTL set_param fail_loc=0
18154         true
18155 }
18156 run_test 171 "test libcfs_debug_dumplog_thread stuck in do_exit() ======"
18157
18158 test_172() {
18159
18160         #define OBD_FAIL_OBD_CLEANUP  0x60e
18161         $LCTL set_param fail_loc=0x60e
18162         umount $MOUNT || error "umount $MOUNT failed"
18163         stack_trap "mount_client $MOUNT"
18164
18165         (( $($LCTL dl | egrep -c " osc | lov | lmv | mdc ") > 0 )) ||
18166                 error "no client OBDs are remained"
18167
18168         $LCTL dl | while read devno state type name foo; do
18169                 case $type in
18170                 lov|osc|lmv|mdc)
18171                         $LCTL --device $name cleanup
18172                         $LCTL --device $name detach
18173                         ;;
18174                 *)
18175                         # skip server devices
18176                         ;;
18177                 esac
18178         done
18179
18180         if (( $($LCTL dl | egrep -c " osc | lov | lmv | mdc ") > 0 )); then
18181                 $LCTL dl | egrep " osc | lov | lmv | mdc "
18182                 error "some client OBDs are still remained"
18183         fi
18184
18185 }
18186 run_test 172 "manual device removal with lctl cleanup/detach ======"
18187
18188 # it would be good to share it with obdfilter-survey/iokit-libecho code
18189 setup_obdecho_osc () {
18190         local rc=0
18191         local ost_nid=$1
18192         local obdfilter_name=$2
18193         echo "Creating new osc for $obdfilter_name on $ost_nid"
18194         # make sure we can find loopback nid
18195         $LCTL add_uuid $ost_nid $ost_nid >/dev/null 2>&1
18196
18197         [ $rc -eq 0 ] && { $LCTL attach osc ${obdfilter_name}_osc     \
18198                            ${obdfilter_name}_osc_UUID || rc=2; }
18199         [ $rc -eq 0 ] && { $LCTL --device ${obdfilter_name}_osc setup \
18200                            ${obdfilter_name}_UUID  $ost_nid || rc=3; }
18201         return $rc
18202 }
18203
18204 cleanup_obdecho_osc () {
18205         local obdfilter_name=$1
18206         $LCTL --device ${obdfilter_name}_osc cleanup >/dev/null
18207         $LCTL --device ${obdfilter_name}_osc detach  >/dev/null
18208         return 0
18209 }
18210
18211 obdecho_test() {
18212         local OBD=$1
18213         local node=$2
18214         local pages=${3:-64}
18215         local rc=0
18216         local id
18217
18218         local count=10
18219         local obd_size=$(get_obd_size $node $OBD)
18220         local page_size=$(get_page_size $node)
18221         if [[ -n "$obd_size" ]]; then
18222                 local new_count=$((obd_size / (pages * page_size / 1024)))
18223                 [[ $new_count -ge $count ]] || count=$new_count
18224         fi
18225
18226         do_facet $node "$LCTL attach echo_client ec ec_uuid" || rc=1
18227         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec setup $OBD" ||
18228                            rc=2; }
18229         if [ $rc -eq 0 ]; then
18230             id=$(do_facet $node "$LCTL --device ec create 1"  | awk '/object id/ {print $6}')
18231             [ ${PIPESTATUS[0]} -eq 0 -a -n "$id" ] || rc=3
18232         fi
18233         echo "New object id is $id"
18234         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec getattr $id" ||
18235                            rc=4; }
18236         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec "                 \
18237                            "test_brw $count w v $pages $id" || rc=4; }
18238         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec destroy $id 1" ||
18239                            rc=4; }
18240         [ $rc -eq 0 ] || [ $rc -gt 2 ] &&
18241                 { do_facet $node "$LCTL --device ec cleanup" || rc=5; }
18242         [ $rc -eq 0 ] || [ $rc -gt 1 ] &&
18243                 { do_facet $node "$LCTL --device ec detach" || rc=6; }
18244         [ $rc -ne 0 ] && echo "obecho_create_test failed: $rc"
18245         return $rc
18246 }
18247
18248 test_180a() {
18249         skip "obdecho on osc is no longer supported"
18250 }
18251 run_test 180a "test obdecho on osc"
18252
18253 test_180b() {
18254         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18255         remote_ost_nodsh && skip "remote OST with nodsh"
18256
18257         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
18258                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
18259                 error "failed to load module obdecho"
18260
18261         local target=$(do_facet ost1 $LCTL dl |
18262                        awk '/obdfilter/ { print $4; exit; }')
18263
18264         if [ -n "$target" ]; then
18265                 obdecho_test $target ost1 || error "obdecho_test failed with $?"
18266         else
18267                 do_facet ost1 $LCTL dl
18268                 error "there is no obdfilter target on ost1"
18269         fi
18270 }
18271 run_test 180b "test obdecho directly on obdfilter"
18272
18273 test_180c() { # LU-2598
18274         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18275         remote_ost_nodsh && skip "remote OST with nodsh"
18276         [[ $MDS1_VERSION -lt $(version_code 2.4.0) ]] &&
18277                 skip "Need MDS version at least 2.4.0"
18278
18279         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
18280                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
18281                 error "failed to load module obdecho"
18282
18283         local target=$(do_facet ost1 $LCTL dl |
18284                        awk '/obdfilter/ { print $4; exit; }')
18285
18286         if [ -n "$target" ]; then
18287                 local pages=16384 # 64MB bulk I/O RPC size
18288
18289                 obdecho_test "$target" ost1 "$pages" ||
18290                         error "obdecho_test with pages=$pages failed with $?"
18291         else
18292                 do_facet ost1 $LCTL dl
18293                 error "there is no obdfilter target on ost1"
18294         fi
18295 }
18296 run_test 180c "test huge bulk I/O size on obdfilter, don't LASSERT"
18297
18298 test_181() { # bug 22177
18299         test_mkdir $DIR/$tdir
18300         # create enough files to index the directory
18301         createmany -o $DIR/$tdir/foobar 4000
18302         # print attributes for debug purpose
18303         lsattr -d .
18304         # open dir
18305         multiop_bg_pause $DIR/$tdir D_Sc || return 1
18306         MULTIPID=$!
18307         # remove the files & current working dir
18308         unlinkmany $DIR/$tdir/foobar 4000
18309         rmdir $DIR/$tdir
18310         kill -USR1 $MULTIPID
18311         wait $MULTIPID
18312         stat $DIR/$tdir && error "open-unlinked dir was not removed!"
18313         return 0
18314 }
18315 run_test 181 "Test open-unlinked dir ========================"
18316
18317 test_182a() {
18318         local fcount=1000
18319         local tcount=10
18320
18321         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
18322
18323         $LCTL set_param mdc.*.rpc_stats=clear
18324
18325         for (( i = 0; i < $tcount; i++ )) ; do
18326                 mkdir $DIR/$tdir/$i
18327         done
18328
18329         for (( i = 0; i < $tcount; i++ )) ; do
18330                 createmany -o $DIR/$tdir/$i/f- $fcount &
18331         done
18332         wait
18333
18334         for (( i = 0; i < $tcount; i++ )) ; do
18335                 unlinkmany $DIR/$tdir/$i/f- $fcount &
18336         done
18337         wait
18338
18339         $LCTL get_param mdc.*.rpc_stats
18340
18341         rm -rf $DIR/$tdir
18342 }
18343 run_test 182a "Test parallel modify metadata operations from mdc"
18344
18345 test_182b() {
18346         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
18347         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
18348         local dcount=1000
18349         local tcount=10
18350         local stime
18351         local etime
18352         local delta
18353
18354         do_facet mds1 $LCTL list_param \
18355                 osp.$FSNAME-MDT*-osp-MDT*.rpc_stats ||
18356                 skip "MDS lacks parallel RPC handling"
18357
18358         $LFS mkdir -i 0 $DIR/$tdir || error "creating dir $DIR/$tdir"
18359
18360         rpc_count=$(do_facet mds1 $LCTL get_param -n \
18361                     osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight)
18362
18363         stime=$(date +%s)
18364         createmany -i 0 -d $DIR/$tdir/t- $tcount
18365
18366         for (( i = 0; i < $tcount; i++ )) ; do
18367                 createmany -i 0 -d $DIR/$tdir/t-$i/d- 0 $dcount &
18368         done
18369         wait
18370         etime=$(date +%s)
18371         delta=$((etime - stime))
18372         echo "Time for file creation $delta sec for $rpc_count parallel RPCs"
18373
18374         stime=$(date +%s)
18375         for (( i = 0; i < $tcount; i++ )) ; do
18376                 unlinkmany -d $DIR/$tdir/$i/d- $dcount &
18377         done
18378         wait
18379         etime=$(date +%s)
18380         delta=$((etime - stime))
18381         echo "Time for file removal $delta sec for $rpc_count parallel RPCs"
18382
18383         rm -rf $DIR/$tdir
18384
18385         $LFS mkdir -i 0 $DIR/$tdir || error "creating dir $DIR/$tdir"
18386
18387         do_facet mds1 $LCTL set_param osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight=1
18388
18389         stime=$(date +%s)
18390         createmany -i 0 -d $DIR/$tdir/t- $tcount
18391
18392         for (( i = 0; i < $tcount; i++ )) ; do
18393                 createmany -i 0 -d $DIR/$tdir/t-$i/d- 0 $dcount &
18394         done
18395         wait
18396         etime=$(date +%s)
18397         delta=$((etime - stime))
18398         echo "Time for file creation $delta sec for 1 RPC sent at a time"
18399
18400         stime=$(date +%s)
18401         for (( i = 0; i < $tcount; i++ )) ; do
18402                 unlinkmany -d $DIR/$tdir/t-$i/d- $dcount &
18403         done
18404         wait
18405         etime=$(date +%s)
18406         delta=$((etime - stime))
18407         echo "Time for file removal $delta sec for 1 RPC sent at a time"
18408
18409         do_facet mds1 $LCTL set_param osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight=$rpc_count
18410 }
18411 run_test 182b "Test parallel modify metadata operations from osp"
18412
18413 test_183() { # LU-2275
18414         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18415         remote_mds_nodsh && skip "remote MDS with nodsh"
18416         [[ $MDS1_VERSION -lt $(version_code 2.3.56) ]] &&
18417                 skip "Need MDS version at least 2.3.56"
18418
18419         mkdir_on_mdt0 $DIR/$tdir || error "creating dir $DIR/$tdir"
18420         echo aaa > $DIR/$tdir/$tfile
18421
18422 #define OBD_FAIL_MDS_NEGATIVE_POSITIVE  0x148
18423         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x148
18424
18425         ls -l $DIR/$tdir && error "ls succeeded, should have failed"
18426         cat $DIR/$tdir/$tfile && error "cat succeeded, should have failed"
18427
18428         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
18429
18430         # Flush negative dentry cache
18431         touch $DIR/$tdir/$tfile
18432
18433         # We are not checking for any leaked references here, they'll
18434         # become evident next time we do cleanup with module unload.
18435         rm -rf $DIR/$tdir
18436 }
18437 run_test 183 "No crash or request leak in case of strange dispositions ========"
18438
18439 # test suite 184 is for LU-2016, LU-2017
18440 test_184a() {
18441         check_swap_layouts_support
18442
18443         dir0=$DIR/$tdir/$testnum
18444         test_mkdir -p -c1 $dir0
18445         ref1=/etc/passwd
18446         ref2=/etc/group
18447         file1=$dir0/f1
18448         file2=$dir0/f2
18449         $LFS setstripe -c1 $file1
18450         cp $ref1 $file1
18451         $LFS setstripe -c2 $file2
18452         cp $ref2 $file2
18453         gen1=$($LFS getstripe -g $file1)
18454         gen2=$($LFS getstripe -g $file2)
18455
18456         $LFS swap_layouts $file1 $file2 || error "swap of file layout failed"
18457         gen=$($LFS getstripe -g $file1)
18458         [[ $gen1 != $gen ]] ||
18459                 error "Layout generation on $file1 does not change"
18460         gen=$($LFS getstripe -g $file2)
18461         [[ $gen2 != $gen ]] ||
18462                 error "Layout generation on $file2 does not change"
18463
18464         cmp $ref1 $file2 || error "content compare failed ($ref1 != $file2)"
18465         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
18466
18467         lfsck_verify_pfid $file1 $file2 || error "PFID are not transferred"
18468 }
18469 run_test 184a "Basic layout swap"
18470
18471 test_184b() {
18472         check_swap_layouts_support
18473
18474         dir0=$DIR/$tdir/$testnum
18475         mkdir -p $dir0 || error "creating dir $dir0"
18476         file1=$dir0/f1
18477         file2=$dir0/f2
18478         file3=$dir0/f3
18479         dir1=$dir0/d1
18480         dir2=$dir0/d2
18481         mkdir $dir1 $dir2
18482         $LFS setstripe -c1 $file1
18483         $LFS setstripe -c2 $file2
18484         $LFS setstripe -c1 $file3
18485         chown $RUNAS_ID $file3
18486         gen1=$($LFS getstripe -g $file1)
18487         gen2=$($LFS getstripe -g $file2)
18488
18489         $LFS swap_layouts $dir1 $dir2 &&
18490                 error "swap of directories layouts should fail"
18491         $LFS swap_layouts $dir1 $file1 &&
18492                 error "swap of directory and file layouts should fail"
18493         $RUNAS $LFS swap_layouts $file1 $file2 &&
18494                 error "swap of file we cannot write should fail"
18495         $LFS swap_layouts $file1 $file3 &&
18496                 error "swap of file with different owner should fail"
18497         /bin/true # to clear error code
18498 }
18499 run_test 184b "Forbidden layout swap (will generate errors)"
18500
18501 test_184c() {
18502         local cmpn_arg=$(cmp -n 2>&1 | grep "invalid option")
18503         [ -n "$cmpn_arg" ] && skip_env "cmp does not support -n"
18504         check_swap_layouts_support
18505         check_swap_layout_no_dom $DIR
18506
18507         local dir0=$DIR/$tdir/$testnum
18508         mkdir -p $dir0 || error "creating dir $dir0"
18509
18510         local ref1=$dir0/ref1
18511         local ref2=$dir0/ref2
18512         local file1=$dir0/file1
18513         local file2=$dir0/file2
18514         # create a file large enough for the concurrent test
18515         dd if=/dev/urandom of=$ref1 bs=1M count=$((RANDOM % 50 + 20))
18516         dd if=/dev/urandom of=$ref2 bs=1M count=$((RANDOM % 50 + 20))
18517         echo "ref file size: ref1($(stat -c %s $ref1))," \
18518              "ref2($(stat -c %s $ref2))"
18519
18520         cp $ref2 $file2
18521         dd if=$ref1 of=$file1 bs=16k &
18522         local DD_PID=$!
18523
18524         # Make sure dd starts to copy file, but wait at most 5 seconds
18525         local loops=0
18526         while [ ! -s $file1 -a $((loops++)) -lt 50 ]; do sleep 0.1; done
18527
18528         $LFS swap_layouts $file1 $file2
18529         local rc=$?
18530         wait $DD_PID
18531         [[ $? == 0 ]] || error "concurrent write on $file1 failed"
18532         [[ $rc == 0 ]] || error "swap of $file1 and $file2 failed"
18533
18534         # how many bytes copied before swapping layout
18535         local copied=$(stat -c %s $file2)
18536         local remaining=$(stat -c %s $ref1)
18537         remaining=$((remaining - copied))
18538         echo "Copied $copied bytes before swapping layout..."
18539
18540         cmp -n $copied $file1 $ref2 | grep differ &&
18541                 error "Content mismatch [0, $copied) of ref2 and file1"
18542         cmp -n $copied $file2 $ref1 ||
18543                 error "Content mismatch [0, $copied) of ref1 and file2"
18544         cmp -i $copied:$copied -n $remaining $file1 $ref1 ||
18545                 error "Content mismatch [$copied, EOF) of ref1 and file1"
18546
18547         # clean up
18548         rm -f $ref1 $ref2 $file1 $file2
18549 }
18550 run_test 184c "Concurrent write and layout swap"
18551
18552 test_184d() {
18553         check_swap_layouts_support
18554         check_swap_layout_no_dom $DIR
18555         [ -z "$(which getfattr 2>/dev/null)" ] &&
18556                 skip_env "no getfattr command"
18557
18558         local file1=$DIR/$tdir/$tfile-1
18559         local file2=$DIR/$tdir/$tfile-2
18560         local file3=$DIR/$tdir/$tfile-3
18561         local lovea1
18562         local lovea2
18563
18564         mkdir -p $DIR/$tdir
18565         touch $file1 || error "create $file1 failed"
18566         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
18567                 error "create $file2 failed"
18568         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
18569                 error "create $file3 failed"
18570         lovea1=$(get_layout_param $file1)
18571
18572         $LFS swap_layouts $file2 $file3 ||
18573                 error "swap $file2 $file3 layouts failed"
18574         $LFS swap_layouts $file1 $file2 ||
18575                 error "swap $file1 $file2 layouts failed"
18576
18577         lovea2=$(get_layout_param $file2)
18578         echo "$lovea1"
18579         echo "$lovea2"
18580         [ "$lovea1" == "$lovea2" ] || error "lovea $lovea1 != $lovea2"
18581
18582         lovea1=$(getfattr -n trusted.lov $file1 | grep ^trusted)
18583         [[ -z "$lovea1" ]] || error "$file1 shouldn't have lovea"
18584 }
18585 run_test 184d "allow stripeless layouts swap"
18586
18587 test_184e() {
18588         [[ $MDS1_VERSION -ge $(version_code 2.6.94) ]] ||
18589                 skip "Need MDS version at least 2.6.94"
18590         check_swap_layouts_support
18591         check_swap_layout_no_dom $DIR
18592         [ -z "$(which getfattr 2>/dev/null)" ] &&
18593                 skip_env "no getfattr command"
18594
18595         local file1=$DIR/$tdir/$tfile-1
18596         local file2=$DIR/$tdir/$tfile-2
18597         local file3=$DIR/$tdir/$tfile-3
18598         local lovea
18599
18600         mkdir -p $DIR/$tdir
18601         touch $file1 || error "create $file1 failed"
18602         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
18603                 error "create $file2 failed"
18604         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
18605                 error "create $file3 failed"
18606
18607         $LFS swap_layouts $file1 $file2 ||
18608                 error "swap $file1 $file2 layouts failed"
18609
18610         lovea=$(getfattr -n trusted.lov $file1 | grep ^trusted)
18611         [[ -z "$lovea" ]] || error "$file1 shouldn't have lovea"
18612
18613         echo 123 > $file1 || error "Should be able to write into $file1"
18614
18615         $LFS swap_layouts $file1 $file3 ||
18616                 error "swap $file1 $file3 layouts failed"
18617
18618         echo 123 > $file1 || error "Should be able to write into $file1"
18619
18620         rm -rf $file1 $file2 $file3
18621 }
18622 run_test 184e "Recreate layout after stripeless layout swaps"
18623
18624 test_184f() {
18625         # Create a file with name longer than sizeof(struct stat) ==
18626         # 144 to see if we can get chars from the file name to appear
18627         # in the returned striping. Note that 'f' == 0x66.
18628         local file=$(for ((i = 0; i < 200; i++)); do echo -n f; done)
18629
18630         mkdir -p $DIR/$tdir
18631         mcreate $DIR/$tdir/$file
18632         if lfs find --stripe-count 0x6666 $DIR/$tdir | grep $file; then
18633                 error "IOC_MDC_GETFILEINFO returned garbage striping"
18634         fi
18635 }
18636 run_test 184f "IOC_MDC_GETFILEINFO for files with long names but no striping"
18637
18638 test_185() { # LU-2441
18639         # LU-3553 - no volatile file support in old servers
18640         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
18641                 skip "Need MDS version at least 2.3.60"
18642
18643         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
18644         touch $DIR/$tdir/spoo
18645         local mtime1=$(stat -c "%Y" $DIR/$tdir)
18646         local fid=$($MULTIOP $DIR/$tdir VFw4096c) ||
18647                 error "cannot create/write a volatile file"
18648         [ "$FILESET" == "" ] &&
18649         $CHECKSTAT -t file $MOUNT/.lustre/fid/$fid 2>/dev/null &&
18650                 error "FID is still valid after close"
18651
18652         multiop_bg_pause $DIR/$tdir vVw4096_c
18653         local multi_pid=$!
18654
18655         local OLD_IFS=$IFS
18656         IFS=":"
18657         local fidv=($fid)
18658         IFS=$OLD_IFS
18659         # assume that the next FID for this client is sequential, since stdout
18660         # is unfortunately eaten by multiop_bg_pause
18661         local n=$((${fidv[1]} + 1))
18662         local next_fid="${fidv[0]}:$(printf "0x%x" $n):${fidv[2]}"
18663         if [ "$FILESET" == "" ]; then
18664                 $CHECKSTAT -t file $MOUNT/.lustre/fid/$next_fid ||
18665                         error "FID is missing before close"
18666         fi
18667         kill -USR1 $multi_pid
18668         # 1 second delay, so if mtime change we will see it
18669         sleep 1
18670         local mtime2=$(stat -c "%Y" $DIR/$tdir)
18671         [[ $mtime1 == $mtime2 ]] || error "mtime has changed"
18672 }
18673 run_test 185 "Volatile file support"
18674
18675 function create_check_volatile() {
18676         local idx=$1
18677         local tgt
18678
18679         $MULTIOP $MOUNT/.lustre/fid V${idx}Fw4096_c >&/tmp/${tfile}.fid &
18680         local PID=$!
18681         sleep 1
18682         local FID=$(cat /tmp/${tfile}.fid)
18683         [ "$FID" == "" ] && error "can't get FID for volatile"
18684         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID || error "can't stat $FID"
18685         tgt=$($LFS getstripe -m $MOUNT/.lustre/fid/$FID)
18686         [ "$tgt" != "$idx" ] && error "wrong MDS $tgt, expected $idx"
18687         kill -USR1 $PID
18688         wait
18689         sleep 1
18690         cancel_lru_locks mdc # flush opencache
18691         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID && error "can stat $FID"
18692         return 0
18693 }
18694
18695 test_185a(){
18696         # LU-12516 - volatile creation via .lustre
18697         [[ $MDS1_VERSION -ge $(version_code 2.12.55) ]] ||
18698                 skip "Need MDS version at least 2.3.55"
18699
18700         create_check_volatile 0
18701         [ $MDSCOUNT -lt 2 ] && return 0
18702
18703         # DNE case
18704         create_check_volatile 1
18705
18706         return 0
18707 }
18708 run_test 185a "Volatile file creation in .lustre/fid/"
18709
18710 test_187a() {
18711         remote_mds_nodsh && skip "remote MDS with nodsh"
18712         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
18713                 skip "Need MDS version at least 2.3.0"
18714
18715         local dir0=$DIR/$tdir/$testnum
18716         mkdir -p $dir0 || error "creating dir $dir0"
18717
18718         local file=$dir0/file1
18719         dd if=/dev/urandom of=$file count=10 bs=1M conv=fsync
18720         local dv1=$($LFS data_version $file)
18721         dd if=/dev/urandom of=$file seek=10 count=1 bs=1M conv=fsync
18722         local dv2=$($LFS data_version $file)
18723         [[ $dv1 != $dv2 ]] ||
18724                 error "data version did not change on write $dv1 == $dv2"
18725
18726         # clean up
18727         rm -f $file1
18728 }
18729 run_test 187a "Test data version change"
18730
18731 test_187b() {
18732         remote_mds_nodsh && skip "remote MDS with nodsh"
18733         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
18734                 skip "Need MDS version at least 2.3.0"
18735
18736         local dir0=$DIR/$tdir/$testnum
18737         mkdir -p $dir0 || error "creating dir $dir0"
18738
18739         declare -a DV=$($MULTIOP $dir0 Vw1000xYw1000xY | cut -f3 -d" ")
18740         [[ ${DV[0]} != ${DV[1]} ]] ||
18741                 error "data version did not change on write"\
18742                       " ${DV[0]} == ${DV[1]}"
18743
18744         # clean up
18745         rm -f $file1
18746 }
18747 run_test 187b "Test data version change on volatile file"
18748
18749 test_200() {
18750         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18751         remote_mgs_nodsh && skip "remote MGS with nodsh"
18752         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
18753
18754         local POOL=${POOL:-cea1}
18755         local POOL_ROOT=${POOL_ROOT:-$DIR/d200.pools}
18756         local POOL_DIR_NAME=${POOL_DIR_NAME:-dir_tst}
18757         # Pool OST targets
18758         local first_ost=0
18759         local last_ost=$(($OSTCOUNT - 1))
18760         local ost_step=2
18761         local ost_list=$(seq $first_ost $ost_step $last_ost)
18762         local ost_range="$first_ost $last_ost $ost_step"
18763         local test_path=$POOL_ROOT/$POOL_DIR_NAME
18764         local file_dir=$POOL_ROOT/file_tst
18765         local subdir=$test_path/subdir
18766         local rc=0
18767
18768         while : ; do
18769                 # former test_200a test_200b
18770                 pool_add $POOL                          || { rc=$? ; break; }
18771                 pool_add_targets  $POOL $ost_range      || { rc=$? ; break; }
18772                 # former test_200c test_200d
18773                 mkdir -p $test_path
18774                 pool_set_dir      $POOL $test_path      || { rc=$? ; break; }
18775                 pool_check_dir    $POOL $test_path      || { rc=$? ; break; }
18776                 mkdir -p $subdir
18777                 pool_check_dir    $POOL $subdir         || { rc=$? ; break; }
18778                 pool_dir_rel_path $POOL $POOL_DIR_NAME $POOL_ROOT \
18779                                                         || { rc=$? ; break; }
18780                 # former test_200e test_200f
18781                 local files=$((OSTCOUNT*3))
18782                 pool_alloc_files  $POOL $test_path $files "$ost_list" \
18783                                                         || { rc=$? ; break; }
18784                 pool_create_files $POOL $file_dir $files "$ost_list" \
18785                                                         || { rc=$? ; break; }
18786                 # former test_200g test_200h
18787                 pool_lfs_df $POOL                       || { rc=$? ; break; }
18788                 pool_file_rel_path $POOL $test_path     || { rc=$? ; break; }
18789
18790                 # former test_201a test_201b test_201c
18791                 pool_remove_first_target $POOL          || { rc=$? ; break; }
18792
18793                 local f=$test_path/$tfile
18794                 pool_remove_all_targets $POOL $f        || { rc=$? ; break; }
18795                 pool_remove $POOL $f                    || { rc=$? ; break; }
18796                 break
18797         done
18798
18799         destroy_test_pools
18800
18801         return $rc
18802 }
18803 run_test 200 "OST pools"
18804
18805 # usage: default_attr <count | size | offset>
18806 default_attr() {
18807         $LCTL get_param -n lov.$FSNAME-clilov-\*.stripe${1}
18808 }
18809
18810 # usage: check_default_stripe_attr
18811 check_default_stripe_attr() {
18812         ACTUAL=$($LFS getstripe $* $DIR/$tdir)
18813         case $1 in
18814         --stripe-count|-c)
18815                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr count);;
18816         --stripe-size|-S)
18817                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr size);;
18818         --stripe-index|-i)
18819                 EXPECTED=-1;;
18820         *)
18821                 error "unknown getstripe attr '$1'"
18822         esac
18823
18824         [ $ACTUAL == $EXPECTED ] ||
18825                 error "$DIR/$tdir has $1 '$ACTUAL', not '$EXPECTED'"
18826 }
18827
18828 test_204a() {
18829         test_mkdir $DIR/$tdir
18830         $LFS setstripe --stripe-count 0 --stripe-size 0 --stripe-index -1 $DIR/$tdir
18831
18832         check_default_stripe_attr --stripe-count
18833         check_default_stripe_attr --stripe-size
18834         check_default_stripe_attr --stripe-index
18835 }
18836 run_test 204a "Print default stripe attributes"
18837
18838 test_204b() {
18839         test_mkdir $DIR/$tdir
18840         $LFS setstripe --stripe-count 1 $DIR/$tdir
18841
18842         check_default_stripe_attr --stripe-size
18843         check_default_stripe_attr --stripe-index
18844 }
18845 run_test 204b "Print default stripe size and offset"
18846
18847 test_204c() {
18848         test_mkdir $DIR/$tdir
18849         $LFS setstripe --stripe-size 65536 $DIR/$tdir
18850
18851         check_default_stripe_attr --stripe-count
18852         check_default_stripe_attr --stripe-index
18853 }
18854 run_test 204c "Print default stripe count and offset"
18855
18856 test_204d() {
18857         test_mkdir $DIR/$tdir
18858         $LFS setstripe --stripe-index 0 $DIR/$tdir
18859
18860         check_default_stripe_attr --stripe-count
18861         check_default_stripe_attr --stripe-size
18862 }
18863 run_test 204d "Print default stripe count and size"
18864
18865 test_204e() {
18866         test_mkdir $DIR/$tdir
18867         $LFS setstripe -d $DIR/$tdir
18868
18869         check_default_stripe_attr --stripe-count --raw
18870         check_default_stripe_attr --stripe-size --raw
18871         check_default_stripe_attr --stripe-index --raw
18872 }
18873 run_test 204e "Print raw stripe attributes"
18874
18875 test_204f() {
18876         test_mkdir $DIR/$tdir
18877         $LFS setstripe --stripe-count 1 $DIR/$tdir
18878
18879         check_default_stripe_attr --stripe-size --raw
18880         check_default_stripe_attr --stripe-index --raw
18881 }
18882 run_test 204f "Print raw stripe size and offset"
18883
18884 test_204g() {
18885         test_mkdir $DIR/$tdir
18886         $LFS setstripe --stripe-size 65536 $DIR/$tdir
18887
18888         check_default_stripe_attr --stripe-count --raw
18889         check_default_stripe_attr --stripe-index --raw
18890 }
18891 run_test 204g "Print raw stripe count and offset"
18892
18893 test_204h() {
18894         test_mkdir $DIR/$tdir
18895         $LFS setstripe --stripe-index 0 $DIR/$tdir
18896
18897         check_default_stripe_attr --stripe-count --raw
18898         check_default_stripe_attr --stripe-size --raw
18899 }
18900 run_test 204h "Print raw stripe count and size"
18901
18902 # Figure out which job scheduler is being used, if any,
18903 # or use a fake one
18904 if [ -n "$SLURM_JOB_ID" ]; then # SLURM
18905         JOBENV=SLURM_JOB_ID
18906 elif [ -n "$LSB_JOBID" ]; then # Load Sharing Facility
18907         JOBENV=LSB_JOBID
18908 elif [ -n "$PBS_JOBID" ]; then # PBS/Maui/Moab
18909         JOBENV=PBS_JOBID
18910 elif [ -n "$LOADL_STEPID" ]; then # LoadLeveller
18911         JOBENV=LOADL_STEP_ID
18912 elif [ -n "$JOB_ID" ]; then # Sun Grid Engine
18913         JOBENV=JOB_ID
18914 else
18915         $LCTL list_param jobid_name > /dev/null 2>&1
18916         if [ $? -eq 0 ]; then
18917                 JOBENV=nodelocal
18918         else
18919                 JOBENV=FAKE_JOBID
18920         fi
18921 fi
18922 LUSTRE_JOBID_SIZE=31 # plus NUL terminator
18923
18924 verify_jobstats() {
18925         local cmd=($1)
18926         shift
18927         local facets="$@"
18928
18929 # we don't really need to clear the stats for this test to work, since each
18930 # command has a unique jobid, but it makes debugging easier if needed.
18931 #       for facet in $facets; do
18932 #               local dev=$(convert_facet2label $facet)
18933 #               # clear old jobstats
18934 #               do_facet $facet lctl set_param *.$dev.job_stats="clear"
18935 #       done
18936
18937         # use a new JobID for each test, or we might see an old one
18938         [ "$JOBENV" = "FAKE_JOBID" ] &&
18939                 FAKE_JOBID=id.$testnum.$(basename ${cmd[0]}).$RANDOM
18940
18941         JOBVAL=${!JOBENV:0:$LUSTRE_JOBID_SIZE}
18942
18943         [ "$JOBENV" = "nodelocal" ] && {
18944                 FAKE_JOBID=id.$testnum.%e.$RANDOM
18945                 $LCTL set_param jobid_name=$FAKE_JOBID
18946                 JOBVAL=${FAKE_JOBID/\%e/$(basename ${cmd[0]})}
18947         }
18948
18949         log "Test: ${cmd[*]}"
18950         log "Using JobID environment $($LCTL get_param -n jobid_var)=$JOBVAL"
18951
18952         if [ $JOBENV = "FAKE_JOBID" ]; then
18953                 FAKE_JOBID=$JOBVAL ${cmd[*]}
18954         else
18955                 ${cmd[*]}
18956         fi
18957
18958         # all files are created on OST0000
18959         for facet in $facets; do
18960                 local stats="*.$(convert_facet2label $facet).job_stats"
18961
18962                 # strip out libtool wrappers for in-tree executables
18963                 if (( $(do_facet $facet lctl get_param $stats |
18964                         sed -e 's/\.lt-/./' | grep -cw $JOBVAL) != 1 )); then
18965                         do_facet $facet lctl get_param $stats
18966                         error "No jobstats for $JOBVAL found on $facet::$stats"
18967                 fi
18968         done
18969 }
18970
18971 jobstats_set() {
18972         local new_jobenv=$1
18973
18974         set_persistent_param_and_check client "jobid_var" \
18975                 "$FSNAME.sys.jobid_var" $new_jobenv
18976 }
18977
18978 test_205a() { # Job stats
18979         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18980         [[ $MDS1_VERSION -ge $(version_code 2.7.1) ]] ||
18981                 skip "Need MDS version with at least 2.7.1"
18982         remote_mgs_nodsh && skip "remote MGS with nodsh"
18983         remote_mds_nodsh && skip "remote MDS with nodsh"
18984         remote_ost_nodsh && skip "remote OST with nodsh"
18985         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep jobstats)" ] &&
18986                 skip "Server doesn't support jobstats"
18987         [[ $JOBID_VAR = disable ]] && skip_env "jobstats is disabled"
18988
18989         local old_jobenv=$($LCTL get_param -n jobid_var)
18990         [ $old_jobenv != $JOBENV ] && jobstats_set $JOBENV
18991
18992         if [[ $PERM_CMD == *"set_param -P"* ]]; then
18993                 stack_trap "do_facet mgs $PERM_CMD jobid_var=$old_jobenv" EXIT
18994         else
18995                 stack_trap "do_facet mgs $PERM_CMD \
18996                         $FSNAME.sys.jobid_var=$old_jobenv" EXIT
18997         fi
18998         changelog_register
18999
19000         local old_interval=$(do_facet $SINGLEMDS lctl get_param -n \
19001                                 mdt.*.job_cleanup_interval | head -n 1)
19002         local new_interval=5
19003         do_facet $SINGLEMDS \
19004                 $LCTL set_param mdt.*.job_cleanup_interval=$new_interval
19005         stack_trap "do_facet $SINGLEMDS \
19006                 $LCTL set_param mdt.*.job_cleanup_interval=$old_interval" EXIT
19007         local start=$SECONDS
19008
19009         local cmd
19010         # mkdir
19011         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir"
19012         verify_jobstats "$cmd" "$SINGLEMDS"
19013         # rmdir
19014         cmd="rmdir $DIR/$tdir"
19015         verify_jobstats "$cmd" "$SINGLEMDS"
19016         # mkdir on secondary MDT
19017         if [ $MDSCOUNT -gt 1 ]; then
19018                 cmd="lfs mkdir -i 1 $DIR/$tdir.remote"
19019                 verify_jobstats "$cmd" "mds2"
19020         fi
19021         # mknod
19022         cmd="mknod $DIR/$tfile c 1 3"
19023         verify_jobstats "$cmd" "$SINGLEMDS"
19024         # unlink
19025         cmd="rm -f $DIR/$tfile"
19026         verify_jobstats "$cmd" "$SINGLEMDS"
19027         # create all files on OST0000 so verify_jobstats can find OST stats
19028         # open & close
19029         cmd="$LFS setstripe -i 0 -c 1 $DIR/$tfile"
19030         verify_jobstats "$cmd" "$SINGLEMDS"
19031         # setattr
19032         cmd="touch $DIR/$tfile"
19033         verify_jobstats "$cmd" "$SINGLEMDS ost1"
19034         # write
19035         cmd="dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=sync"
19036         verify_jobstats "$cmd" "ost1"
19037         # read
19038         cancel_lru_locks osc
19039         cmd="dd if=$DIR/$tfile of=/dev/null bs=1M count=1 iflag=direct"
19040         verify_jobstats "$cmd" "ost1"
19041         # truncate
19042         cmd="$TRUNCATE $DIR/$tfile 0"
19043         verify_jobstats "$cmd" "$SINGLEMDS ost1"
19044         # rename
19045         cmd="mv -f $DIR/$tfile $DIR/$tdir.rename"
19046         verify_jobstats "$cmd" "$SINGLEMDS"
19047         # jobstats expiry - sleep until old stats should be expired
19048         local left=$((new_interval + 5 - (SECONDS - start)))
19049         [ $left -ge 0 ] && wait_update_facet $SINGLEMDS \
19050                 "lctl get_param *.*.job_stats | grep -c 'job_id.*mkdir'" \
19051                         "0" $left
19052         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir.expire"
19053         verify_jobstats "$cmd" "$SINGLEMDS"
19054         [ $(do_facet $SINGLEMDS lctl get_param *.*.job_stats |
19055             grep -c "job_id.*mkdir") -gt 1 ] && error "old jobstats not expired"
19056
19057         # Ensure that jobid are present in changelog (if supported by MDS)
19058         if [ $MDS1_VERSION -ge $(version_code 2.6.52) ];then
19059                 changelog_dump | tail -10
19060                 jobids=$(changelog_dump | tail -9 | grep -c "j=")
19061                 [ $jobids -eq 9 ] ||
19062                         error "Wrong changelog jobid count $jobids != 9"
19063
19064                 # LU-5862
19065                 JOBENV="disable"
19066                 jobstats_set $JOBENV
19067                 touch $DIR/$tfile
19068                 changelog_dump | grep $tfile
19069                 jobids=$(changelog_dump | grep $tfile | tail -1 | grep -c "j=")
19070                 [ $jobids -eq 0 ] ||
19071                         error "Unexpected jobids when jobid_var=$JOBENV"
19072         fi
19073
19074         # test '%j' access to environment variable - if supported
19075         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%h.E"; then
19076                 JOBENV="JOBCOMPLEX"
19077                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
19078
19079                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
19080         fi
19081
19082         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%H.E"; then
19083                 JOBENV="JOBCOMPLEX"
19084                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname -s).E"
19085
19086                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
19087         fi
19088
19089         # test '%j' access to per-session jobid - if supported
19090         if lctl list_param jobid_this_session > /dev/null 2>&1
19091         then
19092                 lctl set_param jobid_var=session jobid_name="S.%j.%e.%u.%h.E"
19093                 lctl set_param jobid_this_session=$USER
19094
19095                 JOBENV="JOBCOMPLEX"
19096                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
19097
19098                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
19099         fi
19100 }
19101 run_test 205a "Verify job stats"
19102
19103 # LU-13117, LU-13597
19104 test_205b() {
19105         (( $MDS1_VERSION >= $(version_code 2.13.54.91) )) ||
19106                 skip "Need MDS version at least 2.13.54.91"
19107
19108         local job_stats="mdt.*.job_stats"
19109         local old_jobid=$(do_facet mds1 $LCTL get_param jobid_var)
19110
19111         do_facet mds1 $LCTL set_param $job_stats=clear
19112
19113         # Setting jobid_var to USER might not be supported
19114         [[ -n "$old_jobid" ]] && stack_trap "$LCTL set_param $old_jobid"
19115         $LCTL set_param jobid_var=USER || true
19116         stack_trap "$LCTL set_param $($LCTL get_param jobid_name)"
19117         $LCTL set_param jobid_name="%j.%e.%u"
19118
19119         env -i USERTESTJOBSTATS=foolish touch $DIR/$tfile.1
19120         do_facet mds1 $LCTL get_param $job_stats | grep "job_id:.*foolish" &&
19121                 { do_facet mds1 $LCTL get_param $job_stats;
19122                   error "Unexpected jobid found"; }
19123         do_facet mds1 $LCTL get_param $job_stats | grep "open:.*min.*max.*sum"||
19124                 { do_facet mds1 $LCTL get_param $job_stats;
19125                   error "wrong job_stats format found"; }
19126
19127         (( $MDS1_VERSION <= $(version_code 2.15.0) )) &&
19128                 echo "MDS does not yet escape jobid" && return 0
19129         $LCTL set_param jobid_var=TEST205b
19130         env -i TEST205b="has sp" touch $DIR/$tfile.2
19131         do_facet mds1 $LCTL get_param $job_stats | grep "has.*x20sp" ||
19132                 { do_facet mds1 $LCTL get_param $job_stats;
19133                   error "jobid not escaped"; }
19134 }
19135 run_test 205b "Verify job stats jobid and output format"
19136
19137 # LU-13733
19138 test_205c() {
19139         $LCTL set_param llite.*.stats=0
19140         dd if=/dev/zero of=$DIR/$tfile.1 bs=4k count=1
19141         $LCTL get_param llite.*.stats
19142         $LCTL get_param llite.*.stats | grep \
19143                 "write_bytes *1 samples \[bytes\] 4096 4096 4096 16777216" ||
19144                         error "wrong client stats format found"
19145 }
19146 run_test 205c "Verify client stats format"
19147
19148 test_205d() {
19149         local file=$DIR/$tdir/$tfile
19150
19151         (( $MDS1_VERSION >= $(version_code 2.15.52) )) ||
19152                 skip "need lustre >= 2.15.51"
19153         (( $OST1_VERSION >= $(version_code 2.15.52) )) ||
19154                 skip "need lustre >= 2.15.51"
19155         verify_yaml_available || skip_env "YAML verification not installed"
19156
19157         test_mkdir $DIR/$tdir
19158         $LFS setstripe -E 1M -L mdt -E -1 $file || error "setstripe failed"
19159
19160         dd if=/dev/zero of=$file bs=1M count=10 conv=sync ||
19161                 error "failed to write data to $file"
19162         mv $file $file.2
19163
19164         echo -n 'verify rename_stats...'
19165         output=$(do_facet mds1 \
19166                  "$LCTL get_param -n mdt.$FSNAME-MDT0000.rename_stats")
19167         verify_yaml "$output" || error "rename_stats is not valid YAML"
19168         echo " OK"
19169
19170         echo -n 'verify mdt job_stats...'
19171         output=$(do_facet mds1 \
19172                  "$LCTL get_param -n mdt.$FSNAME-MDT0000.job_stats")
19173         verify_yaml "$output" || error "job_stats on mds1 is not valid YAML"
19174         echo " OK"
19175
19176         echo -n 'verify ost job_stats...'
19177         output=$(do_facet ost1 \
19178                  "$LCTL get_param -n obdfilter.$FSNAME-OST0000.job_stats")
19179         verify_yaml "$output" || error "job_stats on ost1 is not valid YAML"
19180         echo " OK"
19181 }
19182 run_test 205d "verify the format of some stats files"
19183
19184 # LU-1480, LU-1773 and LU-1657
19185 test_206() {
19186         mkdir -p $DIR/$tdir
19187         $LFS setstripe -c -1 $DIR/$tdir
19188 #define OBD_FAIL_LOV_INIT 0x1403
19189         $LCTL set_param fail_loc=0xa0001403
19190         $LCTL set_param fail_val=1
19191         touch $DIR/$tdir/$tfile || true
19192 }
19193 run_test 206 "fail lov_init_raid0() doesn't lbug"
19194
19195 test_207a() {
19196         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
19197         local fsz=`stat -c %s $DIR/$tfile`
19198         cancel_lru_locks mdc
19199
19200         # do not return layout in getattr intent
19201 #define OBD_FAIL_MDS_NO_LL_GETATTR 0x170
19202         $LCTL set_param fail_loc=0x170
19203         local sz=`stat -c %s $DIR/$tfile`
19204
19205         [ $fsz -eq $sz ] || error "file size expected $fsz, actual $sz"
19206
19207         rm -rf $DIR/$tfile
19208 }
19209 run_test 207a "can refresh layout at glimpse"
19210
19211 test_207b() {
19212         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
19213         local cksum=`md5sum $DIR/$tfile`
19214         local fsz=`stat -c %s $DIR/$tfile`
19215         cancel_lru_locks mdc
19216         cancel_lru_locks osc
19217
19218         # do not return layout in getattr intent
19219 #define OBD_FAIL_MDS_NO_LL_OPEN 0x171
19220         $LCTL set_param fail_loc=0x171
19221
19222         # it will refresh layout after the file is opened but before read issues
19223         echo checksum is "$cksum"
19224         echo "$cksum" |md5sum -c --quiet || error "file differs"
19225
19226         rm -rf $DIR/$tfile
19227 }
19228 run_test 207b "can refresh layout at open"
19229
19230 test_208() {
19231         # FIXME: in this test suite, only RD lease is used. This is okay
19232         # for now as only exclusive open is supported. After generic lease
19233         # is done, this test suite should be revised. - Jinshan
19234
19235         remote_mds_nodsh && skip "remote MDS with nodsh"
19236         [[ $MDS1_VERSION -ge $(version_code 2.4.52) ]] ||
19237                 skip "Need MDS version at least 2.4.52"
19238
19239         echo "==== test 1: verify get lease work"
19240         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eRE+eU || error "get lease error"
19241
19242         echo "==== test 2: verify lease can be broken by upcoming open"
19243         $MULTIOP $DIR/$tfile oO_RDWR:eR_E-eUc &
19244         local PID=$!
19245         sleep 2
19246
19247         $MULTIOP $DIR/$tfile oO_RDWR:c
19248         kill -USR1 $PID && wait $PID || error "break lease error"
19249
19250         echo "==== test 3: verify lease can't be granted if an open already exists"
19251         $MULTIOP $DIR/$tfile oO_RDWR:_c &
19252         local PID=$!
19253         sleep 2
19254
19255         $MULTIOP $DIR/$tfile oO_RDWR:eReUc && error "apply lease should fail"
19256         kill -USR1 $PID && wait $PID || error "open file error"
19257
19258         echo "==== test 4: lease can sustain over recovery"
19259         $MULTIOP $DIR/$tfile oO_RDWR:eR_E+eUc &
19260         PID=$!
19261         sleep 2
19262
19263         fail mds1
19264
19265         kill -USR1 $PID && wait $PID || error "lease broken over recovery"
19266
19267         echo "==== test 5: lease broken can't be regained by replay"
19268         $MULTIOP $DIR/$tfile oO_RDWR:eR_E-eUc &
19269         PID=$!
19270         sleep 2
19271
19272         # open file to break lease and then recovery
19273         $MULTIOP $DIR/$tfile oO_RDWR:c || error "open file error"
19274         fail mds1
19275
19276         kill -USR1 $PID && wait $PID || error "lease not broken over recovery"
19277
19278         rm -f $DIR/$tfile
19279 }
19280 run_test 208 "Exclusive open"
19281
19282 test_209() {
19283         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep disp_stripe)" ] &&
19284                 skip_env "must have disp_stripe"
19285
19286         touch $DIR/$tfile
19287         sync; sleep 5; sync;
19288
19289         echo 3 > /proc/sys/vm/drop_caches
19290         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
19291                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
19292         req_before=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
19293
19294         # open/close 500 times
19295         for i in $(seq 500); do
19296                 cat $DIR/$tfile
19297         done
19298
19299         echo 3 > /proc/sys/vm/drop_caches
19300         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
19301                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
19302         req_after=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
19303
19304         echo "before: $req_before, after: $req_after"
19305         [ $((req_after - req_before)) -ge 300 ] &&
19306                 error "open/close requests are not freed"
19307         return 0
19308 }
19309 run_test 209 "read-only open/close requests should be freed promptly"
19310
19311 test_210() {
19312         local pid
19313
19314         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eW_E+eUc &
19315         pid=$!
19316         sleep 1
19317
19318         $LFS getstripe $DIR/$tfile
19319         kill -USR1 $pid
19320         wait $pid || error "multiop failed"
19321
19322         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
19323         pid=$!
19324         sleep 1
19325
19326         $LFS getstripe $DIR/$tfile
19327         kill -USR1 $pid
19328         wait $pid || error "multiop failed"
19329 }
19330 run_test 210 "lfs getstripe does not break leases"
19331
19332 test_212() {
19333         size=`date +%s`
19334         size=$((size % 8192 + 1))
19335         dd if=/dev/urandom of=$DIR/f212 bs=1k count=$size
19336         sendfile $DIR/f212 $DIR/f212.xyz || error "sendfile wrong"
19337         rm -f $DIR/f212 $DIR/f212.xyz
19338 }
19339 run_test 212 "Sendfile test ============================================"
19340
19341 test_213() {
19342         dd if=/dev/zero of=$DIR/$tfile bs=4k count=4
19343         cancel_lru_locks osc
19344         lctl set_param fail_loc=0x8000040f
19345         # generate a read lock
19346         cat $DIR/$tfile > /dev/null
19347         # write to the file, it will try to cancel the above read lock.
19348         cat /etc/hosts >> $DIR/$tfile
19349 }
19350 run_test 213 "OSC lock completion and cancel race don't crash - bug 18829"
19351
19352 test_214() { # for bug 20133
19353         mkdir -p $DIR/$tdir/d214c || error "mkdir $DIR/$tdir/d214c failed"
19354         for (( i=0; i < 340; i++ )) ; do
19355                 touch $DIR/$tdir/d214c/a$i
19356         done
19357
19358         ls -l $DIR/$tdir || error "ls -l $DIR/d214p failed"
19359         mv $DIR/$tdir/d214c $DIR/ || error "mv $DIR/d214p/d214c $DIR/ failed"
19360         ls $DIR/d214c || error "ls $DIR/d214c failed"
19361         rm -rf $DIR/$tdir || error "rm -rf $DIR/d214* failed"
19362         rm -rf $DIR/d214* || error "rm -rf $DIR/d214* failed"
19363 }
19364 run_test 214 "hash-indexed directory test - bug 20133"
19365
19366 # having "abc" as 1st arg, creates $TMP/lnet_abc.out and $TMP/lnet_abc.sys
19367 create_lnet_proc_files() {
19368         lctl get_param -n $1 >$TMP/lnet_$1.sys || error "cannot read lnet.$1"
19369 }
19370
19371 # counterpart of create_lnet_proc_files
19372 remove_lnet_proc_files() {
19373         rm -f $TMP/lnet_$1.sys
19374 }
19375
19376 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
19377 # 3rd arg as regexp for body
19378 check_lnet_proc_stats() {
19379         local l=$(cat "$TMP/lnet_$1" |wc -l)
19380         [ $l = 1 ] || (cat "$TMP/lnet_$1" && error "$2 is not of 1 line: $l")
19381
19382         grep -E "$3" "$TMP/lnet_$1" || (cat "$TMP/lnet_$1" && error "$2 misformatted")
19383 }
19384
19385 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
19386 # 3rd arg as regexp for body, 4th arg as regexp for 1st line, 5th arg is
19387 # optional and can be regexp for 2nd line (lnet.routes case)
19388 check_lnet_proc_entry() {
19389         local blp=2          # blp stands for 'position of 1st line of body'
19390         [ -z "$5" ] || blp=3 # lnet.routes case
19391
19392         local l=$(cat "$TMP/lnet_$1" |wc -l)
19393         # subtracting one from $blp because the body can be empty
19394         [ "$l" -ge "$(($blp - 1))" ] || (cat "$TMP/lnet_$1" && error "$2 is too short: $l")
19395
19396         sed -n '1 p' "$TMP/lnet_$1" |grep -E "$4" >/dev/null ||
19397                 (cat "$TMP/lnet_$1" && error "1st line of $2 misformatted")
19398
19399         [ "$5" = "" ] || sed -n '2 p' "$TMP/lnet_$1" |grep -E "$5" >/dev/null ||
19400                 (cat "$TMP/lnet_$1" && error "2nd line of $2 misformatted")
19401
19402         # bail out if any unexpected line happened
19403         sed -n "$blp p" "$TMP/lnet_$1" | grep -Ev "$3"
19404         [ "$?" != 0 ] || error "$2 misformatted"
19405 }
19406
19407 test_215() { # for bugs 18102, 21079, 21517
19408         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19409
19410         local N='(0|[1-9][0-9]*)'       # non-negative numeric
19411         local P='[1-9][0-9]*'           # positive numeric
19412         local I='(0|-?[1-9][0-9]*|NA)'  # any numeric (0 | >0 | <0) or NA if no value
19413         local NET='[a-z][a-z0-9]*'      # LNET net like o2ib2
19414         local ADDR='[0-9.]+'            # LNET addr like 10.0.0.1
19415         local NID="$ADDR@$NET"          # LNET nid like 10.0.0.1@o2ib2
19416
19417         local L1 # regexp for 1st line
19418         local L2 # regexp for 2nd line (optional)
19419         local BR # regexp for the rest (body)
19420
19421         # lnet.stats should look as 11 space-separated non-negative numerics
19422         BR="^$N $N $N $N $N $N $N $N $N $N $N$"
19423         create_lnet_proc_files "stats"
19424         check_lnet_proc_stats "stats.sys" "lnet.stats" "$BR"
19425         remove_lnet_proc_files "stats"
19426
19427         # lnet.routes should look like this:
19428         # Routing disabled/enabled
19429         # net hops priority state router
19430         # where net is a string like tcp0, hops > 0, priority >= 0,
19431         # state is up/down,
19432         # router is a string like 192.168.1.1@tcp2
19433         L1="^Routing (disabled|enabled)$"
19434         L2="^net +hops +priority +state +router$"
19435         BR="^$NET +$N +(0|1) +(up|down) +$NID$"
19436         create_lnet_proc_files "routes"
19437         check_lnet_proc_entry "routes.sys" "lnet.routes" "$BR" "$L1" "$L2"
19438         remove_lnet_proc_files "routes"
19439
19440         # lnet.routers should look like this:
19441         # ref rtr_ref alive_cnt state last_ping ping_sent deadline down_ni router
19442         # where ref > 0, rtr_ref > 0, alive_cnt >= 0, state is up/down,
19443         # last_ping >= 0, ping_sent is boolean (0/1), deadline and down_ni are
19444         # numeric (0 or >0 or <0), router is a string like 192.168.1.1@tcp2
19445         L1="^ref +rtr_ref +alive +router$"
19446         BR="^$P +$P +(up|down) +$NID$"
19447         create_lnet_proc_files "routers"
19448         check_lnet_proc_entry "routers.sys" "lnet.routers" "$BR" "$L1"
19449         remove_lnet_proc_files "routers"
19450
19451         # lnet.peers should look like this:
19452         # nid refs state last max rtr min tx min queue
19453         # where nid is a string like 192.168.1.1@tcp2, refs > 0,
19454         # state is up/down/NA, max >= 0. last, rtr, min, tx, min are
19455         # numeric (0 or >0 or <0), queue >= 0.
19456         L1="^nid +refs +state +last +max +rtr +min +tx +min +queue$"
19457         BR="^$NID +$P +(up|down|NA) +$I +$N +$I +$I +$I +$I +$N$"
19458         create_lnet_proc_files "peers"
19459         check_lnet_proc_entry "peers.sys" "lnet.peers" "$BR" "$L1"
19460         remove_lnet_proc_files "peers"
19461
19462         # lnet.buffers  should look like this:
19463         # pages count credits min
19464         # where pages >=0, count >=0, credits and min are numeric (0 or >0 or <0)
19465         L1="^pages +count +credits +min$"
19466         BR="^ +$N +$N +$I +$I$"
19467         create_lnet_proc_files "buffers"
19468         check_lnet_proc_entry "buffers.sys" "lnet.buffers" "$BR" "$L1"
19469         remove_lnet_proc_files "buffers"
19470
19471         # lnet.nis should look like this:
19472         # nid status alive refs peer rtr max tx min
19473         # where nid is a string like 192.168.1.1@tcp2, status is up/down,
19474         # alive is numeric (0 or >0 or <0), refs >= 0, peer >= 0,
19475         # rtr >= 0, max >=0, tx and min are numeric (0 or >0 or <0).
19476         L1="^nid +status +alive +refs +peer +rtr +max +tx +min$"
19477         BR="^$NID +(up|down) +$I +$N +$N +$N +$N +$I +$I$"
19478         create_lnet_proc_files "nis"
19479         check_lnet_proc_entry "nis.sys" "lnet.nis" "$BR" "$L1"
19480         remove_lnet_proc_files "nis"
19481
19482         # can we successfully write to lnet.stats?
19483         lctl set_param -n stats=0 || error "cannot write to lnet.stats"
19484 }
19485 run_test 215 "lnet exists and has proper content - bugs 18102, 21079, 21517"
19486
19487 test_216() { # bug 20317
19488         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19489         remote_ost_nodsh && skip "remote OST with nodsh"
19490
19491         local node
19492         local facets=$(get_facets OST)
19493         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
19494
19495         save_lustre_params client "osc.*.contention_seconds" > $p
19496         save_lustre_params $facets \
19497                 "ldlm.namespaces.filter-*.max_nolock_bytes" >> $p
19498         save_lustre_params $facets \
19499                 "ldlm.namespaces.filter-*.contended_locks" >> $p
19500         save_lustre_params $facets \
19501                 "ldlm.namespaces.filter-*.contention_seconds" >> $p
19502         clear_stats osc.*.osc_stats
19503
19504         # agressive lockless i/o settings
19505         do_nodes $(comma_list $(osts_nodes)) \
19506                 "lctl set_param -n ldlm.namespaces.*.max_nolock_bytes=2000000 \
19507                         ldlm.namespaces.filter-*.contended_locks=0 \
19508                         ldlm.namespaces.filter-*.contention_seconds=60"
19509         lctl set_param -n osc.*.contention_seconds=60
19510
19511         $DIRECTIO write $DIR/$tfile 0 10 4096
19512         $CHECKSTAT -s 40960 $DIR/$tfile
19513
19514         # disable lockless i/o
19515         do_nodes $(comma_list $(osts_nodes)) \
19516                 "lctl set_param -n ldlm.namespaces.filter-*.max_nolock_bytes=0 \
19517                         ldlm.namespaces.filter-*.contended_locks=32 \
19518                         ldlm.namespaces.filter-*.contention_seconds=0"
19519         lctl set_param -n osc.*.contention_seconds=0
19520         clear_stats osc.*.osc_stats
19521
19522         dd if=/dev/zero of=$DIR/$tfile count=0
19523         $CHECKSTAT -s 0 $DIR/$tfile
19524
19525         restore_lustre_params <$p
19526         rm -f $p
19527         rm $DIR/$tfile
19528 }
19529 run_test 216 "check lockless direct write updates file size and kms correctly"
19530
19531 test_217() { # bug 22430
19532         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19533
19534         local node
19535         local nid
19536
19537         for node in $(nodes_list); do
19538                 nid=$(host_nids_address $node $NETTYPE)
19539                 if [[ $nid = *-* ]] ; then
19540                         echo "lctl ping $(h2nettype $nid)"
19541                         lctl ping $(h2nettype $nid)
19542                 else
19543                         echo "skipping $node (no hyphen detected)"
19544                 fi
19545         done
19546 }
19547 run_test 217 "check lctl ping for hostnames with hiphen ('-')"
19548
19549 test_218() {
19550        # do directio so as not to populate the page cache
19551        log "creating a 10 Mb file"
19552        $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
19553        log "starting reads"
19554        dd if=$DIR/$tfile of=/dev/null bs=4096 &
19555        log "truncating the file"
19556        $MULTIOP $DIR/$tfile oO_TRUNC:c || error "multiop failed while truncating the file"
19557        log "killing dd"
19558        kill %+ || true # reads might have finished
19559        echo "wait until dd is finished"
19560        wait
19561        log "removing the temporary file"
19562        rm -rf $DIR/$tfile || error "tmp file removal failed"
19563 }
19564 run_test 218 "parallel read and truncate should not deadlock"
19565
19566 test_219() {
19567         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19568
19569         # write one partial page
19570         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1
19571         # set no grant so vvp_io_commit_write will do sync write
19572         $LCTL set_param fail_loc=0x411
19573         # write a full page at the end of file
19574         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=1 conv=notrunc
19575
19576         $LCTL set_param fail_loc=0
19577         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=3
19578         $LCTL set_param fail_loc=0x411
19579         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1 seek=2 conv=notrunc
19580
19581         # LU-4201
19582         dd if=/dev/zero of=$DIR/$tfile-2 bs=1024 count=1
19583         $CHECKSTAT -s 1024 $DIR/$tfile-2 || error "checkstat wrong size"
19584 }
19585 run_test 219 "LU-394: Write partial won't cause uncontiguous pages vec at LND"
19586
19587 test_220() { #LU-325
19588         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19589         remote_ost_nodsh && skip "remote OST with nodsh"
19590         remote_mds_nodsh && skip "remote MDS with nodsh"
19591         remote_mgs_nodsh && skip "remote MGS with nodsh"
19592
19593         local OSTIDX=0
19594
19595         # create on MDT0000 so the last_id and next_id are correct
19596         mkdir_on_mdt0 $DIR/$tdir
19597         local OST=$($LFS df $DIR | awk '/OST:'$OSTIDX'/ { print $1 }')
19598         OST=${OST%_UUID}
19599
19600         # on the mdt's osc
19601         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $OST)
19602         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
19603                         osp.$mdtosc_proc1.prealloc_last_id)
19604         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
19605                         osp.$mdtosc_proc1.prealloc_next_id)
19606
19607         $LFS df -i
19608
19609         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=-1
19610         #define OBD_FAIL_OST_ENOINO              0x229
19611         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0x229
19612         create_pool $FSNAME.$TESTNAME || return 1
19613         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $OST || return 2
19614
19615         $LFS setstripe $DIR/$tdir -i $OSTIDX -c 1 -p $FSNAME.$TESTNAME
19616
19617         MDSOBJS=$((last_id - next_id))
19618         echo "preallocated objects on MDS is $MDSOBJS" "($last_id - $next_id)"
19619
19620         blocks=$($LFS df $MOUNT | awk '($1 == '$OSTIDX') { print $4 }')
19621         echo "OST still has $count kbytes free"
19622
19623         echo "create $MDSOBJS files @next_id..."
19624         createmany -o $DIR/$tdir/f $MDSOBJS || return 3
19625
19626         local last_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
19627                         osp.$mdtosc_proc1.prealloc_last_id)
19628         local next_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
19629                         osp.$mdtosc_proc1.prealloc_next_id)
19630
19631         echo "after creation, last_id=$last_id2, next_id=$next_id2"
19632         $LFS df -i
19633
19634         echo "cleanup..."
19635
19636         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=0
19637         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0
19638
19639         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $OST ||
19640                 error "$LCTL pool_remove $FSNAME.$TESTNAME $OST failed"
19641         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
19642                 error "$LCTL pool_destroy $FSNAME.$TESTNAME failed"
19643         echo "unlink $MDSOBJS files @$next_id..."
19644         unlinkmany $DIR/$tdir/f $MDSOBJS || error "unlinkmany failed"
19645 }
19646 run_test 220 "preallocated MDS objects still used if ENOSPC from OST"
19647
19648 test_221() {
19649         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19650
19651         dd if=`which date` of=$MOUNT/date oflag=sync
19652         chmod +x $MOUNT/date
19653
19654         #define OBD_FAIL_LLITE_FAULT_TRUNC_RACE  0x1401
19655         $LCTL set_param fail_loc=0x80001401
19656
19657         $MOUNT/date > /dev/null
19658         rm -f $MOUNT/date
19659 }
19660 run_test 221 "make sure fault and truncate race to not cause OOM"
19661
19662 test_222a () {
19663         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19664
19665         rm -rf $DIR/$tdir
19666         test_mkdir $DIR/$tdir
19667         $LFS setstripe -c 1 -i 0 $DIR/$tdir
19668         createmany -o $DIR/$tdir/$tfile 10
19669         cancel_lru_locks mdc
19670         cancel_lru_locks osc
19671         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
19672         $LCTL set_param fail_loc=0x31a
19673         ls -l $DIR/$tdir > /dev/null || error "AGL for ls failed"
19674         $LCTL set_param fail_loc=0
19675         rm -r $DIR/$tdir
19676 }
19677 run_test 222a "AGL for ls should not trigger CLIO lock failure"
19678
19679 test_222b () {
19680         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19681
19682         rm -rf $DIR/$tdir
19683         test_mkdir $DIR/$tdir
19684         $LFS setstripe -c 1 -i 0 $DIR/$tdir
19685         createmany -o $DIR/$tdir/$tfile 10
19686         cancel_lru_locks mdc
19687         cancel_lru_locks osc
19688         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
19689         $LCTL set_param fail_loc=0x31a
19690         rm -r $DIR/$tdir || error "AGL for rmdir failed"
19691         $LCTL set_param fail_loc=0
19692 }
19693 run_test 222b "AGL for rmdir should not trigger CLIO lock failure"
19694
19695 test_223 () {
19696         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19697
19698         rm -rf $DIR/$tdir
19699         test_mkdir $DIR/$tdir
19700         $LFS setstripe -c 1 -i 0 $DIR/$tdir
19701         createmany -o $DIR/$tdir/$tfile 10
19702         cancel_lru_locks mdc
19703         cancel_lru_locks osc
19704         #define OBD_FAIL_LDLM_AGL_NOLOCK          0x31b
19705         $LCTL set_param fail_loc=0x31b
19706         ls -l $DIR/$tdir > /dev/null || error "reenqueue failed"
19707         $LCTL set_param fail_loc=0
19708         rm -r $DIR/$tdir
19709 }
19710 run_test 223 "osc reenqueue if without AGL lock granted ======================="
19711
19712 test_224a() { # LU-1039, MRP-303
19713         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19714         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB   0x508
19715         $LCTL set_param fail_loc=0x508
19716         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 conv=fsync
19717         $LCTL set_param fail_loc=0
19718         df $DIR
19719 }
19720 run_test 224a "Don't panic on bulk IO failure"
19721
19722 test_224bd_sub() { # LU-1039, MRP-303
19723         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19724         local timeout=$1
19725
19726         shift
19727         dd if=/dev/urandom of=$TMP/$tfile bs=1M count=1
19728
19729         $LFS setstripe -c 1 -i 0 $DIR/$tfile
19730
19731         dd if=$TMP/$tfile of=$DIR/$tfile bs=1M count=1
19732         cancel_lru_locks osc
19733         set_checksums 0
19734         stack_trap "set_checksums $ORIG_CSUM" EXIT
19735         local at_max_saved=0
19736
19737         # adaptive timeouts may prevent seeing the issue
19738         if at_is_enabled; then
19739                 at_max_saved=$(at_max_get mds)
19740                 at_max_set 0 mds client
19741                 stack_trap "at_max_set $at_max_saved mds client" EXIT
19742         fi
19743
19744         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB2   0x515
19745         do_facet ost1 $LCTL set_param fail_val=$timeout fail_loc=0x80000515
19746         dd of=$TMP/$tfile.new if=$DIR/$tfile bs=1M count=1 || "$@"
19747
19748         do_facet ost1 $LCTL set_param fail_loc=0
19749         cmp $TMP/$tfile $TMP/$tfile.new || error "file contents wrong"
19750         df $DIR
19751 }
19752
19753 test_224b() {
19754         test_224bd_sub 3 error "dd failed"
19755 }
19756 run_test 224b "Don't panic on bulk IO failure"
19757
19758 test_224c() { # LU-6441
19759         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19760         remote_mds_nodsh && skip "remote MDS with nodsh"
19761
19762         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
19763         save_writethrough $p
19764         set_cache writethrough on
19765
19766         local pages_per_rpc=$($LCTL get_param osc.*.max_pages_per_rpc)
19767         local at_max=$($LCTL get_param -n at_max)
19768         local timeout=$($LCTL get_param -n timeout)
19769         local test_at="at_max"
19770         local param_at="$FSNAME.sys.at_max"
19771         local test_timeout="timeout"
19772         local param_timeout="$FSNAME.sys.timeout"
19773
19774         $LCTL set_param -n osc.*.max_pages_per_rpc=1024
19775
19776         set_persistent_param_and_check client "$test_at" "$param_at" 0
19777         set_persistent_param_and_check client "$test_timeout" "$param_timeout" 5
19778
19779         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB3 0x520
19780         do_facet ost1 "$LCTL set_param fail_loc=0x520"
19781         $LFS setstripe -c 1 -i 0 $DIR/$tfile
19782         dd if=/dev/zero of=$DIR/$tfile bs=8MB count=1
19783         sync
19784         do_facet ost1 "$LCTL set_param fail_loc=0"
19785
19786         set_persistent_param_and_check client "$test_at" "$param_at" $at_max
19787         set_persistent_param_and_check client "$test_timeout" "$param_timeout" \
19788                 $timeout
19789
19790         $LCTL set_param -n $pages_per_rpc
19791         restore_lustre_params < $p
19792         rm -f $p
19793 }
19794 run_test 224c "Don't hang if one of md lost during large bulk RPC"
19795
19796 test_224d() { # LU-11169
19797         test_224bd_sub $((TIMEOUT + 2)) error "dd failed"
19798 }
19799 run_test 224d "Don't corrupt data on bulk IO timeout"
19800
19801 MDSSURVEY=${MDSSURVEY:-$(which mds-survey 2>/dev/null || true)}
19802 test_225a () {
19803         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19804         if [ -z ${MDSSURVEY} ]; then
19805                 skip_env "mds-survey not found"
19806         fi
19807         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
19808                 skip "Need MDS version at least 2.2.51"
19809
19810         local mds=$(facet_host $SINGLEMDS)
19811         local target=$(do_nodes $mds 'lctl dl' |
19812                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
19813
19814         local cmd1="file_count=1000 thrhi=4"
19815         local cmd2="dir_count=2 layer=mdd stripe_count=0"
19816         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
19817         local cmd="$cmd1 $cmd2 $cmd3"
19818
19819         rm -f ${TMP}/mds_survey*
19820         echo + $cmd
19821         eval $cmd || error "mds-survey with zero-stripe failed"
19822         cat ${TMP}/mds_survey*
19823         rm -f ${TMP}/mds_survey*
19824 }
19825 run_test 225a "Metadata survey sanity with zero-stripe"
19826
19827 test_225b () {
19828         if [ -z ${MDSSURVEY} ]; then
19829                 skip_env "mds-survey not found"
19830         fi
19831         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
19832                 skip "Need MDS version at least 2.2.51"
19833         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19834         remote_mds_nodsh && skip "remote MDS with nodsh"
19835         if [ $($LCTL dl | grep -c osc) -eq 0 ]; then
19836                 skip_env "Need to mount OST to test"
19837         fi
19838
19839         local mds=$(facet_host $SINGLEMDS)
19840         local target=$(do_nodes $mds 'lctl dl' |
19841                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
19842
19843         local cmd1="file_count=1000 thrhi=4"
19844         local cmd2="dir_count=2 layer=mdd stripe_count=1"
19845         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
19846         local cmd="$cmd1 $cmd2 $cmd3"
19847
19848         rm -f ${TMP}/mds_survey*
19849         echo + $cmd
19850         eval $cmd || error "mds-survey with stripe_count failed"
19851         cat ${TMP}/mds_survey*
19852         rm -f ${TMP}/mds_survey*
19853 }
19854 run_test 225b "Metadata survey sanity with stripe_count = 1"
19855
19856 mcreate_path2fid () {
19857         local mode=$1
19858         local major=$2
19859         local minor=$3
19860         local name=$4
19861         local desc=$5
19862         local path=$DIR/$tdir/$name
19863         local fid
19864         local rc
19865         local fid_path
19866
19867         $MCREATE --mode=$1 --major=$2 --minor=$3 $path ||
19868                 error "cannot create $desc"
19869
19870         fid=$($LFS path2fid $path | tr -d '[' | tr -d ']')
19871         rc=$?
19872         [ $rc -ne 0 ] && error "cannot get fid of a $desc"
19873
19874         fid_path=$($LFS fid2path $MOUNT $fid)
19875         rc=$?
19876         [ $rc -ne 0 ] && error "cannot get path of $desc by $DIR $path $fid"
19877
19878         [ "$path" == "$fid_path" ] ||
19879                 error "fid2path returned $fid_path, expected $path"
19880
19881         echo "pass with $path and $fid"
19882 }
19883
19884 test_226a () {
19885         rm -rf $DIR/$tdir
19886         mkdir -p $DIR/$tdir
19887
19888         mcreate_path2fid 0010666 0 0 fifo "FIFO"
19889         mcreate_path2fid 0020666 1 3 null "character special file (null)"
19890         mcreate_path2fid 0020666 1 255 none "character special file (no device)"
19891         mcreate_path2fid 0040666 0 0 dir "directory"
19892         mcreate_path2fid 0060666 7 0 loop0 "block special file (loop)"
19893         mcreate_path2fid 0100666 0 0 file "regular file"
19894         mcreate_path2fid 0120666 0 0 link "symbolic link"
19895         mcreate_path2fid 0140666 0 0 sock "socket"
19896 }
19897 run_test 226a "call path2fid and fid2path on files of all type"
19898
19899 test_226b () {
19900         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19901
19902         local MDTIDX=1
19903
19904         rm -rf $DIR/$tdir
19905         mkdir -p $DIR/$tdir
19906         $LFS setdirstripe -i $MDTIDX $DIR/$tdir/remote_dir ||
19907                 error "create remote directory failed"
19908         mcreate_path2fid 0010666 0 0 "remote_dir/fifo" "FIFO"
19909         mcreate_path2fid 0020666 1 3 "remote_dir/null" \
19910                                 "character special file (null)"
19911         mcreate_path2fid 0020666 1 255 "remote_dir/none" \
19912                                 "character special file (no device)"
19913         mcreate_path2fid 0040666 0 0 "remote_dir/dir" "directory"
19914         mcreate_path2fid 0060666 7 0 "remote_dir/loop0" \
19915                                 "block special file (loop)"
19916         mcreate_path2fid 0100666 0 0 "remote_dir/file" "regular file"
19917         mcreate_path2fid 0120666 0 0 "remote_dir/link" "symbolic link"
19918         mcreate_path2fid 0140666 0 0 "remote_dir/sock" "socket"
19919 }
19920 run_test 226b "call path2fid and fid2path on files of all type under remote dir"
19921
19922 test_226c () {
19923         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19924         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
19925                 skip "Need MDS version at least 2.13.55"
19926
19927         local submnt=/mnt/submnt
19928         local srcfile=/etc/passwd
19929         local dstfile=$submnt/passwd
19930         local path
19931         local fid
19932
19933         rm -rf $DIR/$tdir
19934         rm -rf $submnt
19935         $LFS setdirstripe -c -1 -i 1 $DIR/$tdir ||
19936                 error "create remote directory failed"
19937         mkdir -p $submnt || error "create $submnt failed"
19938         $MOUNT_CMD $MGSNID:/$FSNAME/$tdir $submnt ||
19939                 error "mount $submnt failed"
19940         stack_trap "umount $submnt" EXIT
19941
19942         cp $srcfile $dstfile
19943         fid=$($LFS path2fid $dstfile)
19944         path=$($LFS fid2path $submnt "$fid")
19945         [ "$path" = "$dstfile" ] ||
19946                 error "fid2path $submnt $fid failed ($path != $dstfile)"
19947 }
19948 run_test 226c "call path2fid and fid2path under remote dir with subdir mount"
19949
19950 # LU-1299 Executing or running ldd on a truncated executable does not
19951 # cause an out-of-memory condition.
19952 test_227() {
19953         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19954         [ -z "$(which ldd)" ] && skip_env "should have ldd tool"
19955
19956         dd if=$(which date) of=$MOUNT/date bs=1k count=1
19957         chmod +x $MOUNT/date
19958
19959         $MOUNT/date > /dev/null
19960         ldd $MOUNT/date > /dev/null
19961         rm -f $MOUNT/date
19962 }
19963 run_test 227 "running truncated executable does not cause OOM"
19964
19965 # LU-1512 try to reuse idle OI blocks
19966 test_228a() {
19967         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19968         remote_mds_nodsh && skip "remote MDS with nodsh"
19969         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
19970
19971         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
19972         local myDIR=$DIR/$tdir
19973
19974         mkdir -p $myDIR
19975         #define OBD_FAIL_SEQ_EXHAUST             0x1002
19976         $LCTL set_param fail_loc=0x80001002
19977         createmany -o $myDIR/t- 10000
19978         $LCTL set_param fail_loc=0
19979         # The guard is current the largest FID holder
19980         touch $myDIR/guard
19981         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
19982                     tr -d '[')
19983         local IDX=$(($SEQ % 64))
19984
19985         do_facet $SINGLEMDS sync
19986         # Make sure journal flushed.
19987         sleep 6
19988         local blk1=$(do_facet $SINGLEMDS \
19989                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19990                      grep Blockcount | awk '{print $4}')
19991
19992         # Remove old files, some OI blocks will become idle.
19993         unlinkmany $myDIR/t- 10000
19994         # Create new files, idle OI blocks should be reused.
19995         createmany -o $myDIR/t- 2000
19996         do_facet $SINGLEMDS sync
19997         # Make sure journal flushed.
19998         sleep 6
19999         local blk2=$(do_facet $SINGLEMDS \
20000                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
20001                      grep Blockcount | awk '{print $4}')
20002
20003         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
20004 }
20005 run_test 228a "try to reuse idle OI blocks"
20006
20007 test_228b() {
20008         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20009         remote_mds_nodsh && skip "remote MDS with nodsh"
20010         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
20011
20012         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
20013         local myDIR=$DIR/$tdir
20014
20015         mkdir -p $myDIR
20016         #define OBD_FAIL_SEQ_EXHAUST             0x1002
20017         $LCTL set_param fail_loc=0x80001002
20018         createmany -o $myDIR/t- 10000
20019         $LCTL set_param fail_loc=0
20020         # The guard is current the largest FID holder
20021         touch $myDIR/guard
20022         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
20023                     tr -d '[')
20024         local IDX=$(($SEQ % 64))
20025
20026         do_facet $SINGLEMDS sync
20027         # Make sure journal flushed.
20028         sleep 6
20029         local blk1=$(do_facet $SINGLEMDS \
20030                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
20031                      grep Blockcount | awk '{print $4}')
20032
20033         # Remove old files, some OI blocks will become idle.
20034         unlinkmany $myDIR/t- 10000
20035
20036         # stop the MDT
20037         stop $SINGLEMDS || error "Fail to stop MDT."
20038         # remount the MDT
20039         start $SINGLEMDS $(facet_device $SINGLEMDS) $MDS_MOUNT_OPTS ||
20040                 error "Fail to start MDT."
20041
20042         df $MOUNT || error "Fail to df."
20043         # Create new files, idle OI blocks should be reused.
20044         createmany -o $myDIR/t- 2000
20045         do_facet $SINGLEMDS sync
20046         # Make sure journal flushed.
20047         sleep 6
20048         local blk2=$(do_facet $SINGLEMDS \
20049                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
20050                      grep Blockcount | awk '{print $4}')
20051
20052         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
20053 }
20054 run_test 228b "idle OI blocks can be reused after MDT restart"
20055
20056 #LU-1881
20057 test_228c() {
20058         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20059         remote_mds_nodsh && skip "remote MDS with nodsh"
20060         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
20061
20062         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
20063         local myDIR=$DIR/$tdir
20064
20065         mkdir -p $myDIR
20066         #define OBD_FAIL_SEQ_EXHAUST             0x1002
20067         $LCTL set_param fail_loc=0x80001002
20068         # 20000 files can guarantee there are index nodes in the OI file
20069         createmany -o $myDIR/t- 20000
20070         $LCTL set_param fail_loc=0
20071         # The guard is current the largest FID holder
20072         touch $myDIR/guard
20073         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
20074                     tr -d '[')
20075         local IDX=$(($SEQ % 64))
20076
20077         do_facet $SINGLEMDS sync
20078         # Make sure journal flushed.
20079         sleep 6
20080         local blk1=$(do_facet $SINGLEMDS \
20081                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
20082                      grep Blockcount | awk '{print $4}')
20083
20084         # Remove old files, some OI blocks will become idle.
20085         unlinkmany $myDIR/t- 20000
20086         rm -f $myDIR/guard
20087         # The OI file should become empty now
20088
20089         # Create new files, idle OI blocks should be reused.
20090         createmany -o $myDIR/t- 2000
20091         do_facet $SINGLEMDS sync
20092         # Make sure journal flushed.
20093         sleep 6
20094         local blk2=$(do_facet $SINGLEMDS \
20095                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
20096                      grep Blockcount | awk '{print $4}')
20097
20098         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
20099 }
20100 run_test 228c "NOT shrink the last entry in OI index node to recycle idle leaf"
20101
20102 test_229() { # LU-2482, LU-3448
20103         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20104         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
20105         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
20106                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
20107
20108         rm -f $DIR/$tfile
20109
20110         # Create a file with a released layout and stripe count 2.
20111         $MULTIOP $DIR/$tfile H2c ||
20112                 error "failed to create file with released layout"
20113
20114         $LFS getstripe -v $DIR/$tfile
20115
20116         local pattern=$($LFS getstripe -L $DIR/$tfile)
20117         [ X"$pattern" = X"released" ] || error "pattern error ($pattern)"
20118
20119         local stripe_count=$($LFS getstripe -c $DIR/$tfile) ||
20120                 error "getstripe"
20121         [ $stripe_count -eq 2 ] || error "stripe count not 2 ($stripe_count)"
20122         stat $DIR/$tfile || error "failed to stat released file"
20123
20124         chown $RUNAS_ID $DIR/$tfile ||
20125                 error "chown $RUNAS_ID $DIR/$tfile failed"
20126
20127         chgrp $RUNAS_ID $DIR/$tfile ||
20128                 error "chgrp $RUNAS_ID $DIR/$tfile failed"
20129
20130         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
20131         rm $DIR/$tfile || error "failed to remove released file"
20132 }
20133 run_test 229 "getstripe/stat/rm/attr changes work on released files"
20134
20135 test_230a() {
20136         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20137         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20138         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20139                 skip "Need MDS version at least 2.11.52"
20140
20141         local MDTIDX=1
20142
20143         test_mkdir $DIR/$tdir
20144         test_mkdir -i0 -c1 $DIR/$tdir/test_230_local
20145         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230_local)
20146         [ $mdt_idx -ne 0 ] &&
20147                 error "create local directory on wrong MDT $mdt_idx"
20148
20149         $LFS mkdir -i $MDTIDX $DIR/$tdir/test_230 ||
20150                         error "create remote directory failed"
20151         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230)
20152         [ $mdt_idx -ne $MDTIDX ] &&
20153                 error "create remote directory on wrong MDT $mdt_idx"
20154
20155         createmany -o $DIR/$tdir/test_230/t- 10 ||
20156                 error "create files on remote directory failed"
20157         mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230/t-0)
20158         [ $mdt_idx -ne $MDTIDX ] && error "create files on wrong MDT $mdt_idx"
20159         rm -r $DIR/$tdir || error "unlink remote directory failed"
20160 }
20161 run_test 230a "Create remote directory and files under the remote directory"
20162
20163 test_230b() {
20164         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20165         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20166         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20167                 skip "Need MDS version at least 2.11.52"
20168
20169         local MDTIDX=1
20170         local mdt_index
20171         local i
20172         local file
20173         local pid
20174         local stripe_count
20175         local migrate_dir=$DIR/$tdir/migrate_dir
20176         local other_dir=$DIR/$tdir/other_dir
20177
20178         test_mkdir $DIR/$tdir
20179         test_mkdir -i0 -c1 $migrate_dir
20180         test_mkdir -i0 -c1 $other_dir
20181         for ((i=0; i<10; i++)); do
20182                 mkdir -p $migrate_dir/dir_${i}
20183                 createmany -o $migrate_dir/dir_${i}/f 10 ||
20184                         error "create files under remote dir failed $i"
20185         done
20186
20187         cp /etc/passwd $migrate_dir/$tfile
20188         cp /etc/passwd $other_dir/$tfile
20189         chattr +SAD $migrate_dir
20190         chattr +SAD $migrate_dir/$tfile
20191
20192         local old_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
20193         local old_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
20194         local old_dir_mode=$(stat -c%f $migrate_dir)
20195         local old_file_mode=$(stat -c%f $migrate_dir/$tfile)
20196
20197         mkdir -p $migrate_dir/dir_default_stripe2
20198         $LFS setstripe -c 2 $migrate_dir/dir_default_stripe2
20199         $LFS setstripe -c 2 $migrate_dir/${tfile}_stripe2
20200
20201         mkdir -p $other_dir
20202         ln $migrate_dir/$tfile $other_dir/luna
20203         ln $migrate_dir/$tfile $migrate_dir/sofia
20204         ln $other_dir/$tfile $migrate_dir/david
20205         ln -s $migrate_dir/$tfile $other_dir/zachary
20206         ln -s $migrate_dir/$tfile $migrate_dir/${tfile}_ln
20207         ln -s $other_dir/$tfile $migrate_dir/${tfile}_ln_other
20208
20209         local len
20210         local lnktgt
20211
20212         # inline symlink
20213         for len in 58 59 60; do
20214                 lnktgt=$(str_repeat 'l' $len)
20215                 touch $migrate_dir/$lnktgt
20216                 ln -s $lnktgt $migrate_dir/${len}char_ln
20217         done
20218
20219         # PATH_MAX
20220         for len in 4094 4095; do
20221                 lnktgt=$(str_repeat 'l' $len)
20222                 ln -s $lnktgt $migrate_dir/${len}char_ln
20223         done
20224
20225         # NAME_MAX
20226         for len in 254 255; do
20227                 touch $migrate_dir/$(str_repeat 'l' $len)
20228         done
20229
20230         $LFS migrate -m $MDTIDX $migrate_dir ||
20231                 error "fails on migrating remote dir to MDT1"
20232
20233         echo "migratate to MDT1, then checking.."
20234         for ((i = 0; i < 10; i++)); do
20235                 for file in $(find $migrate_dir/dir_${i}); do
20236                         mdt_index=$($LFS getstripe -m $file)
20237                         # broken symlink getstripe will fail
20238                         [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
20239                                 error "$file is not on MDT${MDTIDX}"
20240                 done
20241         done
20242
20243         # the multiple link file should still in MDT0
20244         mdt_index=$($LFS getstripe -m $migrate_dir/$tfile)
20245         [ $mdt_index == 0 ] ||
20246                 error "$file is not on MDT${MDTIDX}"
20247
20248         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
20249         [ "$old_dir_flag" = "$new_dir_flag" ] ||
20250                 error " expect $old_dir_flag get $new_dir_flag"
20251
20252         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
20253         [ "$old_file_flag" = "$new_file_flag" ] ||
20254                 error " expect $old_file_flag get $new_file_flag"
20255
20256         local new_dir_mode=$(stat -c%f $migrate_dir)
20257         [ "$old_dir_mode" = "$new_dir_mode" ] ||
20258                 error "expect mode $old_dir_mode get $new_dir_mode"
20259
20260         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
20261         [ "$old_file_mode" = "$new_file_mode" ] ||
20262                 error "expect mode $old_file_mode get $new_file_mode"
20263
20264         diff /etc/passwd $migrate_dir/$tfile ||
20265                 error "$tfile different after migration"
20266
20267         diff /etc/passwd $other_dir/luna ||
20268                 error "luna different after migration"
20269
20270         diff /etc/passwd $migrate_dir/sofia ||
20271                 error "sofia different after migration"
20272
20273         diff /etc/passwd $migrate_dir/david ||
20274                 error "david different after migration"
20275
20276         diff /etc/passwd $other_dir/zachary ||
20277                 error "zachary different after migration"
20278
20279         diff /etc/passwd $migrate_dir/${tfile}_ln ||
20280                 error "${tfile}_ln different after migration"
20281
20282         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
20283                 error "${tfile}_ln_other different after migration"
20284
20285         stripe_count=$($LFS getstripe -c $migrate_dir/dir_default_stripe2)
20286         [ $stripe_count = 2 ] ||
20287                 error "dir strpe_count $d != 2 after migration."
20288
20289         stripe_count=$($LFS getstripe -c $migrate_dir/${tfile}_stripe2)
20290         [ $stripe_count = 2 ] ||
20291                 error "file strpe_count $d != 2 after migration."
20292
20293         #migrate back to MDT0
20294         MDTIDX=0
20295
20296         $LFS migrate -m $MDTIDX $migrate_dir ||
20297                 error "fails on migrating remote dir to MDT0"
20298
20299         echo "migrate back to MDT0, checking.."
20300         for file in $(find $migrate_dir); do
20301                 mdt_index=$($LFS getstripe -m $file)
20302                 [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
20303                         error "$file is not on MDT${MDTIDX}"
20304         done
20305
20306         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
20307         [ "$old_dir_flag" = "$new_dir_flag" ] ||
20308                 error " expect $old_dir_flag get $new_dir_flag"
20309
20310         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
20311         [ "$old_file_flag" = "$new_file_flag" ] ||
20312                 error " expect $old_file_flag get $new_file_flag"
20313
20314         local new_dir_mode=$(stat -c%f $migrate_dir)
20315         [ "$old_dir_mode" = "$new_dir_mode" ] ||
20316                 error "expect mode $old_dir_mode get $new_dir_mode"
20317
20318         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
20319         [ "$old_file_mode" = "$new_file_mode" ] ||
20320                 error "expect mode $old_file_mode get $new_file_mode"
20321
20322         diff /etc/passwd ${migrate_dir}/$tfile ||
20323                 error "$tfile different after migration"
20324
20325         diff /etc/passwd ${other_dir}/luna ||
20326                 error "luna different after migration"
20327
20328         diff /etc/passwd ${migrate_dir}/sofia ||
20329                 error "sofia different after migration"
20330
20331         diff /etc/passwd ${other_dir}/zachary ||
20332                 error "zachary different after migration"
20333
20334         diff /etc/passwd $migrate_dir/${tfile}_ln ||
20335                 error "${tfile}_ln different after migration"
20336
20337         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
20338                 error "${tfile}_ln_other different after migration"
20339
20340         stripe_count=$($LFS getstripe -c ${migrate_dir}/dir_default_stripe2)
20341         [ $stripe_count = 2 ] ||
20342                 error "dir strpe_count $d != 2 after migration."
20343
20344         stripe_count=$($LFS getstripe -c ${migrate_dir}/${tfile}_stripe2)
20345         [ $stripe_count = 2 ] ||
20346                 error "file strpe_count $d != 2 after migration."
20347
20348         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20349 }
20350 run_test 230b "migrate directory"
20351
20352 test_230c() {
20353         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20354         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20355         remote_mds_nodsh && skip "remote MDS with nodsh"
20356         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20357                 skip "Need MDS version at least 2.11.52"
20358
20359         local MDTIDX=1
20360         local total=3
20361         local mdt_index
20362         local file
20363         local migrate_dir=$DIR/$tdir/migrate_dir
20364
20365         #If migrating directory fails in the middle, all entries of
20366         #the directory is still accessiable.
20367         test_mkdir $DIR/$tdir
20368         test_mkdir -i0 -c1 $migrate_dir
20369         test_mkdir -i1 -c1 $DIR/$tdir/remote_dir
20370         stat $migrate_dir
20371         createmany -o $migrate_dir/f $total ||
20372                 error "create files under ${migrate_dir} failed"
20373
20374         # fail after migrating top dir, and this will fail only once, so the
20375         # first sub file migration will fail (currently f3), others succeed.
20376         #OBD_FAIL_MIGRATE_ENTRIES       0x1801
20377         do_facet mds1 lctl set_param fail_loc=0x1801
20378         local t=$(ls $migrate_dir | wc -l)
20379         $LFS migrate --mdt-index $MDTIDX $migrate_dir &&
20380                 error "migrate should fail"
20381         local u=$(ls $migrate_dir | wc -l)
20382         [ "$u" == "$t" ] || error "$u != $t during migration"
20383
20384         # add new dir/file should succeed
20385         mkdir $migrate_dir/dir ||
20386                 error "mkdir failed under migrating directory"
20387         touch $migrate_dir/file ||
20388                 error "create file failed under migrating directory"
20389
20390         # add file with existing name should fail
20391         for file in $migrate_dir/f*; do
20392                 stat $file > /dev/null || error "stat $file failed"
20393                 $OPENFILE -f O_CREAT:O_EXCL $file &&
20394                         error "open(O_CREAT|O_EXCL) $file should fail"
20395                 $MULTIOP $file m && error "create $file should fail"
20396                 touch $DIR/$tdir/remote_dir/$tfile ||
20397                         error "touch $tfile failed"
20398                 ln $DIR/$tdir/remote_dir/$tfile $file &&
20399                         error "link $file should fail"
20400                 mdt_index=$($LFS getstripe -m $file)
20401                 if [ $mdt_index == 0 ]; then
20402                         # file failed to migrate is not allowed to rename to
20403                         mv $DIR/$tdir/remote_dir/$tfile $file &&
20404                                 error "rename to $file should fail"
20405                 else
20406                         mv $DIR/$tdir/remote_dir/$tfile $file ||
20407                                 error "rename to $file failed"
20408                 fi
20409                 echo hello >> $file || error "write $file failed"
20410         done
20411
20412         # resume migration with different options should fail
20413         $LFS migrate -m 0 $migrate_dir &&
20414                 error "migrate -m 0 $migrate_dir should fail"
20415
20416         $LFS migrate -m $MDTIDX -c 2 $migrate_dir &&
20417                 error "migrate -c 2 $migrate_dir should fail"
20418
20419         # resume migration should succeed
20420         $LFS migrate -m $MDTIDX $migrate_dir ||
20421                 error "migrate $migrate_dir failed"
20422
20423         echo "Finish migration, then checking.."
20424         for file in $(find $migrate_dir); do
20425                 mdt_index=$($LFS getstripe -m $file)
20426                 [ $mdt_index == $MDTIDX ] ||
20427                         error "$file is not on MDT${MDTIDX}"
20428         done
20429
20430         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20431 }
20432 run_test 230c "check directory accessiblity if migration failed"
20433
20434 test_230d() {
20435         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20436         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20437         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20438                 skip "Need MDS version at least 2.11.52"
20439         # LU-11235
20440         [ "$mds1_FSTYPE" == "zfs" ] && skip "skip ZFS backend"
20441
20442         local migrate_dir=$DIR/$tdir/migrate_dir
20443         local old_index
20444         local new_index
20445         local old_count
20446         local new_count
20447         local new_hash
20448         local mdt_index
20449         local i
20450         local j
20451
20452         old_index=$((RANDOM % MDSCOUNT))
20453         old_count=$((MDSCOUNT - old_index))
20454         new_index=$((RANDOM % MDSCOUNT))
20455         new_count=$((MDSCOUNT - new_index))
20456         new_hash=1 # for all_char
20457
20458         [ $old_count -gt 1 ] && old_count=$((old_count - RANDOM % old_count))
20459         [ $new_count -gt 1 ] && new_count=$((new_count - RANDOM % new_count))
20460
20461         test_mkdir $DIR/$tdir
20462         test_mkdir -i $old_index -c $old_count $migrate_dir
20463
20464         for ((i=0; i<100; i++)); do
20465                 test_mkdir -i0 -c1 $migrate_dir/dir_${i}
20466                 createmany -o $migrate_dir/dir_${i}/f 100 ||
20467                         error "create files under remote dir failed $i"
20468         done
20469
20470         echo -n "Migrate from MDT$old_index "
20471         [ $old_count -gt 1 ] && echo -n "... MDT$((old_index + old_count - 1)) "
20472         echo -n "to MDT$new_index"
20473         [ $new_count -gt 1 ] && echo -n " ... MDT$((new_index + new_count - 1))"
20474         echo
20475
20476         echo "$LFS migrate -m$new_index -c$new_count -H $new_hash $migrate_dir"
20477         $LFS migrate -m $new_index -c $new_count -H $new_hash $migrate_dir ||
20478                 error "migrate remote dir error"
20479
20480         echo "Finish migration, then checking.."
20481         for file in $(find $migrate_dir -maxdepth 1); do
20482                 mdt_index=$($LFS getstripe -m $file)
20483                 if [ $mdt_index -lt $new_index ] ||
20484                    [ $mdt_index -gt $((new_index + new_count - 1)) ]; then
20485                         error "$file is on MDT$mdt_index"
20486                 fi
20487         done
20488
20489         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20490 }
20491 run_test 230d "check migrate big directory"
20492
20493 test_230e() {
20494         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20495         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20496         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20497                 skip "Need MDS version at least 2.11.52"
20498
20499         local i
20500         local j
20501         local a_fid
20502         local b_fid
20503
20504         mkdir_on_mdt0 $DIR/$tdir
20505         mkdir $DIR/$tdir/migrate_dir
20506         mkdir $DIR/$tdir/other_dir
20507         touch $DIR/$tdir/migrate_dir/a
20508         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/b
20509         ls $DIR/$tdir/other_dir
20510
20511         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
20512                 error "migrate dir fails"
20513
20514         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
20515         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
20516
20517         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
20518         [ $mdt_index == 0 ] || error "a is not on MDT0"
20519
20520         $LFS migrate -m 1 $DIR/$tdir/other_dir ||
20521                 error "migrate dir fails"
20522
20523         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir)
20524         [ $mdt_index == 1 ] || error "other_dir is not on MDT1"
20525
20526         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
20527         [ $mdt_index == 1 ] || error "a is not on MDT1"
20528
20529         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir/b)
20530         [ $mdt_index == 1 ] || error "b is not on MDT1"
20531
20532         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
20533         b_fid=$($LFS path2fid $DIR/$tdir/other_dir/b)
20534
20535         [ "$a_fid" = "$b_fid" ] || error "different fid after migration"
20536
20537         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20538 }
20539 run_test 230e "migrate mulitple local link files"
20540
20541 test_230f() {
20542         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20543         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20544         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20545                 skip "Need MDS version at least 2.11.52"
20546
20547         local a_fid
20548         local ln_fid
20549
20550         mkdir -p $DIR/$tdir
20551         mkdir $DIR/$tdir/migrate_dir
20552         $LFS mkdir -i1 $DIR/$tdir/other_dir
20553         touch $DIR/$tdir/migrate_dir/a
20554         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln1
20555         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln2
20556         ls $DIR/$tdir/other_dir
20557
20558         # a should be migrated to MDT1, since no other links on MDT0
20559         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
20560                 error "#1 migrate dir fails"
20561         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
20562         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
20563         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
20564         [ $mdt_index == 1 ] || error "a is not on MDT1"
20565
20566         # a should stay on MDT1, because it is a mulitple link file
20567         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
20568                 error "#2 migrate dir fails"
20569         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
20570         [ $mdt_index == 1 ] || error "a is not on MDT1"
20571
20572         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
20573                 error "#3 migrate dir fails"
20574
20575         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
20576         ln_fid=$($LFS path2fid $DIR/$tdir/other_dir/ln1)
20577         [ "$a_fid" = "$ln_fid" ] || error "different fid after migrate to MDT1"
20578
20579         rm -rf $DIR/$tdir/other_dir/ln1 || error "unlink ln1 fails"
20580         rm -rf $DIR/$tdir/other_dir/ln2 || error "unlink ln2 fails"
20581
20582         # a should be migrated to MDT0, since no other links on MDT1
20583         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
20584                 error "#4 migrate dir fails"
20585         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
20586         [ $mdt_index == 0 ] || error "a is not on MDT0"
20587
20588         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20589 }
20590 run_test 230f "migrate mulitple remote link files"
20591
20592 test_230g() {
20593         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20594         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20595         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20596                 skip "Need MDS version at least 2.11.52"
20597
20598         mkdir -p $DIR/$tdir/migrate_dir
20599
20600         $LFS migrate -m 1000 $DIR/$tdir/migrate_dir &&
20601                 error "migrating dir to non-exist MDT succeeds"
20602         true
20603 }
20604 run_test 230g "migrate dir to non-exist MDT"
20605
20606 test_230h() {
20607         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20608         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20609         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20610                 skip "Need MDS version at least 2.11.52"
20611
20612         local mdt_index
20613
20614         mkdir -p $DIR/$tdir/migrate_dir
20615
20616         $LFS migrate -m1 $DIR &&
20617                 error "migrating mountpoint1 should fail"
20618
20619         $LFS migrate -m1 $DIR/$tdir/.. &&
20620                 error "migrating mountpoint2 should fail"
20621
20622         # same as mv
20623         $LFS migrate -m1 $DIR/$tdir/migrate_dir/.. &&
20624                 error "migrating $tdir/migrate_dir/.. should fail"
20625
20626         true
20627 }
20628 run_test 230h "migrate .. and root"
20629
20630 test_230i() {
20631         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20632         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20633         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20634                 skip "Need MDS version at least 2.11.52"
20635
20636         mkdir -p $DIR/$tdir/migrate_dir
20637
20638         $LFS migrate -m 1 $DIR/$tdir/migrate_dir/ ||
20639                 error "migration fails with a tailing slash"
20640
20641         $LFS migrate -m 0 $DIR/$tdir/migrate_dir// ||
20642                 error "migration fails with two tailing slashes"
20643 }
20644 run_test 230i "lfs migrate -m tolerates trailing slashes"
20645
20646 test_230j() {
20647         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20648         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
20649                 skip "Need MDS version at least 2.11.52"
20650
20651         $LFS mkdir -m 0 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
20652         $LFS setstripe -E 1M -L mdt $DIR/$tdir/$tfile ||
20653                 error "create $tfile failed"
20654         cat /etc/passwd > $DIR/$tdir/$tfile
20655
20656         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
20657
20658         cmp /etc/passwd $DIR/$tdir/$tfile ||
20659                 error "DoM file mismatch after migration"
20660 }
20661 run_test 230j "DoM file data not changed after dir migration"
20662
20663 test_230k() {
20664         [ $MDSCOUNT -lt 4 ] && skip "needs >= 4 MDTs"
20665         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
20666                 skip "Need MDS version at least 2.11.56"
20667
20668         local total=20
20669         local files_on_starting_mdt=0
20670
20671         $LFS mkdir -i -1 -c 2 $DIR/$tdir || error "mkdir failed"
20672         $LFS getdirstripe $DIR/$tdir
20673         for i in $(seq $total); do
20674                 echo $((i*i - i)) > $DIR/$tdir/$tfile.$i || error "write failed"
20675                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
20676                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
20677         done
20678
20679         echo "$files_on_starting_mdt files on MDT0"
20680
20681         $LFS migrate -m 1,3 $DIR/$tdir || error "migrate -m 1,3 failed"
20682         $LFS getdirstripe $DIR/$tdir
20683
20684         files_on_starting_mdt=0
20685         for i in $(seq $total); do
20686                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
20687                         error "file $tfile.$i mismatch after migration"
20688                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 1 ]] &&
20689                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
20690         done
20691
20692         echo "$files_on_starting_mdt files on MDT1 after migration"
20693         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT1"
20694
20695         $LFS migrate -m 0 -c 2 $DIR/$tdir || error "migrate -m 0 -c 2 failed"
20696         $LFS getdirstripe $DIR/$tdir
20697
20698         files_on_starting_mdt=0
20699         for i in $(seq $total); do
20700                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
20701                         error "file $tfile.$i mismatch after 2nd migration"
20702                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
20703                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
20704         done
20705
20706         echo "$files_on_starting_mdt files on MDT0 after 2nd migration"
20707         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT0"
20708
20709         true
20710 }
20711 run_test 230k "file data not changed after dir migration"
20712
20713 test_230l() {
20714         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20715         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
20716                 skip "Need MDS version at least 2.11.56"
20717
20718         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir failed"
20719         createmany -o $DIR/$tdir/f___________________________________ 1000 ||
20720                 error "create files under remote dir failed $i"
20721         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
20722 }
20723 run_test 230l "readdir between MDTs won't crash"
20724
20725 test_230m() {
20726         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20727         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
20728                 skip "Need MDS version at least 2.11.56"
20729
20730         local MDTIDX=1
20731         local mig_dir=$DIR/$tdir/migrate_dir
20732         local longstr="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
20733         local shortstr="b"
20734         local val
20735
20736         echo "Creating files and dirs with xattrs"
20737         test_mkdir $DIR/$tdir
20738         test_mkdir -i0 -c1 $mig_dir
20739         mkdir $mig_dir/dir
20740         setfattr -n user.attr1 -v $longstr $mig_dir/dir ||
20741                 error "cannot set xattr attr1 on dir"
20742         setfattr -n user.attr2 -v $shortstr $mig_dir/dir ||
20743                 error "cannot set xattr attr2 on dir"
20744         touch $mig_dir/dir/f0
20745         setfattr -n user.attr1 -v $longstr $mig_dir/dir/f0 ||
20746                 error "cannot set xattr attr1 on file"
20747         setfattr -n user.attr2 -v $shortstr $mig_dir/dir/f0 ||
20748                 error "cannot set xattr attr2 on file"
20749         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
20750         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
20751         [ "$val" = $longstr ] || error "xattr attr1 not set properly on dir"
20752         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
20753         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on dir"
20754         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
20755         [ "$val" = $longstr ] || error "xattr attr1 not set properly on file"
20756         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
20757         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on file"
20758
20759         echo "Migrating to MDT1"
20760         $LFS migrate -m $MDTIDX $mig_dir ||
20761                 error "fails on migrating dir to MDT1"
20762
20763         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
20764         echo "Checking xattrs"
20765         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
20766         [ "$val" = $longstr ] ||
20767                 error "expecting xattr1 $longstr on dir, found $val"
20768         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
20769         [ "$val" = $shortstr ] ||
20770                 error "expecting xattr2 $shortstr on dir, found $val"
20771         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
20772         [ "$val" = $longstr ] ||
20773                 error "expecting xattr1 $longstr on file, found $val"
20774         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
20775         [ "$val" = $shortstr ] ||
20776                 error "expecting xattr2 $shortstr on file, found $val"
20777 }
20778 run_test 230m "xattrs not changed after dir migration"
20779
20780 test_230n() {
20781         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20782         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
20783                 skip "Need MDS version at least 2.13.53"
20784
20785         $LFS mkdir -i 0 $DIR/$tdir || error "mkdir $tdir failed"
20786         cat /etc/hosts > $DIR/$tdir/$tfile
20787         $LFS mirror extend -N1 $DIR/$tdir/$tfile || error "Mirroring failed"
20788         $LFS migrate -m 1 $DIR/$tdir || error "Migration failed"
20789
20790         cmp /etc/hosts $DIR/$tdir/$tfile ||
20791                 error "File data mismatch after migration"
20792 }
20793 run_test 230n "Dir migration with mirrored file"
20794
20795 test_230o() {
20796         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
20797         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
20798                 skip "Need MDS version at least 2.13.52"
20799
20800         local mdts=$(comma_list $(mdts_nodes))
20801         local timeout=100
20802         local restripe_status
20803         local delta
20804         local i
20805
20806         [[ $mds1_FSTYPE == zfs ]] && timeout=300
20807
20808         # in case "crush" hash type is not set
20809         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
20810
20811         restripe_status=$(do_facet mds1 $LCTL get_param -n \
20812                            mdt.*MDT0000.enable_dir_restripe)
20813         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
20814         stack_trap "do_nodes $mdts $LCTL set_param \
20815                     mdt.*.enable_dir_restripe=$restripe_status"
20816
20817         mkdir $DIR/$tdir
20818         createmany -m $DIR/$tdir/f 100 ||
20819                 error "create files under remote dir failed $i"
20820         createmany -d $DIR/$tdir/d 100 ||
20821                 error "create dirs under remote dir failed $i"
20822
20823         for i in $(seq 2 $MDSCOUNT); do
20824                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
20825                 $LFS setdirstripe -c $i $DIR/$tdir ||
20826                         error "split -c $i $tdir failed"
20827                 wait_update $HOSTNAME \
20828                         "$LFS getdirstripe -H $DIR/$tdir" "crush" $timeout ||
20829                         error "dir split not finished"
20830                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
20831                         awk '/migrate/ {sum += $2} END { print sum }')
20832                 echo "$delta migrated when dir split $((i - 1)) to $i stripes"
20833                 # delta is around total_files/stripe_count
20834                 (( $delta < 200 / (i - 1) + 4 )) ||
20835                         error "$delta files migrated >= $((200 / (i - 1) + 4))"
20836         done
20837 }
20838 run_test 230o "dir split"
20839
20840 test_230p() {
20841         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
20842         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
20843                 skip "Need MDS version at least 2.13.52"
20844
20845         local mdts=$(comma_list $(mdts_nodes))
20846         local timeout=100
20847         local restripe_status
20848         local delta
20849         local c
20850
20851         [[ $mds1_FSTYPE == zfs ]] && timeout=300
20852
20853         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
20854
20855         restripe_status=$(do_facet mds1 $LCTL get_param -n \
20856                            mdt.*MDT0000.enable_dir_restripe)
20857         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
20858         stack_trap "do_nodes $mdts $LCTL set_param \
20859                     mdt.*.enable_dir_restripe=$restripe_status"
20860
20861         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir
20862         createmany -m $DIR/$tdir/f 100 ||
20863                 error "create files under remote dir failed"
20864         createmany -d $DIR/$tdir/d 100 ||
20865                 error "create dirs under remote dir failed"
20866
20867         for c in $(seq $((MDSCOUNT - 1)) -1 1); do
20868                 local mdt_hash="crush"
20869
20870                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
20871                 $LFS setdirstripe -c $c $DIR/$tdir ||
20872                         error "split -c $c $tdir failed"
20873                 if (( MDS1_VERSION >= $(version_code 2.14.51) )); then
20874                         mdt_hash="$mdt_hash,fixed"
20875                 elif [ $c -eq 1 ]; then
20876                         mdt_hash="none"
20877                 fi
20878                 wait_update $HOSTNAME \
20879                         "$LFS getdirstripe -H $DIR/$tdir" $mdt_hash $timeout ||
20880                         error "dir merge not finished"
20881                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
20882                         awk '/migrate/ {sum += $2} END { print sum }')
20883                 echo "$delta migrated when dir merge $((c + 1)) to $c stripes"
20884                 # delta is around total_files/stripe_count
20885                 (( delta < 200 / c + 4 )) ||
20886                         error "$delta files migrated >= $((200 / c + 4))"
20887         done
20888 }
20889 run_test 230p "dir merge"
20890
20891 test_230q() {
20892         (( MDSCOUNT > 1)) || skip "needs >= 2 MDTs"
20893         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
20894                 skip "Need MDS version at least 2.13.52"
20895
20896         local mdts=$(comma_list $(mdts_nodes))
20897         local saved_threshold=$(do_facet mds1 \
20898                         $LCTL get_param -n mdt.*-MDT0000.dir_split_count)
20899         local saved_delta=$(do_facet mds1 \
20900                         $LCTL get_param -n mdt.*-MDT0000.dir_split_delta)
20901         local threshold=100
20902         local delta=2
20903         local total=0
20904         local stripe_count=0
20905         local stripe_index
20906         local nr_files
20907         local create
20908
20909         # test with fewer files on ZFS
20910         [ "$mds1_FSTYPE" == "zfs" ] && threshold=40
20911
20912         stack_trap "do_nodes $mdts $LCTL set_param \
20913                     mdt.*.dir_split_count=$saved_threshold"
20914         stack_trap "do_nodes $mdts $LCTL set_param \
20915                     mdt.*.dir_split_delta=$saved_delta"
20916         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.dir_restripe_nsonly=1"
20917         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_auto_split=1"
20918         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_count=$threshold"
20919         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_delta=$delta"
20920         do_nodes $mdts "$LCTL set_param mdt.*.dir_restripe_nsonly=0"
20921         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
20922
20923         $LFS mkdir -i -1 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
20924         stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
20925
20926         create=$((threshold * 3 / 2))
20927         while [ $stripe_count -lt $MDSCOUNT ]; do
20928                 createmany -m $DIR/$tdir/f $total $create ||
20929                         error "create sub files failed"
20930                 stat $DIR/$tdir > /dev/null
20931                 total=$((total + create))
20932                 stripe_count=$((stripe_count + delta))
20933                 [ $stripe_count -gt $MDSCOUNT ] && stripe_count=$MDSCOUNT
20934
20935                 wait_update $HOSTNAME \
20936                         "$LFS getdirstripe -c $DIR/$tdir" "$stripe_count" 40 ||
20937                         error "stripe count $($LFS getdirstripe -c $DIR/$tdir) != $stripe_count"
20938
20939                 wait_update $HOSTNAME \
20940                         "$LFS getdirstripe -H $DIR/$tdir" "crush" 200 ||
20941                         error "stripe hash $($LFS getdirstripe -H $DIR/$tdir) != crush"
20942
20943                 nr_files=$($LFS find -m 1 $DIR/$tdir | grep -c -w $stripe_index)
20944                 echo "$nr_files/$total files on MDT$stripe_index after split"
20945                 # allow 10% margin of imbalance with crush hash
20946                 (( $nr_files <= $total / $stripe_count + $create / 10)) ||
20947                         error "$nr_files files on MDT$stripe_index after split"
20948
20949                 nr_files=$($LFS find -type f $DIR/$tdir | wc -l)
20950                 [ $nr_files -eq $total ] ||
20951                         error "total sub files $nr_files != $total"
20952         done
20953
20954         (( MDS1_VERSION >= $(version_code 2.14.51) )) || return 0
20955
20956         echo "fixed layout directory won't auto split"
20957         $LFS migrate -m 0 $DIR/$tdir || error "migrate $tdir failed"
20958         wait_update $HOSTNAME "$LFS getdirstripe -H $DIR/$tdir" "crush,fixed" \
20959                 10 || error "stripe hash $($LFS getdirstripe -H $DIR/$tdir)"
20960         wait_update $HOSTNAME "$LFS getdirstripe -c $DIR/$tdir" 1 10 ||
20961                 error "stripe count $($LFS getdirstripe -c $DIR/$tdir)"
20962 }
20963 run_test 230q "dir auto split"
20964
20965 test_230r() {
20966         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
20967         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
20968         [[ $MDS1_VERSION -ge $(version_code 2.13.54) ]] ||
20969                 skip "Need MDS version at least 2.13.54"
20970
20971         # maximum amount of local locks:
20972         # parent striped dir - 2 locks
20973         # new stripe in parent to migrate to - 1 lock
20974         # source and target - 2 locks
20975         # Total 5 locks for regular file
20976         mkdir -p $DIR/$tdir
20977         $LFS mkdir -i1 -c2 $DIR/$tdir/dir1
20978         touch $DIR/$tdir/dir1/eee
20979
20980         # create 4 hardlink for 4 more locks
20981         # Total: 9 locks > RS_MAX_LOCKS (8)
20982         $LFS mkdir -i1 -c1 $DIR/$tdir/dir2
20983         $LFS mkdir -i1 -c1 $DIR/$tdir/dir3
20984         $LFS mkdir -i1 -c1 $DIR/$tdir/dir4
20985         $LFS mkdir -i1 -c1 $DIR/$tdir/dir5
20986         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir2/eee
20987         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir3/eee
20988         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir4/eee
20989         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir5/eee
20990
20991         cancel_lru_locks mdc
20992
20993         $LFS migrate -m1 -c1 $DIR/$tdir/dir1 ||
20994                 error "migrate dir fails"
20995
20996         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20997 }
20998 run_test 230r "migrate with too many local locks"
20999
21000 test_230s() {
21001         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
21002                 skip "Need MDS version at least 2.14.52"
21003
21004         local mdts=$(comma_list $(mdts_nodes))
21005         local restripe_status=$(do_facet mds1 $LCTL get_param -n \
21006                                 mdt.*MDT0000.enable_dir_restripe)
21007
21008         stack_trap "do_nodes $mdts $LCTL set_param \
21009                     mdt.*.enable_dir_restripe=$restripe_status"
21010
21011         local st
21012         for st in 0 1; do
21013                 do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=$st"
21014                 test_mkdir $DIR/$tdir
21015                 $LFS mkdir $DIR/$tdir |& grep "File exists" ||
21016                         error "$LFS mkdir should return EEXIST if target exists"
21017                 rmdir $DIR/$tdir
21018         done
21019 }
21020 run_test 230s "lfs mkdir should return -EEXIST if target exists"
21021
21022 test_230t()
21023 {
21024         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
21025         [[ $MDS1_VERSION -ge $(version_code 2.14.50) ]] ||
21026                 skip "Need MDS version at least 2.14.50"
21027
21028         test_mkdir $DIR/$tdir || error "mkdir $tdir failed"
21029         test_mkdir $DIR/$tdir/subdir || error "mkdir subdir failed"
21030         $LFS project -p 1 -s $DIR/$tdir ||
21031                 error "set $tdir project id failed"
21032         $LFS project -p 2 -s $DIR/$tdir/subdir ||
21033                 error "set subdir project id failed"
21034         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir || error "migrate failed"
21035 }
21036 run_test 230t "migrate directory with project ID set"
21037
21038 test_230u()
21039 {
21040         (( MDSCOUNT > 3 )) || skip_env "needs >= 4 MDTs"
21041         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
21042                 skip "Need MDS version at least 2.14.53"
21043
21044         local count
21045
21046         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
21047         mkdir $DIR/$tdir/sub{0..99} || error "mkdir sub failed"
21048         $LFS migrate -m -1 $DIR/$tdir/sub{0..99} || error "migrate sub failed"
21049         for i in $(seq 0 $((MDSCOUNT - 1))); do
21050                 count=$($LFS getstripe -m $DIR/$tdir/sub* | grep -c ^$i)
21051                 echo "$count dirs migrated to MDT$i"
21052         done
21053         count=$($LFS getstripe -m $DIR/$tdir/sub* | sort -u | wc -l)
21054         (( count >= MDSCOUNT - 1 )) || error "dirs migrated to $count MDTs"
21055 }
21056 run_test 230u "migrate directory by QOS"
21057
21058 test_230v()
21059 {
21060         (( MDSCOUNT > 3 )) || skip_env "needs >= 4 MDTs"
21061         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
21062                 skip "Need MDS version at least 2.14.53"
21063
21064         local count
21065
21066         mkdir $DIR/$tdir || error "mkdir $tdir failed"
21067         mkdir $DIR/$tdir/sub{0..99} || error "mkdir sub failed"
21068         $LFS migrate -m 0,2,1 $DIR/$tdir || error "migrate $tdir failed"
21069         for i in $(seq 0 $((MDSCOUNT - 1))); do
21070                 count=$($LFS getstripe -m $DIR/$tdir/sub* | grep -c ^$i)
21071                 echo "$count subdirs migrated to MDT$i"
21072                 (( i == 3 )) && (( count > 0 )) &&
21073                         error "subdir shouldn't be migrated to MDT3"
21074         done
21075         count=$($LFS getstripe -m $DIR/$tdir/sub* | sort -u | wc -l)
21076         (( count == 3 )) || error "dirs migrated to $count MDTs"
21077 }
21078 run_test 230v "subdir migrated to the MDT where its parent is located"
21079
21080 test_230w() {
21081         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
21082         (( MDS1_VERSION >= $(version_code 2.15.0) )) ||
21083                 skip "Need MDS version at least 2.15.0"
21084
21085         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
21086         createmany -o $DIR/$tdir/f 10 || error "create files failed"
21087         createmany -d $DIR/$tdir/d 10 || error "create dirs failed"
21088
21089         $LFS migrate -m 1 -c $MDSCOUNT -d $DIR/$tdir ||
21090                 error "migrate failed"
21091
21092         (( $($LFS getdirstripe -c $DIR/$tdir) == MDSCOUNT )) ||
21093                 error "$tdir stripe count mismatch"
21094
21095         for i in $(seq 0 9); do
21096                 (( $($LFS getdirstripe -c $DIR/$tdir/d$i) == 0 )) ||
21097                         error "d$i is striped"
21098         done
21099 }
21100 run_test 230w "non-recursive mode dir migration"
21101
21102 test_230x() {
21103         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
21104         (( MDS1_VERSION >= $(version_code 2.15.0) )) ||
21105                 skip "Need MDS version at least 2.15.0"
21106
21107         mkdir -p $DIR/$tdir || error "mkdir failed"
21108         createmany -d $DIR/$tdir/sub 100 || error "createmany failed"
21109
21110         local mdt_name=$(mdtname_from_index 0)
21111         local low=$(do_facet mds2 $LCTL get_param -n \
21112                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low)
21113         local high=$(do_facet mds2 $LCTL get_param -n \
21114                 osp.*$mdt_name-osp-MDT0001.reserved_ino_high)
21115         local ffree=$($LFS df -i $MOUNT | awk "/$mdt_name/ { print \$4 }")
21116         local maxage=$(do_facet mds2 $LCTL get_param -n \
21117                 osp.*$mdt_name-osp-MDT0001.maxage)
21118
21119         stack_trap "do_facet mds2 $LCTL set_param -n \
21120                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low=$low \
21121                 osp.*$mdt_name-osp-MDT0001.reserved_ino_high=$high" EXIT
21122         stack_trap "do_facet mds2 $LCTL set_param -n \
21123                 osp.*$mdt_name-osp-MDT0001.maxage=$maxage" EXIT
21124
21125         do_facet mds2 $LCTL set_param -n \
21126                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low=$((ffree + 1))
21127         do_facet mds2 $LCTL set_param -n osp.*$mdt_name-osp-MDT0001.maxage=1
21128         sleep 4
21129         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir &&
21130                 error "migrate $tdir should fail"
21131
21132         do_facet mds2 $LCTL set_param -n \
21133                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low=$low
21134         do_facet mds2 $LCTL set_param -n \
21135                 osp.*$mdt_name-osp-MDT0001.reserved_ino_high=$high
21136         sleep 4
21137         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir ||
21138                 error "migrate failed"
21139         (( $($LFS getdirstripe -c $DIR/$tdir) == $MDSCOUNT )) ||
21140                 error "$tdir stripe count mismatch"
21141 }
21142 run_test 230x "dir migration check space"
21143
21144 test_231a()
21145 {
21146         # For simplicity this test assumes that max_pages_per_rpc
21147         # is the same across all OSCs
21148         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
21149         local bulk_size=$((max_pages * PAGE_SIZE))
21150         local brw_size=$(do_facet ost1 $LCTL get_param -n obdfilter.*.brw_size |
21151                                        head -n 1)
21152
21153         mkdir -p $DIR/$tdir
21154         $LFS setstripe -S ${brw_size}M $DIR/$tdir ||
21155                 error "failed to set stripe with -S ${brw_size}M option"
21156
21157         # clear the OSC stats
21158         $LCTL set_param osc.*.stats=0 &>/dev/null
21159         stop_writeback
21160
21161         # Client writes $bulk_size - there must be 1 rpc for $max_pages.
21162         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=$bulk_size count=1 \
21163                 oflag=direct &>/dev/null || error "dd failed"
21164
21165         sync; sleep 1; sync # just to be safe
21166         local nrpcs=$($LCTL get_param osc.*.stats |awk '/ost_write/ {print $2}')
21167         if [ x$nrpcs != "x1" ]; then
21168                 $LCTL get_param osc.*.stats
21169                 error "found $nrpcs ost_write RPCs, not 1 as expected"
21170         fi
21171
21172         start_writeback
21173         # Drop the OSC cache, otherwise we will read from it
21174         cancel_lru_locks osc
21175
21176         # clear the OSC stats
21177         $LCTL set_param osc.*.stats=0 &>/dev/null
21178
21179         # Client reads $bulk_size.
21180         dd if=$DIR/$tdir/$tfile of=/dev/null bs=$bulk_size count=1 \
21181                 iflag=direct &>/dev/null || error "dd failed"
21182
21183         nrpcs=$($LCTL get_param osc.*.stats | awk '/ost_read/ { print $2 }')
21184         if [ x$nrpcs != "x1" ]; then
21185                 $LCTL get_param osc.*.stats
21186                 error "found $nrpcs ost_read RPCs, not 1 as expected"
21187         fi
21188 }
21189 run_test 231a "checking that reading/writing of BRW RPC size results in one RPC"
21190
21191 test_231b() {
21192         mkdir -p $DIR/$tdir
21193         local i
21194         for i in {0..1023}; do
21195                 dd if=/dev/zero of=$DIR/$tdir/$tfile conv=notrunc \
21196                         seek=$((2 * i)) bs=4096 count=1 &>/dev/null ||
21197                         error "dd of=$DIR/$tdir/$tfile seek=$((2 * i)) failed"
21198         done
21199         sync
21200 }
21201 run_test 231b "must not assert on fully utilized OST request buffer"
21202
21203 test_232a() {
21204         mkdir -p $DIR/$tdir
21205         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
21206
21207         #define OBD_FAIL_LDLM_OST_LVB            0x31c
21208         do_facet ost1 $LCTL set_param fail_loc=0x31c
21209
21210         # ignore dd failure
21211         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1 || true
21212
21213         do_facet ost1 $LCTL set_param fail_loc=0
21214         umount_client $MOUNT || error "umount failed"
21215         mount_client $MOUNT || error "mount failed"
21216         stop ost1 || error "cannot stop ost1"
21217         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
21218 }
21219 run_test 232a "failed lock should not block umount"
21220
21221 test_232b() {
21222         [ $MDS1_VERSION -ge $(version_code 2.10.58) ] ||
21223                 skip "Need MDS version at least 2.10.58"
21224
21225         mkdir -p $DIR/$tdir
21226         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
21227         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1
21228         sync
21229         cancel_lru_locks osc
21230
21231         #define OBD_FAIL_LDLM_OST_LVB            0x31c
21232         do_facet ost1 $LCTL set_param fail_loc=0x31c
21233
21234         # ignore failure
21235         $LFS data_version $DIR/$tdir/$tfile || true
21236
21237         do_facet ost1 $LCTL set_param fail_loc=0
21238         umount_client $MOUNT || error "umount failed"
21239         mount_client $MOUNT || error "mount failed"
21240         stop ost1 || error "cannot stop ost1"
21241         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
21242 }
21243 run_test 232b "failed data version lock should not block umount"
21244
21245 test_233a() {
21246         [ $MDS1_VERSION -ge $(version_code 2.3.64) ] ||
21247                 skip "Need MDS version at least 2.3.64"
21248         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
21249
21250         local fid=$($LFS path2fid $MOUNT)
21251
21252         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
21253                 error "cannot access $MOUNT using its FID '$fid'"
21254 }
21255 run_test 233a "checking that OBF of the FS root succeeds"
21256
21257 test_233b() {
21258         [ $MDS1_VERSION -ge $(version_code 2.5.90) ] ||
21259                 skip "Need MDS version at least 2.5.90"
21260         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
21261
21262         local fid=$($LFS path2fid $MOUNT/.lustre)
21263
21264         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
21265                 error "cannot access $MOUNT/.lustre using its FID '$fid'"
21266
21267         fid=$($LFS path2fid $MOUNT/.lustre/fid)
21268         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
21269                 error "cannot access $MOUNT/.lustre/fid using its FID '$fid'"
21270 }
21271 run_test 233b "checking that OBF of the FS .lustre succeeds"
21272
21273 test_234() {
21274         local p="$TMP/sanityN-$TESTNAME.parameters"
21275         save_lustre_params client "llite.*.xattr_cache" > $p
21276         lctl set_param llite.*.xattr_cache 1 ||
21277                 skip_env "xattr cache is not supported"
21278
21279         mkdir -p $DIR/$tdir || error "mkdir failed"
21280         touch $DIR/$tdir/$tfile || error "touch failed"
21281         # OBD_FAIL_LLITE_XATTR_ENOMEM
21282         $LCTL set_param fail_loc=0x1405
21283         getfattr -n user.attr $DIR/$tdir/$tfile &&
21284                 error "getfattr should have failed with ENOMEM"
21285         $LCTL set_param fail_loc=0x0
21286         rm -rf $DIR/$tdir
21287
21288         restore_lustre_params < $p
21289         rm -f $p
21290 }
21291 run_test 234 "xattr cache should not crash on ENOMEM"
21292
21293 test_235() {
21294         [ $MDS1_VERSION -lt $(version_code 2.4.52) ] &&
21295                 skip "Need MDS version at least 2.4.52"
21296
21297         flock_deadlock $DIR/$tfile
21298         local RC=$?
21299         case $RC in
21300                 0)
21301                 ;;
21302                 124) error "process hangs on a deadlock"
21303                 ;;
21304                 *) error "error executing flock_deadlock $DIR/$tfile"
21305                 ;;
21306         esac
21307 }
21308 run_test 235 "LU-1715: flock deadlock detection does not work properly"
21309
21310 #LU-2935
21311 test_236() {
21312         check_swap_layouts_support
21313
21314         local ref1=/etc/passwd
21315         local ref2=/etc/group
21316         local file1=$DIR/$tdir/f1
21317         local file2=$DIR/$tdir/f2
21318
21319         test_mkdir -c1 $DIR/$tdir
21320         $LFS setstripe -c 1 $file1 || error "cannot setstripe on '$file1': rc = $?"
21321         cp $ref1 $file1 || error "cp $ref1 $file1 failed: rc = $?"
21322         $LFS setstripe -c 2 $file2 || error "cannot setstripe on '$file2': rc = $?"
21323         cp $ref2 $file2 || error "cp $ref2 $file2 failed: rc = $?"
21324         local fd=$(free_fd)
21325         local cmd="exec $fd<>$file2"
21326         eval $cmd
21327         rm $file2
21328         $LFS swap_layouts $file1 /proc/self/fd/${fd} ||
21329                 error "cannot swap layouts of '$file1' and /proc/self/fd/${fd}"
21330         cmd="exec $fd>&-"
21331         eval $cmd
21332         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
21333
21334         #cleanup
21335         rm -rf $DIR/$tdir
21336 }
21337 run_test 236 "Layout swap on open unlinked file"
21338
21339 # LU-4659 linkea consistency
21340 test_238() {
21341         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
21342                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
21343                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
21344                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
21345
21346         touch $DIR/$tfile
21347         ln $DIR/$tfile $DIR/$tfile.lnk
21348         touch $DIR/$tfile.new
21349         mv $DIR/$tfile.new $DIR/$tfile
21350         local fid1=$($LFS path2fid $DIR/$tfile)
21351         local fid2=$($LFS path2fid $DIR/$tfile.lnk)
21352         local path1=$($LFS fid2path $FSNAME "$fid1")
21353         [ $tfile == $path1 ] || error "linkea inconsistent: $tfile $fid1 $path1"
21354         local path2=$($LFS fid2path $FSNAME "$fid2")
21355         [ $tfile.lnk == $path2 ] ||
21356                 error "linkea inconsistent: $tfile.lnk $fid2 $path2!"
21357         rm -f $DIR/$tfile*
21358 }
21359 run_test 238 "Verify linkea consistency"
21360
21361 test_239A() { # was test_239
21362         [ $MDS1_VERSION -lt $(version_code 2.5.60) ] &&
21363                 skip "Need MDS version at least 2.5.60"
21364
21365         local list=$(comma_list $(mdts_nodes))
21366
21367         mkdir -p $DIR/$tdir
21368         createmany -o $DIR/$tdir/f- 5000
21369         unlinkmany $DIR/$tdir/f- 5000
21370         [ $MDS1_VERSION -gt $(version_code 2.10.4) ] &&
21371                 do_nodes $list "lctl set_param -n osp.*.force_sync=1"
21372         changes=$(do_nodes $list "lctl get_param -n osp.*MDT*.sync_changes \
21373                         osp.*MDT*.sync_in_flight" | calc_sum)
21374         [ "$changes" -eq 0 ] || error "$changes not synced"
21375 }
21376 run_test 239A "osp_sync test"
21377
21378 test_239a() { #LU-5297
21379         remote_mds_nodsh && skip "remote MDS with nodsh"
21380
21381         touch $DIR/$tfile
21382         #define OBD_FAIL_OSP_CHECK_INVALID_REC     0x2100
21383         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2100
21384         chgrp $RUNAS_GID $DIR/$tfile
21385         wait_delete_completed
21386 }
21387 run_test 239a "process invalid osp sync record correctly"
21388
21389 test_239b() { #LU-5297
21390         remote_mds_nodsh && skip "remote MDS with nodsh"
21391
21392         touch $DIR/$tfile1
21393         #define OBD_FAIL_OSP_CHECK_ENOMEM     0x2101
21394         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2101
21395         chgrp $RUNAS_GID $DIR/$tfile1
21396         wait_delete_completed
21397         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
21398         touch $DIR/$tfile2
21399         chgrp $RUNAS_GID $DIR/$tfile2
21400         wait_delete_completed
21401 }
21402 run_test 239b "process osp sync record with ENOMEM error correctly"
21403
21404 test_240() {
21405         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21406         remote_mds_nodsh && skip "remote MDS with nodsh"
21407
21408         mkdir -p $DIR/$tdir
21409
21410         $LFS mkdir -i 0 $DIR/$tdir/d0 ||
21411                 error "failed to mkdir $DIR/$tdir/d0 on MDT0"
21412         $LFS mkdir -i 1 $DIR/$tdir/d0/d1 ||
21413                 error "failed to mkdir $DIR/$tdir/d0/d1 on MDT1"
21414
21415         umount_client $MOUNT || error "umount failed"
21416         #define OBD_FAIL_TGT_DELAY_CONDITIONAL   0x713
21417         do_facet mds2 lctl set_param fail_loc=0x713 fail_val=1
21418         mount_client $MOUNT || error "failed to mount client"
21419
21420         echo "stat $DIR/$tdir/d0/d1, should not fail/ASSERT"
21421         stat $DIR/$tdir/d0/d1 || error "fail to stat $DIR/$tdir/d0/d1"
21422 }
21423 run_test 240 "race between ldlm enqueue and the connection RPC (no ASSERT)"
21424
21425 test_241_bio() {
21426         local count=$1
21427         local bsize=$2
21428
21429         for LOOP in $(seq $count); do
21430                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 2>/dev/null
21431                 cancel_lru_locks $OSC || true
21432         done
21433 }
21434
21435 test_241_dio() {
21436         local count=$1
21437         local bsize=$2
21438
21439         for LOOP in $(seq $1); do
21440                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 iflag=direct \
21441                         2>/dev/null
21442         done
21443 }
21444
21445 test_241a() { # was test_241
21446         local bsize=$PAGE_SIZE
21447
21448         (( bsize < 40960 )) && bsize=40960
21449         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
21450         ls -la $DIR/$tfile
21451         cancel_lru_locks $OSC
21452         test_241_bio 1000 $bsize &
21453         PID=$!
21454         test_241_dio 1000 $bsize
21455         wait $PID
21456 }
21457 run_test 241a "bio vs dio"
21458
21459 test_241b() {
21460         local bsize=$PAGE_SIZE
21461
21462         (( bsize < 40960 )) && bsize=40960
21463         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
21464         ls -la $DIR/$tfile
21465         test_241_dio 1000 $bsize &
21466         PID=$!
21467         test_241_dio 1000 $bsize
21468         wait $PID
21469 }
21470 run_test 241b "dio vs dio"
21471
21472 test_242() {
21473         remote_mds_nodsh && skip "remote MDS with nodsh"
21474
21475         mkdir_on_mdt0 $DIR/$tdir
21476         touch $DIR/$tdir/$tfile
21477
21478         #define OBD_FAIL_MDS_READPAGE_PACK      0x105
21479         do_facet mds1 lctl set_param fail_loc=0x105
21480         /bin/ls $DIR/$tdir && error "ls $DIR/$tdir should fail"
21481
21482         do_facet mds1 lctl set_param fail_loc=0
21483         /bin/ls $DIR/$tdir || error "ls $DIR/$tdir failed"
21484 }
21485 run_test 242 "mdt_readpage failure should not cause directory unreadable"
21486
21487 test_243()
21488 {
21489         test_mkdir $DIR/$tdir
21490         group_lock_test -d $DIR/$tdir || error "A group lock test failed"
21491 }
21492 run_test 243 "various group lock tests"
21493
21494 test_244a()
21495 {
21496         test_mkdir $DIR/$tdir
21497         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=35
21498         sendfile_grouplock $DIR/$tdir/$tfile || \
21499                 error "sendfile+grouplock failed"
21500         rm -rf $DIR/$tdir
21501 }
21502 run_test 244a "sendfile with group lock tests"
21503
21504 test_244b()
21505 {
21506         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
21507
21508         local threads=50
21509         local size=$((1024*1024))
21510
21511         test_mkdir $DIR/$tdir
21512         for i in $(seq 1 $threads); do
21513                 local file=$DIR/$tdir/file_$((i / 10))
21514                 $MULTIOP $file OG1234w$size_$((i % 3))w$size_$((i % 4))g1234c &
21515                 local pids[$i]=$!
21516         done
21517         for i in $(seq 1 $threads); do
21518                 wait ${pids[$i]}
21519         done
21520 }
21521 run_test 244b "multi-threaded write with group lock"
21522
21523 test_245a() {
21524         local flagname="multi_mod_rpcs"
21525         local connect_data_name="max_mod_rpcs"
21526         local out
21527
21528         # check if multiple modify RPCs flag is set
21529         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import |
21530                 grep "connect_flags:")
21531         echo "$out"
21532
21533         echo "$out" | grep -qw $flagname
21534         if [ $? -ne 0 ]; then
21535                 echo "connect flag $flagname is not set"
21536                 return
21537         fi
21538
21539         # check if multiple modify RPCs data is set
21540         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import)
21541         echo "$out"
21542
21543         echo "$out" | grep -qw $connect_data_name ||
21544                 error "import should have connect data $connect_data_name"
21545 }
21546 run_test 245a "check mdc connection flag/data: multiple modify RPCs"
21547
21548 test_245b() {
21549         local flagname="multi_mod_rpcs"
21550         local connect_data_name="max_mod_rpcs"
21551         local out
21552
21553         remote_mds_nodsh && skip "remote MDS with nodsh"
21554         [[ $MDSCOUNT -ge 2 ]] || skip "needs >= 2 MDTs"
21555
21556         # check if multiple modify RPCs flag is set
21557         out=$(do_facet mds1 \
21558               $LCTL get_param osp.$FSNAME-MDT0001-osp-MDT0000.import |
21559               grep "connect_flags:")
21560         echo "$out"
21561
21562         [[ "$out" =~ $flagname ]] || skip "connect flag $flagname is not set"
21563
21564         # check if multiple modify RPCs data is set
21565         out=$(do_facet mds1 \
21566               $LCTL get_param osp.$FSNAME-MDT0001-osp-MDT0000.import)
21567
21568         [[ "$out" =~ $connect_data_name ]] ||
21569                 {
21570                         echo "$out"
21571                         error "missing connect data $connect_data_name"
21572                 }
21573 }
21574 run_test 245b "check osp connection flag/data: multiple modify RPCs"
21575
21576 cleanup_247() {
21577         local submount=$1
21578
21579         trap 0
21580         umount_client $submount
21581         rmdir $submount
21582 }
21583
21584 test_247a() {
21585         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
21586                 grep -q subtree ||
21587                 skip_env "Fileset feature is not supported"
21588
21589         local submount=${MOUNT}_$tdir
21590
21591         mkdir $MOUNT/$tdir
21592         mkdir -p $submount || error "mkdir $submount failed"
21593         FILESET="$FILESET/$tdir" mount_client $submount ||
21594                 error "mount $submount failed"
21595         trap "cleanup_247 $submount" EXIT
21596         echo foo > $submount/$tfile || error "write $submount/$tfile failed"
21597         [ $(cat $MOUNT/$tdir/$tfile) = "foo" ] ||
21598                 error "read $MOUNT/$tdir/$tfile failed"
21599         cleanup_247 $submount
21600 }
21601 run_test 247a "mount subdir as fileset"
21602
21603 test_247b() {
21604         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
21605                 skip_env "Fileset feature is not supported"
21606
21607         local submount=${MOUNT}_$tdir
21608
21609         rm -rf $MOUNT/$tdir
21610         mkdir -p $submount || error "mkdir $submount failed"
21611         SKIP_FILESET=1
21612         FILESET="$FILESET/$tdir" mount_client $submount &&
21613                 error "mount $submount should fail"
21614         rmdir $submount
21615 }
21616 run_test 247b "mount subdir that dose not exist"
21617
21618 test_247c() {
21619         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
21620                 skip_env "Fileset feature is not supported"
21621
21622         local submount=${MOUNT}_$tdir
21623
21624         mkdir -p $MOUNT/$tdir/dir1
21625         mkdir -p $submount || error "mkdir $submount failed"
21626         trap "cleanup_247 $submount" EXIT
21627         FILESET="$FILESET/$tdir" mount_client $submount ||
21628                 error "mount $submount failed"
21629         local fid=$($LFS path2fid $MOUNT/)
21630         $LFS fid2path $submount $fid && error "fid2path should fail"
21631         cleanup_247 $submount
21632 }
21633 run_test 247c "running fid2path outside subdirectory root"
21634
21635 test_247d() {
21636         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
21637                 skip "Fileset feature is not supported"
21638
21639         local submount=${MOUNT}_$tdir
21640
21641         mkdir -p $MOUNT/$tdir/dir1
21642         mkdir -p $submount || error "mkdir $submount failed"
21643         FILESET="$FILESET/$tdir" mount_client $submount ||
21644                 error "mount $submount failed"
21645         trap "cleanup_247 $submount" EXIT
21646
21647         local td=$submount/dir1
21648         local fid=$($LFS path2fid $td)
21649         [ -z "$fid" ] && error "path2fid unable to get $td FID"
21650
21651         # check that we get the same pathname back
21652         local rootpath
21653         local found
21654         for rootpath in "$submount" "$submount///" "$submount/dir1"; do
21655                 echo "$rootpath $fid"
21656                 found=$($LFS fid2path $rootpath "$fid")
21657                 [ -n "$found" ] || error "fid2path should succeed"
21658                 [ "$found" == "$td" ] || error "fid2path $found != $td"
21659         done
21660         # check wrong root path format
21661         rootpath=$submount"_wrong"
21662         found=$($LFS fid2path $rootpath "$fid")
21663         [ -z "$found" ] || error "fid2path should fail ($rootpath != $submount)"
21664
21665         cleanup_247 $submount
21666 }
21667 run_test 247d "running fid2path inside subdirectory root"
21668
21669 # LU-8037
21670 test_247e() {
21671         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
21672                 grep -q subtree ||
21673                 skip "Fileset feature is not supported"
21674
21675         local submount=${MOUNT}_$tdir
21676
21677         mkdir $MOUNT/$tdir
21678         mkdir -p $submount || error "mkdir $submount failed"
21679         FILESET="$FILESET/.." mount_client $submount &&
21680                 error "mount $submount should fail"
21681         rmdir $submount
21682 }
21683 run_test 247e "mount .. as fileset"
21684
21685 test_247f() {
21686         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21687         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
21688                 skip "Need at least version 2.13.52"
21689         [ $CLIENT_VERSION -lt $(version_code 2.14.50) ] &&
21690                 skip "Need at least version 2.14.50"
21691         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
21692                 grep -q subtree ||
21693                 skip "Fileset feature is not supported"
21694
21695         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
21696         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote ||
21697                 error "mkdir remote failed"
21698         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote/subdir ||
21699                 error "mkdir remote/subdir failed"
21700         $LFS mkdir -i 0 -c $MDSCOUNT $DIR/$tdir/striped ||
21701                 error "mkdir striped failed"
21702         mkdir $DIR/$tdir/striped/subdir || error "mkdir striped/subdir failed"
21703
21704         local submount=${MOUNT}_$tdir
21705
21706         mkdir -p $submount || error "mkdir $submount failed"
21707         stack_trap "rmdir $submount"
21708
21709         local dir
21710         local stat
21711         local fileset=$FILESET
21712         local mdts=$(comma_list $(mdts_nodes))
21713
21714         stat=$(do_facet mds1 $LCTL get_param -n \
21715                 mdt.*MDT0000.enable_remote_subdir_mount)
21716         stack_trap "do_nodes $mdts $LCTL set_param \
21717                 mdt.*.enable_remote_subdir_mount=$stat"
21718
21719         do_nodes $mdts "$LCTL set_param mdt.*.enable_remote_subdir_mount=0"
21720         stack_trap "umount_client $submount"
21721         FILESET="$fileset/$tdir/remote" mount_client $submount &&
21722                 error "mount remote dir $dir should fail"
21723
21724         for dir in $tdir/remote/subdir $tdir/striped $tdir/striped/subdir \
21725                 $tdir/striped/. ; do
21726                 FILESET="$fileset/$dir" mount_client $submount ||
21727                         error "mount $dir failed"
21728                 umount_client $submount
21729         done
21730
21731         do_nodes $mdts "$LCTL set_param mdt.*.enable_remote_subdir_mount=1"
21732         FILESET="$fileset/$tdir/remote" mount_client $submount ||
21733                 error "mount $tdir/remote failed"
21734 }
21735 run_test 247f "mount striped or remote directory as fileset"
21736
21737 test_247g() {
21738         [ $MDSCOUNT -lt 4 ] && skip_env "needs >= 4 MDTs"
21739         [ $CLIENT_VERSION -lt $(version_code 2.14.50) ] &&
21740                 skip "Need at least version 2.14.50"
21741
21742         $LFS mkdir -i 0 -c 4 -H fnv_1a_64 $DIR/$tdir ||
21743                 error "mkdir $tdir failed"
21744         touch $DIR/$tdir/$tfile || error "touch $tfile failed"
21745
21746         local submount=${MOUNT}_$tdir
21747
21748         mkdir -p $submount || error "mkdir $submount failed"
21749         stack_trap "rmdir $submount"
21750
21751         FILESET="$fileset/$tdir" mount_client $submount ||
21752                 error "mount $dir failed"
21753         stack_trap "umount $submount"
21754
21755         local mdts=$(comma_list $(mdts_nodes))
21756
21757         local nrpcs
21758
21759         stat $submount > /dev/null
21760         cancel_lru_locks $MDC
21761         stat $submount > /dev/null
21762         stat $submount/$tfile > /dev/null
21763         do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear > /dev/null"
21764         stat $submount/$tfile > /dev/null
21765         nrpcs=$(do_nodes $mdts "lctl get_param -n mdt.*.md_stats" |
21766                 awk '/getattr/ {sum += $2} END {print sum}')
21767
21768         [ -z "$nrpcs" ] || error "$nrpcs extra getattr sent"
21769 }
21770 run_test 247g "mount striped directory as fileset caches ROOT lookup lock"
21771
21772 test_248a() {
21773         local fast_read_sav=$($LCTL get_param -n llite.*.fast_read 2>/dev/null)
21774         [ -z "$fast_read_sav" ] && skip "no fast read support"
21775
21776         # create a large file for fast read verification
21777         dd if=/dev/zero of=$DIR/$tfile bs=1M count=128 > /dev/null 2>&1
21778
21779         # make sure the file is created correctly
21780         $CHECKSTAT -s $((128*1024*1024)) $DIR/$tfile ||
21781                 { rm -f $DIR/$tfile; skip "file creation error"; }
21782
21783         echo "Test 1: verify that fast read is 4 times faster on cache read"
21784
21785         # small read with fast read enabled
21786         $LCTL set_param -n llite.*.fast_read=1
21787         local t_fast=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
21788                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
21789                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
21790         # small read with fast read disabled
21791         $LCTL set_param -n llite.*.fast_read=0
21792         local t_slow=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
21793                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
21794                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
21795
21796         # verify that fast read is 4 times faster for cache read
21797         [ $(bc <<< "4 * $t_fast < $t_slow") -eq 1 ] ||
21798                 error_not_in_vm "fast read was not 4 times faster: " \
21799                            "$t_fast vs $t_slow"
21800
21801         echo "Test 2: verify the performance between big and small read"
21802         $LCTL set_param -n llite.*.fast_read=1
21803
21804         # 1k non-cache read
21805         cancel_lru_locks osc
21806         local t_1k=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
21807                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
21808                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
21809
21810         # 1M non-cache read
21811         cancel_lru_locks osc
21812         local t_1m=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
21813                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
21814                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
21815
21816         # verify that big IO is not 4 times faster than small IO
21817         [ $(bc <<< "4 * $t_1k >= $t_1m") -eq 1 ] ||
21818                 error_not_in_vm "bigger IO is way too fast: $t_1k vs $t_1m"
21819
21820         $LCTL set_param -n llite.*.fast_read=$fast_read_sav
21821         rm -f $DIR/$tfile
21822 }
21823 run_test 248a "fast read verification"
21824
21825 test_248b() {
21826         # Default short_io_bytes=16384, try both smaller and larger sizes.
21827         # Lustre O_DIRECT read and write needs to be a multiple of PAGE_SIZE.
21828         # 6017024 = 2^12*13*113 = 47008*128 = 11752*512 = 4096*1469 = 53248*113
21829         echo "bs=53248 count=113 normal buffered write"
21830         dd if=/dev/urandom of=$TMP/$tfile.0 bs=53248 count=113 ||
21831                 error "dd of initial data file failed"
21832         stack_trap "rm -f $DIR/$tfile.[0-3] $TMP/$tfile.[0-3]" EXIT
21833
21834         echo "bs=47008 count=128 oflag=dsync normal write $tfile.0"
21835         dd if=$TMP/$tfile.0 of=$DIR/$tfile.0 bs=47008 count=128 oflag=dsync ||
21836                 error "dd with sync normal writes failed"
21837         cmp $TMP/$tfile.0 $DIR/$tfile.0 || error "compare $DIR/$tfile.0 failed"
21838
21839         echo "bs=11752 count=512 oflag=dsync small write $tfile.1"
21840         dd if=$TMP/$tfile.0 of=$DIR/$tfile.1 bs=11752 count=512 oflag=dsync ||
21841                 error "dd with sync small writes failed"
21842         cmp $TMP/$tfile.0 $DIR/$tfile.1 || error "compare $DIR/$tfile.1 failed"
21843
21844         cancel_lru_locks osc
21845
21846         # calculate the small O_DIRECT size and count for the client PAGE_SIZE
21847         local num=$((13 * 113 / (PAGE_SIZE / 4096)))
21848         echo "bs=$PAGE_SIZE count=$num iflag=direct small read $tfile.1"
21849         dd if=$DIR/$tfile.1 of=$TMP/$tfile.1 bs=$PAGE_SIZE count=$num \
21850                 iflag=direct || error "dd with O_DIRECT small read failed"
21851         # adjust bytes checked to handle larger PAGE_SIZE for ARM/PPC
21852         cmp --bytes=$((PAGE_SIZE * num)) $TMP/$tfile.0 $TMP/$tfile.1 ||
21853                 error "compare $TMP/$tfile.1 failed"
21854
21855         local save=$($LCTL get_param -n osc.*OST000*.short_io_bytes | head -n 1)
21856         stack_trap "$LCTL set_param osc.$FSNAME-*.short_io_bytes=$save" EXIT
21857
21858         # just to see what the maximum tunable value is, and test parsing
21859         echo "test invalid parameter 2MB"
21860         $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=2M &&
21861                 error "too-large short_io_bytes allowed"
21862         echo "test maximum parameter 512KB"
21863         # if we can set a larger short_io_bytes, run test regardless of version
21864         if ! $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=512K; then
21865                 # older clients may not allow setting it this large, that's OK
21866                 [ $CLIENT_VERSION -ge $(version_code 2.13.50) ] ||
21867                         skip "Need at least client version 2.13.50"
21868                 error "medium short_io_bytes failed"
21869         fi
21870         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
21871         size=$($LCTL get_param -n osc.$FSNAME-OST0000*.short_io_bytes)
21872
21873         echo "test large parameter 64KB"
21874         $LCTL set_param osc.$FSNAME-*.short_io_bytes=65536
21875         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
21876
21877         echo "bs=47008 count=128 oflag=dsync large write $tfile.2"
21878         dd if=$TMP/$tfile.0 of=$DIR/$tfile.2 bs=47008 count=128 oflag=dsync ||
21879                 error "dd with sync large writes failed"
21880         cmp $TMP/$tfile.0 $DIR/$tfile.2 || error "compare $DIR/$tfile.2 failed"
21881
21882         # calculate the large O_DIRECT size and count for the client PAGE_SIZE
21883         local size=$(((4096 * 13 + PAGE_SIZE - 1) / PAGE_SIZE * PAGE_SIZE))
21884         num=$((113 * 4096 / PAGE_SIZE))
21885         echo "bs=$size count=$num oflag=direct large write $tfile.3"
21886         dd if=$TMP/$tfile.0 of=$DIR/$tfile.3 bs=$size count=$num oflag=direct ||
21887                 error "dd with O_DIRECT large writes failed"
21888         cmp --bytes=$((size * num)) $TMP/$tfile.0 $DIR/$tfile.3 ||
21889                 error "compare $DIR/$tfile.3 failed"
21890
21891         cancel_lru_locks osc
21892
21893         echo "bs=$size count=$num iflag=direct large read $tfile.2"
21894         dd if=$DIR/$tfile.2 of=$TMP/$tfile.2 bs=$size count=$num iflag=direct ||
21895                 error "dd with O_DIRECT large read failed"
21896         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.2 ||
21897                 error "compare $TMP/$tfile.2 failed"
21898
21899         echo "bs=$size count=$num iflag=direct large read $tfile.3"
21900         dd if=$DIR/$tfile.3 of=$TMP/$tfile.3 bs=$size count=$num iflag=direct ||
21901                 error "dd with O_DIRECT large read failed"
21902         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.3 ||
21903                 error "compare $TMP/$tfile.3 failed"
21904 }
21905 run_test 248b "test short_io read and write for both small and large sizes"
21906
21907 test_249() { # LU-7890
21908         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
21909                 skip "Need at least version 2.8.54"
21910
21911         rm -f $DIR/$tfile
21912         $LFS setstripe -c 1 $DIR/$tfile
21913         # Offset 2T == 4k * 512M
21914         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 seek=512M ||
21915                 error "dd to 2T offset failed"
21916 }
21917 run_test 249 "Write above 2T file size"
21918
21919 test_250() {
21920         [ "$(facet_fstype ost$(($($LFS getstripe -i $DIR/$tfile) + 1)))" = "zfs" ] \
21921          && skip "no 16TB file size limit on ZFS"
21922
21923         $LFS setstripe -c 1 $DIR/$tfile
21924         # ldiskfs extent file size limit is (16TB - 4KB - 1) bytes
21925         local size=$((16 * 1024 * 1024 * 1024 * 1024 - 4096 - 1))
21926         $TRUNCATE $DIR/$tfile $size || error "truncate $tfile to $size failed"
21927         dd if=/dev/zero of=$DIR/$tfile bs=10 count=1 oflag=append \
21928                 conv=notrunc,fsync && error "append succeeded"
21929         return 0
21930 }
21931 run_test 250 "Write above 16T limit"
21932
21933 test_251() {
21934         $LFS setstripe -c -1 -S 1048576 $DIR/$tfile
21935
21936         #define OBD_FAIL_LLITE_LOST_LAYOUT 0x1407
21937         #Skip once - writing the first stripe will succeed
21938         $LCTL set_param fail_loc=0xa0001407 fail_val=1
21939         $MULTIOP $DIR/$tfile o:O_RDWR:w2097152c 2>&1 | grep -q "short write" &&
21940                 error "short write happened"
21941
21942         $LCTL set_param fail_loc=0xa0001407 fail_val=1
21943         $MULTIOP $DIR/$tfile or2097152c 2>&1 | grep -q "short read" &&
21944                 error "short read happened"
21945
21946         rm -f $DIR/$tfile
21947 }
21948 run_test 251 "Handling short read and write correctly"
21949
21950 test_252() {
21951         remote_mds_nodsh && skip "remote MDS with nodsh"
21952         remote_ost_nodsh && skip "remote OST with nodsh"
21953         if [ "$ost1_FSTYPE" != ldiskfs ] || [ "$mds1_FSTYPE" != ldiskfs ]; then
21954                 skip_env "ldiskfs only test"
21955         fi
21956
21957         local tgt
21958         local dev
21959         local out
21960         local uuid
21961         local num
21962         local gen
21963
21964         # check lr_reader on OST0000
21965         tgt=ost1
21966         dev=$(facet_device $tgt)
21967         out=$(do_facet $tgt $LR_READER $dev)
21968         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
21969         echo "$out"
21970         uuid=$(echo "$out" | grep -i uuid | awk '{ print $2 }')
21971         [ "$uuid" == "$(ostuuid_from_index 0)" ] ||
21972                 error "Invalid uuid returned by $LR_READER on target $tgt"
21973         echo -e "uuid returned by $LR_READER is '$uuid'\n"
21974
21975         # check lr_reader -c on MDT0000
21976         tgt=mds1
21977         dev=$(facet_device $tgt)
21978         if ! do_facet $tgt $LR_READER -h | grep -q OPTIONS; then
21979                 skip "$LR_READER does not support additional options"
21980         fi
21981         out=$(do_facet $tgt $LR_READER -c $dev)
21982         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
21983         echo "$out"
21984         num=$(echo "$out" | grep -c "mdtlov")
21985         [ "$num" -eq $((MDSCOUNT - 1)) ] ||
21986                 error "Invalid number of mdtlov clients returned by $LR_READER"
21987         echo -e "Number of mdtlov clients returned by $LR_READER is '$num'\n"
21988
21989         # check lr_reader -cr on MDT0000
21990         out=$(do_facet $tgt $LR_READER -cr $dev)
21991         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
21992         echo "$out"
21993         echo "$out" | grep -q "^reply_data:$" ||
21994                 error "$LR_READER should have returned 'reply_data' section"
21995         num=$(echo "$out" | grep -c "client_generation")
21996         echo -e "Number of reply data returned by $LR_READER is '$num'\n"
21997 }
21998 run_test 252 "check lr_reader tool"
21999
22000 test_253() {
22001         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22002         remote_mds_nodsh && skip "remote MDS with nodsh"
22003         remote_mgs_nodsh && skip "remote MGS with nodsh"
22004
22005         local ostidx=0
22006         local rc=0
22007         local ost_name=$(ostname_from_index $ostidx)
22008
22009         # on the mdt's osc
22010         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $ost_name)
22011         do_facet $SINGLEMDS $LCTL get_param -n \
22012                 osp.$mdtosc_proc1.reserved_mb_high ||
22013                 skip  "remote MDS does not support reserved_mb_high"
22014
22015         rm -rf $DIR/$tdir
22016         wait_mds_ost_sync
22017         wait_delete_completed
22018         mkdir $DIR/$tdir
22019
22020         pool_add $TESTNAME || error "Pool creation failed"
22021         pool_add_targets $TESTNAME 0 || error "Pool add targets failed"
22022
22023         $LFS setstripe $DIR/$tdir -i $ostidx -c 1 -p $FSNAME.$TESTNAME ||
22024                 error "Setstripe failed"
22025
22026         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M count=10
22027
22028         local wms=$(ost_watermarks_set_enospc $tfile $ostidx |
22029                     grep "watermarks")
22030         stack_trap "ost_watermarks_clear_enospc $tfile $ostidx $wms" EXIT
22031
22032         local oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
22033                         osp.$mdtosc_proc1.prealloc_status)
22034         echo "prealloc_status $oa_status"
22035
22036         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1M count=1 &&
22037                 error "File creation should fail"
22038
22039         #object allocation was stopped, but we still able to append files
22040         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M seek=6 count=5 \
22041                 oflag=append || error "Append failed"
22042
22043         rm -f $DIR/$tdir/$tfile.0
22044
22045         # For this test, we want to delete the files we created to go out of
22046         # space but leave the watermark, so we remain nearly out of space
22047         ost_watermarks_enospc_delete_files $tfile $ostidx
22048
22049         wait_delete_completed
22050
22051         sleep_maxage
22052
22053         for i in $(seq 10 12); do
22054                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$i bs=1M count=1 \
22055                         2>/dev/null || error "File creation failed after rm"
22056         done
22057
22058         oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
22059                         osp.$mdtosc_proc1.prealloc_status)
22060         echo "prealloc_status $oa_status"
22061
22062         if (( oa_status != 0 )); then
22063                 error "Object allocation still disable after rm"
22064         fi
22065 }
22066 run_test 253 "Check object allocation limit"
22067
22068 test_254() {
22069         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22070         remote_mds_nodsh && skip "remote MDS with nodsh"
22071
22072         local mdt=$(facet_svc $SINGLEMDS)
22073
22074         do_facet $SINGLEMDS $LCTL get_param -n mdd.$mdt.changelog_size ||
22075                 skip "MDS does not support changelog_size"
22076
22077         local cl_user
22078
22079         changelog_register || error "changelog_register failed"
22080
22081         changelog_clear 0 || error "changelog_clear failed"
22082
22083         local size1=$(do_facet $SINGLEMDS \
22084                       $LCTL get_param -n mdd.$mdt.changelog_size)
22085         echo "Changelog size $size1"
22086
22087         rm -rf $DIR/$tdir
22088         $LFS mkdir -i 0 $DIR/$tdir
22089         # change something
22090         mkdir -p $DIR/$tdir/pics/2008/zachy
22091         touch $DIR/$tdir/pics/2008/zachy/timestamp
22092         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg
22093         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
22094         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
22095         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
22096         rm $DIR/$tdir/pics/desktop.jpg
22097
22098         local size2=$(do_facet $SINGLEMDS \
22099                       $LCTL get_param -n mdd.$mdt.changelog_size)
22100         echo "Changelog size after work $size2"
22101
22102         (( $size2 > $size1 )) ||
22103                 error "new Changelog size=$size2 less than old size=$size1"
22104 }
22105 run_test 254 "Check changelog size"
22106
22107 ladvise_no_type()
22108 {
22109         local type=$1
22110         local file=$2
22111
22112         lfs ladvise -a invalid $file 2>&1 | grep "Valid types" |
22113                 awk -F: '{print $2}' | grep $type > /dev/null
22114         if [ $? -ne 0 ]; then
22115                 return 0
22116         fi
22117         return 1
22118 }
22119
22120 ladvise_no_ioctl()
22121 {
22122         local file=$1
22123
22124         lfs ladvise -a willread $file > /dev/null 2>&1
22125         if [ $? -eq 0 ]; then
22126                 return 1
22127         fi
22128
22129         lfs ladvise -a willread $file 2>&1 |
22130                 grep "Inappropriate ioctl for device" > /dev/null
22131         if [ $? -eq 0 ]; then
22132                 return 0
22133         fi
22134         return 1
22135 }
22136
22137 percent() {
22138         bc <<<"scale=2; ($1 - $2) * 100 / $2"
22139 }
22140
22141 # run a random read IO workload
22142 # usage: random_read_iops <filename> <filesize> <iosize>
22143 random_read_iops() {
22144         local file=$1
22145         local fsize=$2
22146         local iosize=${3:-4096}
22147
22148         $READS -f $file -s $fsize -b $iosize -n $((fsize / iosize)) -t 60 |
22149                 sed -e '/^$/d' -e 's#.*s, ##' -e 's#MB/s##'
22150 }
22151
22152 drop_file_oss_cache() {
22153         local file="$1"
22154         local nodes="$2"
22155
22156         $LFS ladvise -a dontneed $file 2>/dev/null ||
22157                 do_nodes $nodes "echo 3 > /proc/sys/vm/drop_caches"
22158 }
22159
22160 ladvise_willread_performance()
22161 {
22162         local repeat=10
22163         local average_origin=0
22164         local average_cache=0
22165         local average_ladvise=0
22166
22167         for ((i = 1; i <= $repeat; i++)); do
22168                 echo "Iter $i/$repeat: reading without willread hint"
22169                 cancel_lru_locks osc
22170                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
22171                 local speed_origin=$(random_read_iops $DIR/$tfile $size)
22172                 echo "Iter $i/$repeat: uncached speed: $speed_origin"
22173                 average_origin=$(bc <<<"$average_origin + $speed_origin")
22174
22175                 cancel_lru_locks osc
22176                 local speed_cache=$(random_read_iops $DIR/$tfile $size)
22177                 echo "Iter $i/$repeat: OSS cache speed: $speed_cache"
22178                 average_cache=$(bc <<<"$average_cache + $speed_cache")
22179
22180                 cancel_lru_locks osc
22181                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
22182                 $LFS ladvise -a willread $DIR/$tfile || error "ladvise failed"
22183                 local speed_ladvise=$(random_read_iops $DIR/$tfile $size)
22184                 echo "Iter $i/$repeat: ladvise speed: $speed_ladvise"
22185                 average_ladvise=$(bc <<<"$average_ladvise + $speed_ladvise")
22186         done
22187         average_origin=$(bc <<<"scale=2; $average_origin / $repeat")
22188         average_cache=$(bc <<<"scale=2; $average_cache / $repeat")
22189         average_ladvise=$(bc <<<"scale=2; $average_ladvise / $repeat")
22190
22191         speedup_cache=$(percent $average_cache $average_origin)
22192         speedup_ladvise=$(percent $average_ladvise $average_origin)
22193
22194         echo "Average uncached read: $average_origin"
22195         echo "Average speedup with OSS cached read: " \
22196                 "$average_cache = +$speedup_cache%"
22197         echo "Average speedup with ladvise willread: " \
22198                 "$average_ladvise = +$speedup_ladvise%"
22199
22200         local lowest_speedup=20
22201         if (( ${average_cache%.*} < $lowest_speedup )); then
22202                 echo "Speedup with OSS cached read less than $lowest_speedup%,"\
22203                      " got $average_cache%. Skipping ladvise willread check."
22204                 return 0
22205         fi
22206
22207         # the test won't work on ZFS until it supports 'ladvise dontneed', but
22208         # it is still good to run until then to exercise 'ladvise willread'
22209         ! $LFS ladvise -a dontneed $DIR/$tfile &&
22210                 [ "$ost1_FSTYPE" = "zfs" ] &&
22211                 echo "osd-zfs does not support dontneed or drop_caches" &&
22212                 return 0
22213
22214         lowest_speedup=$(bc <<<"scale=2; $average_cache / 2")
22215         (( ${average_ladvise%.*} > ${lowest_speedup%.*} )) ||
22216                 error_not_in_vm "Speedup with willread is less than " \
22217                         "$lowest_speedup%, got $average_ladvise%"
22218 }
22219
22220 test_255a() {
22221         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
22222                 skip "lustre < 2.8.54 does not support ladvise "
22223         remote_ost_nodsh && skip "remote OST with nodsh"
22224
22225         stack_trap "rm -f $DIR/$tfile"
22226         lfs setstripe -c -1 -i 0 $DIR/$tfile || error "$tfile failed"
22227
22228         ladvise_no_type willread $DIR/$tfile &&
22229                 skip "willread ladvise is not supported"
22230
22231         ladvise_no_ioctl $DIR/$tfile &&
22232                 skip "ladvise ioctl is not supported"
22233
22234         local size_mb=100
22235         local size=$((size_mb * 1048576))
22236         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
22237                 error "dd to $DIR/$tfile failed"
22238
22239         lfs ladvise -a willread $DIR/$tfile ||
22240                 error "Ladvise failed with no range argument"
22241
22242         lfs ladvise -a willread -s 0 $DIR/$tfile ||
22243                 error "Ladvise failed with no -l or -e argument"
22244
22245         lfs ladvise -a willread -e 1 $DIR/$tfile ||
22246                 error "Ladvise failed with only -e argument"
22247
22248         lfs ladvise -a willread -l 1 $DIR/$tfile ||
22249                 error "Ladvise failed with only -l argument"
22250
22251         lfs ladvise -a willread -s 2 -e 1 $DIR/$tfile &&
22252                 error "End offset should not be smaller than start offset"
22253
22254         lfs ladvise -a willread -s 2 -e 2 $DIR/$tfile &&
22255                 error "End offset should not be equal to start offset"
22256
22257         lfs ladvise -a willread -s $size -l 1 $DIR/$tfile ||
22258                 error "Ladvise failed with overflowing -s argument"
22259
22260         lfs ladvise -a willread -s 1 -e $((size + 1)) $DIR/$tfile ||
22261                 error "Ladvise failed with overflowing -e argument"
22262
22263         lfs ladvise -a willread -s 1 -l $size $DIR/$tfile ||
22264                 error "Ladvise failed with overflowing -l argument"
22265
22266         lfs ladvise -a willread -l 1 -e 2 $DIR/$tfile &&
22267                 error "Ladvise succeeded with conflicting -l and -e arguments"
22268
22269         echo "Synchronous ladvise should wait"
22270         local delay=4
22271 #define OBD_FAIL_OST_LADVISE_PAUSE       0x237
22272         do_nodes $(comma_list $(osts_nodes)) \
22273                 $LCTL set_param fail_val=$delay fail_loc=0x237
22274
22275         local start_ts=$SECONDS
22276         lfs ladvise -a willread $DIR/$tfile ||
22277                 error "Ladvise failed with no range argument"
22278         local end_ts=$SECONDS
22279         local inteval_ts=$((end_ts - start_ts))
22280
22281         if [ $inteval_ts -lt $(($delay - 1)) ]; then
22282                 error "Synchronous advice didn't wait reply"
22283         fi
22284
22285         echo "Asynchronous ladvise shouldn't wait"
22286         local start_ts=$SECONDS
22287         lfs ladvise -a willread -b $DIR/$tfile ||
22288                 error "Ladvise failed with no range argument"
22289         local end_ts=$SECONDS
22290         local inteval_ts=$((end_ts - start_ts))
22291
22292         if [ $inteval_ts -gt $(($delay / 2)) ]; then
22293                 error "Asynchronous advice blocked"
22294         fi
22295
22296         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param fail_loc=0
22297         ladvise_willread_performance
22298 }
22299 run_test 255a "check 'lfs ladvise -a willread'"
22300
22301 facet_meminfo() {
22302         local facet=$1
22303         local info=$2
22304
22305         do_facet $facet "cat /proc/meminfo | grep ^${info}:" | awk '{print $2}'
22306 }
22307
22308 test_255b() {
22309         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
22310                 skip "lustre < 2.8.54 does not support ladvise "
22311         remote_ost_nodsh && skip "remote OST with nodsh"
22312
22313         stack_trap "rm -f $DIR/$tfile"
22314         lfs setstripe -c 1 -i 0 $DIR/$tfile
22315
22316         ladvise_no_type dontneed $DIR/$tfile &&
22317                 skip "dontneed ladvise is not supported"
22318
22319         ladvise_no_ioctl $DIR/$tfile &&
22320                 skip "ladvise ioctl is not supported"
22321
22322         ! $LFS ladvise -a dontneed $DIR/$tfile &&
22323                 [ "$ost1_FSTYPE" = "zfs" ] &&
22324                 skip "zfs-osd does not support 'ladvise dontneed'"
22325
22326         local size_mb=100
22327         local size=$((size_mb * 1048576))
22328         # In order to prevent disturbance of other processes, only check 3/4
22329         # of the memory usage
22330         local kibibytes=$((size_mb * 1024 * 3 / 4))
22331
22332         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
22333                 error "dd to $DIR/$tfile failed"
22334
22335         #force write to complete before dropping OST cache & checking memory
22336         sync
22337
22338         local total=$(facet_meminfo ost1 MemTotal)
22339         echo "Total memory: $total KiB"
22340
22341         do_facet ost1 "sync && echo 3 > /proc/sys/vm/drop_caches"
22342         local before_read=$(facet_meminfo ost1 Cached)
22343         echo "Cache used before read: $before_read KiB"
22344
22345         lfs ladvise -a willread $DIR/$tfile ||
22346                 error "Ladvise willread failed"
22347         local after_read=$(facet_meminfo ost1 Cached)
22348         echo "Cache used after read: $after_read KiB"
22349
22350         lfs ladvise -a dontneed $DIR/$tfile ||
22351                 error "Ladvise dontneed again failed"
22352         local no_read=$(facet_meminfo ost1 Cached)
22353         echo "Cache used after dontneed ladvise: $no_read KiB"
22354
22355         if [ $total -lt $((before_read + kibibytes)) ]; then
22356                 echo "Memory is too small, abort checking"
22357                 return 0
22358         fi
22359
22360         if [ $((before_read + kibibytes)) -gt $after_read ]; then
22361                 error "Ladvise willread should use more memory" \
22362                         "than $kibibytes KiB"
22363         fi
22364
22365         if [ $((no_read + kibibytes)) -gt $after_read ]; then
22366                 error "Ladvise dontneed should release more memory" \
22367                         "than $kibibytes KiB"
22368         fi
22369 }
22370 run_test 255b "check 'lfs ladvise -a dontneed'"
22371
22372 test_255c() {
22373         [ $OST1_VERSION -lt $(version_code 2.10.50) ] &&
22374                 skip "lustre < 2.10.50 does not support lockahead"
22375
22376         local ost1_imp=$(get_osc_import_name client ost1)
22377         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
22378                          cut -d'.' -f2)
22379         local count
22380         local new_count
22381         local difference
22382         local i
22383         local rc
22384
22385         test_mkdir -p $DIR/$tdir
22386         $LFS setstripe -i 0 -c 1 $DIR/$tdir
22387
22388         #test 10 returns only success/failure
22389         i=10
22390         lockahead_test -d $DIR/$tdir -t $i -f $tfile
22391         rc=$?
22392         if [ $rc -eq 255 ]; then
22393                 error "Ladvise test${i} failed, ${rc}"
22394         fi
22395
22396         #test 11 counts lock enqueue requests, all others count new locks
22397         i=11
22398         count=$(do_facet ost1 \
22399                 $LCTL get_param -n ost.OSS.ost.stats)
22400         count=$(echo "$count" | grep ldlm_extent_enqueue | awk '{ print $2 }')
22401
22402         lockahead_test -d $DIR/$tdir -t $i -f $tfile
22403         rc=$?
22404         if [ $rc -eq 255 ]; then
22405                 error "Ladvise test${i} failed, ${rc}"
22406         fi
22407
22408         new_count=$(do_facet ost1 \
22409                 $LCTL get_param -n ost.OSS.ost.stats)
22410         new_count=$(echo "$new_count" | grep ldlm_extent_enqueue | \
22411                    awk '{ print $2 }')
22412
22413         difference="$((new_count - count))"
22414         if [ $difference -ne $rc ]; then
22415                 error "Ladvise test${i}, bad enqueue count, returned " \
22416                       "${rc}, actual ${difference}"
22417         fi
22418
22419         for i in $(seq 12 21); do
22420                 # If we do not do this, we run the risk of having too many
22421                 # locks and starting lock cancellation while we are checking
22422                 # lock counts.
22423                 cancel_lru_locks osc
22424
22425                 count=$($LCTL get_param -n \
22426                        ldlm.namespaces.$imp_name.lock_unused_count)
22427
22428                 lockahead_test -d $DIR/$tdir -t $i -f $tfile
22429                 rc=$?
22430                 if [ $rc -eq 255 ]; then
22431                         error "Ladvise test ${i} failed, ${rc}"
22432                 fi
22433
22434                 new_count=$($LCTL get_param -n \
22435                        ldlm.namespaces.$imp_name.lock_unused_count)
22436                 difference="$((new_count - count))"
22437
22438                 # Test 15 output is divided by 100 to map down to valid return
22439                 if [ $i -eq 15 ]; then
22440                         rc="$((rc * 100))"
22441                 fi
22442
22443                 if [ $difference -ne $rc ]; then
22444                         error "Ladvise test ${i}, bad lock count, returned " \
22445                               "${rc}, actual ${difference}"
22446                 fi
22447         done
22448
22449         #test 22 returns only success/failure
22450         i=22
22451         lockahead_test -d $DIR/$tdir -t $i -f $tfile
22452         rc=$?
22453         if [ $rc -eq 255 ]; then
22454                 error "Ladvise test${i} failed, ${rc}"
22455         fi
22456 }
22457 run_test 255c "suite of ladvise lockahead tests"
22458
22459 test_256() {
22460         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22461         remote_mds_nodsh && skip "remote MDS with nodsh"
22462         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
22463         changelog_users $SINGLEMDS | grep "^cl" &&
22464                 skip "active changelog user"
22465
22466         local cl_user
22467         local cat_sl
22468         local mdt_dev
22469
22470         mdt_dev=$(facet_device $SINGLEMDS)
22471         echo $mdt_dev
22472
22473         changelog_register || error "changelog_register failed"
22474
22475         rm -rf $DIR/$tdir
22476         mkdir_on_mdt -i$(($(facet_number $SINGLEMDS) - 1)) $DIR/$tdir
22477
22478         changelog_clear 0 || error "changelog_clear failed"
22479
22480         # change something
22481         touch $DIR/$tdir/{1..10}
22482
22483         # stop the MDT
22484         stop $SINGLEMDS || error "Fail to stop MDT"
22485
22486         # remount the MDT
22487         start $SINGLEMDS $(facet_device $SINGLEMDS) $MDS_MOUNT_OPTS ||
22488                 error "Fail to start MDT"
22489
22490         #after mount new plainllog is used
22491         touch $DIR/$tdir/{11..19}
22492         local tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
22493         stack_trap "rm -f $tmpfile"
22494         cat_sl=$(do_facet $SINGLEMDS "sync; \
22495                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
22496                  llog_reader $tmpfile | grep -c type=1064553b")
22497         do_facet $SINGLEMDS llog_reader $tmpfile
22498
22499         [ $cat_sl != 2 ] && error "Changelog catalog has $cat_sl != 2 slots"
22500
22501         changelog_clear 0 || error "changelog_clear failed"
22502
22503         cat_sl=$(do_facet $SINGLEMDS "sync; \
22504                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
22505                  llog_reader $tmpfile | grep -c type=1064553b")
22506
22507         if (( cat_sl == 2 )); then
22508                 error "Empty plain llog was not deleted from changelog catalog"
22509         elif (( cat_sl != 1 )); then
22510                 error "Active plain llog shouldn't be deleted from catalog"
22511         fi
22512 }
22513 run_test 256 "Check llog delete for empty and not full state"
22514
22515 test_257() {
22516         remote_mds_nodsh && skip "remote MDS with nodsh"
22517         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
22518                 skip "Need MDS version at least 2.8.55"
22519
22520         test_mkdir $DIR/$tdir
22521
22522         setfattr -n trusted.name1 -v value1 $DIR/$tdir ||
22523                 error "setfattr -n trusted.name1=value1 $DIR/$tdir failed"
22524         stat $DIR/$tdir
22525
22526 #define OBD_FAIL_MDS_XATTR_REP                  0x161
22527         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
22528         local facet=mds$((mdtidx + 1))
22529         set_nodes_failloc $(facet_active_host $facet) 0x80000161
22530         getfattr -n trusted.name1 $DIR/$tdir 2> /dev/null
22531
22532         stop $facet || error "stop MDS failed"
22533         start $facet $(mdsdevname $((mdtidx + 1))) $MDS_MOUNT_OPTS ||
22534                 error "start MDS fail"
22535         wait_recovery_complete $facet
22536 }
22537 run_test 257 "xattr locks are not lost"
22538
22539 # Verify we take the i_mutex when security requires it
22540 test_258a() {
22541 #define OBD_FAIL_IMUTEX_SEC 0x141c
22542         $LCTL set_param fail_loc=0x141c
22543         touch $DIR/$tfile
22544         chmod u+s $DIR/$tfile
22545         chmod a+rwx $DIR/$tfile
22546         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
22547         RC=$?
22548         if [ $RC -ne 0 ]; then
22549                 error "error, failed to take i_mutex, rc=$?"
22550         fi
22551         rm -f $DIR/$tfile
22552 }
22553 run_test 258a "verify i_mutex security behavior when suid attributes is set"
22554
22555 # Verify we do NOT take the i_mutex in the normal case
22556 test_258b() {
22557 #define OBD_FAIL_IMUTEX_NOSEC 0x141d
22558         $LCTL set_param fail_loc=0x141d
22559         touch $DIR/$tfile
22560         chmod a+rwx $DIR
22561         chmod a+rw $DIR/$tfile
22562         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
22563         RC=$?
22564         if [ $RC -ne 0 ]; then
22565                 error "error, took i_mutex unnecessarily, rc=$?"
22566         fi
22567         rm -f $DIR/$tfile
22568
22569 }
22570 run_test 258b "verify i_mutex security behavior"
22571
22572 test_259() {
22573         local file=$DIR/$tfile
22574         local before
22575         local after
22576
22577         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
22578
22579         stack_trap "rm -f $file" EXIT
22580
22581         wait_delete_completed
22582         before=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
22583         echo "before: $before"
22584
22585         $LFS setstripe -i 0 -c 1 $file
22586         dd if=/dev/zero of=$file bs=1M count=10 || error "couldn't write"
22587         sync_all_data
22588         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
22589         echo "after write: $after"
22590
22591 #define OBD_FAIL_OSD_FAIL_AT_TRUNCATE          0x2301
22592         do_facet ost1 $LCTL set_param fail_loc=0x2301
22593         $TRUNCATE $file 0
22594         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
22595         echo "after truncate: $after"
22596
22597         stop ost1
22598         do_facet ost1 $LCTL set_param fail_loc=0
22599         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
22600         sleep 2
22601         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
22602         echo "after restart: $after"
22603         [ $((after - before)) -ge $(fs_log_size ost1) ] &&
22604                 error "missing truncate?"
22605
22606         return 0
22607 }
22608 run_test 259 "crash at delayed truncate"
22609
22610 test_260() {
22611 #define OBD_FAIL_MDC_CLOSE               0x806
22612         $LCTL set_param fail_loc=0x80000806
22613         touch $DIR/$tfile
22614
22615 }
22616 run_test 260 "Check mdc_close fail"
22617
22618 ### Data-on-MDT sanity tests ###
22619 test_270a() {
22620         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22621                 skip "Need MDS version at least 2.10.55 for DoM"
22622
22623         # create DoM file
22624         local dom=$DIR/$tdir/dom_file
22625         local tmp=$DIR/$tdir/tmp_file
22626
22627         mkdir_on_mdt0 $DIR/$tdir
22628
22629         # basic checks for DoM component creation
22630         $LFS setstripe -E 1024K -E 2048K -L mdt $dom 2>/dev/null &&
22631                 error "Can set MDT layout to non-first entry"
22632
22633         $LFS setstripe -E 1024K -L mdt -E 2048K -L mdt $dom 2>/dev/null &&
22634                 error "Can define multiple entries as MDT layout"
22635
22636         $LFS setstripe -E 1M -L mdt $dom || error "Can't create DoM layout"
22637
22638         [ $($LFS getstripe -L $dom) == "mdt" ] || error "bad pattern"
22639         [ $($LFS getstripe -c $dom) == 0 ] || error "bad stripe count"
22640         [ $($LFS getstripe -S $dom) == 1048576 ] || error "bad stripe size"
22641
22642         local mdtidx=$($LFS getstripe -m $dom)
22643         local mdtname=MDT$(printf %04x $mdtidx)
22644         local facet=mds$((mdtidx + 1))
22645         local space_check=1
22646
22647         # Skip free space checks with ZFS
22648         [ "$(facet_fstype $facet)" == "zfs" ] && space_check=0
22649
22650         # write
22651         sync
22652         local size_tmp=$((65536 * 3))
22653         local mdtfree1=$(do_facet $facet \
22654                          lctl get_param -n osd*.*$mdtname.kbytesfree)
22655
22656         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
22657         # check also direct IO along write
22658         # IO size must be a multiple of PAGE_SIZE on all platforms (ARM=64KB)
22659         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
22660         sync
22661         cmp $tmp $dom || error "file data is different"
22662         [ $(stat -c%s $dom) == $size_tmp ] ||
22663                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
22664         if [ $space_check == 1 ]; then
22665                 local mdtfree2=$(do_facet $facet \
22666                                  lctl get_param -n osd*.*$mdtname.kbytesfree)
22667
22668                 # increase in usage from by $size_tmp
22669                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
22670                         error "MDT free space wrong after write: " \
22671                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
22672         fi
22673
22674         # truncate
22675         local size_dom=10000
22676
22677         $TRUNCATE $dom $size_dom
22678         [ $(stat -c%s $dom) == $size_dom ] ||
22679                 error "bad size after truncate: $(stat -c%s $dom) != $size_dom"
22680         if [ $space_check == 1 ]; then
22681                 mdtfree1=$(do_facet $facet \
22682                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22683                 # decrease in usage from $size_tmp to new $size_dom
22684                 [ $(($mdtfree1 - $mdtfree2)) -ge \
22685                   $(((size_tmp - size_dom) / 1024)) ] ||
22686                         error "MDT free space is wrong after truncate: " \
22687                               "$mdtfree1 >= $mdtfree2 + ($size_tmp - $size_dom) / 1024"
22688         fi
22689
22690         # append
22691         cat $tmp >> $dom
22692         sync
22693         size_dom=$((size_dom + size_tmp))
22694         [ $(stat -c%s $dom) == $size_dom ] ||
22695                 error "bad size after append: $(stat -c%s $dom) != $size_dom"
22696         if [ $space_check == 1 ]; then
22697                 mdtfree2=$(do_facet $facet \
22698                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22699                 # increase in usage by $size_tmp from previous
22700                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
22701                         error "MDT free space is wrong after append: " \
22702                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
22703         fi
22704
22705         # delete
22706         rm $dom
22707         if [ $space_check == 1 ]; then
22708                 mdtfree1=$(do_facet $facet \
22709                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22710                 # decrease in usage by $size_dom from previous
22711                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_dom / 1024)) ] ||
22712                         error "MDT free space is wrong after removal: " \
22713                               "$mdtfree1 >= $mdtfree2 + $size_dom/1024"
22714         fi
22715
22716         # combined striping
22717         $LFS setstripe -E 1024K -L mdt -E EOF $dom ||
22718                 error "Can't create DoM + OST striping"
22719
22720         size_tmp=2031616 # must be a multiple of PAGE_SIZE=65536 on ARM
22721         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
22722         # check also direct IO along write
22723         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
22724         sync
22725         cmp $tmp $dom || error "file data is different"
22726         [ $(stat -c%s $dom) == $size_tmp ] ||
22727                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
22728         rm $dom $tmp
22729
22730         return 0
22731 }
22732 run_test 270a "DoM: basic functionality tests"
22733
22734 test_270b() {
22735         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22736                 skip "Need MDS version at least 2.10.55"
22737
22738         local dom=$DIR/$tdir/dom_file
22739         local max_size=1048576
22740
22741         mkdir -p $DIR/$tdir
22742         $LFS setstripe -E $max_size -L mdt $dom
22743
22744         # truncate over the limit
22745         $TRUNCATE $dom $(($max_size + 1)) &&
22746                 error "successful truncate over the maximum size"
22747         # write over the limit
22748         dd if=/dev/zero of=$dom bs=$max_size seek=1 count=1 &&
22749                 error "successful write over the maximum size"
22750         # append over the limit
22751         dd if=/dev/zero of=$dom bs=$(($max_size - 3)) count=1
22752         echo "12345" >> $dom && error "successful append over the maximum size"
22753         rm $dom
22754
22755         return 0
22756 }
22757 run_test 270b "DoM: maximum size overflow checks for DoM-only file"
22758
22759 test_270c() {
22760         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22761                 skip "Need MDS version at least 2.10.55"
22762
22763         mkdir -p $DIR/$tdir
22764         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
22765
22766         # check files inherit DoM EA
22767         touch $DIR/$tdir/first
22768         [ $($LFS getstripe -L $DIR/$tdir/first) == "mdt" ] ||
22769                 error "bad pattern"
22770         [ $($LFS getstripe -c $DIR/$tdir/first) == 0 ] ||
22771                 error "bad stripe count"
22772         [ $($LFS getstripe -S $DIR/$tdir/first) == 1048576 ] ||
22773                 error "bad stripe size"
22774
22775         # check directory inherits DoM EA and uses it as default
22776         mkdir $DIR/$tdir/subdir
22777         touch $DIR/$tdir/subdir/second
22778         [ $($LFS getstripe -L $DIR/$tdir/subdir/second) == "mdt" ] ||
22779                 error "bad pattern in sub-directory"
22780         [ $($LFS getstripe -c $DIR/$tdir/subdir/second) == 0 ] ||
22781                 error "bad stripe count in sub-directory"
22782         [ $($LFS getstripe -S $DIR/$tdir/subdir/second) == 1048576 ] ||
22783                 error "bad stripe size in sub-directory"
22784         return 0
22785 }
22786 run_test 270c "DoM: DoM EA inheritance tests"
22787
22788 test_270d() {
22789         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22790                 skip "Need MDS version at least 2.10.55"
22791
22792         mkdir -p $DIR/$tdir
22793         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
22794
22795         # inherit default DoM striping
22796         mkdir $DIR/$tdir/subdir
22797         touch $DIR/$tdir/subdir/f1
22798
22799         # change default directory striping
22800         $LFS setstripe -c 1 $DIR/$tdir/subdir
22801         touch $DIR/$tdir/subdir/f2
22802         [ $($LFS getstripe -c $DIR/$tdir/subdir/f2) == 1 ] ||
22803                 error "wrong default striping in file 2"
22804         [ $($LFS getstripe -L $DIR/$tdir/subdir/f2) == "raid0" ] ||
22805                 error "bad pattern in file 2"
22806         return 0
22807 }
22808 run_test 270d "DoM: change striping from DoM to RAID0"
22809
22810 test_270e() {
22811         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22812                 skip "Need MDS version at least 2.10.55"
22813
22814         mkdir -p $DIR/$tdir/dom
22815         mkdir -p $DIR/$tdir/norm
22816         DOMFILES=20
22817         NORMFILES=10
22818         $LFS setstripe -E 1M -L mdt $DIR/$tdir/dom
22819         $LFS setstripe -i 0 -S 2M $DIR/$tdir/norm
22820
22821         createmany -o $DIR/$tdir/dom/dom- $DOMFILES
22822         createmany -o $DIR/$tdir/norm/norm- $NORMFILES
22823
22824         # find DoM files by layout
22825         NUM=$($LFS find -L mdt -type f $DIR/$tdir 2>/dev/null | wc -l)
22826         [ $NUM -eq  $DOMFILES ] ||
22827                 error "lfs find -L: found $NUM, expected $DOMFILES"
22828         echo "Test 1: lfs find 20 DOM files by layout: OK"
22829
22830         # there should be 1 dir with default DOM striping
22831         NUM=$($LFS find -L mdt -type d $DIR/$tdir 2>/dev/null | wc -l)
22832         [ $NUM -eq  1 ] ||
22833                 error "lfs find -L: found $NUM, expected 1 dir"
22834         echo "Test 2: lfs find 1 DOM dir by layout: OK"
22835
22836         # find DoM files by stripe size
22837         NUM=$($LFS find -S -1200K -type f $DIR/$tdir 2>/dev/null | wc -l)
22838         [ $NUM -eq  $DOMFILES ] ||
22839                 error "lfs find -S: found $NUM, expected $DOMFILES"
22840         echo "Test 4: lfs find 20 DOM files by stripe size: OK"
22841
22842         # find files by stripe offset except DoM files
22843         NUM=$($LFS find -i 0 -type f $DIR/$tdir 2>/dev/null | wc -l)
22844         [ $NUM -eq  $NORMFILES ] ||
22845                 error "lfs find -i: found $NUM, expected $NORMFILES"
22846         echo "Test 5: lfs find no DOM files by stripe index: OK"
22847         return 0
22848 }
22849 run_test 270e "DoM: lfs find with DoM files test"
22850
22851 test_270f() {
22852         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22853                 skip "Need MDS version at least 2.10.55"
22854
22855         local mdtname=${FSNAME}-MDT0000-mdtlov
22856         local dom=$DIR/$tdir/dom_file
22857         local dom_limit_saved=$(do_facet mds1 $LCTL get_param -n \
22858                                                 lod.$mdtname.dom_stripesize)
22859         local dom_limit=131072
22860
22861         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=$dom_limit
22862         local dom_current=$(do_facet mds1 $LCTL get_param -n \
22863                                                 lod.$mdtname.dom_stripesize)
22864         [ ${dom_limit} -eq ${dom_current} ] ||
22865                 error "Cannot change per-MDT DoM stripe limit to $dom_limit"
22866
22867         $LFS mkdir -i 0 -c 1 $DIR/$tdir
22868         $LFS setstripe -d $DIR/$tdir
22869         $LFS setstripe -E $dom_limit -L mdt $DIR/$tdir ||
22870                 error "Can't set directory default striping"
22871
22872         # exceed maximum stripe size
22873         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
22874                 error "Can't create file with $((dom_limit * 2)) DoM stripe"
22875         [ $($LFS getstripe -S $dom) -eq $((dom_limit * 2)) ] &&
22876                 error "Able to create DoM component size more than LOD limit"
22877
22878         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
22879         dom_current=$(do_facet mds1 $LCTL get_param -n \
22880                                                 lod.$mdtname.dom_stripesize)
22881         [ 0 -eq ${dom_current} ] ||
22882                 error "Can't set zero DoM stripe limit"
22883         rm $dom
22884
22885         # attempt to create DoM file on server with disabled DoM should
22886         # remove DoM entry from layout and be succeed
22887         $LFS setstripe -E $dom_limit -L mdt -E -1 $dom ||
22888                 error "Can't create DoM file (DoM is disabled)"
22889         [ $($LFS getstripe -L $dom) == "mdt" ] &&
22890                 error "File has DoM component while DoM is disabled"
22891         rm $dom
22892
22893         # attempt to create DoM file with only DoM stripe should return error
22894         $LFS setstripe -E $dom_limit -L mdt $dom &&
22895                 error "Able to create DoM-only file while DoM is disabled"
22896
22897         # too low values to be aligned with smallest stripe size 64K
22898         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=30000
22899         dom_current=$(do_facet mds1 $LCTL get_param -n \
22900                                                 lod.$mdtname.dom_stripesize)
22901         [ 30000 -eq ${dom_current} ] &&
22902                 error "Can set too small DoM stripe limit"
22903
22904         # 64K is a minimal stripe size in Lustre, expect limit of that size
22905         [ 65536 -eq ${dom_current} ] ||
22906                 error "Limit is not set to 64K but ${dom_current}"
22907
22908         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=2147483648
22909         dom_current=$(do_facet mds1 $LCTL get_param -n \
22910                                                 lod.$mdtname.dom_stripesize)
22911         echo $dom_current
22912         [ 2147483648 -eq ${dom_current} ] &&
22913                 error "Can set too large DoM stripe limit"
22914
22915         do_facet mds1 $LCTL set_param -n \
22916                                 lod.$mdtname.dom_stripesize=$((dom_limit * 2))
22917         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
22918                 error "Can't create DoM component size after limit change"
22919         do_facet mds1 $LCTL set_param -n \
22920                                 lod.$mdtname.dom_stripesize=$((dom_limit / 2))
22921         $LFS setstripe -E $dom_limit -L mdt ${dom}_big ||
22922                 error "Can't create DoM file after limit decrease"
22923         [ $($LFS getstripe -S ${dom}_big) -eq $((dom_limit / 2)) ] ||
22924                 error "Can create big DoM component after limit decrease"
22925         touch ${dom}_def ||
22926                 error "Can't create file with old default layout"
22927
22928         do_facet mds1 $LCTL set_param -n lod.*.dom_stripesize=$dom_limit_saved
22929         return 0
22930 }
22931 run_test 270f "DoM: maximum DoM stripe size checks"
22932
22933 test_270g() {
22934         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
22935                 skip "Need MDS version at least 2.13.52"
22936         local dom=$DIR/$tdir/$tfile
22937
22938         $LFS mkdir -i 0 -c 1 $DIR/$tdir
22939         local lodname=${FSNAME}-MDT0000-mdtlov
22940
22941         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
22942         save_lustre_params mds1 "lod.${lodname}.dom_stripesize_max_kb" > $save
22943         save_lustre_params mds1 "lod.${lodname}.dom_threshold_free_mb" >> $save
22944         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
22945
22946         local dom_limit=1024
22947         local dom_threshold="50%"
22948
22949         $LFS setstripe -d $DIR/$tdir
22950         $LFS setstripe -E ${dom_limit}K -L mdt $DIR/$tdir ||
22951                 error "Can't set directory default striping"
22952
22953         do_facet mds1 $LCTL set_param -n \
22954                                 lod.${lodname}.dom_stripesize_max_kb=$dom_limit
22955         # set 0 threshold and create DOM file to change tunable stripesize
22956         do_facet mds1 $LCTL set_param -n lod.${lodname}.dom_threshold_free_mb=0
22957         $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
22958                 error "Failed to create $dom file"
22959         # now tunable dom_cur_stripesize should reach maximum
22960         local dom_current=$(do_facet mds1 $LCTL get_param -n \
22961                                         lod.${lodname}.dom_stripesize_cur_kb)
22962         [[ $dom_current == $dom_limit ]] ||
22963                 error "Current DOM stripesize is not maximum"
22964         rm $dom
22965
22966         # set threshold for further tests
22967         do_facet mds1 $LCTL set_param -n \
22968                         lod.${lodname}.dom_threshold_free_mb=$dom_threshold
22969         echo "DOM threshold is $dom_threshold free space"
22970         local dom_def
22971         local dom_set
22972         # Spoof bfree to exceed threshold
22973         #define OBD_FAIL_MDS_STATFS_SPOOF   0x168
22974         do_facet mds1 $LCTL set_param -n fail_loc=0x0168
22975         for spfree in 40 20 0 15 30 55; do
22976                 do_facet mds1 $LCTL set_param -n fail_val=$spfree
22977                 $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
22978                         error "Failed to create $dom file"
22979                 dom_def=$(do_facet mds1 $LCTL get_param -n \
22980                                         lod.${lodname}.dom_stripesize_cur_kb)
22981                 echo "Free space: ${spfree}%, default DOM stripe: ${dom_def}K"
22982                 [[ $dom_def != $dom_current ]] ||
22983                         error "Default stripe size was not changed"
22984                 if (( spfree > 0 )) ; then
22985                         dom_set=$($LFS getstripe -S $dom)
22986                         (( dom_set == dom_def * 1024 )) ||
22987                                 error "DOM component size is still old"
22988                 else
22989                         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
22990                                 error "DoM component is set with no free space"
22991                 fi
22992                 rm $dom
22993                 dom_current=$dom_def
22994         done
22995 }
22996 run_test 270g "DoM: default DoM stripe size depends on free space"
22997
22998 test_270h() {
22999         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
23000                 skip "Need MDS version at least 2.13.53"
23001
23002         local mdtname=${FSNAME}-MDT0000-mdtlov
23003         local dom=$DIR/$tdir/$tfile
23004         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
23005
23006         save_lustre_params mds1 "lod.*.dom_stripesize" > $save
23007         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
23008
23009         $LFS mkdir -i 0 -c 1 $DIR/$tdir
23010         $LFS setstripe -E 1M -c1  -E -1 -c2 ${dom}_1 ||
23011                 error "can't create OST file"
23012         # mirrored file with DOM entry in the second mirror
23013         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 ${dom}_1 ||
23014                 error "can't create mirror with DoM component"
23015
23016         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
23017
23018         # DOM component in the middle and has other enries in the same mirror,
23019         # should succeed but lost DoM component
23020         $LFS setstripe --copy=${dom}_1 $dom ||
23021                 error "Can't create file from OST|DOM mirror layout"
23022         # check new file has no DoM layout after all
23023         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
23024                 error "File has DoM component while DoM is disabled"
23025 }
23026 run_test 270h "DoM: DoM stripe removal when disabled on server"
23027
23028 test_270i() {
23029         (( $MDS1_VERSION >= $(version_code 2.14.54) )) ||
23030                 skip "Need MDS version at least 2.14.54"
23031
23032         mkdir $DIR/$tdir
23033         # DoM with plain layout
23034         $LFS setstripe -L mdt -S 128k -c -1 $DIR/$tdir &&
23035                 error "default plain layout with DoM must fail"
23036         $LFS setstripe -L mdt -S 128k -c -1 $DIR/$tdir/$tfile &&
23037                 error "setstripe plain file layout with DoM must fail"
23038         $LFS setstripe -E 1M -L mdt -S 128k -c -1 -E eof $DIR/$tdir &&
23039                 error "default DoM layout with bad striping must fail"
23040         $LFS setstripe -E 1M -L mdt -S 128k -c -1 -E eof $DIR/$tdir/$tfile &&
23041                 error "setstripe to DoM layout with bad striping must fail"
23042         return 0
23043 }
23044 run_test 270i "DoM: setting invalid DoM striping should fail"
23045
23046 test_271a() {
23047         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23048                 skip "Need MDS version at least 2.10.55"
23049
23050         local dom=$DIR/$tdir/dom
23051
23052         mkdir -p $DIR/$tdir
23053
23054         $LFS setstripe -E 1024K -L mdt $dom
23055
23056         lctl set_param -n mdc.*.stats=clear
23057         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
23058         cat $dom > /dev/null
23059         local reads=$(lctl get_param -n mdc.*.stats | grep -c ost_read)
23060         [ $reads -eq 0 ] || error "Unexpected $reads READ RPCs"
23061         ls $dom
23062         rm -f $dom
23063 }
23064 run_test 271a "DoM: data is cached for read after write"
23065
23066 test_271b() {
23067         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23068                 skip "Need MDS version at least 2.10.55"
23069
23070         local dom=$DIR/$tdir/dom
23071
23072         mkdir -p $DIR/$tdir
23073
23074         $LFS setstripe -E 1024K -L mdt -E EOF $dom
23075
23076         lctl set_param -n mdc.*.stats=clear
23077         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
23078         cancel_lru_locks mdc
23079         $CHECKSTAT -t file -s 4096 $dom || error "stat #1 fails"
23080         # second stat to check size is cached on client
23081         $CHECKSTAT -t file -s 4096 $dom || error "stat #2 fails"
23082         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
23083         [ $gls -eq 0 ] || error "Unexpected $gls glimpse RPCs"
23084         rm -f $dom
23085 }
23086 run_test 271b "DoM: no glimpse RPC for stat (DoM only file)"
23087
23088 test_271ba() {
23089         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23090                 skip "Need MDS version at least 2.10.55"
23091
23092         local dom=$DIR/$tdir/dom
23093
23094         mkdir -p $DIR/$tdir
23095
23096         $LFS setstripe -E 1024K -L mdt -E EOF $dom
23097
23098         lctl set_param -n mdc.*.stats=clear
23099         lctl set_param -n osc.*.stats=clear
23100         dd if=/dev/zero of=$dom bs=2048K count=1 || return 1
23101         cancel_lru_locks mdc
23102         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
23103         # second stat to check size is cached on client
23104         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
23105         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
23106         [ $gls == 0 ] || error "Unexpected $gls glimpse RPCs"
23107         local gls=$(lctl get_param -n osc.*.stats | grep -c ldlm_glimpse)
23108         [ $gls == 0 ] || error "Unexpected $gls OSC glimpse RPCs"
23109         rm -f $dom
23110 }
23111 run_test 271ba "DoM: no glimpse RPC for stat (combined file)"
23112
23113
23114 get_mdc_stats() {
23115         local mdtidx=$1
23116         local param=$2
23117         local mdt=MDT$(printf %04x $mdtidx)
23118
23119         if [ -z $param ]; then
23120                 lctl get_param -n mdc.*$mdt*.stats
23121         else
23122                 lctl get_param -n mdc.*$mdt*.stats | awk "/$param/"'{print $2}'
23123         fi
23124 }
23125
23126 test_271c() {
23127         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23128                 skip "Need MDS version at least 2.10.55"
23129
23130         local dom=$DIR/$tdir/dom
23131
23132         mkdir -p $DIR/$tdir
23133
23134         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
23135
23136         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
23137         local facet=mds$((mdtidx + 1))
23138
23139         cancel_lru_locks mdc
23140         do_facet $facet lctl set_param -n mdt.*.dom_lock=0
23141         createmany -o $dom 1000
23142         lctl set_param -n mdc.*.stats=clear
23143         smalliomany -w $dom 1000 200
23144         get_mdc_stats $mdtidx
23145         local enq=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
23146         # Each file has 1 open, 1 IO enqueues, total 2000
23147         # but now we have also +1 getxattr for security.capability, total 3000
23148         [ $enq -ge 2000 ] || error "Too few enqueues $enq, expected > 2000"
23149         unlinkmany $dom 1000
23150
23151         cancel_lru_locks mdc
23152         do_facet $facet lctl set_param -n mdt.*.dom_lock=1
23153         createmany -o $dom 1000
23154         lctl set_param -n mdc.*.stats=clear
23155         smalliomany -w $dom 1000 200
23156         local enq_2=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
23157         # Expect to see reduced amount of RPCs by 1000 due to single enqueue
23158         # for OPEN and IO lock.
23159         [ $((enq - enq_2)) -ge 1000 ] ||
23160                 error "Too many enqueues $enq_2, expected about $((enq - 1000))"
23161         unlinkmany $dom 1000
23162         return 0
23163 }
23164 run_test 271c "DoM: IO lock at open saves enqueue RPCs"
23165
23166 cleanup_271def_tests() {
23167         trap 0
23168         rm -f $1
23169 }
23170
23171 test_271d() {
23172         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
23173                 skip "Need MDS version at least 2.10.57"
23174
23175         local dom=$DIR/$tdir/dom
23176         local tmp=$TMP/$tfile
23177         trap "cleanup_271def_tests $tmp" EXIT
23178
23179         mkdir -p $DIR/$tdir
23180
23181         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
23182
23183         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
23184
23185         cancel_lru_locks mdc
23186         dd if=/dev/urandom of=$tmp bs=1000 count=1
23187         dd if=$tmp of=$dom bs=1000 count=1
23188         cancel_lru_locks mdc
23189
23190         cat /etc/hosts >> $tmp
23191         lctl set_param -n mdc.*.stats=clear
23192
23193         # append data to the same file it should update local page
23194         echo "Append to the same page"
23195         cat /etc/hosts >> $dom
23196         local num=$(get_mdc_stats $mdtidx ost_read)
23197         local ra=$(get_mdc_stats $mdtidx req_active)
23198         local rw=$(get_mdc_stats $mdtidx req_waittime)
23199
23200         [ -z $num ] || error "$num READ RPC occured"
23201         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
23202         echo "... DONE"
23203
23204         # compare content
23205         cmp $tmp $dom || error "file miscompare"
23206
23207         cancel_lru_locks mdc
23208         lctl set_param -n mdc.*.stats=clear
23209
23210         echo "Open and read file"
23211         cat $dom > /dev/null
23212         local num=$(get_mdc_stats $mdtidx ost_read)
23213         local ra=$(get_mdc_stats $mdtidx req_active)
23214         local rw=$(get_mdc_stats $mdtidx req_waittime)
23215
23216         [ -z $num ] || error "$num READ RPC occured"
23217         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
23218         echo "... DONE"
23219
23220         # compare content
23221         cmp $tmp $dom || error "file miscompare"
23222
23223         return 0
23224 }
23225 run_test 271d "DoM: read on open (1K file in reply buffer)"
23226
23227 test_271f() {
23228         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
23229                 skip "Need MDS version at least 2.10.57"
23230
23231         local dom=$DIR/$tdir/dom
23232         local tmp=$TMP/$tfile
23233         trap "cleanup_271def_tests $tmp" EXIT
23234
23235         mkdir -p $DIR/$tdir
23236
23237         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
23238
23239         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
23240
23241         cancel_lru_locks mdc
23242         dd if=/dev/urandom of=$tmp bs=265000 count=1
23243         dd if=$tmp of=$dom bs=265000 count=1
23244         cancel_lru_locks mdc
23245         cat /etc/hosts >> $tmp
23246         lctl set_param -n mdc.*.stats=clear
23247
23248         echo "Append to the same page"
23249         cat /etc/hosts >> $dom
23250         local num=$(get_mdc_stats $mdtidx ost_read)
23251         local ra=$(get_mdc_stats $mdtidx req_active)
23252         local rw=$(get_mdc_stats $mdtidx req_waittime)
23253
23254         [ -z $num ] || error "$num READ RPC occured"
23255         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
23256         echo "... DONE"
23257
23258         # compare content
23259         cmp $tmp $dom || error "file miscompare"
23260
23261         cancel_lru_locks mdc
23262         lctl set_param -n mdc.*.stats=clear
23263
23264         echo "Open and read file"
23265         cat $dom > /dev/null
23266         local num=$(get_mdc_stats $mdtidx ost_read)
23267         local ra=$(get_mdc_stats $mdtidx req_active)
23268         local rw=$(get_mdc_stats $mdtidx req_waittime)
23269
23270         [ -z $num ] && num=0
23271         [ $num -eq 1 ] || error "expect 1 READ RPC, $num occured"
23272         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
23273         echo "... DONE"
23274
23275         # compare content
23276         cmp $tmp $dom || error "file miscompare"
23277
23278         return 0
23279 }
23280 run_test 271f "DoM: read on open (200K file and read tail)"
23281
23282 test_271g() {
23283         [[ $($LCTL get_param mdc.*.import) =~ async_discard ]] ||
23284                 skip "Skipping due to old client or server version"
23285
23286         $LFS setstripe -E 1024K -L mdt -E EOF $DIR1/$tfile
23287         # to get layout
23288         $CHECKSTAT -t file $DIR1/$tfile
23289
23290         $MULTIOP $DIR1/$tfile Ow40960_w4096c &
23291         MULTIOP_PID=$!
23292         sleep 1
23293         #define OBD_FAIL_LDLM_CANCEL_BL_CB_RACE
23294         $LCTL set_param fail_loc=0x80000314
23295         rm $DIR1/$tfile || error "Unlink fails"
23296         RC=$?
23297         kill -USR1 $MULTIOP_PID && wait $MULTIOP_PID || error "multiop failure"
23298         [ $RC -eq 0 ] || error "Failed write to stale object"
23299 }
23300 run_test 271g "Discard DoM data vs client flush race"
23301
23302 test_272a() {
23303         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
23304                 skip "Need MDS version at least 2.11.50"
23305
23306         local dom=$DIR/$tdir/dom
23307         mkdir -p $DIR/$tdir
23308
23309         $LFS setstripe -E 256K -L mdt -E -1 -c1 $dom
23310         dd if=/dev/urandom of=$dom bs=512K count=1 ||
23311                 error "failed to write data into $dom"
23312         local old_md5=$(md5sum $dom)
23313
23314         $LFS migrate -E 256K -L mdt -E -1 -c2 $dom ||
23315                 error "failed to migrate to the same DoM component"
23316
23317         local new_md5=$(md5sum $dom)
23318
23319         [ "$old_md5" == "$new_md5" ] ||
23320                 error "md5sum differ: $old_md5, $new_md5"
23321
23322         [ $($LFS getstripe -c $dom) -eq 2 ] ||
23323                 error "bad final stripe count: $($LFS getstripe -c $dom) != 2"
23324 }
23325 run_test 272a "DoM migration: new layout with the same DOM component"
23326
23327 test_272b() {
23328         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
23329                 skip "Need MDS version at least 2.11.50"
23330
23331         local dom=$DIR/$tdir/dom
23332         mkdir -p $DIR/$tdir
23333         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
23334
23335         local mdtidx=$($LFS getstripe -m $dom)
23336         local mdtname=MDT$(printf %04x $mdtidx)
23337         local facet=mds$((mdtidx + 1))
23338
23339         local mdtfree1=$(do_facet $facet \
23340                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23341         dd if=/dev/urandom of=$dom bs=2M count=1 ||
23342                 error "failed to write data into $dom"
23343         local old_md5=$(md5sum $dom)
23344         cancel_lru_locks mdc
23345         local mdtfree1=$(do_facet $facet \
23346                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23347
23348         $LFS migrate -c2 $dom ||
23349                 error "failed to migrate to the new composite layout"
23350         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
23351                 error "MDT stripe was not removed"
23352
23353         cancel_lru_locks mdc
23354         local new_md5=$(md5sum $dom)
23355         [ "$old_md5" == "$new_md5" ] ||
23356                 error "$old_md5 != $new_md5"
23357
23358         # Skip free space checks with ZFS
23359         if [ "$(facet_fstype $facet)" != "zfs" ]; then
23360                 local mdtfree2=$(do_facet $facet \
23361                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23362                 [ $mdtfree2 -gt $mdtfree1 ] ||
23363                         error "MDT space is not freed after migration"
23364         fi
23365         return 0
23366 }
23367 run_test 272b "DoM migration: DOM file to the OST-striped file (plain)"
23368
23369 test_272c() {
23370         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
23371                 skip "Need MDS version at least 2.11.50"
23372
23373         local dom=$DIR/$tdir/$tfile
23374         mkdir -p $DIR/$tdir
23375         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
23376
23377         local mdtidx=$($LFS getstripe -m $dom)
23378         local mdtname=MDT$(printf %04x $mdtidx)
23379         local facet=mds$((mdtidx + 1))
23380
23381         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
23382                 error "failed to write data into $dom"
23383         local old_md5=$(md5sum $dom)
23384         cancel_lru_locks mdc
23385         local mdtfree1=$(do_facet $facet \
23386                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23387
23388         $LFS migrate -E 2M -c1 -E -1 -c2 $dom ||
23389                 error "failed to migrate to the new composite layout"
23390         [ $($LFS getstripe -L $dom) == 'mdt' ] &&
23391                 error "MDT stripe was not removed"
23392
23393         cancel_lru_locks mdc
23394         local new_md5=$(md5sum $dom)
23395         [ "$old_md5" == "$new_md5" ] ||
23396                 error "$old_md5 != $new_md5"
23397
23398         # Skip free space checks with ZFS
23399         if [ "$(facet_fstype $facet)" != "zfs" ]; then
23400                 local mdtfree2=$(do_facet $facet \
23401                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23402                 [ $mdtfree2 -gt $mdtfree1 ] ||
23403                         error "MDS space is not freed after migration"
23404         fi
23405         return 0
23406 }
23407 run_test 272c "DoM migration: DOM file to the OST-striped file (composite)"
23408
23409 test_272d() {
23410         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
23411                 skip "Need MDS version at least 2.12.55"
23412
23413         local dom=$DIR/$tdir/$tfile
23414         mkdir -p $DIR/$tdir
23415         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
23416
23417         local mdtidx=$($LFS getstripe -m $dom)
23418         local mdtname=MDT$(printf %04x $mdtidx)
23419         local facet=mds$((mdtidx + 1))
23420
23421         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
23422                 error "failed to write data into $dom"
23423         local old_md5=$(md5sum $dom)
23424         cancel_lru_locks mdc
23425         local mdtfree1=$(do_facet $facet \
23426                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23427
23428         $LFS mirror extend -N -E 2M -c1 -E -1 -c2 $dom ||
23429                 error "failed mirroring to the new composite layout"
23430         $LFS mirror resync $dom ||
23431                 error "failed mirror resync"
23432         $LFS mirror split --mirror-id 1 -d $dom ||
23433                 error "failed mirror split"
23434
23435         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
23436                 error "MDT stripe was not removed"
23437
23438         cancel_lru_locks mdc
23439         local new_md5=$(md5sum $dom)
23440         [ "$old_md5" == "$new_md5" ] ||
23441                 error "$old_md5 != $new_md5"
23442
23443         # Skip free space checks with ZFS
23444         if [ "$(facet_fstype $facet)" != "zfs" ]; then
23445                 local mdtfree2=$(do_facet $facet \
23446                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23447                 [ $mdtfree2 -gt $mdtfree1 ] ||
23448                         error "MDS space is not freed after DOM mirror deletion"
23449         fi
23450         return 0
23451 }
23452 run_test 272d "DoM mirroring: OST-striped mirror to DOM file"
23453
23454 test_272e() {
23455         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
23456                 skip "Need MDS version at least 2.12.55"
23457
23458         local dom=$DIR/$tdir/$tfile
23459         mkdir -p $DIR/$tdir
23460         $LFS setstripe -c 2 $dom
23461
23462         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
23463                 error "failed to write data into $dom"
23464         local old_md5=$(md5sum $dom)
23465         cancel_lru_locks
23466
23467         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 $dom ||
23468                 error "failed mirroring to the DOM layout"
23469         $LFS mirror resync $dom ||
23470                 error "failed mirror resync"
23471         $LFS mirror split --mirror-id 1 -d $dom ||
23472                 error "failed mirror split"
23473
23474         [[ $($LFS getstripe -L --component-start=0 $dom) == 'mdt' ]] ||
23475                 error "MDT stripe wasn't set"
23476
23477         cancel_lru_locks
23478         local new_md5=$(md5sum $dom)
23479         [ "$old_md5" == "$new_md5" ] ||
23480                 error "$old_md5 != $new_md5"
23481
23482         return 0
23483 }
23484 run_test 272e "DoM mirroring: DOM mirror to the OST-striped file"
23485
23486 test_272f() {
23487         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
23488                 skip "Need MDS version at least 2.12.55"
23489
23490         local dom=$DIR/$tdir/$tfile
23491         mkdir -p $DIR/$tdir
23492         $LFS setstripe -c 2 $dom
23493
23494         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
23495                 error "failed to write data into $dom"
23496         local old_md5=$(md5sum $dom)
23497         cancel_lru_locks
23498
23499         $LFS migrate -E 1M -L mdt -E eof -c2 -v $dom ||
23500                 error "failed migrating to the DOM file"
23501
23502         [[ $($LFS getstripe -L --component-start=0 $dom) == 'mdt' ]] ||
23503                 error "MDT stripe wasn't set"
23504
23505         cancel_lru_locks
23506         local new_md5=$(md5sum $dom)
23507         [ "$old_md5" != "$new_md5" ] &&
23508                 error "$old_md5 != $new_md5"
23509
23510         return 0
23511 }
23512 run_test 272f "DoM migration: OST-striped file to DOM file"
23513
23514 test_273a() {
23515         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
23516                 skip "Need MDS version at least 2.11.50"
23517
23518         # Layout swap cannot be done if either file has DOM component,
23519         # this will never be supported, migration should be used instead
23520
23521         local dom=$DIR/$tdir/$tfile
23522         mkdir -p $DIR/$tdir
23523
23524         $LFS setstripe -c2 ${dom}_plain
23525         $LFS setstripe -E 1M -L mdt -E -1 -c2 ${dom}_dom
23526         $LFS swap_layouts ${dom}_plain ${dom}_dom &&
23527                 error "can swap layout with DoM component"
23528         $LFS swap_layouts ${dom}_dom ${dom}_plain &&
23529                 error "can swap layout with DoM component"
23530
23531         $LFS setstripe -E 1M -c1 -E -1 -c2 ${dom}_comp
23532         $LFS swap_layouts ${dom}_comp ${dom}_dom &&
23533                 error "can swap layout with DoM component"
23534         $LFS swap_layouts ${dom}_dom ${dom}_comp &&
23535                 error "can swap layout with DoM component"
23536         return 0
23537 }
23538 run_test 273a "DoM: layout swapping should fail with DOM"
23539
23540 test_273b() {
23541         mkdir -p $DIR/$tdir
23542         $LFS setstripe -E 1M -L mdt -E -1 -c -1 $DIR/$tdir
23543
23544 #define OBD_FAIL_MDS_COMMITRW_DELAY      0x16b
23545         do_facet mds1 $LCTL set_param fail_loc=0x8000016b fail_val=2
23546
23547         $MULTIOP $DIR/$tdir/$tfile Ouw2097152c
23548 }
23549 run_test 273b "DoM: race writeback and object destroy"
23550
23551 test_275() {
23552         remote_ost_nodsh && skip "remote OST with nodsh"
23553         [ $OST1_VERSION -lt $(version_code 2.10.57) ] &&
23554                 skip "Need OST version >= 2.10.57"
23555
23556         local file=$DIR/$tfile
23557         local oss
23558
23559         oss=$(comma_list $(osts_nodes))
23560
23561         dd if=/dev/urandom of=$file bs=1M count=2 ||
23562                 error "failed to create a file"
23563         cancel_lru_locks osc
23564
23565         #lock 1
23566         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
23567                 error "failed to read a file"
23568
23569 #define OBD_FAIL_LDLM_PAUSE_CANCEL2      0x31f
23570         $LCTL set_param fail_loc=0x8000031f
23571
23572         cancel_lru_locks osc &
23573         sleep 1
23574
23575 #define OBD_FAIL_LDLM_PROLONG_PAUSE      0x32b
23576         do_nodes $oss $LCTL set_param fail_loc=0x8000032b
23577         #IO takes another lock, but matches the PENDING one
23578         #and places it to the IO RPC
23579         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
23580                 error "failed to read a file with PENDING lock"
23581 }
23582 run_test 275 "Read on a canceled duplicate lock"
23583
23584 test_276() {
23585         remote_ost_nodsh && skip "remote OST with nodsh"
23586         local pid
23587
23588         do_facet ost1 "(while true; do \
23589                 $LCTL get_param obdfilter.*.filesfree > /dev/null 2>&1; \
23590                 done) & pid=\\\$!; echo \\\$pid > $TMP/sanity_276_pid" &
23591         pid=$!
23592
23593         for LOOP in $(seq 20); do
23594                 stop ost1
23595                 start ost1 $(ostdevname 1) $OST_MOUNT_OPTS
23596         done
23597         kill -9 $pid
23598         do_facet ost1 "pid=\\\$(cat $TMP/sanity_276_pid); kill -9 \\\$pid; \
23599                 rm $TMP/sanity_276_pid"
23600 }
23601 run_test 276 "Race between mount and obd_statfs"
23602
23603 test_277() {
23604         $LCTL set_param ldlm.namespaces.*.lru_size=0
23605         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
23606         local cached_mb=$($LCTL get_param llite.*.max_cached_mb |
23607                         grep ^used_mb | awk '{print $2}')
23608         [ $cached_mb -eq 1 ] || error "expected mb 1 got $cached_mb"
23609         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 \
23610                 oflag=direct conv=notrunc
23611         cached_mb=$($LCTL get_param llite.*.max_cached_mb |
23612                         grep ^used_mb | awk '{print $2}')
23613         [ $cached_mb -eq 0 ] || error "expected mb 0 got $cached_mb"
23614 }
23615 run_test 277 "Direct IO shall drop page cache"
23616
23617 test_278() {
23618         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
23619         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
23620         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] &&
23621                 skip "needs the same host for mdt1 mdt2" && return
23622
23623         local pid1
23624         local pid2
23625
23626 #define OBD_FAIL_OBD_STOP_MDS_RACE     0x60b
23627         do_facet mds2 $LCTL set_param fail_loc=0x8000060c
23628         stop mds2 &
23629         pid2=$!
23630
23631         stop mds1
23632
23633         echo "Starting MDTs"
23634         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
23635         wait $pid2
23636 #For the error assertion will happen. lu_env_get_key(..., &mdt_thread_key)
23637 #will return NULL
23638         do_facet mds2 $LCTL set_param fail_loc=0
23639
23640         start mds2 $(mdsdevname 2) $MDS_MOUNT_OPTS
23641         wait_recovery_complete mds2
23642 }
23643 run_test 278 "Race starting MDS between MDTs stop/start"
23644
23645 test_280() {
23646         [ $MGS_VERSION -lt $(version_code 2.13.52) ] &&
23647                 skip "Need MGS version at least 2.13.52"
23648         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23649         combined_mgs_mds || skip "needs combined MGS/MDT"
23650
23651         umount_client $MOUNT
23652 #define OBD_FAIL_MDS_LLOG_UMOUNT_RACE   0x15e
23653         do_facet mgs $LCTL set_param fail_loc=0x8000015e fail_val=0
23654
23655         mount_client $MOUNT &
23656         sleep 1
23657         stop mgs || error "stop mgs failed"
23658         #for a race mgs would crash
23659         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
23660         # make sure we unmount client before remounting
23661         wait
23662         umount_client $MOUNT
23663         mount_client $MOUNT || error "mount client failed"
23664 }
23665 run_test 280 "Race between MGS umount and client llog processing"
23666
23667 cleanup_test_300() {
23668         trap 0
23669         umask $SAVE_UMASK
23670 }
23671 test_striped_dir() {
23672         local mdt_index=$1
23673         local stripe_count
23674         local stripe_index
23675
23676         mkdir -p $DIR/$tdir
23677
23678         SAVE_UMASK=$(umask)
23679         trap cleanup_test_300 RETURN EXIT
23680
23681         $LFS setdirstripe -i $mdt_index -c 2 -H all_char -o 755 \
23682                                                 $DIR/$tdir/striped_dir ||
23683                 error "set striped dir error"
23684
23685         local mode=$(stat -c%a $DIR/$tdir/striped_dir)
23686         [ "$mode" = "755" ] || error "expect 755 got $mode"
23687
23688         $LFS getdirstripe $DIR/$tdir/striped_dir > /dev/null 2>&1 ||
23689                 error "getdirstripe failed"
23690         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir)
23691         if [ "$stripe_count" != "2" ]; then
23692                 error "1:stripe_count is $stripe_count, expect 2"
23693         fi
23694         stripe_count=$($LFS getdirstripe -T $DIR/$tdir/striped_dir)
23695         if [ "$stripe_count" != "2" ]; then
23696                 error "2:stripe_count is $stripe_count, expect 2"
23697         fi
23698
23699         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir)
23700         if [ "$stripe_index" != "$mdt_index" ]; then
23701                 error "stripe_index is $stripe_index, expect $mdt_index"
23702         fi
23703
23704         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
23705                 error "nlink error after create striped dir"
23706
23707         mkdir $DIR/$tdir/striped_dir/a
23708         mkdir $DIR/$tdir/striped_dir/b
23709
23710         stat $DIR/$tdir/striped_dir/a ||
23711                 error "create dir under striped dir failed"
23712         stat $DIR/$tdir/striped_dir/b ||
23713                 error "create dir under striped dir failed"
23714
23715         [ $(stat -c%h $DIR/$tdir/striped_dir) == '4' ] ||
23716                 error "nlink error after mkdir"
23717
23718         rmdir $DIR/$tdir/striped_dir/a
23719         [ $(stat -c%h $DIR/$tdir/striped_dir) == '3' ] ||
23720                 error "nlink error after rmdir"
23721
23722         rmdir $DIR/$tdir/striped_dir/b
23723         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
23724                 error "nlink error after rmdir"
23725
23726         chattr +i $DIR/$tdir/striped_dir
23727         createmany -o $DIR/$tdir/striped_dir/f 10 &&
23728                 error "immutable flags not working under striped dir!"
23729         chattr -i $DIR/$tdir/striped_dir
23730
23731         rmdir $DIR/$tdir/striped_dir ||
23732                 error "rmdir striped dir error"
23733
23734         cleanup_test_300
23735
23736         true
23737 }
23738
23739 test_300a() {
23740         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
23741                 skip "skipped for lustre < 2.7.0"
23742         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23743         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23744
23745         test_striped_dir 0 || error "failed on striped dir on MDT0"
23746         test_striped_dir 1 || error "failed on striped dir on MDT0"
23747 }
23748 run_test 300a "basic striped dir sanity test"
23749
23750 test_300b() {
23751         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
23752                 skip "skipped for lustre < 2.7.0"
23753         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23754         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23755
23756         local i
23757         local mtime1
23758         local mtime2
23759         local mtime3
23760
23761         test_mkdir $DIR/$tdir || error "mkdir fail"
23762         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
23763                 error "set striped dir error"
23764         for i in {0..9}; do
23765                 mtime1=$(stat -c %Y $DIR/$tdir/striped_dir)
23766                 sleep 1
23767                 touch $DIR/$tdir/striped_dir/file_$i || error "touch error $i"
23768                 mtime2=$(stat -c %Y $DIR/$tdir/striped_dir)
23769                 [ $mtime1 -eq $mtime2 ] && error "mtime unchanged after create"
23770                 sleep 1
23771                 rm -f $DIR/$tdir/striped_dir/file_$i || error "unlink error $i"
23772                 mtime3=$(stat -c %Y $DIR/$tdir/striped_dir)
23773                 [ $mtime2 -eq $mtime3 ] && error "mtime unchanged after unlink"
23774         done
23775         true
23776 }
23777 run_test 300b "check ctime/mtime for striped dir"
23778
23779 test_300c() {
23780         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
23781                 skip "skipped for lustre < 2.7.0"
23782         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23783         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23784
23785         local file_count
23786
23787         mkdir_on_mdt0 $DIR/$tdir
23788         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir ||
23789                 error "set striped dir error"
23790
23791         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/striped_dir ||
23792                 error "chown striped dir failed"
23793
23794         $RUNAS createmany -o $DIR/$tdir/striped_dir/f 5000 ||
23795                 error "create 5k files failed"
23796
23797         file_count=$(ls $DIR/$tdir/striped_dir | wc -l)
23798
23799         [ "$file_count" = 5000 ] || error "file count $file_count != 5000"
23800
23801         rm -rf $DIR/$tdir
23802 }
23803 run_test 300c "chown && check ls under striped directory"
23804
23805 test_300d() {
23806         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
23807                 skip "skipped for lustre < 2.7.0"
23808         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23809         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23810
23811         local stripe_count
23812         local file
23813
23814         mkdir -p $DIR/$tdir
23815         $LFS setstripe -c 2 $DIR/$tdir
23816
23817         #local striped directory
23818         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
23819                 error "set striped dir error"
23820         #look at the directories for debug purposes
23821         ls -l $DIR/$tdir
23822         $LFS getdirstripe $DIR/$tdir
23823         ls -l $DIR/$tdir/striped_dir
23824         $LFS getdirstripe $DIR/$tdir/striped_dir
23825         createmany -o $DIR/$tdir/striped_dir/f 10 ||
23826                 error "create 10 files failed"
23827
23828         #remote striped directory
23829         $LFS setdirstripe -i 1 -c 2 $DIR/$tdir/remote_striped_dir ||
23830                 error "set striped dir error"
23831         #look at the directories for debug purposes
23832         ls -l $DIR/$tdir
23833         $LFS getdirstripe $DIR/$tdir
23834         ls -l $DIR/$tdir/remote_striped_dir
23835         $LFS getdirstripe $DIR/$tdir/remote_striped_dir
23836         createmany -o $DIR/$tdir/remote_striped_dir/f 10 ||
23837                 error "create 10 files failed"
23838
23839         for file in $(find $DIR/$tdir); do
23840                 stripe_count=$($LFS getstripe -c $file)
23841                 [ $stripe_count -eq 2 ] ||
23842                         error "wrong stripe $stripe_count for $file"
23843         done
23844
23845         rm -rf $DIR/$tdir
23846 }
23847 run_test 300d "check default stripe under striped directory"
23848
23849 test_300e() {
23850         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23851                 skip "Need MDS version at least 2.7.55"
23852         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23853         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23854
23855         local stripe_count
23856         local file
23857
23858         mkdir -p $DIR/$tdir
23859
23860         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
23861                 error "set striped dir error"
23862
23863         touch $DIR/$tdir/striped_dir/a
23864         touch $DIR/$tdir/striped_dir/b
23865         touch $DIR/$tdir/striped_dir/c
23866
23867         mkdir $DIR/$tdir/striped_dir/dir_a
23868         mkdir $DIR/$tdir/striped_dir/dir_b
23869         mkdir $DIR/$tdir/striped_dir/dir_c
23870
23871         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_a ||
23872                 error "set striped adir under striped dir error"
23873
23874         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_b ||
23875                 error "set striped bdir under striped dir error"
23876
23877         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_c ||
23878                 error "set striped cdir under striped dir error"
23879
23880         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir/dir_b ||
23881                 error "rename dir under striped dir fails"
23882
23883         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir/stp_b ||
23884                 error "rename dir under different stripes fails"
23885
23886         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir/c ||
23887                 error "rename file under striped dir should succeed"
23888
23889         mrename $DIR/$tdir/striped_dir/dir_b $DIR/$tdir/striped_dir/dir_c ||
23890                 error "rename dir under striped dir should succeed"
23891
23892         rm -rf $DIR/$tdir
23893 }
23894 run_test 300e "check rename under striped directory"
23895
23896 test_300f() {
23897         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23898         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23899         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23900                 skip "Need MDS version at least 2.7.55"
23901
23902         local stripe_count
23903         local file
23904
23905         rm -rf $DIR/$tdir
23906         mkdir -p $DIR/$tdir
23907
23908         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
23909                 error "set striped dir error"
23910
23911         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir1 ||
23912                 error "set striped dir error"
23913
23914         touch $DIR/$tdir/striped_dir/a
23915         mkdir $DIR/$tdir/striped_dir/dir_a
23916         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_a ||
23917                 error "create striped dir under striped dir fails"
23918
23919         touch $DIR/$tdir/striped_dir1/b
23920         mkdir $DIR/$tdir/striped_dir1/dir_b
23921         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_b ||
23922                 error "create striped dir under striped dir fails"
23923
23924         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir1/dir_b ||
23925                 error "rename dir under different striped dir should fail"
23926
23927         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir1/stp_b ||
23928                 error "rename striped dir under diff striped dir should fail"
23929
23930         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir1/a ||
23931                 error "rename file under diff striped dirs fails"
23932
23933         rm -rf $DIR/$tdir
23934 }
23935 run_test 300f "check rename cross striped directory"
23936
23937 test_300_check_default_striped_dir()
23938 {
23939         local dirname=$1
23940         local default_count=$2
23941         local default_index=$3
23942         local stripe_count
23943         local stripe_index
23944         local dir_stripe_index
23945         local dir
23946
23947         echo "checking $dirname $default_count $default_index"
23948         $LFS setdirstripe -D -c $default_count -i $default_index \
23949                                 -H all_char $DIR/$tdir/$dirname ||
23950                 error "set default stripe on striped dir error"
23951         stripe_count=$($LFS getdirstripe -D -c $DIR/$tdir/$dirname)
23952         [ $stripe_count -eq $default_count ] ||
23953                 error "expect $default_count get $stripe_count for $dirname"
23954
23955         stripe_index=$($LFS getdirstripe -D -i $DIR/$tdir/$dirname)
23956         [ $stripe_index -eq $default_index ] ||
23957                 error "expect $default_index get $stripe_index for $dirname"
23958
23959         mkdir $DIR/$tdir/$dirname/{test1,test2,test3,test4} ||
23960                                                 error "create dirs failed"
23961
23962         createmany -o $DIR/$tdir/$dirname/f- 10 || error "create files failed"
23963         unlinkmany $DIR/$tdir/$dirname/f- 10    || error "unlink files failed"
23964         for dir in $(find $DIR/$tdir/$dirname/*); do
23965                 stripe_count=$($LFS getdirstripe -c $dir)
23966                 (( $stripe_count == $default_count )) ||
23967                 (( $stripe_count == $MDSCOUNT && $default_count == -1 )) ||
23968                 (( $stripe_count == 0 )) || (( $default_count == 1 )) ||
23969                 error "stripe count $default_count != $stripe_count for $dir"
23970
23971                 stripe_index=$($LFS getdirstripe -i $dir)
23972                 [ $default_index -eq -1 ] ||
23973                         [ $stripe_index -eq $default_index ] ||
23974                         error "$stripe_index != $default_index for $dir"
23975
23976                 #check default stripe
23977                 stripe_count=$($LFS getdirstripe -D -c $dir)
23978                 [ $stripe_count -eq $default_count ] ||
23979                 error "default count $default_count != $stripe_count for $dir"
23980
23981                 stripe_index=$($LFS getdirstripe -D -i $dir)
23982                 [ $stripe_index -eq $default_index ] ||
23983                 error "default index $default_index != $stripe_index for $dir"
23984         done
23985         rmdir $DIR/$tdir/$dirname/* || error "rmdir failed"
23986 }
23987
23988 test_300g() {
23989         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23990         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23991                 skip "Need MDS version at least 2.7.55"
23992
23993         local dir
23994         local stripe_count
23995         local stripe_index
23996
23997         mkdir_on_mdt0 $DIR/$tdir
23998         mkdir $DIR/$tdir/normal_dir
23999
24000         #Checking when client cache stripe index
24001         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
24002         $LFS setdirstripe -D -i1 $DIR/$tdir/striped_dir ||
24003                 error "create striped_dir failed"
24004
24005         $LFS setdirstripe -i0 $DIR/$tdir/striped_dir/dir0 ||
24006                 error "create dir0 fails"
24007         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir0)
24008         [ $stripe_index -eq 0 ] ||
24009                 error "dir0 expect index 0 got $stripe_index"
24010
24011         mkdir $DIR/$tdir/striped_dir/dir1 ||
24012                 error "create dir1 fails"
24013         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir1)
24014         [ $stripe_index -eq 1 ] ||
24015                 error "dir1 expect index 1 got $stripe_index"
24016
24017         #check default stripe count/stripe index
24018         test_300_check_default_striped_dir normal_dir $MDSCOUNT 1
24019         test_300_check_default_striped_dir normal_dir 1 0
24020         test_300_check_default_striped_dir normal_dir -1 1
24021         test_300_check_default_striped_dir normal_dir 2 -1
24022
24023         #delete default stripe information
24024         echo "delete default stripeEA"
24025         $LFS setdirstripe -d $DIR/$tdir/normal_dir ||
24026                 error "set default stripe on striped dir error"
24027
24028         mkdir -p $DIR/$tdir/normal_dir/{test1,test2,test3,test4}
24029         for dir in $(find $DIR/$tdir/normal_dir/*); do
24030                 stripe_count=$($LFS getdirstripe -c $dir)
24031                 [ $stripe_count -eq 0 ] ||
24032                         error "expect 1 get $stripe_count for $dir"
24033         done
24034 }
24035 run_test 300g "check default striped directory for normal directory"
24036
24037 test_300h() {
24038         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24039         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24040                 skip "Need MDS version at least 2.7.55"
24041
24042         local dir
24043         local stripe_count
24044
24045         mkdir $DIR/$tdir
24046         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
24047                 error "set striped dir error"
24048
24049         test_300_check_default_striped_dir striped_dir $MDSCOUNT 1
24050         test_300_check_default_striped_dir striped_dir 1 0
24051         test_300_check_default_striped_dir striped_dir -1 1
24052         test_300_check_default_striped_dir striped_dir 2 -1
24053
24054         #delete default stripe information
24055         $LFS setdirstripe -d $DIR/$tdir/striped_dir ||
24056                 error "set default stripe on striped dir error"
24057
24058         mkdir -p $DIR/$tdir/striped_dir/{test1,test2,test3,test4}
24059         for dir in $(find $DIR/$tdir/striped_dir/*); do
24060                 stripe_count=$($LFS getdirstripe -c $dir)
24061                 [ $stripe_count -eq 0 ] ||
24062                         error "expect 1 get $stripe_count for $dir"
24063         done
24064 }
24065 run_test 300h "check default striped directory for striped directory"
24066
24067 test_300i() {
24068         [[ $PARALLEL == "yes" ]] && skip "skip parallel run"
24069         (( $MDSCOUNT >= 2 )) || skip_env "needs >= 2 MDTs"
24070         (( $MDS1_VERSION >= $(version_code 2.7.55) )) ||
24071                 skip "Need MDS version at least 2.7.55"
24072
24073         local stripe_count
24074         local file
24075
24076         mkdir $DIR/$tdir
24077
24078         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
24079                 error "set striped dir error"
24080
24081         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
24082                 error "create files under striped dir failed"
24083
24084         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir ||
24085                 error "set striped hashdir error"
24086
24087         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir/d0 ||
24088                 error "create dir0 under hash dir failed"
24089         $LFS setdirstripe -i0 -c$MDSCOUNT -H fnv_1a_64 $DIR/$tdir/hashdir/d1 ||
24090                 error "create dir1 under hash dir failed"
24091         $LFS setdirstripe -i0 -c$MDSCOUNT -H crush $DIR/$tdir/hashdir/d2 ||
24092                 error "create dir2 under hash dir failed"
24093
24094         # unfortunately, we need to umount to clear dir layout cache for now
24095         # once we fully implement dir layout, we can drop this
24096         umount_client $MOUNT || error "umount failed"
24097         mount_client $MOUNT || error "mount failed"
24098
24099         $LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir
24100         local dircnt=$($LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir | wc -l)
24101         (( $dircnt == 2 )) || error "lfs find striped dir got $dircnt != 2"
24102
24103         if (( $MDS1_VERSION > $(version_code 2.15.0) )); then
24104                 $LFS mkdir -i0 -c$MDSCOUNT -H crush2 $DIR/$tdir/hashdir/d3 ||
24105                         error "create crush2 dir $tdir/hashdir/d3 failed"
24106                 $LFS find -H crush2 $DIR/$tdir/hashdir
24107                 dircnt=$($LFS find -H crush2 $DIR/$tdir/hashdir | wc -l)
24108                 (( $dircnt == 1 )) || error "find crush2 dir got $dircnt != 1"
24109
24110                 # mkdir with an invalid hash type (hash=fail_val) from client
24111                 # should be replaced on MDS with a valid (default) hash type
24112                 #define OBD_FAIL_LMV_UNKNOWN_STRIPE     0x1901
24113                 $LCTL set_param fail_loc=0x1901 fail_val=99
24114                 $LFS mkdir -c2 $DIR/$tdir/hashdir/d99
24115
24116                 local hash=$($LFS getdirstripe -H $DIR/$tdir/hashdir/d99)
24117                 local expect=$(do_facet mds1 \
24118                         $LCTL get_param -n lod.$FSNAME-MDT0000-mdtlov.mdt_hash)
24119                 [[ $hash == $expect ]] ||
24120                         error "d99 hash '$hash' != expected hash '$expect'"
24121         fi
24122
24123         #set the stripe to be unknown hash type on read
24124         #define OBD_FAIL_LMV_UNKNOWN_STRIPE     0x1901
24125         $LCTL set_param fail_loc=0x1901 fail_val=99
24126         for ((i = 0; i < 10; i++)); do
24127                 $CHECKSTAT -t file $DIR/$tdir/striped_dir/f-$i ||
24128                         error "stat f-$i failed"
24129                 rm $DIR/$tdir/striped_dir/f-$i || error "unlink f-$i failed"
24130         done
24131
24132         touch $DIR/$tdir/striped_dir/f0 &&
24133                 error "create under striped dir with unknown hash should fail"
24134
24135         $LCTL set_param fail_loc=0
24136
24137         umount_client $MOUNT || error "umount failed"
24138         mount_client $MOUNT || error "mount failed"
24139
24140         return 0
24141 }
24142 run_test 300i "client handle unknown hash type striped directory"
24143
24144 test_300j() {
24145         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24146         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24147         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24148                 skip "Need MDS version at least 2.7.55"
24149
24150         local stripe_count
24151         local file
24152
24153         mkdir $DIR/$tdir
24154
24155         #define OBD_FAIL_SPLIT_UPDATE_REC       0x1702
24156         $LCTL set_param fail_loc=0x1702
24157         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
24158                 error "set striped dir error"
24159
24160         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
24161                 error "create files under striped dir failed"
24162
24163         $LCTL set_param fail_loc=0
24164
24165         rm -rf $DIR/$tdir || error "unlink striped dir fails"
24166
24167         return 0
24168 }
24169 run_test 300j "test large update record"
24170
24171 test_300k() {
24172         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24173         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24174         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24175                 skip "Need MDS version at least 2.7.55"
24176
24177         # this test needs a huge transaction
24178         local kb
24179         kb=$(do_facet $SINGLEMDS "$LCTL get_param -n \
24180              osd*.$FSNAME-MDT0000.kbytestotal")
24181         [ $kb -lt $((1024*1024)) ] && skip "MDT0 too small: $kb"
24182
24183         local stripe_count
24184         local file
24185
24186         mkdir $DIR/$tdir
24187
24188         #define OBD_FAIL_LARGE_STRIPE   0x1703
24189         $LCTL set_param fail_loc=0x1703
24190         $LFS setdirstripe -i 0 -c192 $DIR/$tdir/striped_dir ||
24191                 error "set striped dir error"
24192         $LCTL set_param fail_loc=0
24193
24194         $LFS getdirstripe $DIR/$tdir/striped_dir ||
24195                 error "getstripeddir fails"
24196         rm -rf $DIR/$tdir/striped_dir ||
24197                 error "unlink striped dir fails"
24198
24199         return 0
24200 }
24201 run_test 300k "test large striped directory"
24202
24203 test_300l() {
24204         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24205         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24206         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24207                 skip "Need MDS version at least 2.7.55"
24208
24209         local stripe_index
24210
24211         test_mkdir -p $DIR/$tdir/striped_dir
24212         chown $RUNAS_ID $DIR/$tdir/striped_dir ||
24213                         error "chown $RUNAS_ID failed"
24214         $LFS setdirstripe -i 1 -D $DIR/$tdir/striped_dir ||
24215                 error "set default striped dir failed"
24216
24217         #define OBD_FAIL_MDS_STALE_DIR_LAYOUT    0x158
24218         $LCTL set_param fail_loc=0x80000158
24219         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir || error "create dir fails"
24220
24221         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/test_dir)
24222         [ $stripe_index -eq 1 ] ||
24223                 error "expect 1 get $stripe_index for $dir"
24224 }
24225 run_test 300l "non-root user to create dir under striped dir with stale layout"
24226
24227 test_300m() {
24228         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24229         [ $MDSCOUNT -ge 2 ] && skip_env "Only for single MDT"
24230         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24231                 skip "Need MDS version at least 2.7.55"
24232
24233         mkdir -p $DIR/$tdir/striped_dir
24234         $LFS setdirstripe -D -c 1 $DIR/$tdir/striped_dir ||
24235                 error "set default stripes dir error"
24236
24237         mkdir $DIR/$tdir/striped_dir/a || error "mkdir a fails"
24238
24239         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/a)
24240         [ $stripe_count -eq 0 ] ||
24241                         error "expect 0 get $stripe_count for a"
24242
24243         $LFS setdirstripe -D -c 2 $DIR/$tdir/striped_dir ||
24244                 error "set default stripes dir error"
24245
24246         mkdir $DIR/$tdir/striped_dir/b || error "mkdir b fails"
24247
24248         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/b)
24249         [ $stripe_count -eq 0 ] ||
24250                         error "expect 0 get $stripe_count for b"
24251
24252         $LFS setdirstripe -D -c1 -i2 $DIR/$tdir/striped_dir ||
24253                 error "set default stripes dir error"
24254
24255         mkdir $DIR/$tdir/striped_dir/c &&
24256                 error "default stripe_index is invalid, mkdir c should fails"
24257
24258         rm -rf $DIR/$tdir || error "rmdir fails"
24259 }
24260 run_test 300m "setstriped directory on single MDT FS"
24261
24262 cleanup_300n() {
24263         local list=$(comma_list $(mdts_nodes))
24264
24265         trap 0
24266         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
24267 }
24268
24269 test_300n() {
24270         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24271         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24272         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24273                 skip "Need MDS version at least 2.7.55"
24274         remote_mds_nodsh && skip "remote MDS with nodsh"
24275
24276         local stripe_index
24277         local list=$(comma_list $(mdts_nodes))
24278
24279         trap cleanup_300n RETURN EXIT
24280         mkdir -p $DIR/$tdir
24281         chmod 777 $DIR/$tdir
24282         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT \
24283                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
24284                 error "create striped dir succeeds with gid=0"
24285
24286         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
24287         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
24288                 error "create striped dir fails with gid=-1"
24289
24290         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
24291         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D \
24292                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
24293                 error "set default striped dir succeeds with gid=0"
24294
24295
24296         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
24297         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D $DIR/$tdir/striped_dir ||
24298                 error "set default striped dir fails with gid=-1"
24299
24300
24301         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
24302         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir ||
24303                                         error "create test_dir fails"
24304         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir1 ||
24305                                         error "create test_dir1 fails"
24306         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir2 ||
24307                                         error "create test_dir2 fails"
24308         cleanup_300n
24309 }
24310 run_test 300n "non-root user to create dir under striped dir with default EA"
24311
24312 test_300o() {
24313         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24314         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24315         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24316                 skip "Need MDS version at least 2.7.55"
24317
24318         local numfree1
24319         local numfree2
24320
24321         mkdir -p $DIR/$tdir
24322
24323         numfree1=$(lctl get_param -n mdc.*MDT0000*.filesfree)
24324         numfree2=$(lctl get_param -n mdc.*MDT0001*.filesfree)
24325         if [ $numfree1 -lt 66000 ] || [ $numfree2 -lt 66000 ]; then
24326                 skip "not enough free inodes $numfree1 $numfree2"
24327         fi
24328
24329         numfree1=$(lctl get_param -n mdc.*MDT0000-mdc-*.kbytesfree)
24330         numfree2=$(lctl get_param -n mdc.*MDT0001-mdc-*.kbytesfree)
24331         if [ $numfree1 -lt 300000 ] || [ $numfree2 -lt 300000 ]; then
24332                 skip "not enough free space $numfree1 $numfree2"
24333         fi
24334
24335         $LFS setdirstripe -c2 $DIR/$tdir/striped_dir ||
24336                 error "setdirstripe fails"
24337
24338         createmany -d $DIR/$tdir/striped_dir/d 131000 ||
24339                 error "create dirs fails"
24340
24341         $LCTL set_param ldlm.namespaces.*mdc-*.lru_size=0
24342         ls $DIR/$tdir/striped_dir > /dev/null ||
24343                 error "ls striped dir fails"
24344         unlinkmany -d $DIR/$tdir/striped_dir/d 131000 ||
24345                 error "unlink big striped dir fails"
24346 }
24347 run_test 300o "unlink big sub stripe(> 65000 subdirs)"
24348
24349 test_300p() {
24350         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24351         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24352         remote_mds_nodsh && skip "remote MDS with nodsh"
24353
24354         mkdir_on_mdt0 $DIR/$tdir
24355
24356         #define OBD_FAIL_OUT_ENOSPC     0x1704
24357         do_facet mds2 lctl set_param fail_loc=0x80001704
24358         $LFS setdirstripe -i 0 -c2 $DIR/$tdir/bad_striped_dir > /dev/null 2>&1 \
24359                  && error "create striped directory should fail"
24360
24361         [ -e $DIR/$tdir/bad_striped_dir ] && error "striped dir exists"
24362
24363         $LFS setdirstripe -c2 $DIR/$tdir/bad_striped_dir
24364         true
24365 }
24366 run_test 300p "create striped directory without space"
24367
24368 test_300q() {
24369         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24370         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24371
24372         local fd=$(free_fd)
24373         local cmd="exec $fd<$tdir"
24374         cd $DIR
24375         $LFS mkdir -c $MDSCOUNT $tdir || error "create $tdir fails"
24376         eval $cmd
24377         cmd="exec $fd<&-"
24378         trap "eval $cmd" EXIT
24379         cd $tdir || error "cd $tdir fails"
24380         rmdir  ../$tdir || error "rmdir $tdir fails"
24381         mkdir local_dir && error "create dir succeeds"
24382         $LFS setdirstripe -i1 remote_dir && error "create remote dir succeeds"
24383         eval $cmd
24384         return 0
24385 }
24386 run_test 300q "create remote directory under orphan directory"
24387
24388 test_300r() {
24389         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24390                 skip "Need MDS version at least 2.7.55" && return
24391         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
24392
24393         mkdir $DIR/$tdir
24394
24395         $LFS setdirstripe -i 0 -c -1 $DIR/$tdir/striped_dir ||
24396                 error "set striped dir error"
24397
24398         $LFS getdirstripe $DIR/$tdir/striped_dir ||
24399                 error "getstripeddir fails"
24400
24401         local stripe_count
24402         stripe_count=$($LFS getdirstripe $DIR/$tdir/striped_dir |
24403                       awk '/lmv_stripe_count:/ { print $2 }')
24404
24405         [ $MDSCOUNT -ne $stripe_count ] &&
24406                 error "wrong stripe count $stripe_count expected $MDSCOUNT"
24407
24408         rm -rf $DIR/$tdir/striped_dir ||
24409                 error "unlink striped dir fails"
24410 }
24411 run_test 300r "test -1 striped directory"
24412
24413 test_300s_helper() {
24414         local count=$1
24415
24416         local stripe_dir=$DIR/$tdir/striped_dir.$count
24417
24418         $LFS mkdir -c $count $stripe_dir ||
24419                 error "lfs mkdir -c error"
24420
24421         $LFS getdirstripe $stripe_dir ||
24422                 error "lfs getdirstripe fails"
24423
24424         local stripe_count
24425         stripe_count=$($LFS getdirstripe $stripe_dir |
24426                       awk '/lmv_stripe_count:/ { print $2 }')
24427
24428         [ $count -ne $stripe_count ] &&
24429                 error_noexit "bad stripe count $stripe_count expected $count"
24430
24431         local dupe_stripes
24432         dupe_stripes=$($LFS getdirstripe $stripe_dir |
24433                 awk '/0x/ {count[$1] += 1}; END {
24434                         for (idx in count) {
24435                                 if (count[idx]>1) {
24436                                         print "index " idx " count " count[idx]
24437                                 }
24438                         }
24439                 }')
24440
24441         if [[ -n "$dupe_stripes" ]] ; then
24442                 lfs getdirstripe $stripe_dir
24443                 error_noexit "Dupe MDT above: $dupe_stripes "
24444         fi
24445
24446         rm -rf $stripe_dir ||
24447                 error_noexit "unlink $stripe_dir fails"
24448 }
24449
24450 test_300s() {
24451         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24452                 skip "Need MDS version at least 2.7.55" && return
24453         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
24454
24455         mkdir $DIR/$tdir
24456         for count in $(seq 2 $MDSCOUNT); do
24457                 test_300s_helper $count
24458         done
24459 }
24460 run_test 300s "test lfs mkdir -c without -i"
24461
24462 test_300t() {
24463         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
24464                 skip "need MDS 2.14.55 or later"
24465         (( $MDSCOUNT >= 2 )) || skip "needs at least 2 MDTs"
24466
24467         local testdir="$DIR/$tdir/striped_dir"
24468         local dir1=$testdir/dir1
24469         local dir2=$testdir/dir2
24470
24471         mkdir -p $testdir
24472
24473         $LFS setdirstripe -D -c -1 --max-inherit=3 $testdir ||
24474                 error "failed to set default stripe count for $testdir"
24475
24476         mkdir $dir1
24477         local stripe_count=$($LFS getdirstripe -c $dir1)
24478
24479         (( $stripe_count == $MDSCOUNT )) || error "wrong stripe count"
24480
24481         local max_count=$((MDSCOUNT - 1))
24482         local mdts=$(comma_list $(mdts_nodes))
24483
24484         do_nodes $mdts $LCTL set_param lod.*.max_mdt_stripecount=$max_count
24485         stack_trap "do_nodes $mdts $LCTL set_param lod.*.max_mdt_stripecount=0"
24486
24487         mkdir $dir2
24488         stripe_count=$($LFS getdirstripe -c $dir2)
24489
24490         (( $stripe_count == $max_count )) || error "wrong stripe count"
24491 }
24492 run_test 300t "test max_mdt_stripecount"
24493
24494 prepare_remote_file() {
24495         mkdir $DIR/$tdir/src_dir ||
24496                 error "create remote source failed"
24497
24498         cp /etc/hosts $DIR/$tdir/src_dir/a ||
24499                  error "cp to remote source failed"
24500         touch $DIR/$tdir/src_dir/a
24501
24502         $LFS mkdir -i 1 $DIR/$tdir/tgt_dir ||
24503                 error "create remote target dir failed"
24504
24505         touch $DIR/$tdir/tgt_dir/b
24506
24507         mrename $DIR/$tdir/src_dir/a $DIR/$tdir/tgt_dir/b ||
24508                 error "rename dir cross MDT failed!"
24509
24510         $CHECKSTAT -t file $DIR/$tdir/src_dir/a &&
24511                 error "src_child still exists after rename"
24512
24513         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/b ||
24514                 error "missing file(a) after rename"
24515
24516         diff /etc/hosts $DIR/$tdir/tgt_dir/b ||
24517                 error "diff after rename"
24518 }
24519
24520 test_310a() {
24521         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
24522         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24523
24524         local remote_file=$DIR/$tdir/tgt_dir/b
24525
24526         mkdir -p $DIR/$tdir
24527
24528         prepare_remote_file || error "prepare remote file failed"
24529
24530         #open-unlink file
24531         $OPENUNLINK $remote_file $remote_file ||
24532                 error "openunlink $remote_file failed"
24533         $CHECKSTAT -a $remote_file || error "$remote_file exists"
24534 }
24535 run_test 310a "open unlink remote file"
24536
24537 test_310b() {
24538         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
24539         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24540
24541         local remote_file=$DIR/$tdir/tgt_dir/b
24542
24543         mkdir -p $DIR/$tdir
24544
24545         prepare_remote_file || error "prepare remote file failed"
24546
24547         ln $remote_file $DIR/$tfile || error "link failed for remote file"
24548         $MULTIOP $DIR/$tfile Ouc || error "mulitop failed"
24549         $CHECKSTAT -t file $remote_file || error "check file failed"
24550 }
24551 run_test 310b "unlink remote file with multiple links while open"
24552
24553 test_310c() {
24554         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24555         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
24556
24557         local remote_file=$DIR/$tdir/tgt_dir/b
24558
24559         mkdir -p $DIR/$tdir
24560
24561         prepare_remote_file || error "prepare remote file failed"
24562
24563         ln $remote_file $DIR/$tfile || error "link failed for remote file"
24564         multiop_bg_pause $remote_file O_uc ||
24565                         error "mulitop failed for remote file"
24566         MULTIPID=$!
24567         $MULTIOP $DIR/$tfile Ouc
24568         kill -USR1 $MULTIPID
24569         wait $MULTIPID
24570 }
24571 run_test 310c "open-unlink remote file with multiple links"
24572
24573 #LU-4825
24574 test_311() {
24575         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24576         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
24577         [ $MDS1_VERSION -lt $(version_code 2.8.54) ] &&
24578                 skip "lustre < 2.8.54 does not contain LU-4825 fix"
24579         remote_mds_nodsh && skip "remote MDS with nodsh"
24580
24581         local old_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
24582         local mdts=$(comma_list $(mdts_nodes))
24583
24584         mkdir -p $DIR/$tdir
24585         $LFS setstripe -i 0 -c 1 $DIR/$tdir
24586         createmany -o $DIR/$tdir/$tfile. 1000
24587
24588         # statfs data is not real time, let's just calculate it
24589         old_iused=$((old_iused + 1000))
24590
24591         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
24592                         osp.*OST0000*MDT0000.create_count")
24593         local max_count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
24594                                 osp.*OST0000*MDT0000.max_create_count")
24595         do_nodes $mdts "$LCTL set_param -n osp.*OST0000*.max_create_count=0"
24596
24597         $LFS setstripe -i 0 $DIR/$tdir/$tfile || error "setstripe failed"
24598         local index=$($LFS getstripe -i $DIR/$tdir/$tfile)
24599         [ $index -ne 0 ] || error "$tfile stripe index is 0"
24600
24601         unlinkmany $DIR/$tdir/$tfile. 1000
24602
24603         do_nodes $mdts "$LCTL set_param -n \
24604                         osp.*OST0000*.max_create_count=$max_count"
24605         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
24606                 do_nodes $mdts "$LCTL set_param -n \
24607                                 osp.*OST0000*.create_count=$count"
24608         do_nodes $mdts "$LCTL get_param osp.*OST0000*.create_count" |
24609                         grep "=0" && error "create_count is zero"
24610
24611         local new_iused
24612         for i in $(seq 120); do
24613                 new_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
24614                 # system may be too busy to destroy all objs in time, use
24615                 # a somewhat small value to not fail autotest
24616                 [ $((old_iused - new_iused)) -gt 400 ] && break
24617                 sleep 1
24618         done
24619
24620         echo "waited $i sec, old Iused $old_iused, new Iused $new_iused"
24621         [ $((old_iused - new_iused)) -gt 400 ] ||
24622                 error "objs not destroyed after unlink"
24623 }
24624 run_test 311 "disable OSP precreate, and unlink should destroy objs"
24625
24626 zfs_oid_to_objid()
24627 {
24628         local ost=$1
24629         local objid=$2
24630
24631         local vdevdir=$(dirname $(facet_vdevice $ost))
24632         local cmd="$ZDB -e -p $vdevdir -ddddd $(facet_device $ost)"
24633         local zfs_zapid=$(do_facet $ost $cmd |
24634                           grep -w "/O/0/d$((objid%32))" -C 5 |
24635                           awk '/Object/{getline; print $1}')
24636         local zfs_objid=$(do_facet $ost $cmd $zfs_zapid |
24637                           awk "/$objid = /"'{printf $3}')
24638
24639         echo $zfs_objid
24640 }
24641
24642 zfs_object_blksz() {
24643         local ost=$1
24644         local objid=$2
24645
24646         local vdevdir=$(dirname $(facet_vdevice $ost))
24647         local cmd="$ZDB -e -p $vdevdir -dddd $(facet_device $ost)"
24648         local blksz=$(do_facet $ost $cmd $objid |
24649                       awk '/dblk/{getline; printf $4}')
24650
24651         case "${blksz: -1}" in
24652                 k|K) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024)) ;;
24653                 m|M) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024*1024)) ;;
24654                 *) ;;
24655         esac
24656
24657         echo $blksz
24658 }
24659
24660 test_312() { # LU-4856
24661         remote_ost_nodsh && skip "remote OST with nodsh"
24662         [ "$ost1_FSTYPE" = "zfs" ] ||
24663                 skip_env "the test only applies to zfs"
24664
24665         local max_blksz=$(do_facet ost1 \
24666                           $ZFS get -p recordsize $(facet_device ost1) |
24667                           awk '!/VALUE/{print $3}')
24668
24669         # to make life a little bit easier
24670         $LFS mkdir -c 1 -i 0 $DIR/$tdir
24671         $LFS setstripe -c 1 -i 0 $DIR/$tdir
24672
24673         local tf=$DIR/$tdir/$tfile
24674         touch $tf
24675         local oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
24676
24677         # Get ZFS object id
24678         local zfs_objid=$(zfs_oid_to_objid ost1 $oid)
24679         # block size change by sequential overwrite
24680         local bs
24681
24682         for ((bs=$PAGE_SIZE; bs <= max_blksz; bs *= 4)) ; do
24683                 dd if=/dev/zero of=$tf bs=$bs count=1 oflag=sync conv=notrunc
24684
24685                 local blksz=$(zfs_object_blksz ost1 $zfs_objid)
24686                 [ $blksz -eq $bs ] || error "blksz error: $blksz, expected: $bs"
24687         done
24688         rm -f $tf
24689
24690         # block size change by sequential append write
24691         dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=1 oflag=sync conv=notrunc
24692         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
24693         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
24694         local count
24695
24696         for ((count = 1; count < $((max_blksz / PAGE_SIZE)); count *= 2)); do
24697                 dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=$count seek=$count \
24698                         oflag=sync conv=notrunc
24699
24700                 blksz=$(zfs_object_blksz ost1 $zfs_objid)
24701                 [ $blksz -eq $((2 * count * PAGE_SIZE)) ] ||
24702                         error "blksz error, actual $blksz, " \
24703                                 "expected: 2 * $count * $PAGE_SIZE"
24704         done
24705         rm -f $tf
24706
24707         # random write
24708         touch $tf
24709         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
24710         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
24711
24712         dd if=/dev/zero of=$tf bs=1K count=1 oflag=sync conv=notrunc
24713         blksz=$(zfs_object_blksz ost1 $zfs_objid)
24714         [ $blksz -eq $PAGE_SIZE ] ||
24715                 error "blksz error: $blksz, expected: $PAGE_SIZE"
24716
24717         dd if=/dev/zero of=$tf bs=64K count=1 oflag=sync conv=notrunc seek=128
24718         blksz=$(zfs_object_blksz ost1 $zfs_objid)
24719         [ $blksz -eq 65536 ] || error "blksz error: $blksz, expected: 64k"
24720
24721         dd if=/dev/zero of=$tf bs=1M count=1 oflag=sync conv=notrunc
24722         blksz=$(zfs_object_blksz ost1 $zfs_objid)
24723         [ $blksz -eq 65536 ] || error "rewrite error: $blksz, expected: 64k"
24724 }
24725 run_test 312 "make sure ZFS adjusts its block size by write pattern"
24726
24727 test_313() {
24728         remote_ost_nodsh && skip "remote OST with nodsh"
24729
24730         local file=$DIR/$tfile
24731
24732         rm -f $file
24733         $LFS setstripe -c 1 -i 0 $file || error "setstripe failed"
24734
24735         # define OBD_FAIL_TGT_RCVD_EIO           0x720
24736         do_facet ost1 "$LCTL set_param fail_loc=0x720"
24737         dd if=/dev/zero of=$file bs=$PAGE_SIZE oflag=direct count=1 &&
24738                 error "write should failed"
24739         do_facet ost1 "$LCTL set_param fail_loc=0"
24740         rm -f $file
24741 }
24742 run_test 313 "io should fail after last_rcvd update fail"
24743
24744 test_314() {
24745         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
24746
24747         $LFS setstripe -c 2 -i 0 $DIR/$tfile || error "setstripe failed"
24748         do_facet ost1 "$LCTL set_param fail_loc=0x720"
24749         rm -f $DIR/$tfile
24750         wait_delete_completed
24751         do_facet ost1 "$LCTL set_param fail_loc=0"
24752 }
24753 run_test 314 "OSP shouldn't fail after last_rcvd update failure"
24754
24755 test_315() { # LU-618
24756         [ -f /proc/$$/io ] || skip_env "no IO accounting in kernel"
24757
24758         local file=$DIR/$tfile
24759         rm -f $file
24760
24761         $MULTIOP $file oO_CREAT:O_DIRECT:O_RDWR:w4063232c ||
24762                 error "multiop file write failed"
24763         $MULTIOP $file oO_RDONLY:r4063232_c &
24764         PID=$!
24765
24766         sleep 2
24767
24768         local rbytes=$(awk '/read_bytes/ { print $2 }' /proc/$PID/io)
24769         kill -USR1 $PID
24770
24771         [ $rbytes -gt 4000000 ] || error "read is not accounted ($rbytes)"
24772         rm -f $file
24773 }
24774 run_test 315 "read should be accounted"
24775
24776 test_316() {
24777         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
24778         large_xattr_enabled || skip "ea_inode feature disabled"
24779
24780         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
24781         mkdir $DIR/$tdir/d || error "mkdir $tdir/d failed"
24782         chown nobody $DIR/$tdir/d || error "chown $tdir/d failed"
24783         touch $DIR/$tdir/d/$tfile || error "touch $tdir/d/$tfile failed"
24784
24785         $LFS migrate -m1 $DIR/$tdir/d || error "lfs migrate -m1 failed"
24786 }
24787 run_test 316 "lfs migrate of file with large_xattr enabled"
24788
24789 test_317() {
24790         [ $MDS1_VERSION -lt $(version_code 2.11.53) ] &&
24791                 skip "Need MDS version at least 2.11.53"
24792         if [ "$ost1_FSTYPE" == "zfs" ]; then
24793                 skip "LU-10370: no implementation for ZFS"
24794         fi
24795
24796         local trunc_sz
24797         local grant_blk_size
24798
24799         grant_blk_size=$($LCTL get_param osc.$FSNAME*.import |
24800                         awk '/grant_block_size:/ { print $2; exit; }')
24801         #
24802         # Create File of size 5M. Truncate it to below size's and verify
24803         # blocks count.
24804         #
24805         dd if=/dev/zero of=$DIR/$tfile bs=5M count=1 conv=fsync ||
24806                 error "Create file $DIR/$tfile failed"
24807         stack_trap "rm -f $DIR/$tfile" EXIT
24808
24809         for trunc_sz in 2097152 4097 4000 509 0; do
24810                 $TRUNCATE $DIR/$tfile $trunc_sz ||
24811                         error "truncate $tfile to $trunc_sz failed"
24812                 local sz=$(stat --format=%s $DIR/$tfile)
24813                 local blk=$(stat --format=%b $DIR/$tfile)
24814                 local trunc_blk=$((((trunc_sz + (grant_blk_size - 1) ) /
24815                                      grant_blk_size) * 8))
24816
24817                 if [[ $blk -ne $trunc_blk ]]; then
24818                         $(which stat) $DIR/$tfile
24819                         error "Expected Block $trunc_blk got $blk for $tfile"
24820                 fi
24821
24822                 $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
24823                         error "Expected Size $trunc_sz got $sz for $tfile"
24824         done
24825
24826         #
24827         # sparse file test
24828         # Create file with a hole and write actual 65536 bytes which aligned
24829         # with 4K and 64K PAGE_SIZE. Block count must be 128.
24830         #
24831         local bs=65536
24832         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 seek=5 conv=fsync ||
24833                 error "Create file : $DIR/$tfile"
24834
24835         #
24836         # Truncate to size $trunc_sz bytes. Strip tail blocks and leave only 8
24837         # blocks. The block count must drop to 8.
24838         #
24839         trunc_sz=$(($(stat --format=%s $DIR/$tfile) -
24840                 ((bs - grant_blk_size) + 1)))
24841         $TRUNCATE $DIR/$tfile $trunc_sz ||
24842                 error "truncate $tfile to $trunc_sz failed"
24843
24844         local trunc_bsz=$((grant_blk_size / $(stat --format=%B $DIR/$tfile)))
24845         sz=$(stat --format=%s $DIR/$tfile)
24846         blk=$(stat --format=%b $DIR/$tfile)
24847
24848         if [[ $blk -ne $trunc_bsz ]]; then
24849                 $(which stat) $DIR/$tfile
24850                 error "Expected Block $trunc_bsz got $blk for $tfile"
24851         fi
24852
24853         $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
24854                 error "Expected Size $trunc_sz got $sz for $tfile"
24855 }
24856 run_test 317 "Verify blocks get correctly update after truncate"
24857
24858 test_318() {
24859         local llite_name="llite.$($LFS getname $MOUNT | awk '{print $1}')"
24860         local old_max_active=$($LCTL get_param -n \
24861                             ${llite_name}.max_read_ahead_async_active \
24862                             2>/dev/null)
24863
24864         $LCTL set_param llite.*.max_read_ahead_async_active=256
24865         local max_active=$($LCTL get_param -n \
24866                            ${llite_name}.max_read_ahead_async_active \
24867                            2>/dev/null)
24868         [ $max_active -ne 256 ] && error "expected 256 but got $max_active"
24869
24870         $LCTL set_param llite.*.max_read_ahead_async_active=0 ||
24871                 error "set max_read_ahead_async_active should succeed"
24872
24873         $LCTL set_param llite.*.max_read_ahead_async_active=512
24874         max_active=$($LCTL get_param -n \
24875                      ${llite_name}.max_read_ahead_async_active 2>/dev/null)
24876         [ $max_active -eq 512 ] || error "expected 512 but got $max_active"
24877
24878         # restore @max_active
24879         [ $old_max_active -ne 0 ] && $LCTL set_param \
24880                 llite.*.max_read_ahead_async_active=$old_max_active
24881
24882         local old_threshold=$($LCTL get_param -n \
24883                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
24884         local max_per_file_mb=$($LCTL get_param -n \
24885                 ${llite_name}.max_read_ahead_per_file_mb 2>/dev/null)
24886
24887         local invalid=$(($max_per_file_mb + 1))
24888         $LCTL set_param \
24889                 llite.*.read_ahead_async_file_threshold_mb=$invalid\
24890                         && error "set $invalid should fail"
24891
24892         local valid=$(($invalid - 1))
24893         $LCTL set_param \
24894                 llite.*.read_ahead_async_file_threshold_mb=$valid ||
24895                         error "set $valid should succeed"
24896         local threshold=$($LCTL get_param -n \
24897                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
24898         [ $threshold -eq $valid ] || error \
24899                 "expect threshold $valid got $threshold"
24900         $LCTL set_param \
24901                 llite.*.read_ahead_async_file_threshold_mb=$old_threshold
24902 }
24903 run_test 318 "Verify async readahead tunables"
24904
24905 test_319() {
24906         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
24907
24908         local before=$(date +%s)
24909         local evict
24910         local mdir=$DIR/$tdir
24911         local file=$mdir/xxx
24912
24913         $LFS mkdir -i0 $mdir || error "mkdir $mdir fails"
24914         touch $file
24915
24916 #define OBD_FAIL_LDLM_LOCAL_CANCEL_PAUSE 0x32c
24917         $LCTL set_param fail_val=5 fail_loc=0x8000032c
24918         $LFS migrate -m1 $mdir &
24919
24920         sleep 1
24921         dd if=$file of=/dev/null
24922         wait
24923         evict=$($LCTL get_param mdc.$FSNAME-MDT*.state |
24924           awk -F"[ [,]" '/EVICTED ]$/ { if (mx<$5) {mx=$5;} } END { print mx }')
24925
24926         [ -z "$evict" ] || [[ $evict -le $before ]] || error "eviction happened"
24927 }
24928 run_test 319 "lost lease lock on migrate error"
24929
24930 test_398a() { # LU-4198
24931         local ost1_imp=$(get_osc_import_name client ost1)
24932         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
24933                          cut -d'.' -f2)
24934
24935         $LFS setstripe -c 1 -i 0 $DIR/$tfile
24936         $LCTL set_param ldlm.namespaces.*.lru_size=clear
24937
24938         # Disabled: DIO does not push out buffered I/O pages, see LU-12587
24939         # request a new lock on client
24940         #dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
24941
24942         #dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
24943         #local lock_count=$($LCTL get_param -n \
24944         #                  ldlm.namespaces.$imp_name.lru_size)
24945         #[[ $lock_count -eq 0 ]] || error "lock should be cancelled by direct IO"
24946
24947         $LCTL set_param ldlm.namespaces.*-OST0000-osc-ffff*.lru_size=clear
24948
24949         # no lock cached, should use lockless DIO and not enqueue new lock
24950         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct \
24951                 conv=notrunc ||
24952                 error "dio write failed"
24953         lock_count=$($LCTL get_param -n \
24954                      ldlm.namespaces.$imp_name.lru_size)
24955         [[ $lock_count -eq 0 ]] || error "no lock should be held by direct IO"
24956
24957         $LCTL set_param ldlm.namespaces.*-OST0000-osc-ffff*.lru_size=clear
24958
24959         # no lock cached, should use locked DIO append
24960         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct oflag=append \
24961                 conv=notrunc || error "DIO append failed"
24962         lock_count=$($LCTL get_param -n \
24963                      ldlm.namespaces.*-OST0000-osc-ffff*.lru_size)
24964         [[ $lock_count -ne 0 ]] || error "lock still must be held by DIO append"
24965 }
24966 run_test 398a "direct IO should cancel lock otherwise lockless"
24967
24968 test_398b() { # LU-4198
24969         which fio || skip_env "no fio installed"
24970         $LFS setstripe -c -1 -S 1M $DIR/$tfile
24971
24972         local size=48
24973         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size
24974
24975         local njobs=4
24976         # Single page, multiple pages, stripe size, 4*stripe size
24977         for bsize in $(( $PAGE_SIZE )) $(( 4*$PAGE_SIZE )) 1048576 4194304; do
24978                 echo "mix direct rw ${bsize} by fio with $njobs jobs..."
24979                 fio --name=rand-rw --rw=randrw --bs=$bsize --direct=1 \
24980                         --numjobs=$njobs --fallocate=none \
24981                         --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
24982                         --filename=$DIR/$tfile &
24983                 bg_pid=$!
24984
24985                 echo "mix buffer rw ${bsize} by fio with $njobs jobs..."
24986                 fio --name=rand-rw --rw=randrw --bs=$bsize \
24987                         --numjobs=$njobs --fallocate=none \
24988                         --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
24989                         --filename=$DIR/$tfile || true
24990                 wait $bg_pid
24991         done
24992
24993         evict=$(do_facet client $LCTL get_param \
24994                 osc.$FSNAME-OST*-osc-*/state |
24995             awk -F"[ [,]" '/EVICTED ]$/ { if (t<$5) {t=$5;} } END { print t }')
24996
24997         [ -z "$evict" ] || [[ $evict -le $before ]] ||
24998                 (do_facet client $LCTL get_param \
24999                         osc.$FSNAME-OST*-osc-*/state;
25000                     error "eviction happened: $evict before:$before")
25001
25002         rm -f $DIR/$tfile
25003 }
25004 run_test 398b "DIO and buffer IO race"
25005
25006 test_398c() { # LU-4198
25007         local ost1_imp=$(get_osc_import_name client ost1)
25008         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
25009                          cut -d'.' -f2)
25010
25011         which fio || skip_env "no fio installed"
25012
25013         saved_debug=$($LCTL get_param -n debug)
25014         $LCTL set_param debug=0
25015
25016         local size=$(lctl get_param -n osc.$FSNAME-OST0000*.kbytesavail | head -1)
25017         ((size /= 1024)) # by megabytes
25018         ((size /= 2)) # write half of the OST at most
25019         [ $size -gt 40 ] && size=40 #reduce test time anyway
25020
25021         $LFS setstripe -c 1 $DIR/$tfile
25022
25023         # it seems like ldiskfs reserves more space than necessary if the
25024         # writing blocks are not mapped, so it extends the file firstly
25025         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size && sync
25026         cancel_lru_locks osc
25027
25028         # clear and verify rpc_stats later
25029         $LCTL set_param osc.${FSNAME}-OST0000-osc-ffff*.rpc_stats=clear
25030
25031         local njobs=4
25032         echo "writing ${size}M to OST0 by fio with $njobs jobs..."
25033         fio --name=rand-write --rw=randwrite --bs=$PAGE_SIZE --direct=1 \
25034                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
25035                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
25036                 --filename=$DIR/$tfile
25037         [ $? -eq 0 ] || error "fio write error"
25038
25039         [ $($LCTL get_param -n ldlm.namespaces.$imp_name.lock_count) -eq 0 ] ||
25040                 error "Locks were requested while doing AIO"
25041
25042         # get the percentage of 1-page I/O
25043         pct=$($LCTL get_param osc.${imp_name}.rpc_stats |
25044                 grep -A 1 'pages per rpc' | grep -v 'pages per rpc' |
25045                 awk '{print $7}')
25046         [ $pct -le 50 ] || error "$pct% of I/O are 1-page"
25047
25048         echo "mix rw ${size}M to OST0 by fio with $njobs jobs..."
25049         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
25050                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
25051                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
25052                 --filename=$DIR/$tfile
25053         [ $? -eq 0 ] || error "fio mixed read write error"
25054
25055         echo "AIO with large block size ${size}M"
25056         fio --name=rand-rw --rw=randrw --bs=${size}M --direct=1 \
25057                 --numjobs=1 --fallocate=none --ioengine=libaio \
25058                 --iodepth=16 --allow_file_create=0 --size=${size}M \
25059                 --filename=$DIR/$tfile
25060         [ $? -eq 0 ] || error "fio large block size failed"
25061
25062         rm -f $DIR/$tfile
25063         $LCTL set_param debug="$saved_debug"
25064 }
25065 run_test 398c "run fio to test AIO"
25066
25067 test_398d() { #  LU-13846
25068         which aiocp || skip_env "no aiocp installed"
25069         local aio_file=$DIR/$tfile.aio
25070
25071         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
25072
25073         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=64
25074         aiocp -a $PAGE_SIZE -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file
25075         stack_trap "rm -f $DIR/$tfile $aio_file"
25076
25077         diff $DIR/$tfile $aio_file || error "file diff after aiocp"
25078
25079         # make sure we don't crash and fail properly
25080         aiocp -a 512 -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
25081                 error "aio not aligned with PAGE SIZE should fail"
25082
25083         rm -f $DIR/$tfile $aio_file
25084 }
25085 run_test 398d "run aiocp to verify block size > stripe size"
25086
25087 test_398e() {
25088         dd if=/dev/zero of=$DIR/$tfile bs=1234 count=1
25089         touch $DIR/$tfile.new
25090         dd if=$DIR/$tfile of=$DIR/$tfile.new bs=1M count=1 oflag=direct
25091 }
25092 run_test 398e "O_Direct open cleared by fcntl doesn't cause hang"
25093
25094 test_398f() { #  LU-14687
25095         which aiocp || skip_env "no aiocp installed"
25096         local aio_file=$DIR/$tfile.aio
25097
25098         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
25099
25100         dd if=/dev/zero of=$DIR/$tfile bs=1M count=64
25101         stack_trap "rm -f $DIR/$tfile $aio_file"
25102
25103         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
25104         $LCTL set_param fail_loc=0x1418
25105         # make sure we don't crash and fail properly
25106         aiocp -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
25107                 error "aio with page allocation failure succeeded"
25108         $LCTL set_param fail_loc=0
25109         diff $DIR/$tfile $aio_file
25110         [[ $? != 0 ]] || error "no diff after failed aiocp"
25111 }
25112 run_test 398f "verify aio handles ll_direct_rw_pages errors correctly"
25113
25114 # NB: To get the parallel DIO behavior in LU-13798, there must be > 1
25115 # stripe and i/o size must be > stripe size
25116 # Old style synchronous DIO waits after submitting each chunk, resulting in a
25117 # single RPC in flight.  This test shows async DIO submission is working by
25118 # showing multiple RPCs in flight.
25119 test_398g() { #  LU-13798
25120         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
25121
25122         # We need to do some i/o first to acquire enough grant to put our RPCs
25123         # in flight; otherwise a new connection may not have enough grant
25124         # available
25125         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
25126                 error "parallel dio failed"
25127         stack_trap "rm -f $DIR/$tfile"
25128
25129         # Reduce RPC size to 1M to avoid combination in to larger RPCs
25130         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
25131         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
25132         stack_trap "$LCTL set_param -n $pages_per_rpc"
25133
25134         # Recreate file so it's empty
25135         rm -f $DIR/$tfile
25136         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
25137         #Pause rpc completion to guarantee we see multiple rpcs in flight
25138         #define OBD_FAIL_OST_BRW_PAUSE_BULK
25139         do_facet ost1 $LCTL set_param fail_loc=0x214 fail_val=2
25140         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
25141
25142         # Clear rpc stats
25143         $LCTL set_param osc.*.rpc_stats=c
25144
25145         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
25146                 error "parallel dio failed"
25147         stack_trap "rm -f $DIR/$tfile"
25148
25149         $LCTL get_param osc.*-OST0000-*.rpc_stats
25150         pct=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
25151                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
25152                 grep "8:" | awk '{print $8}')
25153         # We look at the "8 rpcs in flight" field, and verify A) it is present
25154         # and B) it includes all RPCs.  This proves we had 8 RPCs in flight,
25155         # as expected for an 8M DIO to a file with 1M stripes.
25156         [ $pct -eq 100 ] || error "we should see 8 RPCs in flight"
25157
25158         # Verify turning off parallel dio works as expected
25159         # Clear rpc stats
25160         $LCTL set_param osc.*.rpc_stats=c
25161         $LCTL set_param llite.*.parallel_dio=0
25162         stack_trap '$LCTL set_param llite.*.parallel_dio=1'
25163
25164         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
25165                 error "dio with parallel dio disabled failed"
25166
25167         # Ideally, we would see only one RPC in flight here, but there is an
25168         # unavoidable race between i/o completion and RPC in flight counting,
25169         # so while only 1 i/o is in flight at a time, the RPC in flight counter
25170         # will sometimes exceed 1 (3 or 4 is not rare on VM testing).
25171         # So instead we just verify it's always < 8.
25172         $LCTL get_param osc.*-OST0000-*.rpc_stats
25173         ret=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
25174                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
25175                 grep '^$' -B1 | grep . | awk '{print $1}')
25176         [ $ret != "8:" ] ||
25177                 error "we should see fewer than 8 RPCs in flight (saw $ret)"
25178 }
25179 run_test 398g "verify parallel dio async RPC submission"
25180
25181 test_398h() { #  LU-13798
25182         local dio_file=$DIR/$tfile.dio
25183
25184         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
25185
25186         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
25187         stack_trap "rm -f $DIR/$tfile $dio_file"
25188
25189         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct ||
25190                 error "parallel dio failed"
25191         diff $DIR/$tfile $dio_file
25192         [[ $? == 0 ]] || error "file diff after aiocp"
25193 }
25194 run_test 398h "verify correctness of read & write with i/o size >> stripe size"
25195
25196 test_398i() { #  LU-13798
25197         local dio_file=$DIR/$tfile.dio
25198
25199         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
25200
25201         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
25202         stack_trap "rm -f $DIR/$tfile $dio_file"
25203
25204         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
25205         $LCTL set_param fail_loc=0x1418
25206         # make sure we don't crash and fail properly
25207         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct &&
25208                 error "parallel dio page allocation failure succeeded"
25209         diff $DIR/$tfile $dio_file
25210         [[ $? != 0 ]] || error "no diff after failed aiocp"
25211 }
25212 run_test 398i "verify parallel dio handles ll_direct_rw_pages errors correctly"
25213
25214 test_398j() { #  LU-13798
25215         # Stripe size > RPC size but less than i/o size tests split across
25216         # stripes and RPCs for individual i/o op
25217         $LFS setstripe -o 0,0 -S 4M $DIR/$tfile $DIR/$tfile.2
25218
25219         # Reduce RPC size to 1M to guarantee split to multiple RPCs per stripe
25220         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
25221         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
25222         stack_trap "$LCTL set_param -n $pages_per_rpc"
25223
25224         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
25225                 error "parallel dio write failed"
25226         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.2"
25227
25228         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct ||
25229                 error "parallel dio read failed"
25230         diff $DIR/$tfile $DIR/$tfile.2
25231         [[ $? == 0 ]] || error "file diff after parallel dio read"
25232 }
25233 run_test 398j "test parallel dio where stripe size > rpc_size"
25234
25235 test_398k() { #  LU-13798
25236         wait_delete_completed
25237         wait_mds_ost_sync
25238
25239         # 4 stripe file; we will cause out of space on OST0
25240         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
25241
25242         # Fill OST0 (if it's not too large)
25243         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
25244                    head -n1)
25245         if [[ $ORIGFREE -gt $MAXFREE ]]; then
25246                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
25247         fi
25248         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
25249         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
25250                 error "dd should fill OST0"
25251         stack_trap "rm -f $DIR/$tfile.1"
25252
25253         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
25254         err=$?
25255
25256         ls -la $DIR/$tfile
25257         $CHECKSTAT -t file -s 0 $DIR/$tfile ||
25258                 error "file is not 0 bytes in size"
25259
25260         # dd above should not succeed, but don't error until here so we can
25261         # get debug info above
25262         [[ $err != 0 ]] ||
25263                 error "parallel dio write with enospc succeeded"
25264         stack_trap "rm -f $DIR/$tfile"
25265 }
25266 run_test 398k "test enospc on first stripe"
25267
25268 test_398l() { #  LU-13798
25269         wait_delete_completed
25270         wait_mds_ost_sync
25271
25272         # 4 stripe file; we will cause out of space on OST0
25273         # Note the 1M stripe size and the > 1M i/o size mean this ENOSPC
25274         # happens on the second i/o chunk we issue
25275         $LFS setstripe -o 1,0,1,0 -S 1M $DIR/$tfile $DIR/$tfile.2
25276
25277         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=2 oflag=direct
25278         stack_trap "rm -f $DIR/$tfile"
25279
25280         # Fill OST0 (if it's not too large)
25281         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
25282                    head -n1)
25283         if [[ $ORIGFREE -gt $MAXFREE ]]; then
25284                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
25285         fi
25286         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
25287         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
25288                 error "dd should fill OST0"
25289         stack_trap "rm -f $DIR/$tfile.1"
25290
25291         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 oflag=direct
25292         err=$?
25293         stack_trap "rm -f $DIR/$tfile.2"
25294
25295         # Check that short write completed as expected
25296         ls -la $DIR/$tfile.2
25297         $CHECKSTAT -t file -s 1048576 $DIR/$tfile.2 ||
25298                 error "file is not 1M in size"
25299
25300         # dd above should not succeed, but don't error until here so we can
25301         # get debug info above
25302         [[ $err != 0 ]] ||
25303                 error "parallel dio write with enospc succeeded"
25304
25305         # Truncate source file to same length as output file and diff them
25306         $TRUNCATE $DIR/$tfile 1048576
25307         diff $DIR/$tfile $DIR/$tfile.2
25308         [[ $? == 0 ]] || error "data incorrect after short write"
25309 }
25310 run_test 398l "test enospc on intermediate stripe/RPC"
25311
25312 test_398m() { #  LU-13798
25313         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
25314
25315         # Set up failure on OST0, the first stripe:
25316         #define OBD_FAIL_OST_BRW_WRITE_BULK     0x20e
25317         #NB: Fail val is ost # + 1, because we cannot use cfs_fail_val = 0
25318         # So this fail_val specifies OST0
25319         do_facet ost1 $LCTL set_param fail_loc=0x20e fail_val=1
25320         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
25321
25322         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
25323                 error "parallel dio write with failure on first stripe succeeded"
25324         stack_trap "rm -f $DIR/$tfile"
25325         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
25326
25327         # Place data in file for read
25328         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
25329                 error "parallel dio write failed"
25330
25331         # Fail read on OST0, first stripe
25332         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
25333         do_facet ost1 $LCTL set_param fail_loc=0x20f fail_val=1
25334         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
25335                 error "parallel dio read with error on first stripe succeeded"
25336         rm -f $DIR/$tfile.2
25337         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
25338
25339         # Switch to testing on OST1, second stripe
25340         # Clear file contents, maintain striping
25341         echo > $DIR/$tfile
25342         # Set up failure on OST1, second stripe:
25343         do_facet ost1 $LCTL set_param fail_loc=0x20e fail_val=2
25344         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
25345
25346         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
25347                 error "parallel dio write with failure on first stripe succeeded"
25348         stack_trap "rm -f $DIR/$tfile"
25349         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
25350
25351         # Place data in file for read
25352         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
25353                 error "parallel dio write failed"
25354
25355         # Fail read on OST1, second stripe
25356         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
25357         do_facet ost2 $LCTL set_param fail_loc=0x20f fail_val=2
25358         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
25359                 error "parallel dio read with error on first stripe succeeded"
25360         rm -f $DIR/$tfile.2
25361         do_facet ost2 $LCTL set_param fail_loc=0 fail_val=0
25362 }
25363 run_test 398m "test RPC failures with parallel dio"
25364
25365 # Parallel submission of DIO should not cause problems for append, but it's
25366 # important to verify.
25367 test_398n() { #  LU-13798
25368         $LFS setstripe -C 2 -S 1M $DIR/$tfile
25369
25370         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 ||
25371                 error "dd to create source file failed"
25372         stack_trap "rm -f $DIR/$tfile"
25373
25374         dd if=$DIR/$tfile of=$DIR/$tfile.1 bs=8M count=8 oflag=direct oflag=append ||
25375                 error "parallel dio write with failure on second stripe succeeded"
25376         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.1"
25377         diff $DIR/$tfile $DIR/$tfile.1
25378         [[ $? == 0 ]] || error "data incorrect after append"
25379
25380 }
25381 run_test 398n "test append with parallel DIO"
25382
25383 test_398o() {
25384         directio rdwr $DIR/$tfile 0 1 1 || error "bad KMS"
25385 }
25386 run_test 398o "right kms with DIO"
25387
25388 test_fake_rw() {
25389         local read_write=$1
25390         if [ "$read_write" = "write" ]; then
25391                 local dd_cmd="dd if=/dev/zero of=$DIR/$tfile"
25392         elif [ "$read_write" = "read" ]; then
25393                 local dd_cmd="dd of=/dev/null if=$DIR/$tfile"
25394         else
25395                 error "argument error"
25396         fi
25397
25398         # turn off debug for performance testing
25399         local saved_debug=$($LCTL get_param -n debug)
25400         $LCTL set_param debug=0
25401
25402         $LFS setstripe -c 1 -i 0 $DIR/$tfile
25403
25404         # get ost1 size - $FSNAME-OST0000
25405         local ost1_avail_size=$($LFS df $DIR | awk /${ost1_svc}/'{ print $4 }')
25406         local blocks=$((ost1_avail_size/2/1024)) # half avail space by megabytes
25407         [ $blocks -gt 1000 ] && blocks=1000 # 1G in maximum
25408
25409         if [ "$read_write" = "read" ]; then
25410                 $TRUNCATE $DIR/$tfile $(expr 1048576 \* $blocks)
25411         fi
25412
25413         local start_time=$(date +%s.%N)
25414         $dd_cmd bs=1M count=$blocks oflag=sync ||
25415                 error "real dd $read_write error"
25416         local duration=$(bc <<< "$(date +%s.%N) - $start_time")
25417
25418         if [ "$read_write" = "write" ]; then
25419                 rm -f $DIR/$tfile
25420         fi
25421
25422         # define OBD_FAIL_OST_FAKE_RW           0x238
25423         do_facet ost1 $LCTL set_param fail_loc=0x238
25424
25425         local start_time=$(date +%s.%N)
25426         $dd_cmd bs=1M count=$blocks oflag=sync ||
25427                 error "fake dd $read_write error"
25428         local duration_fake=$(bc <<< "$(date +%s.%N) - $start_time")
25429
25430         if [ "$read_write" = "write" ]; then
25431                 # verify file size
25432                 cancel_lru_locks osc
25433                 $CHECKSTAT -t file -s $((blocks * 1024 * 1024)) $DIR/$tfile ||
25434                         error "$tfile size not $blocks MB"
25435         fi
25436         do_facet ost1 $LCTL set_param fail_loc=0
25437
25438         echo "fake $read_write $duration_fake vs. normal $read_write" \
25439                 "$duration in seconds"
25440         [ $(bc <<< "$duration_fake < $duration") -eq 1 ] ||
25441                 error_not_in_vm "fake write is slower"
25442
25443         $LCTL set_param -n debug="$saved_debug"
25444         rm -f $DIR/$tfile
25445 }
25446 test_399a() { # LU-7655 for OST fake write
25447         remote_ost_nodsh && skip "remote OST with nodsh"
25448
25449         test_fake_rw write
25450 }
25451 run_test 399a "fake write should not be slower than normal write"
25452
25453 test_399b() { # LU-8726 for OST fake read
25454         remote_ost_nodsh && skip "remote OST with nodsh"
25455         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
25456                 skip_env "ldiskfs only test"
25457         fi
25458
25459         test_fake_rw read
25460 }
25461 run_test 399b "fake read should not be slower than normal read"
25462
25463 test_400a() { # LU-1606, was conf-sanity test_74
25464         if ! which $CC > /dev/null 2>&1; then
25465                 skip_env "$CC is not installed"
25466         fi
25467
25468         local extra_flags=''
25469         local out=$TMP/$tfile
25470         local prefix=/usr/include/lustre
25471         local prog
25472
25473         # Oleg removes c files in his test rig so test if any c files exist
25474         [ -z "$(ls -A $LUSTRE_TESTS_API_DIR)" ] && \
25475                 skip_env "Needed c test files are missing"
25476
25477         if ! [[ -d $prefix ]]; then
25478                 # Assume we're running in tree and fixup the include path.
25479                 extra_flags+=" -I$LUSTRE/../lnet/include/uapi -I$LUSTRE/include/uapi -I$LUSTRE/include"
25480                 extra_flags+=" -L$LUSTRE/utils/.lib"
25481         fi
25482
25483         for prog in $LUSTRE_TESTS_API_DIR/*.c; do
25484                 $CC -Wall -Werror -std=c99 $extra_flags -o $out $prog -llustreapi ||
25485                         error "client api broken"
25486         done
25487         rm -f $out
25488 }
25489 run_test 400a "Lustre client api program can compile and link"
25490
25491 test_400b() { # LU-1606, LU-5011
25492         local header
25493         local out=$TMP/$tfile
25494         local prefix=/usr/include/linux/lustre
25495
25496         # We use a hard coded prefix so that this test will not fail
25497         # when run in tree. There are headers in lustre/include/lustre/
25498         # that are not packaged (like lustre_idl.h) and have more
25499         # complicated include dependencies (like config.h and lnet/types.h).
25500         # Since this test about correct packaging we just skip them when
25501         # they don't exist (see below) rather than try to fixup cppflags.
25502
25503         if ! which $CC > /dev/null 2>&1; then
25504                 skip_env "$CC is not installed"
25505         fi
25506
25507         for header in $prefix/*.h; do
25508                 if ! [[ -f "$header" ]]; then
25509                         continue
25510                 fi
25511
25512                 if [[ "$(basename $header)" == lustre_ioctl.h ]]; then
25513                         continue # lustre_ioctl.h is internal header
25514                 fi
25515
25516                 $CC -Wall -Werror -std=c99 -include $header -c -x c /dev/null -o $out ||
25517                         error "cannot compile '$header'"
25518         done
25519         rm -f $out
25520 }
25521 run_test 400b "packaged headers can be compiled"
25522
25523 test_401a() { #LU-7437
25524         local printf_arg=$(find -printf 2>&1 | grep "unrecognized:")
25525         [ -n "$printf_arg" ] && skip_env "find does not support -printf"
25526
25527         #count the number of parameters by "list_param -R"
25528         local params=$($LCTL list_param -R '*' 2>/dev/null | wc -l)
25529         #count the number of parameters by listing proc files
25530         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
25531         echo "proc_dirs='$proc_dirs'"
25532         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
25533         local procs=$(find -L $proc_dirs -mindepth 1 -printf '%P\n' 2>/dev/null|
25534                       sort -u | wc -l)
25535
25536         [ $params -eq $procs ] ||
25537                 error "found $params parameters vs. $procs proc files"
25538
25539         # test the list_param -D option only returns directories
25540         params=$($LCTL list_param -R -D '*' 2>/dev/null | wc -l)
25541         #count the number of parameters by listing proc directories
25542         procs=$(find -L $proc_dirs -mindepth 1 -type d -printf '%P\n' 2>/dev/null |
25543                 sort -u | wc -l)
25544
25545         [ $params -eq $procs ] ||
25546                 error "found $params parameters vs. $procs proc files"
25547 }
25548 run_test 401a "Verify if 'lctl list_param -R' can list parameters recursively"
25549
25550 test_401b() {
25551         # jobid_var may not allow arbitrary values, so use jobid_name
25552         # if available
25553         if $LCTL list_param jobid_name > /dev/null 2>&1; then
25554                 local testname=jobid_name tmp='testing%p'
25555         else
25556                 local testname=jobid_var tmp=testing
25557         fi
25558
25559         local save=$($LCTL get_param -n $testname)
25560
25561         $LCTL set_param foo=bar $testname=$tmp bar=baz &&
25562                 error "no error returned when setting bad parameters"
25563
25564         local jobid_new=$($LCTL get_param -n foe $testname baz)
25565         [[ "$jobid_new" == "$tmp" ]] || error "jobid tmp $jobid_new != $tmp"
25566
25567         $LCTL set_param -n fog=bam $testname=$save bat=fog
25568         local jobid_old=$($LCTL get_param -n foe $testname bag)
25569         [[ "$jobid_old" == "$save" ]] || error "jobid new $jobid_old != $save"
25570 }
25571 run_test 401b "Verify 'lctl {get,set}_param' continue after error"
25572
25573 test_401c() {
25574         # jobid_var may not allow arbitrary values, so use jobid_name
25575         # if available
25576         if $LCTL list_param jobid_name > /dev/null 2>&1; then
25577                 local testname=jobid_name
25578         else
25579                 local testname=jobid_var
25580         fi
25581
25582         local jobid_var_old=$($LCTL get_param -n $testname)
25583         local jobid_var_new
25584
25585         $LCTL set_param $testname= &&
25586                 error "no error returned for 'set_param a='"
25587
25588         jobid_var_new=$($LCTL get_param -n $testname)
25589         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
25590                 error "$testname was changed by setting without value"
25591
25592         $LCTL set_param $testname &&
25593                 error "no error returned for 'set_param a'"
25594
25595         jobid_var_new=$($LCTL get_param -n $testname)
25596         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
25597                 error "$testname was changed by setting without value"
25598 }
25599 run_test 401c "Verify 'lctl set_param' without value fails in either format."
25600
25601 test_401d() {
25602         # jobid_var may not allow arbitrary values, so use jobid_name
25603         # if available
25604         if $LCTL list_param jobid_name > /dev/null 2>&1; then
25605                 local testname=jobid_name new_value='foo=bar%p'
25606         else
25607                 local testname=jobid_var new_valuie=foo=bar
25608         fi
25609
25610         local jobid_var_old=$($LCTL get_param -n $testname)
25611         local jobid_var_new
25612
25613         $LCTL set_param $testname=$new_value ||
25614                 error "'set_param a=b' did not accept a value containing '='"
25615
25616         jobid_var_new=$($LCTL get_param -n $testname)
25617         [[ "$jobid_var_new" == "$new_value" ]] ||
25618                 error "'set_param a=b' failed on a value containing '='"
25619
25620         # Reset the $testname to test the other format
25621         $LCTL set_param $testname=$jobid_var_old
25622         jobid_var_new=$($LCTL get_param -n $testname)
25623         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
25624                 error "failed to reset $testname"
25625
25626         $LCTL set_param $testname $new_value ||
25627                 error "'set_param a b' did not accept a value containing '='"
25628
25629         jobid_var_new=$($LCTL get_param -n $testname)
25630         [[ "$jobid_var_new" == "$new_value" ]] ||
25631                 error "'set_param a b' failed on a value containing '='"
25632
25633         $LCTL set_param $testname $jobid_var_old
25634         jobid_var_new=$($LCTL get_param -n $testname)
25635         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
25636                 error "failed to reset $testname"
25637 }
25638 run_test 401d "Verify 'lctl set_param' accepts values containing '='"
25639
25640 test_401e() { # LU-14779
25641         $LCTL list_param -R "ldlm.namespaces.MGC*" ||
25642                 error "lctl list_param MGC* failed"
25643         $LCTL get_param "ldlm.namespaces.MGC*" || error "lctl get_param failed"
25644         $LCTL get_param "ldlm.namespaces.MGC*.lru_size" ||
25645                 error "lctl get_param lru_size failed"
25646 }
25647 run_test 401e "verify 'lctl get_param' works with NID in parameter"
25648
25649 test_402() {
25650         [[ $MDS1_VERSION -ge $(version_code 2.7.66) ]] ||
25651         [[ $MDS1_VERSION -ge $(version_code 2.7.18.4) &&
25652                 $MDS1_VERSION -lt $(version_code 2.7.50) ]] ||
25653         [[ $MDS1_VERSION -ge $(version_code 2.7.2) &&
25654                 $MDS1_VERSION -lt $(version_code 2.7.11) ]] ||
25655                 skip "Need MDS version 2.7.2+ or 2.7.18.4+ or 2.7.66+"
25656         remote_mds_nodsh && skip "remote MDS with nodsh"
25657
25658         $LFS setdirstripe -i 0 $DIR/$tdir || error "setdirstripe -i 0 failed"
25659 #define OBD_FAIL_MDS_FLD_LOOKUP 0x15c
25660         do_facet mds1 "lctl set_param fail_loc=0x8000015c"
25661         touch $DIR/$tdir/$tfile && error "touch should fail with ENOENT" ||
25662                 echo "Touch failed - OK"
25663 }
25664 run_test 402 "Return ENOENT to lod_generate_and_set_lovea"
25665
25666 test_403() {
25667         local file1=$DIR/$tfile.1
25668         local file2=$DIR/$tfile.2
25669         local tfile=$TMP/$tfile
25670
25671         rm -f $file1 $file2 $tfile
25672
25673         touch $file1
25674         ln $file1 $file2
25675
25676         # 30 sec OBD_TIMEOUT in ll_getattr()
25677         # right before populating st_nlink
25678         $LCTL set_param fail_loc=0x80001409
25679         stat -c %h $file1 > $tfile &
25680
25681         # create an alias, drop all locks and reclaim the dentry
25682         < $file2
25683         cancel_lru_locks mdc
25684         cancel_lru_locks osc
25685         sysctl -w vm.drop_caches=2
25686
25687         wait
25688
25689         [ $(cat $tfile) -gt 0 ] || error "wrong nlink count: $(cat $tfile)"
25690
25691         rm -f $tfile $file1 $file2
25692 }
25693 run_test 403 "i_nlink should not drop to zero due to aliasing"
25694
25695 test_404() { # LU-6601
25696         [[ $MDS1_VERSION -ge $(version_code 2.8.53) ]] ||
25697                 skip "Need server version newer than 2.8.52"
25698         remote_mds_nodsh && skip "remote MDS with nodsh"
25699
25700         local mosps=$(do_facet $SINGLEMDS $LCTL dl |
25701                 awk '/osp .*-osc-MDT/ { print $4}')
25702
25703         local osp
25704         for osp in $mosps; do
25705                 echo "Deactivate: " $osp
25706                 do_facet $SINGLEMDS $LCTL --device %$osp deactivate
25707                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
25708                         awk -vp=$osp '$4 == p { print $2 }')
25709                 [ $stat = IN ] || {
25710                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
25711                         error "deactivate error"
25712                 }
25713                 echo "Activate: " $osp
25714                 do_facet $SINGLEMDS $LCTL --device %$osp activate
25715                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
25716                         awk -vp=$osp '$4 == p { print $2 }')
25717                 [ $stat = UP ] || {
25718                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
25719                         error "activate error"
25720                 }
25721         done
25722 }
25723 run_test 404 "validate manual {de}activated works properly for OSPs"
25724
25725 test_405() {
25726         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
25727         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] ||
25728                 [ $CLIENT_VERSION -lt $(version_code 2.6.99) ] &&
25729                         skip "Layout swap lock is not supported"
25730
25731         check_swap_layouts_support
25732         check_swap_layout_no_dom $DIR
25733
25734         test_mkdir $DIR/$tdir
25735         swap_lock_test -d $DIR/$tdir ||
25736                 error "One layout swap locked test failed"
25737 }
25738 run_test 405 "Various layout swap lock tests"
25739
25740 test_406() {
25741         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25742         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
25743         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
25744         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25745         [ $MDS1_VERSION -lt $(version_code 2.8.50) ] &&
25746                 skip "Need MDS version at least 2.8.50"
25747
25748         local def_stripe_size=$($LFS getstripe -S $MOUNT)
25749         local test_pool=$TESTNAME
25750
25751         pool_add $test_pool || error "pool_add failed"
25752         pool_add_targets $test_pool 0 $(($OSTCOUNT - 1)) 1 ||
25753                 error "pool_add_targets failed"
25754
25755         save_layout_restore_at_exit $MOUNT
25756
25757         # parent set default stripe count only, child will stripe from both
25758         # parent and fs default
25759         $LFS setstripe -c 1 -i 1 -S $((def_stripe_size * 2)) -p $test_pool $MOUNT ||
25760                 error "setstripe $MOUNT failed"
25761         $LFS mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
25762         $LFS setstripe -c $OSTCOUNT $DIR/$tdir || error "setstripe $tdir failed"
25763         for i in $(seq 10); do
25764                 local f=$DIR/$tdir/$tfile.$i
25765                 touch $f || error "touch failed"
25766                 local count=$($LFS getstripe -c $f)
25767                 [ $count -eq $OSTCOUNT ] ||
25768                         error "$f stripe count $count != $OSTCOUNT"
25769                 local offset=$($LFS getstripe -i $f)
25770                 [ $offset -eq 1 ] || error "$f stripe offset $offset != 1"
25771                 local size=$($LFS getstripe -S $f)
25772                 [ $size -eq $((def_stripe_size * 2)) ] ||
25773                         error "$f stripe size $size != $((def_stripe_size * 2))"
25774                 local pool=$($LFS getstripe -p $f)
25775                 [ $pool == $test_pool ] || error "$f pool $pool != $test_pool"
25776         done
25777
25778         # change fs default striping, delete parent default striping, now child
25779         # will stripe from new fs default striping only
25780         $LFS setstripe -c 1 -S $def_stripe_size -i 0 $MOUNT ||
25781                 error "change $MOUNT default stripe failed"
25782         $LFS setstripe -c 0 $DIR/$tdir ||
25783                 error "delete $tdir default stripe failed"
25784         for i in $(seq 11 20); do
25785                 local f=$DIR/$tdir/$tfile.$i
25786                 touch $f || error "touch $f failed"
25787                 local count=$($LFS getstripe -c $f)
25788                 [ $count -eq 1 ] || error "$f stripe count $count != 1"
25789                 local offset=$($LFS getstripe -i $f)
25790                 [ $offset -eq 0 ] || error "$f stripe offset $offset != 0"
25791                 local size=$($LFS getstripe -S $f)
25792                 [ $size -eq $def_stripe_size ] ||
25793                         error "$f stripe size $size != $def_stripe_size"
25794                 local pool=$($LFS getstripe -p $f)
25795                 [ $pool == $test_pool ] || error "$f pool $pool isn't set"
25796         done
25797
25798         unlinkmany $DIR/$tdir/$tfile. 1 20
25799
25800         local f=$DIR/$tdir/$tfile
25801         pool_remove_all_targets $test_pool $f
25802         pool_remove $test_pool $f
25803 }
25804 run_test 406 "DNE support fs default striping"
25805
25806 test_407() {
25807         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25808         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
25809                 skip "Need MDS version at least 2.8.55"
25810         remote_mds_nodsh && skip "remote MDS with nodsh"
25811
25812         $LFS mkdir -i 0 -c 1 $DIR/$tdir.0 ||
25813                 error "$LFS mkdir -i 0 -c 1 $tdir.0 failed"
25814         $LFS mkdir -i 1 -c 1 $DIR/$tdir.1 ||
25815                 error "$LFS mkdir -i 1 -c 1 $tdir.1 failed"
25816         touch $DIR/$tdir.0/$tfile.0 || error "touch $tdir.0/$tfile.0 failed"
25817
25818         #define OBD_FAIL_DT_TXN_STOP    0x2019
25819         for idx in $(seq $MDSCOUNT); do
25820                 do_facet mds$idx "lctl set_param fail_loc=0x2019"
25821         done
25822         $LFS mkdir -c 2 $DIR/$tdir && error "$LFS mkdir -c 2 $tdir should fail"
25823         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1/$tfile.1 &&
25824                 error "mv $tdir.0/$tfile.0 $tdir.1/$tfile.1 should fail"
25825         true
25826 }
25827 run_test 407 "transaction fail should cause operation fail"
25828
25829 test_408() {
25830         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
25831
25832         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
25833         lctl set_param fail_loc=0x8000040a
25834         # let ll_prepare_partial_page() fail
25835         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 conv=notrunc || true
25836
25837         rm -f $DIR/$tfile
25838
25839         # create at least 100 unused inodes so that
25840         # shrink_icache_memory(0) should not return 0
25841         touch $DIR/$tfile-{0..100}
25842         rm -f $DIR/$tfile-{0..100}
25843         sync
25844
25845         echo 2 > /proc/sys/vm/drop_caches
25846 }
25847 run_test 408 "drop_caches should not hang due to page leaks"
25848
25849 test_409()
25850 {
25851         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
25852
25853         mkdir -p $DIR/$tdir || error "(0) Fail to mkdir"
25854         $LFS mkdir -i 1 -c 2 $DIR/$tdir/foo || error "(1) Fail to mkdir"
25855         touch $DIR/$tdir/guard || error "(2) Fail to create"
25856
25857         local PREFIX=$(str_repeat 'A' 128)
25858         echo "Create 1K hard links start at $(date)"
25859         createmany -l $DIR/$tdir/guard $DIR/$tdir/foo/${PREFIX}_ 1000 ||
25860                 error "(3) Fail to hard link"
25861
25862         echo "Links count should be right although linkEA overflow"
25863         stat $DIR/$tdir/guard || error "(4) Fail to stat"
25864         local linkcount=$(stat --format=%h $DIR/$tdir/guard)
25865         [ $linkcount -eq 1001 ] ||
25866                 error "(5) Unexpected hard links count: $linkcount"
25867
25868         echo "List all links start at $(date)"
25869         ls -l $DIR/$tdir/foo > /dev/null ||
25870                 error "(6) Fail to list $DIR/$tdir/foo"
25871
25872         echo "Unlink hard links start at $(date)"
25873         unlinkmany $DIR/$tdir/foo/${PREFIX}_ 1000 ||
25874                 error "(7) Fail to unlink"
25875         echo "Unlink hard links finished at $(date)"
25876 }
25877 run_test 409 "Large amount of cross-MDTs hard links on the same file"
25878
25879 test_410()
25880 {
25881         [[ $CLIENT_VERSION -lt $(version_code 2.9.59) ]] &&
25882                 skip "Need client version at least 2.9.59"
25883         [ -f $LUSTRE/tests/kernel/kinode.ko ] ||
25884                 skip "Need MODULES build"
25885
25886         # Create a file, and stat it from the kernel
25887         local testfile=$DIR/$tfile
25888         touch $testfile
25889
25890         local run_id=$RANDOM
25891         local my_ino=$(stat --format "%i" $testfile)
25892
25893         # Try to insert the module. This will always fail as the
25894         # module is designed to not be inserted.
25895         insmod $LUSTRE/tests/kernel/kinode.ko run_id=$run_id fname=$testfile \
25896             &> /dev/null
25897
25898         # Anything but success is a test failure
25899         dmesg | grep -q \
25900             "lustre_kinode_$run_id: inode numbers are identical: $my_ino" ||
25901             error "no inode match"
25902 }
25903 run_test 410 "Test inode number returned from kernel thread"
25904
25905 cleanup_test411_cgroup() {
25906         trap 0
25907         rmdir "$1"
25908 }
25909
25910 test_411() {
25911         local cg_basedir=/sys/fs/cgroup/memory
25912         # LU-9966
25913         test -f "$cg_basedir/memory.kmem.limit_in_bytes" ||
25914                 skip "no setup for cgroup"
25915
25916         dd if=/dev/zero of=$DIR/$tfile bs=1M count=100 conv=fsync ||
25917                 error "test file creation failed"
25918         cancel_lru_locks osc
25919
25920         # Create a very small memory cgroup to force a slab allocation error
25921         local cgdir=$cg_basedir/osc_slab_alloc
25922         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
25923         trap "cleanup_test411_cgroup $cgdir" EXIT
25924         echo 2M > $cgdir/memory.kmem.limit_in_bytes
25925         echo 1M > $cgdir/memory.limit_in_bytes
25926
25927         # Should not LBUG, just be killed by oom-killer
25928         # dd will return 0 even allocation failure in some environment.
25929         # So don't check return value
25930         bash -c "echo \$$ > $cgdir/tasks && dd if=$DIR/$tfile of=/dev/null"
25931         cleanup_test411_cgroup $cgdir
25932
25933         return 0
25934 }
25935 run_test 411 "Slab allocation error with cgroup does not LBUG"
25936
25937 test_412() {
25938         (( $MDSCOUNT > 1 )) || skip_env "needs >= 2 MDTs"
25939         (( $MDS1_VERSION >= $(version_code 2.10.55) )) ||
25940                 skip "Need server version at least 2.10.55"
25941
25942         $LFS mkdir -i $((MDSCOUNT - 1)),$((MDSCOUNT - 2)) $DIR/$tdir ||
25943                 error "mkdir failed"
25944         $LFS getdirstripe $DIR/$tdir
25945         local stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
25946         [ $stripe_index -eq $((MDSCOUNT - 1)) ] ||
25947                 error "expect $((MDSCOUT - 1)) get $stripe_index"
25948         local stripe_count=$($LFS getdirstripe -T $DIR/$tdir)
25949         [ $stripe_count -eq 2 ] ||
25950                 error "expect 2 get $stripe_count"
25951
25952         (( $MDS1_VERSION >= $(version_code 2.14.55) )) || return 0
25953
25954         local index
25955         local index2
25956
25957         # subdirs should be on the same MDT as parent
25958         for i in $(seq 0 $((MDSCOUNT - 1))); do
25959                 $LFS mkdir -i $i $DIR/$tdir/mdt$i || error "mkdir mdt$i failed"
25960                 mkdir $DIR/$tdir/mdt$i/sub || error "mkdir sub failed"
25961                 index=$($LFS getstripe -m $DIR/$tdir/mdt$i/sub)
25962                 (( index == i )) || error "mdt$i/sub on MDT$index"
25963         done
25964
25965         # stripe offset -1, ditto
25966         for i in {1..10}; do
25967                 $LFS mkdir -i -1 $DIR/$tdir/qos$i || error "mkdir qos$i failed"
25968                 index=$($LFS getstripe -m $DIR/$tdir/qos$i)
25969                 mkdir $DIR/$tdir/qos$i/sub || error "mkdir sub failed"
25970                 index2=$($LFS getstripe -m $DIR/$tdir/qos$i/sub)
25971                 (( index == index2 )) ||
25972                         error "qos$i on MDT$index, sub on MDT$index2"
25973         done
25974
25975         local testdir=$DIR/$tdir/inherit
25976
25977         $LFS mkdir -i 1 --max-inherit=3 $testdir || error "mkdir inherit failed"
25978         # inherit 2 levels
25979         for i in 1 2; do
25980                 testdir=$testdir/s$i
25981                 mkdir $testdir || error "mkdir $testdir failed"
25982                 index=$($LFS getstripe -m $testdir)
25983                 (( index == 1 )) ||
25984                         error "$testdir on MDT$index"
25985         done
25986
25987         # not inherit any more
25988         testdir=$testdir/s3
25989         mkdir $testdir || error "mkdir $testdir failed"
25990         getfattr -d -m dmv $testdir | grep dmv &&
25991                 error "default LMV set on $testdir" || true
25992 }
25993 run_test 412 "mkdir on specific MDTs"
25994
25995 TEST413_COUNT=${TEST413_COUNT:-200}
25996 generate_uneven_mdts() {
25997         local threshold=$1
25998         local lmv_qos_maxage
25999         local lod_qos_maxage
26000         local ffree
26001         local bavail
26002         local max
26003         local min
26004         local max_index
26005         local min_index
26006         local tmp
26007         local i
26008
26009         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
26010         $LCTL set_param lmv.*.qos_maxage=1
26011         stack_trap "$LCTL set_param \
26012                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null" RETURN
26013         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
26014                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
26015         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
26016                 lod.*.mdt_qos_maxage=1
26017         stack_trap "do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
26018                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null" RETURN
26019
26020         echo
26021         echo "Check for uneven MDTs: "
26022
26023         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
26024         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
26025         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
26026
26027         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
26028         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
26029         max_index=0
26030         min_index=0
26031         for ((i = 1; i < ${#ffree[@]}; i++)); do
26032                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
26033                 if [ $tmp -gt $max ]; then
26034                         max=$tmp
26035                         max_index=$i
26036                 fi
26037                 if [ $tmp -lt $min ]; then
26038                         min=$tmp
26039                         min_index=$i
26040                 fi
26041         done
26042
26043         (( ${ffree[min_index]} > 0 )) ||
26044                 skip "no free files in MDT$min_index"
26045         (( ${ffree[min_index]} < 10000000 )) ||
26046                 skip "too many free files in MDT$min_index"
26047
26048         # Check if we need to generate uneven MDTs
26049         local diff=$(((max - min) * 100 / min))
26050         local testdir=$DIR/$tdir-fillmdt
26051         local start
26052
26053         i=0
26054         while (( diff < threshold )); do
26055                 mkdir -p $testdir
26056                 # generate uneven MDTs, create till $threshold% diff
26057                 echo -n "weight diff=$diff% must be > $threshold% ..."
26058                 echo "Fill MDT$min_index with $TEST413_COUNT files: loop $i"
26059                 testdir=$DIR/$tdir-fillmdt/$i
26060                 [ -d $testdir ] && continue
26061                 $LFS mkdir -i $min_index $testdir ||
26062                         error "mkdir $testdir failed"
26063                 $LFS setstripe -E 1M -L mdt $testdir ||
26064                         error "setstripe $testdir failed"
26065                 start=$SECONDS
26066                 for ((F=0; F < TEST413_COUNT; F++)); do
26067                         dd if=/dev/zero of=$testdir/f.$F bs=128K count=1 > \
26068                                 /dev/null 2>&1 || error "dd $F failed"
26069                 done
26070                 sync; sleep 1; sync
26071
26072                 # wait for QOS to update
26073                 (( SECONDS < start + 1 )) && sleep $((start + 1 - SECONDS))
26074
26075                 ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-*.filesfree))
26076                 bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-*.kbytesavail))
26077                 max=$(((${ffree[max_index]} >> 8) *
26078                         (${bavail[max_index]} * bsize >> 16)))
26079                 min=$(((${ffree[min_index]} >> 8) *
26080                         (${bavail[min_index]} * bsize >> 16)))
26081                 diff=$(((max - min) * 100 / min))
26082                 i=$((i + 1))
26083         done
26084
26085         echo "MDT filesfree available: ${ffree[*]}"
26086         echo "MDT blocks available: ${bavail[*]}"
26087         echo "weight diff=$diff%"
26088 }
26089
26090 test_qos_mkdir() {
26091         local mkdir_cmd=$1
26092         local stripe_count=$2
26093         local mdts=$(comma_list $(mdts_nodes))
26094
26095         local testdir
26096         local lmv_qos_prio_free
26097         local lmv_qos_threshold_rr
26098         local lmv_qos_maxage
26099         local lod_qos_prio_free
26100         local lod_qos_threshold_rr
26101         local lod_qos_maxage
26102         local count
26103         local i
26104
26105         lmv_qos_prio_free=$($LCTL get_param -n lmv.*.qos_prio_free | head -n1)
26106         lmv_qos_prio_free=${lmv_qos_prio_free%%%}
26107         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
26108                 head -n1)
26109         lmv_qos_threshold_rr=${lmv_qos_threshold_rr%%%}
26110         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
26111         stack_trap "$LCTL set_param \
26112                 lmv.*.qos_prio_free=$lmv_qos_prio_free > /dev/null"
26113         stack_trap "$LCTL set_param \
26114                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null"
26115         stack_trap "$LCTL set_param \
26116                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null"
26117
26118         lod_qos_prio_free=$(do_facet mds1 $LCTL get_param -n \
26119                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_prio_free | head -n1)
26120         lod_qos_prio_free=${lod_qos_prio_free%%%}
26121         lod_qos_threshold_rr=$(do_facet mds1 $LCTL get_param -n \
26122                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_threshold_rr | head -n1)
26123         lod_qos_threshold_rr=${lod_qos_threshold_rr%%%}
26124         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
26125                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
26126         stack_trap "do_nodes $mdts $LCTL set_param \
26127                 lod.*.mdt_qos_prio_free=$lod_qos_prio_free > /dev/null"
26128         stack_trap "do_nodes $mdts $LCTL set_param \
26129                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null"
26130         stack_trap "do_nodes $mdts $LCTL set_param \
26131                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null"
26132
26133         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
26134         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=100 > /dev/null
26135
26136         testdir=$DIR/$tdir-s$stripe_count/rr
26137
26138         local stripe_index=$($LFS getstripe -m $testdir)
26139         local test_mkdir_rr=true
26140
26141         getfattr -d -m dmv -e hex $testdir | grep dmv
26142         if (( $? == 0 && $MDS1_VERSION >= $(version_code 2.14.51) )); then
26143                 echo "defstripe: '$($LFS getdirstripe -D $testdir)'"
26144                 (( $($LFS getdirstripe -D --max-inherit-rr $testdir) == 0 )) &&
26145                         test_mkdir_rr=false
26146         fi
26147
26148         echo
26149         $test_mkdir_rr &&
26150                 echo "Mkdir (stripe_count $stripe_count) roundrobin:" ||
26151                 echo "Mkdir (stripe_count $stripe_count) on stripe $stripe_index"
26152
26153         stack_trap "unlinkmany -d $testdir/subdir $((100 * MDSCOUNT))"
26154         for (( i = 0; i < 100 * MDSCOUNT; i++ )); do
26155                 eval $mkdir_cmd $testdir/subdir$i ||
26156                         error "$mkdir_cmd subdir$i failed"
26157         done
26158
26159         for (( i = 0; i < $MDSCOUNT; i++ )); do
26160                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
26161                 echo "$count directories created on MDT$i"
26162                 if $test_mkdir_rr; then
26163                         (( $count == 100 )) ||
26164                                 error "subdirs are not evenly distributed"
26165                 elif (( $i == $stripe_index )); then
26166                         (( $count == 100 * MDSCOUNT )) ||
26167                                 error "$count subdirs created on MDT$i"
26168                 else
26169                         (( $count == 0 )) ||
26170                                 error "$count subdirs created on MDT$i"
26171                 fi
26172
26173                 if $test_mkdir_rr && [ $stripe_count -gt 1 ]; then
26174                         count=$($LFS getdirstripe $testdir/* |
26175                                 grep -c -P "^\s+$i\t")
26176                         echo "$count stripes created on MDT$i"
26177                         # deviation should < 5% of average
26178                         (( $count >= 95 * stripe_count &&
26179                            $count <= 105 * stripe_count)) ||
26180                                 error "stripes are not evenly distributed"
26181                 fi
26182         done
26183
26184         echo
26185         echo "Check for uneven MDTs: "
26186
26187         local ffree
26188         local bavail
26189         local max
26190         local min
26191         local max_index
26192         local min_index
26193         local tmp
26194
26195         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
26196         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
26197         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
26198
26199         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
26200         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
26201         max_index=0
26202         min_index=0
26203         for ((i = 1; i < ${#ffree[@]}; i++)); do
26204                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
26205                 if [ $tmp -gt $max ]; then
26206                         max=$tmp
26207                         max_index=$i
26208                 fi
26209                 if [ $tmp -lt $min ]; then
26210                         min=$tmp
26211                         min_index=$i
26212                 fi
26213         done
26214
26215         (( ${ffree[min_index]} > 0 )) ||
26216                 skip "no free files in MDT$min_index"
26217         (( ${ffree[min_index]} < 10000000 )) ||
26218                 skip "too many free files in MDT$min_index"
26219
26220         echo "MDT filesfree available: ${ffree[*]}"
26221         echo "MDT blocks available: ${bavail[*]}"
26222         echo "weight diff=$(((max - min) * 100 / min))%"
26223         echo
26224         echo "Mkdir (stripe_count $stripe_count) with balanced space usage:"
26225
26226         $LCTL set_param lmv.*.qos_threshold_rr=0 > /dev/null
26227         $LCTL set_param lmv.*.qos_prio_free=100 > /dev/null
26228         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=0 > /dev/null
26229         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_prio_free=100 > /dev/null
26230         # decrease statfs age, so that it can be updated in time
26231         $LCTL set_param lmv.*.qos_maxage=1 > /dev/null
26232         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_maxage=1 > /dev/null
26233
26234         sleep 1
26235
26236         testdir=$DIR/$tdir-s$stripe_count/qos
26237         local num=200
26238
26239         stack_trap "unlinkmany -d $testdir/subdir $((num * MDSCOUNT))"
26240         for (( i = 0; i < num * MDSCOUNT; i++ )); do
26241                 eval $mkdir_cmd $testdir/subdir$i ||
26242                         error "$mkdir_cmd subdir$i failed"
26243         done
26244
26245         max=0
26246         for (( i = 0; i < $MDSCOUNT; i++ )); do
26247                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
26248                 (( count > max )) && max=$count
26249                 echo "$count directories created on MDT$i"
26250         done
26251
26252         min=$($LFS getdirstripe -i $testdir/* | grep -c "^$min_index$")
26253
26254         # D-value should > 10% of averge
26255         (( max - min > num / 10 )) ||
26256                 error "subdirs shouldn't be evenly distributed: $max - $min < $((num / 10))"
26257
26258         # ditto for stripes
26259         if (( stripe_count > 1 )); then
26260                 max=0
26261                 for (( i = 0; i < $MDSCOUNT; i++ )); do
26262                         count=$($LFS getdirstripe $testdir/* |
26263                                 grep -c -P "^\s+$i\t")
26264                         (( count > max )) && max=$count
26265                         echo "$count stripes created on MDT$i"
26266                 done
26267
26268                 min=$($LFS getdirstripe $testdir/* |
26269                         grep -c -P "^\s+$min_index\t")
26270                 (( max - min > num * stripe_count / 10 )) ||
26271                         error "stripes shouldn't be evenly distributed: $max - $min < $((num / 10)) * $stripe_count"
26272         fi
26273 }
26274
26275 most_full_mdt() {
26276         local ffree
26277         local bavail
26278         local bsize
26279         local min
26280         local min_index
26281         local tmp
26282
26283         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
26284         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
26285         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
26286
26287         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
26288         min_index=0
26289         for ((i = 1; i < ${#ffree[@]}; i++)); do
26290                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
26291                 (( tmp < min )) && min=$tmp && min_index=$i
26292         done
26293
26294         echo -n $min_index
26295 }
26296
26297 test_413a() {
26298         [ $MDSCOUNT -lt 2 ] &&
26299                 skip "We need at least 2 MDTs for this test"
26300
26301         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
26302                 skip "Need server version at least 2.12.52"
26303
26304         local stripe_count
26305
26306         generate_uneven_mdts 100
26307         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
26308                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
26309                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
26310                 $LFS mkdir -i $(most_full_mdt) $DIR/$tdir-s$stripe_count/qos ||
26311                         error "mkdir failed"
26312                 test_qos_mkdir "$LFS mkdir -i -1 -c $stripe_count" $stripe_count
26313         done
26314 }
26315 run_test 413a "QoS mkdir with 'lfs mkdir -i -1'"
26316
26317 test_413b() {
26318         [ $MDSCOUNT -lt 2 ] &&
26319                 skip "We need at least 2 MDTs for this test"
26320
26321         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
26322                 skip "Need server version at least 2.12.52"
26323
26324         local testdir
26325         local stripe_count
26326
26327         generate_uneven_mdts 100
26328         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
26329                 testdir=$DIR/$tdir-s$stripe_count
26330                 mkdir $testdir || error "mkdir $testdir failed"
26331                 mkdir $testdir/rr || error "mkdir rr failed"
26332                 $LFS mkdir -i $(most_full_mdt) $testdir/qos ||
26333                         error "mkdir qos failed"
26334                 $LFS setdirstripe -D -c $stripe_count --max-inherit-rr 2 \
26335                         $testdir/rr || error "setdirstripe rr failed"
26336                 $LFS setdirstripe -D -c $stripe_count $testdir/qos ||
26337                         error "setdirstripe failed"
26338                 test_qos_mkdir "mkdir" $stripe_count
26339         done
26340 }
26341 run_test 413b "QoS mkdir under dir whose default LMV starting MDT offset is -1"
26342
26343 test_413c() {
26344         (( $MDSCOUNT >= 2 )) ||
26345                 skip "We need at least 2 MDTs for this test"
26346
26347         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
26348                 skip "Need server version at least 2.14.51"
26349
26350         local testdir
26351         local inherit
26352         local inherit_rr
26353
26354         testdir=$DIR/${tdir}-s1
26355         mkdir $testdir || error "mkdir $testdir failed"
26356         mkdir $testdir/rr || error "mkdir rr failed"
26357         $LFS mkdir -i $(most_full_mdt) $testdir/qos || error "mkdir qos failed"
26358         # default max_inherit is -1, default max_inherit_rr is 0
26359         $LFS setdirstripe -D -c 1 $testdir/rr ||
26360                 error "setdirstripe rr failed"
26361         $LFS setdirstripe -D -c 1 -i -1 -X 2 --max-inherit-rr 1 $testdir/qos ||
26362                 error "setdirstripe qos failed"
26363         test_qos_mkdir "mkdir" 1
26364
26365         mkdir $testdir/rr/level1 || error "mkdir rr/level1 failed"
26366         inherit=$($LFS getdirstripe -D -X $testdir/rr/level1)
26367         (( $inherit == -1 )) || error "rr/level1 inherit $inherit != -1"
26368         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/rr/level1)
26369         (( $inherit_rr == 0 )) || error "rr/level1 inherit-rr $inherit_rr != 0"
26370
26371         mkdir $testdir/qos/level1 || error "mkdir qos/level1 failed"
26372         inherit=$($LFS getdirstripe -D -X $testdir/qos/level1)
26373         (( $inherit == 1 )) || error "qos/level1 inherit $inherit != 1"
26374         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/qos/level1)
26375         (( $inherit_rr == 0 )) || error "qos/level1 inherit-rr $inherit_rr != 0"
26376         mkdir $testdir/qos/level1/level2 || error "mkdir level2 failed"
26377         getfattr -d -m dmv -e hex $testdir/qos/level1/level2 | grep dmv &&
26378                 error "level2 shouldn't have default LMV" || true
26379 }
26380 run_test 413c "mkdir with default LMV max inherit rr"
26381
26382 test_413d() {
26383         (( MDSCOUNT >= 2 )) ||
26384                 skip "We need at least 2 MDTs for this test"
26385
26386         (( MDS1_VERSION >= $(version_code 2.14.51) )) ||
26387                 skip "Need server version at least 2.14.51"
26388
26389         local lmv_qos_threshold_rr
26390
26391         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
26392                 head -n1)
26393         stack_trap "$LCTL set_param \
26394                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null" EXIT
26395
26396         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
26397         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
26398         getfattr -d -m dmv -e hex $DIR/$tdir | grep dmv &&
26399                 error "$tdir shouldn't have default LMV"
26400         createmany -d $DIR/$tdir/sub $((100 * MDSCOUNT)) ||
26401                 error "mkdir sub failed"
26402
26403         local count=$($LFS getstripe -m $DIR/$tdir/* | grep -c ^0)
26404
26405         (( count == 100 )) || error "$count subdirs on MDT0"
26406 }
26407 run_test 413d "inherit ROOT default LMV"
26408
26409 test_413e() {
26410         (( MDSCOUNT >= 2 )) ||
26411                 skip "We need at least 2 MDTs for this test"
26412         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
26413                 skip "Need server version at least 2.14.55"
26414
26415         local testdir=$DIR/$tdir
26416         local tmpfile=$TMP/temp.setdirstripe.stderr.$$
26417         local max_inherit
26418         local sub_max_inherit
26419
26420         mkdir -p $testdir || error "failed to create $testdir"
26421
26422         # set default max-inherit to -1 if stripe count is 0 or 1
26423         $LFS setdirstripe -D -c 1 $testdir ||
26424                 error "failed to set default LMV"
26425         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
26426         (( max_inherit == -1 )) ||
26427                 error "wrong max_inherit value $max_inherit"
26428
26429         # set default max_inherit to a fixed value if stripe count is not 0 or 1
26430         $LFS setdirstripe -D -c -1 $testdir ||
26431                 error "failed to set default LMV"
26432         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
26433         (( max_inherit > 0 )) ||
26434                 error "wrong max_inherit value $max_inherit"
26435
26436         # and the subdir will decrease the max_inherit by 1
26437         mkdir -p $testdir/subdir-1 || error "failed to make subdir"
26438         sub_max_inherit=$($LFS getdirstripe -D --max-inherit $testdir/subdir-1)
26439         (( sub_max_inherit == max_inherit - 1)) ||
26440                 error "wrong max-inherit of subdir $sub_max_inherit"
26441
26442         # check specified --max-inherit and warning message
26443         stack_trap "rm -f $tmpfile"
26444         $LFS setdirstripe -D -c 2 --max-inherit=-1 $testdir 2> $tmpfile ||
26445                 error "failed to set default LMV"
26446         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
26447         (( max_inherit == -1 )) ||
26448                 error "wrong max_inherit value $max_inherit"
26449
26450         # check the warning messages
26451         if ! [[ $(cat $tmpfile) =~ "max-inherit=" ]]; then
26452                 error "failed to detect warning string"
26453         fi
26454 }
26455 run_test 413e "check default max-inherit value"
26456
26457 test_fs_dmv_inherit()
26458 {
26459         local testdir=$DIR/$tdir
26460
26461         local count
26462         local inherit
26463         local inherit_rr
26464
26465         for i in 1 2 3; do
26466                 mkdir $testdir || error "mkdir $testdir failed"
26467                 count=$($LFS getdirstripe -D -c $testdir)
26468                 (( count == 1 )) ||
26469                         error "$testdir default LMV count mismatch $count != 1"
26470                 inherit=$($LFS getdirstripe -D -X $testdir)
26471                 (( inherit == 3 - i )) ||
26472                         error "$testdir default LMV max-inherit $inherit != $((3 - i))"
26473                 inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir)
26474                 (( inherit_rr == 3 - i )) ||
26475                         error "$testdir default LMV max-inherit-rr $inherit_rr != $((3 - i))"
26476                 testdir=$testdir/sub
26477         done
26478
26479         mkdir $testdir || error "mkdir $testdir failed"
26480         count=$($LFS getdirstripe -D -c $testdir)
26481         (( count == 0 )) ||
26482                 error "$testdir default LMV count not zero: $count"
26483 }
26484
26485 test_413f() {
26486         (( MDSCOUNT >= 2 )) || skip "We need at least 2 MDTs for this test"
26487
26488         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
26489                 skip "Need server version at least 2.14.55"
26490
26491         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
26492                 error "dump $DIR default LMV failed"
26493         stack_trap "setfattr --restore=$TMP/dmv.ea"
26494
26495         $LFS setdirstripe -D -i -1 -c 1 -X 3 --max-inherit-rr 3 $DIR ||
26496                 error "set $DIR default LMV failed"
26497
26498         test_fs_dmv_inherit
26499 }
26500 run_test 413f "lfs getdirstripe -D list ROOT default LMV if it's not set on dir"
26501
26502 test_413g() {
26503         (( MDSCOUNT >= 2 )) || skip "We need at least 2 MDTs for this test"
26504
26505         mkdir -p $DIR/$tdir/l2/l3/l4 || error "mkdir $tdir/l1/l2/l3 failed"
26506         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
26507                 error "dump $DIR default LMV failed"
26508         stack_trap "setfattr --restore=$TMP/dmv.ea"
26509
26510         $LFS setdirstripe -D -i -1 -c 1 -X 3 --max-inherit-rr 3 $DIR ||
26511                 error "set $DIR default LMV failed"
26512
26513         FILESET="$FILESET/$tdir/l2/l3/l4" mount_client $MOUNT2 ||
26514                 error "mount $MOUNT2 failed"
26515         stack_trap "umount_client $MOUNT2"
26516
26517         local saved_DIR=$DIR
26518
26519         export DIR=$MOUNT2
26520
26521         stack_trap "export DIR=$saved_DIR"
26522
26523         # first check filesystem-wide default LMV inheritance
26524         test_fs_dmv_inherit || error "incorrect fs default LMV inheritance"
26525
26526         # then check subdirs are spread to all MDTs
26527         createmany -d $DIR/s $((MDSCOUNT * 100)) || error "createmany failed"
26528
26529         local count=$($LFS getstripe -m $DIR/s* | sort -u | wc -l)
26530
26531         (( $count == $MDSCOUNT )) || error "dirs are spread to $count MDTs"
26532 }
26533 run_test 413g "enforce ROOT default LMV on subdir mount"
26534
26535 test_413h() {
26536         (( MDSCOUNT >= 2 )) ||
26537                 skip "We need at least 2 MDTs for this test"
26538
26539         (( MDS1_VERSION >= $(version_code 2.15.50.6) )) ||
26540                 skip "Need server version at least 2.15.50.6"
26541
26542         local lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
26543
26544         stack_trap "$LCTL set_param \
26545                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null"
26546         $LCTL set_param lmv.*.qos_maxage=1
26547
26548         local depth=5
26549         local rr_depth=4
26550         local dir=$DIR/$tdir/l1/l2/l3/l4/l5
26551         local count=$((MDSCOUNT * 20))
26552
26553         generate_uneven_mdts 50
26554
26555         mkdir -p $dir || error "mkdir $dir failed"
26556         stack_trap "rm -rf $dir"
26557         $LFS setdirstripe -D -c 1 -i -1 --max-inherit=$depth \
26558                 --max-inherit-rr=$rr_depth $dir
26559
26560         for ((d=0; d < depth + 2; d++)); do
26561                 log "dir=$dir:"
26562                 for ((sub=0; sub < count; sub++)); do
26563                         mkdir $dir/d$sub
26564                 done
26565                 $LFS getdirstripe -i $dir/d* | sort | uniq -c | sort -nr
26566                 local num=($($LFS getdirstripe -i $dir/d* | sort | uniq -c))
26567                 # subdirs within $rr_depth should be created round-robin
26568                 if (( d < rr_depth )); then
26569                         (( ${num[0]} != count )) ||
26570                                 error "all objects created on MDT ${num[1]}"
26571                 fi
26572
26573                 dir=$dir/d0
26574         done
26575 }
26576 run_test 413h "don't stick to parent for round-robin dirs"
26577
26578 test_413z() {
26579         local pids=""
26580         local subdir
26581         local pid
26582
26583         for subdir in $(\ls -1 -d $DIR/d413*-fillmdt/*); do
26584                 unlinkmany $subdir/f. $TEST413_COUNT &
26585                 pids="$pids $!"
26586         done
26587
26588         for pid in $pids; do
26589                 wait $pid
26590         done
26591 }
26592 run_test 413z "413 test cleanup"
26593
26594 test_414() {
26595 #define OBD_FAIL_PTLRPC_BULK_ATTACH      0x521
26596         $LCTL set_param fail_loc=0x80000521
26597         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
26598         rm -f $DIR/$tfile
26599 }
26600 run_test 414 "simulate ENOMEM in ptlrpc_register_bulk()"
26601
26602 test_415() {
26603         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26604         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
26605                 skip "Need server version at least 2.11.52"
26606
26607         # LU-11102
26608         local total
26609         local setattr_pid
26610         local start_time
26611         local end_time
26612         local duration
26613
26614         total=500
26615         # this test may be slow on ZFS
26616         [ "$mds1_FSTYPE" == "zfs" ] && total=50
26617
26618         # though this test is designed for striped directory, let's test normal
26619         # directory too since lock is always saved as CoS lock.
26620         test_mkdir $DIR/$tdir || error "mkdir $tdir"
26621         createmany -o $DIR/$tdir/$tfile. $total || error "createmany"
26622
26623         (
26624                 while true; do
26625                         touch $DIR/$tdir
26626                 done
26627         ) &
26628         setattr_pid=$!
26629
26630         start_time=$(date +%s)
26631         for i in $(seq $total); do
26632                 mrename $DIR/$tdir/$tfile.$i $DIR/$tdir/$tfile-new.$i \
26633                         > /dev/null
26634         done
26635         end_time=$(date +%s)
26636         duration=$((end_time - start_time))
26637
26638         kill -9 $setattr_pid
26639
26640         echo "rename $total files took $duration sec"
26641         [ $duration -lt 100 ] || error "rename took $duration sec"
26642 }
26643 run_test 415 "lock revoke is not missing"
26644
26645 test_416() {
26646         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
26647                 skip "Need server version at least 2.11.55"
26648
26649         # define OBD_FAIL_OSD_TXN_START    0x19a
26650         do_facet mds1 lctl set_param fail_loc=0x19a
26651
26652         lfs mkdir -c $MDSCOUNT $DIR/$tdir
26653
26654         true
26655 }
26656 run_test 416 "transaction start failure won't cause system hung"
26657
26658 cleanup_417() {
26659         trap 0
26660         do_nodes $(comma_list $(mdts_nodes)) \
26661                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=1"
26662         do_nodes $(comma_list $(mdts_nodes)) \
26663                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=1"
26664         do_nodes $(comma_list $(mdts_nodes)) \
26665                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=1"
26666 }
26667
26668 test_417() {
26669         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
26670         [[ $MDS1_VERSION -lt $(version_code 2.11.56) ]] &&
26671                 skip "Need MDS version at least 2.11.56"
26672
26673         trap cleanup_417 RETURN EXIT
26674
26675         $LFS mkdir -i 1 $DIR/$tdir.1 || error "create remote dir $tdir.1 failed"
26676         do_nodes $(comma_list $(mdts_nodes)) \
26677                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=0"
26678         $LFS migrate -m 0 $DIR/$tdir.1 &&
26679                 error "migrate dir $tdir.1 should fail"
26680
26681         do_nodes $(comma_list $(mdts_nodes)) \
26682                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=0"
26683         $LFS mkdir -i 1 $DIR/$tdir.2 &&
26684                 error "create remote dir $tdir.2 should fail"
26685
26686         do_nodes $(comma_list $(mdts_nodes)) \
26687                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=0"
26688         $LFS mkdir -c 2 $DIR/$tdir.3 &&
26689                 error "create striped dir $tdir.3 should fail"
26690         true
26691 }
26692 run_test 417 "disable remote dir, striped dir and dir migration"
26693
26694 # Checks that the outputs of df [-i] and lfs df [-i] match
26695 #
26696 # usage: check_lfs_df <blocks | inodes> <mountpoint>
26697 check_lfs_df() {
26698         local dir=$2
26699         local inodes
26700         local df_out
26701         local lfs_df_out
26702         local count
26703         local passed=false
26704
26705         # blocks or inodes
26706         [ "$1" == "blocks" ] && inodes= || inodes="-i"
26707
26708         for count in {1..100}; do
26709                 do_nodes "$CLIENTS" \
26710                         $LCTL set_param ldlm.namespaces.*.lru_size=clear
26711                 sync; sleep 0.2
26712
26713                 # read the lines of interest
26714                 df_out=($(df -P $inodes $dir | tail -n +2)) ||
26715                         error "df $inodes $dir | tail -n +2 failed"
26716                 lfs_df_out=($($LFS df $inodes $dir | grep summary:)) ||
26717                         error "lfs df $inodes $dir | grep summary: failed"
26718
26719                 # skip first substrings of each output as they are different
26720                 # "<NID>:/<fsname>" for df, "filesystem_summary:" for lfs df
26721                 # compare the two outputs
26722                 passed=true
26723                 #  skip "available" on MDT until LU-13997 is fixed.
26724                 #for i in {1..5}; do
26725                 for i in 1 2 4 5; do
26726                         [ "${df_out[i]}" != "${lfs_df_out[i]}" ] && passed=false
26727                 done
26728                 $passed && break
26729         done
26730
26731         if ! $passed; then
26732                 df -P $inodes $dir
26733                 echo
26734                 lfs df $inodes $dir
26735                 error "df and lfs df $1 output mismatch: "      \
26736                       "df ${inodes}: ${df_out[*]}, "            \
26737                       "lfs df ${inodes}: ${lfs_df_out[*]}"
26738         fi
26739 }
26740
26741 test_418() {
26742         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26743
26744         local dir=$DIR/$tdir
26745         local numfiles=$((RANDOM % 4096 + 2))
26746         local numblocks=$((RANDOM % 256 + 1))
26747
26748         wait_delete_completed
26749         test_mkdir $dir
26750
26751         # check block output
26752         check_lfs_df blocks $dir
26753         # check inode output
26754         check_lfs_df inodes $dir
26755
26756         # create a single file and retest
26757         echo "Creating a single file and testing"
26758         createmany -o $dir/$tfile- 1 &>/dev/null ||
26759                 error "creating 1 file in $dir failed"
26760         check_lfs_df blocks $dir
26761         check_lfs_df inodes $dir
26762
26763         # create a random number of files
26764         echo "Creating $((numfiles - 1)) files and testing"
26765         createmany -o $dir/$tfile- 1 $((numfiles - 1)) &>/dev/null ||
26766                 error "creating $((numfiles - 1)) files in $dir failed"
26767
26768         # write a random number of blocks to the first test file
26769         echo "Writing $numblocks 4K blocks and testing"
26770         dd if=/dev/urandom of=$dir/${tfile}-0 bs=4K conv=fsync \
26771                 count=$numblocks &>/dev/null ||
26772                 error "dd to $dir/${tfile}-0 failed"
26773
26774         # retest
26775         check_lfs_df blocks $dir
26776         check_lfs_df inodes $dir
26777
26778         unlinkmany $dir/$tfile- $numfiles &>/dev/null ||
26779                 error "unlinking $numfiles files in $dir failed"
26780 }
26781 run_test 418 "df and lfs df outputs match"
26782
26783 test_419()
26784 {
26785         local dir=$DIR/$tdir
26786
26787         mkdir -p $dir
26788         touch $dir/file
26789
26790         cancel_lru_locks mdc
26791
26792         #OBD_FAIL_LLITE_OPEN_BY_NAME    0x1410
26793         $LCTL set_param fail_loc=0x1410
26794         cat $dir/file
26795         $LCTL set_param fail_loc=0
26796         rm -rf $dir
26797 }
26798 run_test 419 "Verify open file by name doesn't crash kernel"
26799
26800 test_420()
26801 {
26802         [[ $MDS1_VERSION -ge $(version_code 2.12.53) ]] ||
26803                 skip "Need MDS version at least 2.12.53"
26804
26805         local SAVE_UMASK=$(umask)
26806         local dir=$DIR/$tdir
26807         local uname=$(getent passwd $RUNAS_ID | cut -d: -f1)
26808
26809         mkdir -p $dir
26810         umask 0000
26811         mkdir -m03777 $dir/testdir
26812         ls -dn $dir/testdir
26813         # Need to remove trailing '.' when SELinux is enabled
26814         local dirperms=$(ls -dn $dir/testdir |
26815                          awk '{ sub(/\.$/, "", $1); print $1}')
26816         [ $dirperms == "drwxrwsrwt" ] ||
26817                 error "incorrect perms on $dir/testdir"
26818
26819         su - $uname -c "PATH=$LUSTRE/tests:\$PATH; \
26820                 openfile -f O_RDONLY:O_CREAT -m 02755 $dir/testdir/testfile"
26821         ls -n $dir/testdir/testfile
26822         local fileperms=$(ls -n $dir/testdir/testfile |
26823                           awk '{ sub(/\.$/, "", $1); print $1}')
26824         [ $fileperms == "-rwxr-xr-x" ] ||
26825                 error "incorrect perms on $dir/testdir/testfile"
26826
26827         umask $SAVE_UMASK
26828 }
26829 run_test 420 "clear SGID bit on non-directories for non-members"
26830
26831 test_421a() {
26832         local cnt
26833         local fid1
26834         local fid2
26835
26836         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26837                 skip "Need MDS version at least 2.12.54"
26838
26839         test_mkdir $DIR/$tdir
26840         createmany -o $DIR/$tdir/f 3
26841         cnt=$(ls -1 $DIR/$tdir | wc -l)
26842         [ $cnt != 3 ] && error "unexpected #files: $cnt"
26843
26844         fid1=$(lfs path2fid $DIR/$tdir/f1)
26845         fid2=$(lfs path2fid $DIR/$tdir/f2)
26846         $LFS rmfid $DIR $fid1 $fid2 || error "rmfid failed"
26847
26848         stat $DIR/$tdir/f1 && error "f1 still visible on the client"
26849         stat $DIR/$tdir/f2 && error "f2 still visible on the client"
26850
26851         cnt=$(ls -1 $DIR/$tdir | wc -l)
26852         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
26853
26854         rm -f $DIR/$tdir/f3 || error "can't remove f3"
26855         createmany -o $DIR/$tdir/f 3
26856         cnt=$(ls -1 $DIR/$tdir | wc -l)
26857         [ $cnt != 3 ] && error "unexpected #files: $cnt"
26858
26859         fid1=$(lfs path2fid $DIR/$tdir/f1)
26860         fid2=$(lfs path2fid $DIR/$tdir/f2)
26861         echo "remove using fsname $FSNAME"
26862         $LFS rmfid $FSNAME $fid1 $fid2 || error "rmfid with fsname failed"
26863
26864         cnt=$(ls -1 $DIR/$tdir | wc -l)
26865         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
26866 }
26867 run_test 421a "simple rm by fid"
26868
26869 test_421b() {
26870         local cnt
26871         local FID1
26872         local FID2
26873
26874         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26875                 skip "Need MDS version at least 2.12.54"
26876
26877         test_mkdir $DIR/$tdir
26878         createmany -o $DIR/$tdir/f 3
26879         multiop_bg_pause $DIR/$tdir/f1 o_c || error "multiop failed to start"
26880         MULTIPID=$!
26881
26882         FID1=$(lfs path2fid $DIR/$tdir/f1)
26883         FID2=$(lfs path2fid $DIR/$tdir/f2)
26884         $LFS rmfid $DIR $FID1 $FID2 && error "rmfid didn't fail"
26885
26886         kill -USR1 $MULTIPID
26887         wait
26888
26889         cnt=$(ls $DIR/$tdir | wc -l)
26890         [ $cnt == 2 ] || error "unexpected #files after: $cnt"
26891 }
26892 run_test 421b "rm by fid on open file"
26893
26894 test_421c() {
26895         local cnt
26896         local FIDS
26897
26898         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26899                 skip "Need MDS version at least 2.12.54"
26900
26901         test_mkdir $DIR/$tdir
26902         createmany -o $DIR/$tdir/f 3
26903         touch $DIR/$tdir/$tfile
26904         createmany -l$DIR/$tdir/$tfile $DIR/$tdir/h 180
26905         cnt=$(ls -1 $DIR/$tdir | wc -l)
26906         [ $cnt != 184 ] && error "unexpected #files: $cnt"
26907
26908         FID1=$(lfs path2fid $DIR/$tdir/$tfile)
26909         $LFS rmfid $DIR $FID1 || error "rmfid failed"
26910
26911         cnt=$(ls $DIR/$tdir | wc -l)
26912         [ $cnt == 3 ] || error "unexpected #files after: $cnt"
26913 }
26914 run_test 421c "rm by fid against hardlinked files"
26915
26916 test_421d() {
26917         local cnt
26918         local FIDS
26919
26920         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26921                 skip "Need MDS version at least 2.12.54"
26922
26923         test_mkdir $DIR/$tdir
26924         createmany -o $DIR/$tdir/f 4097
26925         cnt=$(ls -1 $DIR/$tdir | wc -l)
26926         [ $cnt != 4097 ] && error "unexpected #files: $cnt"
26927
26928         FIDS=$(lfs path2fid $DIR/$tdir/f* | sed "s/[/][^:]*://g")
26929         $LFS rmfid $DIR $FIDS || error "rmfid failed"
26930
26931         cnt=$(ls $DIR/$tdir | wc -l)
26932         rm -rf $DIR/$tdir
26933         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
26934 }
26935 run_test 421d "rmfid en masse"
26936
26937 test_421e() {
26938         local cnt
26939         local FID
26940
26941         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
26942         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26943                 skip "Need MDS version at least 2.12.54"
26944
26945         mkdir -p $DIR/$tdir
26946         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
26947         createmany -o $DIR/$tdir/striped_dir/f 512
26948         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
26949         [ $cnt != 512 ] && error "unexpected #files: $cnt"
26950
26951         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
26952                 sed "s/[/][^:]*://g")
26953         $LFS rmfid $DIR $FIDS || error "rmfid failed"
26954
26955         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
26956         rm -rf $DIR/$tdir
26957         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
26958 }
26959 run_test 421e "rmfid in DNE"
26960
26961 test_421f() {
26962         local cnt
26963         local FID
26964
26965         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26966                 skip "Need MDS version at least 2.12.54"
26967
26968         test_mkdir $DIR/$tdir
26969         touch $DIR/$tdir/f
26970         cnt=$(ls -1 $DIR/$tdir | wc -l)
26971         [ $cnt != 1 ] && error "unexpected #files: $cnt"
26972
26973         FID=$(lfs path2fid $DIR/$tdir/f)
26974         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (1)"
26975         # rmfid should fail
26976         cnt=$(ls -1 $DIR/$tdir | wc -l)
26977         [ $cnt != 1 ] && error "unexpected #files after (2): $cnt"
26978
26979         chmod a+rw $DIR/$tdir
26980         ls -la $DIR/$tdir
26981         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (2)"
26982         # rmfid should fail
26983         cnt=$(ls -1 $DIR/$tdir | wc -l)
26984         [ $cnt != 1 ] && error "unexpected #files after (3): $cnt"
26985
26986         rm -f $DIR/$tdir/f
26987         $RUNAS touch $DIR/$tdir/f
26988         FID=$(lfs path2fid $DIR/$tdir/f)
26989         echo "rmfid as root"
26990         $LFS rmfid $DIR $FID || error "rmfid as root failed"
26991         cnt=$(ls -1 $DIR/$tdir | wc -l)
26992         [ $cnt == 0 ] || error "unexpected #files after (4): $cnt"
26993
26994         rm -f $DIR/$tdir/f
26995         $RUNAS touch $DIR/$tdir/f
26996         cnt=$(ls -1 $DIR/$tdir | wc -l)
26997         [ $cnt != 1 ] && error "unexpected #files (4): $cnt"
26998         FID=$(lfs path2fid $DIR/$tdir/f)
26999         # rmfid w/o user_fid2path mount option should fail
27000         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail(3)"
27001         cnt=$(ls -1 $DIR/$tdir | wc -l)
27002         [ $cnt == 1 ] || error "unexpected #files after (5): $cnt"
27003
27004         tmpdir=$(mktemp -d /tmp/lustre-XXXXXX)
27005         stack_trap "rmdir $tmpdir"
27006         mount_client $tmpdir "$MOUNT_OPTS,user_fid2path" ||
27007                 error "failed to mount client'"
27008         stack_trap "umount_client $tmpdir"
27009
27010         $RUNAS $LFS rmfid $tmpdir $FID || error "rmfid failed"
27011         # rmfid should succeed
27012         cnt=$(ls -1 $tmpdir/$tdir | wc -l)
27013         [ $cnt == 0 ] || error "unexpected #files after (6): $cnt"
27014
27015         # rmfid shouldn't allow to remove files due to dir's permission
27016         chmod a+rwx $tmpdir/$tdir
27017         touch $tmpdir/$tdir/f
27018         ls -la $tmpdir/$tdir
27019         FID=$(lfs path2fid $tmpdir/$tdir/f)
27020         $RUNAS $LFS rmfid $tmpdir $FID && error "rmfid didn't fail"
27021         return 0
27022 }
27023 run_test 421f "rmfid checks permissions"
27024
27025 test_421g() {
27026         local cnt
27027         local FIDS
27028
27029         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
27030         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
27031                 skip "Need MDS version at least 2.12.54"
27032
27033         mkdir -p $DIR/$tdir
27034         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
27035         createmany -o $DIR/$tdir/striped_dir/f 512
27036         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
27037         [ $cnt != 512 ] && error "unexpected #files: $cnt"
27038
27039         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
27040                 sed "s/[/][^:]*://g")
27041
27042         rm -f $DIR/$tdir/striped_dir/f1*
27043         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
27044         removed=$((512 - cnt))
27045
27046         # few files have been just removed, so we expect
27047         # rmfid to fail on their fids
27048         errors=$($LFS rmfid $DIR $FIDS 2>&1 | wc -l)
27049         [ $removed != $errors ] && error "$errors != $removed"
27050
27051         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
27052         rm -rf $DIR/$tdir
27053         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
27054 }
27055 run_test 421g "rmfid to return errors properly"
27056
27057 test_422() {
27058         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d1
27059         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d2
27060         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d3
27061         dd if=/dev/zero of=$DIR/$tdir/d1/file1 bs=1k count=1
27062         dd if=/dev/zero of=$DIR/$tdir/d2/file1 bs=1k count=1
27063
27064         local amc=$(at_max_get client)
27065         local amo=$(at_max_get mds1)
27066         local timeout=`lctl get_param -n timeout`
27067
27068         at_max_set 0 client
27069         at_max_set 0 mds1
27070
27071 #define OBD_FAIL_PTLRPC_PAUSE_REQ        0x50a
27072         do_facet mds1 $LCTL set_param fail_loc=0x8000050a \
27073                         fail_val=$(((2*timeout + 10)*1000))
27074         touch $DIR/$tdir/d3/file &
27075         sleep 2
27076 #define OBD_FAIL_TGT_REPLY_DATA_RACE     0x722
27077         do_facet mds1 $LCTL set_param fail_loc=0x80000722 \
27078                         fail_val=$((2*timeout + 5))
27079         mv $DIR/$tdir/d1/file1 $DIR/$tdir/d1/file2 &
27080         local pid=$!
27081         sleep 1
27082         kill -9 $pid
27083         sleep $((2 * timeout))
27084         echo kill $pid
27085         kill -9 $pid
27086         lctl mark touch
27087         touch $DIR/$tdir/d2/file3
27088         touch $DIR/$tdir/d2/file4
27089         touch $DIR/$tdir/d2/file5
27090
27091         wait
27092         at_max_set $amc client
27093         at_max_set $amo mds1
27094
27095         # LU-12838 - verify the ptlrpc thread watchdog is not always throttled
27096         do_facet mds1 "dmesg | grep 'Dumping the stack trace for debugging'" ||
27097                 error "Watchdog is always throttled"
27098 }
27099 run_test 422 "kill a process with RPC in progress"
27100
27101 stat_test() {
27102     df -h $MOUNT &
27103     df -h $MOUNT &
27104     df -h $MOUNT &
27105     df -h $MOUNT &
27106     df -h $MOUNT &
27107     df -h $MOUNT &
27108 }
27109
27110 test_423() {
27111     local _stats
27112     # ensure statfs cache is expired
27113     sleep 2;
27114
27115     _stats=$(stat_test | grep $MOUNT | sort -u | wc -l)
27116     [[ ${_stats} -ne 1 ]] && error "statfs wrong"
27117
27118     return 0
27119 }
27120 run_test 423 "statfs should return a right data"
27121
27122 test_424() {
27123 #define OBD_FAIL_PTLRPC_BULK_REPLY_ATTACH      0x522 | OBD_FAIL_ONCE
27124         $LCTL set_param fail_loc=0x80000522
27125         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
27126         rm -f $DIR/$tfile
27127 }
27128 run_test 424 "simulate ENOMEM in ptl_send_rpc bulk reply ME attach"
27129
27130 test_425() {
27131         test_mkdir -c -1 $DIR/$tdir
27132         $LFS setstripe -c -1 $DIR/$tdir
27133
27134         lru_resize_disable "" 100
27135         stack_trap "lru_resize_enable" EXIT
27136
27137         sleep 5
27138
27139         for i in $(seq $((MDSCOUNT * 125))); do
27140                 local t=$DIR/$tdir/$tfile_$i
27141
27142                 dd if=/dev/zero of=$t bs=4K count=1 > /dev/null 2>&1 ||
27143                         error_noexit "Create file $t"
27144         done
27145         stack_trap "rm -rf $DIR/$tdir" EXIT
27146
27147         for oscparam in $($LCTL list_param ldlm.namespaces.*osc-[-0-9a-f]*); do
27148                 local lru_size=$($LCTL get_param -n $oscparam.lru_size)
27149                 local lock_count=$($LCTL get_param -n $oscparam.lock_count)
27150
27151                 [ $lock_count -le $lru_size ] ||
27152                         error "osc lock count $lock_count > lru size $lru_size"
27153         done
27154
27155         for mdcparam in $($LCTL list_param ldlm.namespaces.*mdc-*); do
27156                 local lru_size=$($LCTL get_param -n $mdcparam.lru_size)
27157                 local lock_count=$($LCTL get_param -n $mdcparam.lock_count)
27158
27159                 [ $lock_count -le $lru_size ] ||
27160                         error "mdc lock count $lock_count > lru size $lru_size"
27161         done
27162 }
27163 run_test 425 "lock count should not exceed lru size"
27164
27165 test_426() {
27166         splice-test -r $DIR/$tfile
27167         splice-test -rd $DIR/$tfile
27168         splice-test $DIR/$tfile
27169         splice-test -d $DIR/$tfile
27170 }
27171 run_test 426 "splice test on Lustre"
27172
27173 test_427() {
27174         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
27175         (( $MDS1_VERSION >= $(version_code 2.12.4) )) ||
27176                 skip "Need MDS version at least 2.12.4"
27177         local log
27178
27179         mkdir $DIR/$tdir
27180         mkdir $DIR/$tdir/1
27181         mkdir $DIR/$tdir/2
27182         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/1/dir
27183         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/2/dir2
27184
27185         $LFS getdirstripe $DIR/$tdir/1/dir
27186
27187         #first setfattr for creating updatelog
27188         setfattr -n user.attr0 -v "some text" $DIR/$tdir/1/dir
27189
27190 #define OBD_FAIL_OUT_OBJECT_MISS        0x1708
27191         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param fail_loc=0x80001708
27192         setfattr -n user.attr1 -v "some text" $DIR/$tdir/1/dir &
27193         setfattr -n user.attr2 -v "another attr"  $DIR/$tdir/2/dir2 &
27194
27195         sleep 2
27196         fail mds2
27197         wait_recovery_complete mds2 $((2*TIMEOUT))
27198
27199         log=$(do_facet mds1 dmesg | tac | sed "/${TESTNAME//_/ }/,$ d")
27200         echo $log | grep "get update log failed" &&
27201                 error "update log corruption is detected" || true
27202 }
27203 run_test 427 "Failed DNE2 update request shouldn't corrupt updatelog"
27204
27205 test_428() {
27206         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27207         local cache_limit=$CACHE_MAX
27208
27209         stack_trap "$LCTL set_param -n llite.*.max_cached_mb=$cache_limit"
27210         $LCTL set_param -n llite.*.max_cached_mb=64
27211
27212         mkdir $DIR/$tdir
27213         $LFS setstripe -c 1 $DIR/$tdir
27214         eval touch $DIR/$tdir/$tfile.{1..$OSTCOUNT}
27215         stack_trap "rm -f $DIR/$tdir/$tfile.*"
27216         #test write
27217         for f in $(seq 4); do
27218                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$f bs=128M count=1 &
27219         done
27220         wait
27221
27222         cancel_lru_locks osc
27223         # Test read
27224         for f in $(seq 4); do
27225                 dd if=$DIR/$tdir/$tfile.$f of=/dev/null bs=128M count=1 &
27226         done
27227         wait
27228 }
27229 run_test 428 "large block size IO should not hang"
27230
27231 test_429() { # LU-7915 / LU-10948
27232         local ll_opencache_threshold_count="llite.*.opencache_threshold_count"
27233         local testfile=$DIR/$tfile
27234         local mdc_rpcstats="mdc.$FSNAME-MDT0000-*.stats"
27235         local new_flag=1
27236         local first_rpc
27237         local second_rpc
27238         local third_rpc
27239
27240         $LCTL get_param $ll_opencache_threshold_count ||
27241                 skip "client does not have opencache parameter"
27242
27243         set_opencache $new_flag
27244         stack_trap "restore_opencache"
27245         [ $($LCTL get_param -n $ll_opencache_threshold_count) == $new_flag ] ||
27246                 error "enable opencache failed"
27247         touch $testfile
27248         # drop MDC DLM locks
27249         cancel_lru_locks mdc
27250         # clear MDC RPC stats counters
27251         $LCTL set_param $mdc_rpcstats=clear
27252
27253         # According to the current implementation, we need to run 3 times
27254         # open & close file to verify if opencache is enabled correctly.
27255         # 1st, RPCs are sent for lookup/open and open handle is released on
27256         #      close finally.
27257         # 2nd, RPC is sent for open, MDS_OPEN_LOCK is fetched automatically,
27258         #      so open handle won't be released thereafter.
27259         # 3rd, No RPC is sent out.
27260         $MULTIOP $testfile oc || error "multiop failed"
27261         first_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
27262         echo "1st: $first_rpc RPCs in flight"
27263
27264         $MULTIOP $testfile oc || error "multiop failed"
27265         second_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
27266         echo "2nd: $second_rpc RPCs in flight"
27267
27268         $MULTIOP $testfile oc || error "multiop failed"
27269         third_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
27270         echo "3rd: $third_rpc RPCs in flight"
27271
27272         #verify no MDC RPC is sent
27273         [[ $second_rpc == $third_rpc ]] || error "MDC RPC is still sent"
27274 }
27275 run_test 429 "verify if opencache flag on client side does work"
27276
27277 lseek_test_430() {
27278         local offset
27279         local file=$1
27280
27281         # data at [200K, 400K)
27282         dd if=/dev/urandom of=$file bs=256K count=1 seek=1 ||
27283                 error "256K->512K dd fails"
27284         # data at [2M, 3M)
27285         dd if=/dev/urandom of=$file bs=1M count=1 seek=2 ||
27286                 error "2M->3M dd fails"
27287         # data at [4M, 5M)
27288         dd if=/dev/urandom of=$file bs=1M count=1 seek=4 ||
27289                 error "4M->5M dd fails"
27290         echo "Data at 256K...512K, 2M...3M and 4M...5M"
27291         # start at first component hole #1
27292         printf "Seeking hole from 1000 ... "
27293         offset=$(lseek_test -l 1000 $file)
27294         echo $offset
27295         [[ $offset == 1000 ]] || error "offset $offset != 1000"
27296         printf "Seeking data from 1000 ... "
27297         offset=$(lseek_test -d 1000 $file)
27298         echo $offset
27299         [[ $offset == 262144 ]] || error "offset $offset != 262144"
27300
27301         # start at first component data block
27302         printf "Seeking hole from 300000 ... "
27303         offset=$(lseek_test -l 300000 $file)
27304         echo $offset
27305         [[ $offset == 524288 ]] || error "offset $offset != 524288"
27306         printf "Seeking data from 300000 ... "
27307         offset=$(lseek_test -d 300000 $file)
27308         echo $offset
27309         [[ $offset == 300000 ]] || error "offset $offset != 300000"
27310
27311         # start at the first component but beyond end of object size
27312         printf "Seeking hole from 1000000 ... "
27313         offset=$(lseek_test -l 1000000 $file)
27314         echo $offset
27315         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
27316         printf "Seeking data from 1000000 ... "
27317         offset=$(lseek_test -d 1000000 $file)
27318         echo $offset
27319         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
27320
27321         # start at second component stripe 2 (empty file)
27322         printf "Seeking hole from 1500000 ... "
27323         offset=$(lseek_test -l 1500000 $file)
27324         echo $offset
27325         [[ $offset == 1500000 ]] || error "offset $offset != 1500000"
27326         printf "Seeking data from 1500000 ... "
27327         offset=$(lseek_test -d 1500000 $file)
27328         echo $offset
27329         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
27330
27331         # start at second component stripe 1 (all data)
27332         printf "Seeking hole from 3000000 ... "
27333         offset=$(lseek_test -l 3000000 $file)
27334         echo $offset
27335         [[ $offset == 3145728 ]] || error "offset $offset != 3145728"
27336         printf "Seeking data from 3000000 ... "
27337         offset=$(lseek_test -d 3000000 $file)
27338         echo $offset
27339         [[ $offset == 3000000 ]] || error "offset $offset != 3000000"
27340
27341         dd if=/dev/urandom of=$file bs=640K count=1 seek=1 ||
27342                 error "2nd dd fails"
27343         echo "Add data block at 640K...1280K"
27344
27345         # start at before new data block, in hole
27346         printf "Seeking hole from 600000 ... "
27347         offset=$(lseek_test -l 600000 $file)
27348         echo $offset
27349         [[ $offset == 600000 ]] || error "offset $offset != 600000"
27350         printf "Seeking data from 600000 ... "
27351         offset=$(lseek_test -d 600000 $file)
27352         echo $offset
27353         [[ $offset == 655360 ]] || error "offset $offset != 655360"
27354
27355         # start at the first component new data block
27356         printf "Seeking hole from 1000000 ... "
27357         offset=$(lseek_test -l 1000000 $file)
27358         echo $offset
27359         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
27360         printf "Seeking data from 1000000 ... "
27361         offset=$(lseek_test -d 1000000 $file)
27362         echo $offset
27363         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
27364
27365         # start at second component stripe 2, new data
27366         printf "Seeking hole from 1200000 ... "
27367         offset=$(lseek_test -l 1200000 $file)
27368         echo $offset
27369         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
27370         printf "Seeking data from 1200000 ... "
27371         offset=$(lseek_test -d 1200000 $file)
27372         echo $offset
27373         [[ $offset == 1200000 ]] || error "offset $offset != 1200000"
27374
27375         # start beyond file end
27376         printf "Using offset > filesize ... "
27377         lseek_test -l 4000000 $file && error "lseek should fail"
27378         printf "Using offset > filesize ... "
27379         lseek_test -d 4000000 $file && error "lseek should fail"
27380
27381         printf "Done\n\n"
27382 }
27383
27384 test_430a() {
27385         $LCTL get_param mdc.*.import | grep -q 'connect_flags:.*seek' ||
27386                 skip "MDT does not support SEEK_HOLE"
27387
27388         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
27389                 skip "OST does not support SEEK_HOLE"
27390
27391         local file=$DIR/$tdir/$tfile
27392
27393         mkdir -p $DIR/$tdir
27394
27395         $LFS setstripe -E 1M -L mdt -E eof -c2 $file
27396         # OST stripe #1 will have continuous data at [1M, 3M)
27397         # OST stripe #2 is empty
27398         echo "Component #1: 1M DoM, component #2: EOF, 2 stripes 1M"
27399         lseek_test_430 $file
27400         rm $file
27401         $LFS setstripe -E 1M -c2 -S 64K -E 10M -c2 -S 1M $file
27402         echo "Component #1: 1M, 2 stripes 64K, component #2: EOF, 2 stripes 1M"
27403         lseek_test_430 $file
27404         rm $file
27405         $LFS setstripe -c2 -S 512K $file
27406         echo "Two stripes, stripe size 512K"
27407         lseek_test_430 $file
27408         rm $file
27409         # FLR with stale mirror
27410         $LFS setstripe -N -E 512K -c1 -S 64K -E eof -c2 -S 512K \
27411                        -N -c2 -S 1M $file
27412         echo "Mirrored file:"
27413         echo "Component #1: 512K, stripe 64K, component #2: EOF, 2 stripes 512K"
27414         echo "Plain 2 stripes 1M"
27415         lseek_test_430 $file
27416         rm $file
27417 }
27418 run_test 430a "lseek: SEEK_DATA/SEEK_HOLE basic functionality"
27419
27420 test_430b() {
27421         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
27422                 skip "OST does not support SEEK_HOLE"
27423
27424         local offset
27425         local file=$DIR/$tdir/$tfile
27426
27427         mkdir -p $DIR/$tdir
27428         # Empty layout lseek should fail
27429         $MCREATE $file
27430         # seek from 0
27431         printf "Seeking hole from 0 ... "
27432         lseek_test -l 0 $file && error "lseek should fail"
27433         printf "Seeking data from 0 ... "
27434         lseek_test -d 0 $file && error "lseek should fail"
27435         rm $file
27436
27437         # 1M-hole file
27438         $LFS setstripe -E 1M -c2 -E eof $file
27439         $TRUNCATE $file 1048576
27440         printf "Seeking hole from 1000000 ... "
27441         offset=$(lseek_test -l 1000000 $file)
27442         echo $offset
27443         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
27444         printf "Seeking data from 1000000 ... "
27445         lseek_test -d 1000000 $file && error "lseek should fail"
27446         rm $file
27447
27448         # full component followed by non-inited one
27449         $LFS setstripe -E 1M -c2 -E eof $file
27450         dd if=/dev/urandom of=$file bs=1M count=1
27451         printf "Seeking hole from 1000000 ... "
27452         offset=$(lseek_test -l 1000000 $file)
27453         echo $offset
27454         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
27455         printf "Seeking hole from 1048576 ... "
27456         lseek_test -l 1048576 $file && error "lseek should fail"
27457         # init second component and truncate back
27458         echo "123" >> $file
27459         $TRUNCATE $file 1048576
27460         printf "Seeking hole from 1000000 ... "
27461         offset=$(lseek_test -l 1000000 $file)
27462         echo $offset
27463         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
27464         printf "Seeking hole from 1048576 ... "
27465         lseek_test -l 1048576 $file && error "lseek should fail"
27466         # boundary checks for big values
27467         dd if=/dev/urandom of=$file.10g bs=1 count=1 seek=10G
27468         offset=$(lseek_test -d 0 $file.10g)
27469         [[ $offset == 10737418240 ]] || error "offset $offset != 10737418240"
27470         dd if=/dev/urandom of=$file.100g bs=1 count=1 seek=100G
27471         offset=$(lseek_test -d 0 $file.100g)
27472         [[ $offset == 107374182400 ]] || error "offset $offset != 107374182400"
27473         return 0
27474 }
27475 run_test 430b "lseek: SEEK_DATA/SEEK_HOLE special cases"
27476
27477 test_430c() {
27478         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
27479                 skip "OST does not support SEEK_HOLE"
27480
27481         local file=$DIR/$tdir/$tfile
27482         local start
27483
27484         mkdir -p $DIR/$tdir
27485         dd if=/dev/urandom of=$file bs=1k count=1 seek=5M
27486
27487         # cp version 8.33+ prefers lseek over fiemap
27488         if [[ $(cp --version | head -n1 | sed "s/[^0-9]//g") -ge 833 ]]; then
27489                 start=$SECONDS
27490                 time cp $file /dev/null
27491                 (( SECONDS - start < 5 )) ||
27492                         error "cp: too long runtime $((SECONDS - start))"
27493
27494         fi
27495         # tar version 1.29+ supports SEEK_HOLE/DATA
27496         if [[ $(tar --version | head -n1 | sed "s/[^0-9]//g") -ge 129 ]]; then
27497                 start=$SECONDS
27498                 time tar cS $file - | cat > /dev/null
27499                 (( SECONDS - start < 5 )) ||
27500                         error "tar: too long runtime $((SECONDS - start))"
27501         fi
27502 }
27503 run_test 430c "lseek: external tools check"
27504
27505 test_431() { # LU-14187
27506         local file=$DIR/$tdir/$tfile
27507
27508         mkdir -p $DIR/$tdir
27509         $LFS setstripe -c 1 -i 0 $file || error "lfs setstripe failed"
27510         dd if=/dev/urandom of=$file bs=4k count=1
27511         dd if=/dev/urandom of=$file bs=4k count=1 seek=10 conv=notrunc
27512         dd if=/dev/urandom of=$file bs=4k count=1 seek=12 conv=notrunc
27513         #define OBD_FAIL_OST_RESTART_IO 0x251
27514         do_facet ost1 "$LCTL set_param fail_loc=0x251"
27515         $LFS setstripe -c 1 -i 0 $file.0 || error "lfs setstripe failed"
27516         cp $file $file.0
27517         cancel_lru_locks
27518         sync_all_data
27519         echo 3 > /proc/sys/vm/drop_caches
27520         diff  $file $file.0 || error "data diff"
27521 }
27522 run_test 431 "Restart transaction for IO"
27523
27524 cleanup_test_432() {
27525         do_facet mgs $LCTL nodemap_activate 0
27526         wait_nm_sync active
27527 }
27528
27529 test_432() {
27530         local tmpdir=$TMP/dir432
27531
27532         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
27533                 skip "Need MDS version at least 2.14.52"
27534
27535         stack_trap cleanup_test_432 EXIT
27536         mkdir $DIR/$tdir
27537         mkdir $tmpdir
27538
27539         do_facet mgs $LCTL nodemap_activate 1
27540         wait_nm_sync active
27541         do_facet mgs $LCTL nodemap_modify --name default \
27542                 --property admin --value 1
27543         do_facet mgs $LCTL nodemap_modify --name default \
27544                 --property trusted --value 1
27545         cancel_lru_locks mdc
27546         wait_nm_sync default admin_nodemap
27547         wait_nm_sync default trusted_nodemap
27548
27549         if [ $(mv $tmpdir $DIR/$tdir/ 2>&1 |
27550                grep -ci "Operation not permitted") -ne 0 ]; then
27551                 error "mv $tmpdir $DIR/$tdir/ hits 'Operation not permitted'"
27552         fi
27553 }
27554 run_test 432 "mv dir from outside Lustre"
27555
27556 test_433() {
27557         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27558
27559         [[ -n "$($LCTL list_param llite.*.inode_cache 2>/dev/null)" ]] ||
27560                 skip "inode cache not supported"
27561
27562         $LCTL set_param llite.*.inode_cache=0
27563         stack_trap "$LCTL set_param llite.*.inode_cache=1"
27564
27565         local count=256
27566         local before
27567         local after
27568
27569         cancel_lru_locks mdc
27570         test_mkdir $DIR/$tdir || error "mkdir $tdir"
27571         createmany -m $DIR/$tdir/f $count
27572         createmany -d $DIR/$tdir/d $count
27573         ls -l $DIR/$tdir > /dev/null
27574         stack_trap "rm -rf $DIR/$tdir"
27575
27576         before=$(num_objects)
27577         cancel_lru_locks mdc
27578         after=$(num_objects)
27579
27580         # sometimes even @before is less than 2 * count
27581         while (( before - after < count )); do
27582                 sleep 1
27583                 after=$(num_objects)
27584                 wait=$((wait + 1))
27585                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
27586                 if (( wait > 60 )); then
27587                         error "inode slab grew from $before to $after"
27588                 fi
27589         done
27590
27591         echo "lustre_inode_cache $before objs before lock cancel, $after after"
27592 }
27593 run_test 433 "ldlm lock cancel releases dentries and inodes"
27594
27595 prep_801() {
27596         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
27597         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
27598                 skip "Need server version at least 2.9.55"
27599
27600         start_full_debug_logging
27601 }
27602
27603 post_801() {
27604         stop_full_debug_logging
27605 }
27606
27607 barrier_stat() {
27608         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
27609                 local st=$(do_facet mgs $LCTL barrier_stat $FSNAME |
27610                            awk '/The barrier for/ { print $7 }')
27611                 echo $st
27612         else
27613                 local st=$(do_facet mgs $LCTL barrier_stat -s $FSNAME)
27614                 echo \'$st\'
27615         fi
27616 }
27617
27618 barrier_expired() {
27619         local expired
27620
27621         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
27622                 expired=$(do_facet mgs $LCTL barrier_stat $FSNAME |
27623                           awk '/will be expired/ { print $7 }')
27624         else
27625                 expired=$(do_facet mgs $LCTL barrier_stat -t $FSNAME)
27626         fi
27627
27628         echo $expired
27629 }
27630
27631 test_801a() {
27632         prep_801
27633
27634         echo "Start barrier_freeze at: $(date)"
27635         #define OBD_FAIL_BARRIER_DELAY          0x2202
27636         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
27637         # Do not reduce barrier time - See LU-11873
27638         do_facet mgs $LCTL barrier_freeze $FSNAME 20 &
27639
27640         sleep 2
27641         local b_status=$(barrier_stat)
27642         echo "Got barrier status at: $(date)"
27643         [ "$b_status" = "'freezing_p1'" ] ||
27644                 error "(1) unexpected barrier status $b_status"
27645
27646         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
27647         wait
27648         b_status=$(barrier_stat)
27649         [ "$b_status" = "'frozen'" ] ||
27650                 error "(2) unexpected barrier status $b_status"
27651
27652         local expired=$(barrier_expired)
27653         echo "sleep $((expired + 3)) seconds, then the barrier will be expired"
27654         sleep $((expired + 3))
27655
27656         b_status=$(barrier_stat)
27657         [ "$b_status" = "'expired'" ] ||
27658                 error "(3) unexpected barrier status $b_status"
27659
27660         # Do not reduce barrier time - See LU-11873
27661         do_facet mgs $LCTL barrier_freeze $FSNAME 20 ||
27662                 error "(4) fail to freeze barrier"
27663
27664         b_status=$(barrier_stat)
27665         [ "$b_status" = "'frozen'" ] ||
27666                 error "(5) unexpected barrier status $b_status"
27667
27668         echo "Start barrier_thaw at: $(date)"
27669         #define OBD_FAIL_BARRIER_DELAY          0x2202
27670         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
27671         do_facet mgs $LCTL barrier_thaw $FSNAME &
27672
27673         sleep 2
27674         b_status=$(barrier_stat)
27675         echo "Got barrier status at: $(date)"
27676         [ "$b_status" = "'thawing'" ] ||
27677                 error "(6) unexpected barrier status $b_status"
27678
27679         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
27680         wait
27681         b_status=$(barrier_stat)
27682         [ "$b_status" = "'thawed'" ] ||
27683                 error "(7) unexpected barrier status $b_status"
27684
27685         #define OBD_FAIL_BARRIER_FAILURE        0x2203
27686         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2203
27687         do_facet mgs $LCTL barrier_freeze $FSNAME
27688
27689         b_status=$(barrier_stat)
27690         [ "$b_status" = "'failed'" ] ||
27691                 error "(8) unexpected barrier status $b_status"
27692
27693         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
27694         do_facet mgs $LCTL barrier_thaw $FSNAME
27695
27696         post_801
27697 }
27698 run_test 801a "write barrier user interfaces and stat machine"
27699
27700 test_801b() {
27701         prep_801
27702
27703         mkdir $DIR/$tdir || error "(1) fail to mkdir"
27704         createmany -d $DIR/$tdir/d 6 || error "(2) fail to mkdir"
27705         touch $DIR/$tdir/d2/f10 || error "(3) fail to touch"
27706         touch $DIR/$tdir/d3/f11 || error "(4) fail to touch"
27707         touch $DIR/$tdir/d4/f12 || error "(5) fail to touch"
27708
27709         cancel_lru_locks mdc
27710
27711         # 180 seconds should be long enough
27712         do_facet mgs $LCTL barrier_freeze $FSNAME 180
27713
27714         local b_status=$(barrier_stat)
27715         [ "$b_status" = "'frozen'" ] ||
27716                 error "(6) unexpected barrier status $b_status"
27717
27718         mkdir $DIR/$tdir/d0/d10 &
27719         mkdir_pid=$!
27720
27721         touch $DIR/$tdir/d1/f13 &
27722         touch_pid=$!
27723
27724         ln $DIR/$tdir/d2/f10 $DIR/$tdir/d2/f14 &
27725         ln_pid=$!
27726
27727         mv $DIR/$tdir/d3/f11 $DIR/$tdir/d3/f15 &
27728         mv_pid=$!
27729
27730         rm -f $DIR/$tdir/d4/f12 &
27731         rm_pid=$!
27732
27733         stat $DIR/$tdir/d5 || error "(7) stat should succeed"
27734
27735         # To guarantee taht the 'stat' is not blocked
27736         b_status=$(barrier_stat)
27737         [ "$b_status" = "'frozen'" ] ||
27738                 error "(8) unexpected barrier status $b_status"
27739
27740         # let above commands to run at background
27741         sleep 5
27742
27743         ps -p $mkdir_pid || error "(9) mkdir should be blocked"
27744         ps -p $touch_pid || error "(10) touch should be blocked"
27745         ps -p $ln_pid || error "(11) link should be blocked"
27746         ps -p $mv_pid || error "(12) rename should be blocked"
27747         ps -p $rm_pid || error "(13) unlink should be blocked"
27748
27749         b_status=$(barrier_stat)
27750         [ "$b_status" = "'frozen'" ] ||
27751                 error "(14) unexpected barrier status $b_status"
27752
27753         do_facet mgs $LCTL barrier_thaw $FSNAME
27754         b_status=$(barrier_stat)
27755         [ "$b_status" = "'thawed'" ] ||
27756                 error "(15) unexpected barrier status $b_status"
27757
27758         wait $mkdir_pid || error "(16) mkdir should succeed"
27759         wait $touch_pid || error "(17) touch should succeed"
27760         wait $ln_pid || error "(18) link should succeed"
27761         wait $mv_pid || error "(19) rename should succeed"
27762         wait $rm_pid || error "(20) unlink should succeed"
27763
27764         post_801
27765 }
27766 run_test 801b "modification will be blocked by write barrier"
27767
27768 test_801c() {
27769         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
27770
27771         prep_801
27772
27773         stop mds2 || error "(1) Fail to stop mds2"
27774
27775         do_facet mgs $LCTL barrier_freeze $FSNAME 30
27776
27777         local b_status=$(barrier_stat)
27778         [ "$b_status" = "'expired'" ] || [ "$b_status" = "'failed'" ] || {
27779                 do_facet mgs $LCTL barrier_thaw $FSNAME
27780                 error "(2) unexpected barrier status $b_status"
27781         }
27782
27783         do_facet mgs $LCTL barrier_rescan $FSNAME ||
27784                 error "(3) Fail to rescan barrier bitmap"
27785
27786         # Do not reduce barrier time - See LU-11873
27787         do_facet mgs $LCTL barrier_freeze $FSNAME 20
27788
27789         b_status=$(barrier_stat)
27790         [ "$b_status" = "'frozen'" ] ||
27791                 error "(4) unexpected barrier status $b_status"
27792
27793         do_facet mgs $LCTL barrier_thaw $FSNAME
27794         b_status=$(barrier_stat)
27795         [ "$b_status" = "'thawed'" ] ||
27796                 error "(5) unexpected barrier status $b_status"
27797
27798         local devname=$(mdsdevname 2)
27799
27800         start mds2 $devname $MDS_MOUNT_OPTS || error "(6) Fail to start mds2"
27801
27802         do_facet mgs $LCTL barrier_rescan $FSNAME ||
27803                 error "(7) Fail to rescan barrier bitmap"
27804
27805         post_801
27806 }
27807 run_test 801c "rescan barrier bitmap"
27808
27809 test_802b() {
27810         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27811         remote_mds_nodsh && skip "remote MDS with nodsh"
27812
27813         do_facet $SINGLEMDS $LCTL get_param mdt.*.readonly ||
27814                 skip "readonly option not available"
27815
27816         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "(1) fail to mkdir"
27817
27818         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
27819                 error "(2) Fail to copy"
27820
27821         # write back all cached data before setting MDT to readonly
27822         cancel_lru_locks
27823         sync_all_data
27824
27825         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=1
27826         stack_trap "do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0" EXIT
27827
27828         echo "Modify should be refused"
27829         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
27830
27831         echo "Read should be allowed"
27832         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
27833                 error "(7) Read should succeed under ro mode"
27834
27835         # disable readonly
27836         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0
27837 }
27838 run_test 802b "be able to set MDTs to readonly"
27839
27840 test_803a() {
27841         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
27842         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
27843                 skip "MDS needs to be newer than 2.10.54"
27844
27845         mkdir_on_mdt0 $DIR/$tdir
27846         # Create some objects on all MDTs to trigger related logs objects
27847         for idx in $(seq $MDSCOUNT); do
27848                 $LFS mkdir -c $MDSCOUNT -i $((idx % $MDSCOUNT)) \
27849                         $DIR/$tdir/dir${idx} ||
27850                         error "Fail to create $DIR/$tdir/dir${idx}"
27851         done
27852
27853         wait_delete_completed # ensure old test cleanups are finished
27854         sleep 3
27855         echo "before create:"
27856         $LFS df -i $MOUNT
27857         local before_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
27858
27859         for i in {1..10}; do
27860                 $LFS mkdir -c 1 -i 1 $DIR/$tdir/foo$i ||
27861                         error "Fail to create $DIR/$tdir/foo$i"
27862         done
27863
27864         # sync ZFS-on-MDS to refresh statfs data
27865         wait_zfs_commit mds1
27866         sleep 3
27867         echo "after create:"
27868         $LFS df -i $MOUNT
27869         local after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
27870
27871         # allow for an llog to be cleaned up during the test
27872         [ $after_used -ge $((before_used + 10 - 1)) ] ||
27873                 error "before ($before_used) + 10 > after ($after_used)"
27874
27875         for i in {1..10}; do
27876                 rm -rf $DIR/$tdir/foo$i ||
27877                         error "Fail to remove $DIR/$tdir/foo$i"
27878         done
27879
27880         # sync ZFS-on-MDS to refresh statfs data
27881         wait_zfs_commit mds1
27882         wait_delete_completed
27883         sleep 3 # avoid MDT return cached statfs
27884         echo "after unlink:"
27885         $LFS df -i $MOUNT
27886         after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
27887
27888         # allow for an llog to be created during the test
27889         [ $after_used -le $((before_used + 1)) ] ||
27890                 error "after ($after_used) > before ($before_used) + 1"
27891 }
27892 run_test 803a "verify agent object for remote object"
27893
27894 test_803b() {
27895         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
27896         [ $MDS1_VERSION -lt $(version_code 2.13.56) ] &&
27897                 skip "MDS needs to be newer than 2.13.56"
27898         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27899
27900         for i in $(seq 0 $((MDSCOUNT - 1))); do
27901                 $LFS mkdir -i $i $DIR/$tdir.$i || error "mkdir $tdir.$i"
27902         done
27903
27904         local before=0
27905         local after=0
27906
27907         local tmp
27908
27909         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
27910         for i in $(seq 0 $((MDSCOUNT - 1))); do
27911                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
27912                         awk '/getattr/ { print $2 }')
27913                 before=$((before + tmp))
27914         done
27915         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
27916         for i in $(seq 0 $((MDSCOUNT - 1))); do
27917                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
27918                         awk '/getattr/ { print $2 }')
27919                 after=$((after + tmp))
27920         done
27921
27922         [ $before -eq $after ] || error "getattr count $before != $after"
27923 }
27924 run_test 803b "remote object can getattr from cache"
27925
27926 test_804() {
27927         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
27928         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
27929                 skip "MDS needs to be newer than 2.10.54"
27930         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
27931
27932         mkdir -p $DIR/$tdir
27933         $LFS mkdir -c 1 -i 1 $DIR/$tdir/dir0 ||
27934                 error "Fail to create $DIR/$tdir/dir0"
27935
27936         local fid=$($LFS path2fid $DIR/$tdir/dir0)
27937         local dev=$(mdsdevname 2)
27938
27939         do_facet mds2 "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
27940                 grep ${fid} || error "NOT found agent entry for dir0"
27941
27942         $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir/dir1 ||
27943                 error "Fail to create $DIR/$tdir/dir1"
27944
27945         touch $DIR/$tdir/dir1/foo0 ||
27946                 error "Fail to create $DIR/$tdir/dir1/foo0"
27947         fid=$($LFS path2fid $DIR/$tdir/dir1/foo0)
27948         local rc=0
27949
27950         for idx in $(seq $MDSCOUNT); do
27951                 dev=$(mdsdevname $idx)
27952                 do_facet mds${idx} \
27953                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
27954                         grep ${fid} && rc=$idx
27955         done
27956
27957         mv $DIR/$tdir/dir1/foo0 $DIR/$tdir/dir1/foo1 ||
27958                 error "Fail to rename foo0 to foo1"
27959         if [ $rc -eq 0 ]; then
27960                 for idx in $(seq $MDSCOUNT); do
27961                         dev=$(mdsdevname $idx)
27962                         do_facet mds${idx} \
27963                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
27964                         grep ${fid} && rc=$idx
27965                 done
27966         fi
27967
27968         mv $DIR/$tdir/dir1/foo1 $DIR/$tdir/dir1/foo2 ||
27969                 error "Fail to rename foo1 to foo2"
27970         if [ $rc -eq 0 ]; then
27971                 for idx in $(seq $MDSCOUNT); do
27972                         dev=$(mdsdevname $idx)
27973                         do_facet mds${idx} \
27974                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
27975                         grep ${fid} && rc=$idx
27976                 done
27977         fi
27978
27979         [ $rc -ne 0 ] || error "NOT found agent entry for foo"
27980
27981         ln $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir0/guard ||
27982                 error "Fail to link to $DIR/$tdir/dir1/foo2"
27983         mv $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir1/foo0 ||
27984                 error "Fail to rename foo2 to foo0"
27985         unlink $DIR/$tdir/dir1/foo0 ||
27986                 error "Fail to unlink $DIR/$tdir/dir1/foo0"
27987         rm -rf $DIR/$tdir/dir0 ||
27988                 error "Fail to rm $DIR/$tdir/dir0"
27989
27990         for idx in $(seq $MDSCOUNT); do
27991                 rc=0
27992
27993                 stop mds${idx}
27994                 dev=$(mdsdevname $idx)
27995                 run_e2fsck $(facet_active_host mds$idx) $dev -n ||
27996                         rc=$?
27997                 start mds${idx} $dev $MDS_MOUNT_OPTS ||
27998                         error "mount mds$idx failed"
27999                 df $MOUNT > /dev/null 2>&1
28000
28001                 # e2fsck should not return error
28002                 [ $rc -eq 0 ] ||
28003                         error "e2fsck detected error on MDT${idx}: rc=$rc"
28004         done
28005 }
28006 run_test 804 "verify agent entry for remote entry"
28007
28008 cleanup_805() {
28009         do_facet $SINGLEMDS zfs set quota=$old $fsset
28010         unlinkmany $DIR/$tdir/f- 1000000
28011         trap 0
28012 }
28013
28014 test_805() {
28015         local zfs_version=$(do_facet mds1 cat /sys/module/zfs/version)
28016         [ "$mds1_FSTYPE" != "zfs" ] && skip "ZFS specific test"
28017         [ $(version_code $zfs_version) -lt $(version_code 0.7.2) ] &&
28018                 skip "netfree not implemented before 0.7"
28019         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
28020                 skip "Need MDS version at least 2.10.57"
28021
28022         local fsset
28023         local freekb
28024         local usedkb
28025         local old
28026         local quota
28027         local pref="osd-zfs.$FSNAME-MDT0000."
28028
28029         # limit available space on MDS dataset to meet nospace issue
28030         # quickly. then ZFS 0.7.2 can use reserved space if asked
28031         # properly (using netfree flag in osd_declare_destroy()
28032         fsset=$(do_facet $SINGLEMDS lctl get_param -n $pref.mntdev)
28033         old=$(do_facet $SINGLEMDS zfs get -H quota $fsset | \
28034                 gawk '{print $3}')
28035         freekb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytesfree)
28036         usedkb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytestotal)
28037         let "usedkb=usedkb-freekb"
28038         let "freekb=freekb/2"
28039         if let "freekb > 5000"; then
28040                 let "freekb=5000"
28041         fi
28042         do_facet $SINGLEMDS zfs set quota=$(((usedkb+freekb)*1024)) $fsset
28043         trap cleanup_805 EXIT
28044         mkdir_on_mdt0 $DIR/$tdir
28045         $LFS setstripe -E 1M -c2 -E 4M -c2 -E -1 -c2 $DIR/$tdir ||
28046                 error "Can't set PFL layout"
28047         createmany -m $DIR/$tdir/f- 1000000 && error "ENOSPC wasn't met"
28048         rm -rf $DIR/$tdir || error "not able to remove"
28049         do_facet $SINGLEMDS zfs set quota=$old $fsset
28050         trap 0
28051 }
28052 run_test 805 "ZFS can remove from full fs"
28053
28054 # Size-on-MDS test
28055 check_lsom_data()
28056 {
28057         local file=$1
28058         local expect=$(stat -c %s $file)
28059
28060         check_lsom_size $1 $expect
28061
28062         local blocks=$($LFS getsom -b $file)
28063         expect=$(stat -c %b $file)
28064         [[ $blocks == $expect ]] ||
28065                 error "$file expected blocks: $expect, got: $blocks"
28066 }
28067
28068 check_lsom_size()
28069 {
28070         local size
28071         local expect=$2
28072
28073         cancel_lru_locks mdc
28074
28075         size=$($LFS getsom -s $1)
28076         [[ $size == $expect ]] ||
28077                 error "$file expected size: $expect, got: $size"
28078 }
28079
28080 test_806() {
28081         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
28082                 skip "Need MDS version at least 2.11.52"
28083
28084         local bs=1048576
28085
28086         touch $DIR/$tfile || error "touch $tfile failed"
28087
28088         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
28089         save_lustre_params client "llite.*.xattr_cache" > $save
28090         lctl set_param llite.*.xattr_cache=0
28091         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
28092
28093         # single-threaded write
28094         echo "Test SOM for single-threaded write"
28095         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 ||
28096                 error "write $tfile failed"
28097         check_lsom_size $DIR/$tfile $bs
28098
28099         local num=32
28100         local size=$(($num * $bs))
28101         local offset=0
28102         local i
28103
28104         echo "Test SOM for single client multi-threaded($num) write"
28105         $TRUNCATE $DIR/$tfile 0
28106         for ((i = 0; i < $num; i++)); do
28107                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
28108                 local pids[$i]=$!
28109                 offset=$((offset + $bs))
28110         done
28111         for (( i=0; i < $num; i++ )); do
28112                 wait ${pids[$i]}
28113         done
28114         check_lsom_size $DIR/$tfile $size
28115
28116         $TRUNCATE $DIR/$tfile 0
28117         for ((i = 0; i < $num; i++)); do
28118                 offset=$((offset - $bs))
28119                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
28120                 local pids[$i]=$!
28121         done
28122         for (( i=0; i < $num; i++ )); do
28123                 wait ${pids[$i]}
28124         done
28125         check_lsom_size $DIR/$tfile $size
28126
28127         # multi-client writes
28128         num=$(get_node_count ${CLIENTS//,/ })
28129         size=$(($num * $bs))
28130         offset=0
28131         i=0
28132
28133         echo "Test SOM for multi-client ($num) writes"
28134         $TRUNCATE $DIR/$tfile 0
28135         for client in ${CLIENTS//,/ }; do
28136                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
28137                 local pids[$i]=$!
28138                 i=$((i + 1))
28139                 offset=$((offset + $bs))
28140         done
28141         for (( i=0; i < $num; i++ )); do
28142                 wait ${pids[$i]}
28143         done
28144         check_lsom_size $DIR/$tfile $offset
28145
28146         i=0
28147         $TRUNCATE $DIR/$tfile 0
28148         for client in ${CLIENTS//,/ }; do
28149                 offset=$((offset - $bs))
28150                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
28151                 local pids[$i]=$!
28152                 i=$((i + 1))
28153         done
28154         for (( i=0; i < $num; i++ )); do
28155                 wait ${pids[$i]}
28156         done
28157         check_lsom_size $DIR/$tfile $size
28158
28159         # verify truncate
28160         echo "Test SOM for truncate"
28161         $TRUNCATE $DIR/$tfile 1048576
28162         check_lsom_size $DIR/$tfile 1048576
28163         $TRUNCATE $DIR/$tfile 1234
28164         check_lsom_size $DIR/$tfile 1234
28165
28166         # verify SOM blocks count
28167         echo "Verify SOM block count"
28168         $TRUNCATE $DIR/$tfile 0
28169         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w1048576YSc ||
28170                 error "failed to write file $tfile"
28171         check_lsom_data $DIR/$tfile
28172 }
28173 run_test 806 "Verify Lazy Size on MDS"
28174
28175 test_807() {
28176         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
28177         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
28178                 skip "Need MDS version at least 2.11.52"
28179
28180         # Registration step
28181         changelog_register || error "changelog_register failed"
28182         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
28183         changelog_users $SINGLEMDS | grep -q $cl_user ||
28184                 error "User $cl_user not found in changelog_users"
28185
28186         rm -rf $DIR/$tdir || error "rm $tdir failed"
28187         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
28188         touch $DIR/$tdir/trunc || error "touch $tdir/trunc failed"
28189         $TRUNCATE $DIR/$tdir/trunc 1024 || error "truncate $tdir/trunc failed"
28190         $TRUNCATE $DIR/$tdir/trunc 1048576 ||
28191                 error "truncate $tdir/trunc failed"
28192
28193         local bs=1048576
28194         dd if=/dev/zero of=$DIR/$tdir/single_dd bs=$bs count=1 conv=fsync ||
28195                 error "write $tfile failed"
28196
28197         # multi-client wirtes
28198         local num=$(get_node_count ${CLIENTS//,/ })
28199         local offset=0
28200         local i=0
28201
28202         echo "Test SOM for multi-client ($num) writes"
28203         touch $DIR/$tfile || error "touch $tfile failed"
28204         $TRUNCATE $DIR/$tfile 0
28205         for client in ${CLIENTS//,/ }; do
28206                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
28207                 local pids[$i]=$!
28208                 i=$((i + 1))
28209                 offset=$((offset + $bs))
28210         done
28211         for (( i=0; i < $num; i++ )); do
28212                 wait ${pids[$i]}
28213         done
28214
28215         do_rpc_nodes "$CLIENTS" cancel_lru_locks osc
28216         do_nodes "$CLIENTS" "sync ; sleep 5 ; sync"
28217         $LSOM_SYNC -u $cl_user -m $FSNAME-MDT0000 $MOUNT
28218         check_lsom_data $DIR/$tdir/trunc
28219         check_lsom_data $DIR/$tdir/single_dd
28220         check_lsom_data $DIR/$tfile
28221
28222         rm -rf $DIR/$tdir
28223         # Deregistration step
28224         changelog_deregister || error "changelog_deregister failed"
28225 }
28226 run_test 807 "verify LSOM syncing tool"
28227
28228 check_som_nologged()
28229 {
28230         local lines=$($LFS changelog $FSNAME-MDT0000 |
28231                 grep 'x=trusted.som' | wc -l)
28232         [ $lines -ne 0 ] && error "trusted.som xattr is logged in Changelogs"
28233 }
28234
28235 test_808() {
28236         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
28237                 skip "Need MDS version at least 2.11.55"
28238
28239         # Registration step
28240         changelog_register || error "changelog_register failed"
28241
28242         touch $DIR/$tfile || error "touch $tfile failed"
28243         check_som_nologged
28244
28245         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=1 ||
28246                 error "write $tfile failed"
28247         check_som_nologged
28248
28249         $TRUNCATE $DIR/$tfile 1234
28250         check_som_nologged
28251
28252         $TRUNCATE $DIR/$tfile 1048576
28253         check_som_nologged
28254
28255         # Deregistration step
28256         changelog_deregister || error "changelog_deregister failed"
28257 }
28258 run_test 808 "Check trusted.som xattr not logged in Changelogs"
28259
28260 check_som_nodata()
28261 {
28262         $LFS getsom $1
28263         [[ $? -eq 61 ]] || error "DoM-only file $1 has SOM xattr"
28264 }
28265
28266 test_809() {
28267         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
28268                 skip "Need MDS version at least 2.11.56"
28269
28270         $LFS setstripe -E 1M -L mdt $DIR/$tfile ||
28271                 error "failed to create DoM-only file $DIR/$tfile"
28272         touch $DIR/$tfile || error "touch $tfile failed"
28273         check_som_nodata $DIR/$tfile
28274
28275         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 ||
28276                 error "write $tfile failed"
28277         check_som_nodata $DIR/$tfile
28278
28279         $TRUNCATE $DIR/$tfile 1234
28280         check_som_nodata $DIR/$tfile
28281
28282         $TRUNCATE $DIR/$tfile 4097
28283         check_som_nodata $DIR/$file
28284 }
28285 run_test 809 "Verify no SOM xattr store for DoM-only files"
28286
28287 test_810() {
28288         [ $PARALLEL == "yes" ] && skip "skip parallel run"
28289         $GSS && skip_env "could not run with gss"
28290         [[ $OST1_VERSION -gt $(version_code 2.12.58) ]] ||
28291                 skip "OST < 2.12.58 doesn't align checksum"
28292
28293         set_checksums 1
28294         stack_trap "set_checksums $ORIG_CSUM" EXIT
28295         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
28296
28297         local csum
28298         local before
28299         local after
28300         for csum in $CKSUM_TYPES; do
28301                 #define OBD_FAIL_OSC_NO_GRANT   0x411
28302                 $LCTL set_param osc.*.checksum_type=$csum fail_loc=0x411
28303                 for i in "10240 0" "10000 0" "4000 1" "500 1"; do
28304                         eval set -- $i
28305                         dd if=/dev/urandom of=$DIR/$tfile bs=$1 count=2 seek=$2
28306                         before=$(md5sum $DIR/$tfile)
28307                         $LCTL set_param ldlm.namespaces.*osc*.lru_size=clear
28308                         after=$(md5sum $DIR/$tfile)
28309                         [ "$before" == "$after" ] ||
28310                                 error "$csum: $before != $after bs=$1 seek=$2"
28311                 done
28312         done
28313 }
28314 run_test 810 "partial page writes on ZFS (LU-11663)"
28315
28316 test_812a() {
28317         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
28318                 skip "OST < 2.12.51 doesn't support this fail_loc"
28319
28320         $LFS setstripe -c 1 -i 0 $DIR/$tfile
28321         # ensure ost1 is connected
28322         stat $DIR/$tfile >/dev/null || error "can't stat"
28323         wait_osc_import_state client ost1 FULL
28324         # no locks, no reqs to let the connection idle
28325         cancel_lru_locks osc
28326
28327         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
28328 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
28329         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
28330         wait_osc_import_state client ost1 CONNECTING
28331         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
28332
28333         stat $DIR/$tfile >/dev/null || error "can't stat file"
28334 }
28335 run_test 812a "do not drop reqs generated when imp is going to idle (LU-11951)"
28336
28337 test_812b() { # LU-12378
28338         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
28339                 skip "OST < 2.12.51 doesn't support this fail_loc"
28340
28341         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "setstripe failed"
28342         # ensure ost1 is connected
28343         stat $DIR/$tfile >/dev/null || error "can't stat"
28344         wait_osc_import_state client ost1 FULL
28345         # no locks, no reqs to let the connection idle
28346         cancel_lru_locks osc
28347
28348         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
28349 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
28350         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
28351         wait_osc_import_state client ost1 CONNECTING
28352         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
28353
28354         $LFS quota -u 0 $DIR/ || error "lfs quota should succeed"
28355         wait_osc_import_state client ost1 IDLE
28356 }
28357 run_test 812b "do not drop no resend request for idle connect"
28358
28359 test_812c() {
28360         local old
28361
28362         old=$($LCTL get_param -n osc.*.idle_timeout | head -n 1)
28363
28364         $LFS setstripe -c 1 -o 0 $DIR/$tfile
28365         $LFS getstripe $DIR/$tfile
28366         $LCTL set_param osc.*.idle_timeout=10
28367         stack_trap "$LCTL set_param osc.*.idle_timeout=$old" EXIT
28368         # ensure ost1 is connected
28369         stat $DIR/$tfile >/dev/null || error "can't stat"
28370         wait_osc_import_state client ost1 FULL
28371         # no locks, no reqs to let the connection idle
28372         cancel_lru_locks osc
28373
28374 #define OBD_FAIL_PTLRPC_IDLE_RACE        0x533
28375         $LCTL set_param fail_loc=0x80000533
28376         sleep 15
28377         dd if=/dev/zero of=$DIR/$tfile count=1 conv=sync || error "dd failed"
28378 }
28379 run_test 812c "idle import vs lock enqueue race"
28380
28381 test_813() {
28382         local file_heat_sav=$($LCTL get_param -n llite.*.file_heat 2>/dev/null)
28383         [ -z "$file_heat_sav" ] && skip "no file heat support"
28384
28385         local readsample
28386         local writesample
28387         local readbyte
28388         local writebyte
28389         local readsample1
28390         local writesample1
28391         local readbyte1
28392         local writebyte1
28393
28394         local period_second=$($LCTL get_param -n llite.*.heat_period_second)
28395         local decay_pct=$($LCTL get_param -n llite.*.heat_decay_percentage)
28396
28397         $LCTL set_param -n llite.*.file_heat=1
28398         echo "Turn on file heat"
28399         echo "Period second: $period_second, Decay percentage: $decay_pct"
28400
28401         echo "QQQQ" > $DIR/$tfile
28402         echo "QQQQ" > $DIR/$tfile
28403         echo "QQQQ" > $DIR/$tfile
28404         cat $DIR/$tfile > /dev/null
28405         cat $DIR/$tfile > /dev/null
28406         cat $DIR/$tfile > /dev/null
28407         cat $DIR/$tfile > /dev/null
28408
28409         local out=$($LFS heat_get $DIR/$tfile)
28410
28411         $LFS heat_get $DIR/$tfile
28412         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
28413         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
28414         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
28415         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
28416
28417         [ $readsample -le 4 ] || error "read sample ($readsample) is wrong"
28418         [ $writesample -le 3 ] || error "write sample ($writesample) is wrong"
28419         [ $readbyte -le 20 ] || error "read bytes ($readbyte) is wrong"
28420         [ $writebyte -le 15 ] || error "write bytes ($writebyte) is wrong"
28421
28422         sleep $((period_second + 3))
28423         echo "Sleep $((period_second + 3)) seconds..."
28424         # The recursion formula to calculate the heat of the file f is as
28425         # follow:
28426         # Hi+1(f) = (1-P)*Hi(f)+ P*Ci
28427         # Where Hi is the heat value in the period between time points i*I and
28428         # (i+1)*I; Ci is the access count in the period; the symbol P refers
28429         # to the weight of Ci.
28430         out=$($LFS heat_get $DIR/$tfile)
28431         $LFS heat_get $DIR/$tfile
28432         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
28433         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
28434         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
28435         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
28436
28437         [ $(bc <<< "$readsample <= 4 * $decay_pct / 100") -eq 1 ] ||
28438                 error "read sample ($readsample) is wrong"
28439         [ $(bc <<< "$writesample <= 3 * $decay_pct / 100") -eq 1 ] ||
28440                 error "write sample ($writesample) is wrong"
28441         [ $(bc <<< "$readbyte <= 20 * $decay_pct / 100") -eq 1 ] ||
28442                 error "read bytes ($readbyte) is wrong"
28443         [ $(bc <<< "$writebyte <= 15 * $decay_pct / 100") -eq 1 ] ||
28444                 error "write bytes ($writebyte) is wrong"
28445
28446         echo "QQQQ" > $DIR/$tfile
28447         echo "QQQQ" > $DIR/$tfile
28448         echo "QQQQ" > $DIR/$tfile
28449         cat $DIR/$tfile > /dev/null
28450         cat $DIR/$tfile > /dev/null
28451         cat $DIR/$tfile > /dev/null
28452         cat $DIR/$tfile > /dev/null
28453
28454         sleep $((period_second + 3))
28455         echo "Sleep $((period_second + 3)) seconds..."
28456
28457         out=$($LFS heat_get $DIR/$tfile)
28458         $LFS heat_get $DIR/$tfile
28459         readsample1=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
28460         writesample1=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
28461         readbyte1=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
28462         writebyte1=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
28463
28464         [ $(bc <<< "$readsample1 <= ($readsample * (100 - $decay_pct) + \
28465                 4 * $decay_pct) / 100") -eq 1 ] ||
28466                 error "read sample ($readsample1) is wrong"
28467         [ $(bc <<< "$writesample1 <= ($writesample * (100 - $decay_pct) + \
28468                 3 * $decay_pct) / 100") -eq 1 ] ||
28469                 error "write sample ($writesample1) is wrong"
28470         [ $(bc <<< "$readbyte1 <= ($readbyte * (100 - $decay_pct) + \
28471                 20 * $decay_pct) / 100") -eq 1 ] ||
28472                 error "read bytes ($readbyte1) is wrong"
28473         [ $(bc <<< "$writebyte1 <= ($writebyte * (100 - $decay_pct) + \
28474                 15 * $decay_pct) / 100") -eq 1 ] ||
28475                 error "write bytes ($writebyte1) is wrong"
28476
28477         echo "Turn off file heat for the file $DIR/$tfile"
28478         $LFS heat_set -o $DIR/$tfile
28479
28480         echo "QQQQ" > $DIR/$tfile
28481         echo "QQQQ" > $DIR/$tfile
28482         echo "QQQQ" > $DIR/$tfile
28483         cat $DIR/$tfile > /dev/null
28484         cat $DIR/$tfile > /dev/null
28485         cat $DIR/$tfile > /dev/null
28486         cat $DIR/$tfile > /dev/null
28487
28488         out=$($LFS heat_get $DIR/$tfile)
28489         $LFS heat_get $DIR/$tfile
28490         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
28491         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
28492         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
28493         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
28494
28495         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
28496         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
28497         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
28498         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
28499
28500         echo "Trun on file heat for the file $DIR/$tfile"
28501         $LFS heat_set -O $DIR/$tfile
28502
28503         echo "QQQQ" > $DIR/$tfile
28504         echo "QQQQ" > $DIR/$tfile
28505         echo "QQQQ" > $DIR/$tfile
28506         cat $DIR/$tfile > /dev/null
28507         cat $DIR/$tfile > /dev/null
28508         cat $DIR/$tfile > /dev/null
28509         cat $DIR/$tfile > /dev/null
28510
28511         out=$($LFS heat_get $DIR/$tfile)
28512         $LFS heat_get $DIR/$tfile
28513         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
28514         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
28515         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
28516         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
28517
28518         [ $readsample -gt 0 ] || error "read sample ($readsample) is wrong"
28519         [ $writesample -gt 0 ] || error "write sample ($writesample) is wrong"
28520         [ $readbyte -gt 0 ] || error "read bytes ($readbyte) is wrong"
28521         [ $writebyte -gt 0 ] || error "write bytes ($writebyte) is wrong"
28522
28523         $LFS heat_set -c $DIR/$tfile
28524         $LCTL set_param -n llite.*.file_heat=0
28525         echo "Turn off file heat support for the Lustre filesystem"
28526
28527         echo "QQQQ" > $DIR/$tfile
28528         echo "QQQQ" > $DIR/$tfile
28529         echo "QQQQ" > $DIR/$tfile
28530         cat $DIR/$tfile > /dev/null
28531         cat $DIR/$tfile > /dev/null
28532         cat $DIR/$tfile > /dev/null
28533         cat $DIR/$tfile > /dev/null
28534
28535         out=$($LFS heat_get $DIR/$tfile)
28536         $LFS heat_get $DIR/$tfile
28537         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
28538         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
28539         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
28540         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
28541
28542         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
28543         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
28544         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
28545         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
28546
28547         $LCTL set_param -n llite.*.file_heat=$file_heat_sav
28548         rm -f $DIR/$tfile
28549 }
28550 run_test 813 "File heat verfication"
28551
28552 test_814()
28553 {
28554         dd of=$DIR/$tfile seek=128 bs=1k < /dev/null
28555         echo -n y >> $DIR/$tfile
28556         cp --sparse=always $DIR/$tfile $DIR/${tfile}.cp || error "copy failed"
28557         diff $DIR/$tfile $DIR/${tfile}.cp || error "files should be same"
28558 }
28559 run_test 814 "sparse cp works as expected (LU-12361)"
28560
28561 test_815()
28562 {
28563         writeme -b 100 $DIR/$tfile || error "write 100 bytes failed"
28564         writeme -b 0 $DIR/$tfile || error "write 0 byte failed"
28565 }
28566 run_test 815 "zero byte tiny write doesn't hang (LU-12382)"
28567
28568 test_816() {
28569         local ost1_imp=$(get_osc_import_name client ost1)
28570         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
28571                          cut -d'.' -f2)
28572
28573         $LFS setstripe -c 1 -i 0 $DIR/$tfile
28574         # ensure ost1 is connected
28575
28576         stat $DIR/$tfile >/dev/null || error "can't stat"
28577         wait_osc_import_state client ost1 FULL
28578         # no locks, no reqs to let the connection idle
28579         cancel_lru_locks osc
28580         lru_resize_disable osc
28581         local before
28582         local now
28583         before=$($LCTL get_param -n \
28584                  ldlm.namespaces.$imp_name.lru_size)
28585
28586         wait_osc_import_state client ost1 IDLE
28587         dd if=/dev/null of=$DIR/$tfile bs=1k count=1 conv=sync
28588         now=$($LCTL get_param -n \
28589               ldlm.namespaces.$imp_name.lru_size)
28590         [ $before == $now ] || error "lru_size changed $before != $now"
28591 }
28592 run_test 816 "do not reset lru_resize on idle reconnect"
28593
28594 cleanup_817() {
28595         umount $tmpdir
28596         exportfs -u localhost:$DIR/nfsexp
28597         rm -rf $DIR/nfsexp
28598 }
28599
28600 test_817() {
28601         systemctl restart nfs-server.service || skip "failed to restart nfsd"
28602
28603         mkdir -p $DIR/nfsexp
28604         exportfs -orw,no_root_squash localhost:$DIR/nfsexp ||
28605                 error "failed to export nfs"
28606
28607         tmpdir=$(mktemp -d /tmp/nfs-XXXXXX)
28608         stack_trap cleanup_817 EXIT
28609
28610         mount -t nfs -orw localhost:$DIR/nfsexp $tmpdir ||
28611                 error "failed to mount nfs to $tmpdir"
28612
28613         cp /bin/true $tmpdir
28614         $DIR/nfsexp/true || error "failed to execute 'true' command"
28615 }
28616 run_test 817 "nfsd won't cache write lock for exec file"
28617
28618 test_818() {
28619         test_mkdir -i0 -c1 $DIR/$tdir
28620         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
28621         $LFS setstripe -c1 -i1 $DIR/$tdir/$tfile
28622         stop $SINGLEMDS
28623
28624         # restore osp-syn threads
28625         stack_trap "fail $SINGLEMDS"
28626
28627         #define OBD_FAIL_OSP_CANT_PROCESS_LLOG          0x2105
28628         do_facet $SINGLEMDS lctl set_param fail_loc=0x80002105
28629         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
28630                 error "start $SINGLEMDS failed"
28631         rm -rf $DIR/$tdir
28632
28633         local testid=$(echo $TESTNAME | tr '_' ' ')
28634
28635         do_facet mds1 dmesg | tac | sed "/$testid/,$ d" |
28636                 grep "run LFSCK" || error "run LFSCK is not suggested"
28637 }
28638 run_test 818 "unlink with failed llog"
28639
28640 test_819a() {
28641         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
28642         cancel_lru_locks osc
28643         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
28644         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
28645         dd if=$DIR/$tfile of=/dev/null bs=1M count=1
28646         rm -f $TDIR/$tfile
28647 }
28648 run_test 819a "too big niobuf in read"
28649
28650 test_819b() {
28651         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
28652         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
28653         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
28654         cancel_lru_locks osc
28655         sleep 1
28656         rm -f $TDIR/$tfile
28657 }
28658 run_test 819b "too big niobuf in write"
28659
28660
28661 function test_820_start_ost() {
28662         sleep 5
28663
28664         for num in $(seq $OSTCOUNT); do
28665                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS
28666         done
28667 }
28668
28669 test_820() {
28670         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
28671
28672         mkdir $DIR/$tdir
28673         umount_client $MOUNT || error "umount failed"
28674         for num in $(seq $OSTCOUNT); do
28675                 stop ost$num
28676         done
28677
28678         # mount client with no active OSTs
28679         # so that the client can't initialize max LOV EA size
28680         # from OSC notifications
28681         mount_client $MOUNT || error "mount failed"
28682         # delay OST starting to keep this 0 max EA size for a while
28683         test_820_start_ost &
28684
28685         # create a directory on MDS2
28686         test_mkdir -i 1 -c1 $DIR/$tdir/mds2 ||
28687                 error "Failed to create directory"
28688         # open intent should update default EA size
28689         # see mdc_update_max_ea_from_body()
28690         # notice this is the very first RPC to MDS2
28691         out=$(cp /etc/services $DIR/$tdir/mds2 2>&1)
28692         ret=$?
28693         echo $out
28694         # With SSK, this situation can lead to -EPERM being returned.
28695         # In that case, simply retry.
28696         if [ $ret -ne 0 ] && $SHARED_KEY; then
28697                 if echo "$out" | grep -q "not permitted"; then
28698                         cp /etc/services $DIR/$tdir/mds2
28699                         ret=$?
28700                 fi
28701         fi
28702         [ $ret -eq 0 ] || error "Failed to copy files to mds$n"
28703 }
28704 run_test 820 "update max EA from open intent"
28705
28706 test_823() {
28707         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
28708         local OST_MAX_PRECREATE=20000
28709
28710         (( $MDS1_VERSION >= $(version_code 2.14.56) )) ||
28711                 skip "Need MDS version at least 2.14.56"
28712
28713         save_lustre_params mds1 \
28714                 "osp.$FSNAME-OST*-osc-MDT0000.max_create_count" > $p
28715         do_facet $SINGLEMDS "$LCTL set_param -n \
28716                 osp.$FSNAME-OST*MDT0000.max_create_count=0"
28717         do_facet $SINGLEMDS "$LCTL set_param -n \
28718                 osp.$FSNAME-OST0000*MDT0000.max_create_count=$OST_MAX_PRECREATE"
28719
28720         stack_trap "restore_lustre_params < $p; rm $p"
28721
28722         do_facet $SINGLEMDS "$LCTL set_param -n \
28723                 osp.$FSNAME-OST*-osc-MDT*.create_count=100200"
28724
28725         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
28726                       osp.$FSNAME-OST0000*MDT0000.create_count")
28727         local max=$(do_facet $SINGLEMDS "$LCTL get_param -n \
28728                     osp.$FSNAME-OST0000*MDT0000.max_create_count")
28729         local expect_count=$(((($max/2)/256) * 256))
28730
28731         log "setting create_count to 100200:"
28732         log " -result- count: $count with max: $max, expecting: $expect_count"
28733
28734         [[ $count -eq expect_count ]] ||
28735                 error "Create count not set to max precreate."
28736 }
28737 run_test 823 "Setting create_count > OST_MAX_PRECREATE is lowered to maximum"
28738
28739 test_831() {
28740         [[ $MDS1_VERSION -lt $(version_code 2.14.56) ]] &&
28741                 skip "Need MDS version 2.14.56"
28742
28743         local sync_changes=$(do_facet $SINGLEMDS \
28744                 $LCTL get_param -n osp.$FSNAME-OST0000-osc-MDT0000.sync_changes)
28745
28746         [ "$sync_changes" -gt 100 ] &&
28747                 skip "Sync changes $sync_changes > 100 already"
28748
28749         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
28750
28751         $LFS mkdir -i 0 $DIR/$tdir
28752         $LFS setstripe -c 1 -i 0 $DIR/$tdir
28753
28754         save_lustre_params mds1 \
28755                 "osp.$FSNAME-OST*-osc-MDT0000.max_sync_changes" > $p
28756         save_lustre_params mds1 \
28757                 "osp.$FSNAME-OST*-osc-MDT0000.max_rpcs_in_progress" >> $p
28758
28759         do_facet mds1 "$LCTL set_param -n \
28760                 osp.$FSNAME-OST*-osc-MDT0000.max_sync_changes=100 \
28761                 osp.$FSNAME-OST*-osc-MDT0000.max_rpcs_in_progress=128"
28762         stack_trap "restore_lustre_params < $p" EXIT
28763
28764         createmany -o $DIR/$tdir/f- 1000
28765         unlinkmany $DIR/$tdir/f- 1000 &
28766         local UNLINK_PID=$!
28767
28768         while sleep 1; do
28769                 sync_changes=$(do_facet mds1 \
28770                 $LCTL get_param -n osp.$FSNAME-OST0000-osc-MDT0000.sync_changes)
28771                 # the check in the code is racy, fail the test
28772                 # if the value above the limit by 10.
28773                 [ $sync_changes -gt 110 ] && {
28774                         kill -2 $UNLINK_PID
28775                         wait
28776                         error "osp changes throttling failed, $sync_changes>110"
28777                 }
28778                 kill -0 $UNLINK_PID 2> /dev/null || break
28779         done
28780         wait
28781 }
28782 run_test 831 "throttling unlink/setattr queuing on OSP"
28783
28784 #
28785 # tests that do cleanup/setup should be run at the end
28786 #
28787
28788 test_900() {
28789         [ $PARALLEL == "yes" ] && skip "skip parallel run"
28790         local ls
28791
28792         #define OBD_FAIL_MGC_PAUSE_PROCESS_LOG   0x903
28793         $LCTL set_param fail_loc=0x903
28794
28795         cancel_lru_locks MGC
28796
28797         FAIL_ON_ERROR=true cleanup
28798         FAIL_ON_ERROR=true setup
28799 }
28800 run_test 900 "umount should not race with any mgc requeue thread"
28801
28802 # LUS-6253/LU-11185
28803 test_901() {
28804         local old
28805         local count
28806         local oldc
28807         local newc
28808         local olds
28809         local news
28810         [ $PARALLEL == "yes" ] && skip "skip parallel run"
28811
28812         # some get_param have a bug to handle dot in param name
28813         cancel_lru_locks MGC
28814         old=$(mount -t lustre | wc -l)
28815         # 1 config+sptlrpc
28816         # 2 params
28817         # 3 nodemap
28818         # 4 IR
28819         old=$((old * 4))
28820         oldc=0
28821         count=0
28822         while [ $old -ne $oldc ]; do
28823                 oldc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
28824                 sleep 1
28825                 ((count++))
28826                 if [ $count -ge $TIMEOUT ]; then
28827                         error "too large timeout"
28828                 fi
28829         done
28830         umount_client $MOUNT || error "umount failed"
28831         mount_client $MOUNT || error "mount failed"
28832         cancel_lru_locks MGC
28833         newc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
28834
28835         [ $oldc -lt $newc ] && error "mgc lock leak ($oldc != $newc)"
28836
28837         return 0
28838 }
28839 run_test 901 "don't leak a mgc lock on client umount"
28840
28841 # LU-13377
28842 test_902() {
28843         [ $CLIENT_VERSION -lt $(version_code 2.13.52) ] &&
28844                 skip "client does not have LU-13377 fix"
28845         #define OBD_FAIL_LLITE_SHORT_COMMIT 0x1415
28846         $LCTL set_param fail_loc=0x1415
28847         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
28848         cancel_lru_locks osc
28849         rm -f $DIR/$tfile
28850 }
28851 run_test 902 "test short write doesn't hang lustre"
28852
28853 # LU-14711
28854 test_903() {
28855         $LFS setstripe -i 0 -c 1 $DIR/$tfile $DIR/${tfile}-2
28856         echo "blah" > $DIR/${tfile}-2
28857         dd if=/dev/zero of=$DIR/$tfile bs=1M count=6 conv=fsync
28858         #define OBD_FAIL_OSC_SLOW_PAGE_EVICT 0x417
28859         $LCTL set_param fail_loc=0x417 fail_val=20
28860
28861         mv $DIR/${tfile}-2 $DIR/$tfile # Destroys the big object
28862         sleep 1 # To start the destroy
28863         wait_destroy_complete 150 || error "Destroy taking too long"
28864         cat $DIR/$tfile > /dev/null || error "Evicted"
28865 }
28866 run_test 903 "Test long page discard does not cause evictions"
28867
28868 test_904() {
28869         [ "$mds1_FSTYPE" == "ldiskfs" ] || skip "ldiskfs only test"
28870         do_facet mds1 $DEBUGFS -R features $(mdsdevname 1) |
28871                 grep -q project || skip "skip project quota not supported"
28872
28873         local testfile="$DIR/$tdir/$tfile"
28874         local xattr="trusted.projid"
28875         local projid
28876         local mdts=$(comma_list $(mdts_nodes))
28877         local saved=$(do_facet mds1 $LCTL get_param -n \
28878                 osd-ldiskfs.*MDT0000.enable_projid_xattr)
28879
28880         do_nodes $mdts $LCTL set_param osd-ldiskfs.*MDT*.enable_projid_xattr=0
28881         stack_trap "do_nodes $mdts $LCTL set_param \
28882                 osd-ldiskfs.*MDT*.enable_projid_xattr=$saved"
28883
28884         mkdir -p $DIR/$tdir
28885         touch $testfile
28886         #hide projid xattr on server
28887         $LFS project -p 1 $testfile ||
28888                 error "set $testfile project id failed"
28889         getfattr -m - $testfile | grep $xattr &&
28890                 error "do not show trusted.projid when disabled on server"
28891         do_nodes $mdts $LCTL set_param osd-ldiskfs.*MDT*.enable_projid_xattr=1
28892         #should be hidden when projid is 0
28893         $LFS project -p 0 $testfile ||
28894                 error "set $testfile project id failed"
28895         getfattr -m - $testfile | grep $xattr &&
28896                 error "do not show trusted.projid with project ID 0"
28897
28898         #still can getxattr explicitly
28899         projid=$(getfattr -n $xattr $testfile |
28900                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
28901         [ $projid == "0" ] ||
28902                 error "projid expected 0 not $projid"
28903
28904         #set the projid via setxattr
28905         setfattr -n $xattr -v "1000" $testfile ||
28906                 error "setattr failed with $?"
28907         projid=($($LFS project $testfile))
28908         [ ${projid[0]} == "1000" ] ||
28909                 error "projid expected 1000 not $projid"
28910
28911         #check the new projid via getxattr
28912         $LFS project -p 1001 $testfile ||
28913                 error "set $testfile project id failed"
28914         getfattr -m - $testfile | grep $xattr ||
28915                 error "should show trusted.projid when project ID != 0"
28916         projid=$(getfattr -n $xattr $testfile |
28917                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
28918         [ $projid == "1001" ] ||
28919                 error "projid expected 1001 not $projid"
28920
28921         #try to set invalid projid
28922         setfattr -n $xattr -v "4294967295" $testfile &&
28923                 error "set invalid projid should fail"
28924
28925         #remove the xattr means setting projid to 0
28926         setfattr -x $xattr $testfile ||
28927                 error "setfattr failed with $?"
28928         projid=($($LFS project $testfile))
28929         [ ${projid[0]} == "0" ] ||
28930                 error "projid expected 0 not $projid"
28931
28932         #should be hidden when parent has inherit flag and same projid
28933         $LFS project -srp 1002 $DIR/$tdir ||
28934                 error "set $tdir project id failed"
28935         getfattr -m - $testfile | grep $xattr &&
28936                 error "do not show trusted.projid with inherit flag"
28937
28938         #still can getxattr explicitly
28939         projid=$(getfattr -n $xattr $testfile |
28940                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
28941         [ $projid == "1002" ] ||
28942                 error "projid expected 1002 not $projid"
28943 }
28944 run_test 904 "virtual project ID xattr"
28945
28946 # LU-8582
28947 test_905() {
28948         (( $OST1_VERSION >= $(version_code 2.8.54) )) ||
28949                 skip "lustre < 2.8.54 does not support ladvise"
28950
28951         remote_ost_nodsh && skip "remote OST with nodsh"
28952         $LFS setstripe -c -1 -i 0 $DIR/$tfile || error "setstripe failed"
28953
28954         $LFS ladvise -a willread $DIR/$tfile || error "ladvise does not work"
28955
28956         #define OBD_FAIL_OST_OPCODE 0x253
28957         # OST_LADVISE = 21
28958         do_facet ost1 "$LCTL set_param fail_val=21 fail_loc=0x0253"
28959         $LFS ladvise -a willread $DIR/$tfile &&
28960                 error "unexpected success of ladvise with fault injection"
28961         $LFS ladvise -a willread $DIR/$tfile |&
28962                 grep -q "Operation not supported"
28963         (( $? == 0 )) || error "unexpected stderr of ladvise with fault injection"
28964 }
28965 run_test 905 "bad or new opcode should not stuck client"
28966
28967 test_906() {
28968         grep -q io_uring_setup /proc/kallsyms ||
28969                 skip "Client OS does not support io_uring I/O engine"
28970         io_uring_probe || skip "kernel does not support io_uring fully"
28971         which fio || skip_env "no fio installed"
28972         fio --enghelp | grep -q io_uring ||
28973                 skip_env "fio does not support io_uring I/O engine"
28974
28975         local file=$DIR/$tfile
28976         local ioengine="io_uring"
28977         local numjobs=2
28978         local size=50M
28979
28980         fio --name=seqwrite --ioengine=$ioengine        \
28981                 --bs=$PAGE_SIZE --direct=1 --numjobs=$numjobs   \
28982                 --iodepth=64 --size=$size --filename=$file --rw=write ||
28983                 error "fio seqwrite $file failed"
28984
28985         fio --name=seqread --ioengine=$ioengine \
28986                 --bs=$PAGE_SIZE --direct=1 --numjobs=$numjobs   \
28987                 --iodepth=64 --size=$size --filename=$file --rw=read ||
28988                 error "fio seqread $file failed"
28989
28990         rm -f $file || error "rm -f $file failed"
28991 }
28992 run_test 906 "Simple test for io_uring I/O engine via fio"
28993
28994 complete $SECONDS
28995 [ -f $EXT2_DEV ] && rm $EXT2_DEV || true
28996 check_and_cleanup_lustre
28997 if [ "$I_MOUNTED" != "yes" ]; then
28998         lctl set_param debug="$OLDDEBUG" 2> /dev/null || true
28999 fi
29000 exit_status