Whamcloud - gitweb
423527382c813028940db8bd3c6059e14730ae68
[fs/lustre-release.git] / lustre / tests / sanity.sh
1 #!/bin/bash
2 #
3 # Run select tests by setting ONLY, or as arguments to the script.
4 # Skip specific tests by setting EXCEPT.
5 #
6 # e.g. ONLY="22 23" or ONLY="`seq 32 39`" or EXCEPT="31"
7 set -e
8
9 ONLY=${ONLY:-"$*"}
10
11 # Check Grants after these tests
12 GRANT_CHECK_LIST="$GRANT_CHECK_LIST 42a 42b 42c 42d 42e 63a 63b 64a 64b 64c 64d"
13
14 OSC=${OSC:-"osc"}
15
16 CC=${CC:-cc}
17 CREATETEST=${CREATETEST:-createtest}
18 LVERIFY=${LVERIFY:-ll_dirstripe_verify}
19 OPENFILE=${OPENFILE:-openfile}
20 OPENUNLINK=${OPENUNLINK:-openunlink}
21 READS=${READS:-"reads"}
22 MUNLINK=${MUNLINK:-munlink}
23 SOCKETSERVER=${SOCKETSERVER:-socketserver}
24 SOCKETCLIENT=${SOCKETCLIENT:-socketclient}
25 MEMHOG=${MEMHOG:-memhog}
26 DIRECTIO=${DIRECTIO:-directio}
27 ACCEPTOR_PORT=${ACCEPTOR_PORT:-988}
28 DEF_STRIPE_COUNT=-1
29 CHECK_GRANT=${CHECK_GRANT:-"yes"}
30 GRANT_CHECK_LIST=${GRANT_CHECK_LIST:-""}
31
32 TRACE=${TRACE:-""}
33 LUSTRE=${LUSTRE:-$(dirname $0)/..}
34 LUSTRE_TESTS_API_DIR=${LUSTRE_TESTS_API_DIR:-${LUSTRE}/tests/clientapi}
35 . $LUSTRE/tests/test-framework.sh
36 init_test_env "$@"
37
38 init_logging
39
40 ALWAYS_EXCEPT="$SANITY_EXCEPT "
41 always_except LU-9693  42a 42c
42 always_except LU-6493  42b
43 always_except LU-16515 118c 118d
44 always_except LU-8411  407
45
46 if $SHARED_KEY; then
47         always_except LU-14181 64e 64f
48 fi
49
50 # skip the grant tests for ARM until they are fixed
51 if [[ $(uname -m) = aarch64 ]]; then
52         always_except LU-11671 45
53 fi
54
55 # skip nfs tests on kernels >= 4.12.0 until they are fixed
56 if [ $LINUX_VERSION_CODE -ge $(version_code 4.12.0) ]; then
57         always_except LU-12661 817
58 fi
59 # skip cgroup tests on RHEL8.1 kernels until they are fixed
60 if (( $LINUX_VERSION_CODE >= $(version_code 4.18.0) &&
61       $LINUX_VERSION_CODE <  $(version_code 5.4.0) )); then
62         always_except LU-13063 411
63 fi
64
65 # skip basic ops on file with foreign LOV tests on 5.16.0+ kernels
66 # until the filemap_read() issue is fixed
67 if (( $LINUX_VERSION_CODE >= $(version_code 5.16.0) )); then
68         always_except LU-16101 27J
69 fi
70
71 #                                  5              12     8   12  15   (min)"
72 [[ "$SLOW" = "no" ]] && EXCEPT_SLOW="27m 60i 64b 68 71 135 136 230d 300o"
73
74 if [[ "$mds1_FSTYPE" == "zfs" ]]; then
75         #                                               13    (min)"
76         [[ "$SLOW" == "no" ]] && EXCEPT_SLOW="$EXCEPT_SLOW 51b"
77 fi
78
79 if [[ "$ost1_FSTYPE" = "zfs" ]]; then
80         always_except LU-1941 130b 130c 130d 130e 130f 130g
81         always_except LU-9054 312
82 fi
83
84 proc_regexp="/{proc,sys}/{fs,sys,kernel/debug}/{lustre,lnet}/"
85
86 # Get the SLES distro version
87 #
88 # Returns a version string that should only be used in comparing
89 # strings returned by version_code()
90 sles_version_code()
91 {
92         local version=$(grep VERSION_ID /etc/os-release | cut -d'"' -f2)
93
94         # All SuSE Linux versions have one decimal. version_code expects two
95         local sles_version=$version.0
96         version_code $sles_version
97 }
98
99 # Check if we are running on Ubuntu or SLES so we can make decisions on
100 # what tests to run
101 if [ -r /etc/SuSE-release ] || [ -r /etc/SUSE-brand ]; then
102         sles_version=$(sles_version_code)
103         [ $sles_version -lt $(version_code 11.4.0) ] &&
104                 always_except LU-4341 170
105
106         [ $sles_version -lt $(version_code 12.0.0) ] &&
107                 always_except LU-3703 234
108
109         [ $sles_version -ge $(version_code 15.4.0) ] &&
110                 always_except LU-16101 27J
111 elif [ -r /etc/os-release ]; then
112         if grep -qi ubuntu /etc/os-release; then
113                 ubuntu_version=$(version_code $(sed -n -e 's/"//g' \
114                                                 -e 's/^VERSION=//p' \
115                                                 /etc/os-release |
116                                                 awk '{ print $1 }'))
117
118                 if [[ $ubuntu_version -gt $(version_code 16.0.0) ]]; then
119                         always_except LU-10366 410
120                 fi
121         fi
122 fi
123
124 build_test_filter
125 FAIL_ON_ERROR=false
126
127 cleanup() {
128         echo -n "cln.."
129         pgrep ll_sa > /dev/null && { echo "There are ll_sa thread not exit!"; exit 20; }
130         cleanupall ${FORCE} $* || { echo "FAILed to clean up"; exit 20; }
131 }
132 setup() {
133         echo -n "mnt.."
134         load_modules
135         setupall || exit 10
136         echo "done"
137 }
138
139 check_swap_layouts_support()
140 {
141         $LCTL get_param -n llite.*.sbi_flags | grep -q layout ||
142                 skip "Does not support layout lock."
143 }
144
145 check_swap_layout_no_dom()
146 {
147         local FOLDER=$1
148         local SUPP=$(lfs getstripe $FOLDER | grep "pattern:       mdt" | wc -l)
149         [ $SUPP -eq 0 ] || skip "layout swap does not support DOM files so far"
150 }
151
152 check_and_setup_lustre
153 DIR=${DIR:-$MOUNT}
154 assert_DIR
155
156 MAXFREE=${MAXFREE:-$((300000 * $OSTCOUNT))}
157
158 [ -f $DIR/d52a/foo ] && chattr -a $DIR/d52a/foo
159 [ -f $DIR/d52b/foo ] && chattr -i $DIR/d52b/foo
160 rm -rf $DIR/[Rdfs][0-9]*
161
162 # $RUNAS_ID may get set incorrectly somewhere else
163 [ $UID -eq 0 -a $RUNAS_ID -eq 0 ] &&
164         error "\$RUNAS_ID set to 0, but \$UID is also 0!"
165
166 check_runas_id $RUNAS_ID $RUNAS_GID $RUNAS
167
168 if [ "${ONLY}" = "MOUNT" ] ; then
169         echo "Lustre is up, please go on"
170         exit
171 fi
172
173 echo "preparing for tests involving mounts"
174 EXT2_DEV=${EXT2_DEV:-$TMP/SANITY.LOOP}
175 touch $EXT2_DEV
176 mke2fs -j -F $EXT2_DEV 8000 > /dev/null
177 echo # add a newline after mke2fs.
178
179 umask 077
180
181 OLDDEBUG=$(lctl get_param -n debug 2> /dev/null)
182
183 # ensure all internal functions know we want full debug
184 export PTLDEBUG=all
185 lctl set_param debug=$PTLDEBUG 2> /dev/null || true
186
187 test_0a() {
188         touch $DIR/$tfile
189         $CHECKSTAT -t file $DIR/$tfile || error "$tfile is not a file"
190         rm $DIR/$tfile
191         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
192 }
193 run_test 0a "touch; rm ====================="
194
195 test_0b() {
196         chmod 0755 $DIR || error "chmod 0755 $DIR failed"
197         $CHECKSTAT -p 0755 $DIR || error "$DIR permission is not 0755"
198 }
199 run_test 0b "chmod 0755 $DIR ============================="
200
201 test_0c() {
202         $LCTL get_param mdc.*.import | grep "state: FULL" ||
203                 error "import not FULL"
204         $LCTL get_param mdc.*.import | grep "target: $FSNAME-MDT" ||
205                 error "bad target"
206 }
207 run_test 0c "check import proc"
208
209 test_0d() { # LU-3397
210         [ $MGS_VERSION -lt $(version_code 2.10.57) ] &&
211                 skip "proc exports not supported before 2.10.57"
212
213         local mgs_exp="mgs.MGS.exports"
214         local client_uuid=$($LCTL get_param -n mgc.*.uuid)
215         local exp_client_nid
216         local exp_client_version
217         local exp_val
218         local imp_val
219         local temp_imp=$DIR/$tfile.import
220         local temp_exp=$DIR/$tfile.export
221
222         # save mgc import file to $temp_imp
223         $LCTL get_param mgc.*.import | tee $temp_imp
224         # Check if client uuid is found in MGS export
225         for exp_client_nid in $(do_facet mgs $LCTL get_param -N $mgs_exp.*); do
226                 [ $(do_facet mgs $LCTL get_param -n $exp_client_nid.uuid) == \
227                         $client_uuid ] &&
228                         break;
229         done
230         # save mgs export file to $temp_exp
231         do_facet mgs $LCTL get_param $exp_client_nid.export | tee $temp_exp
232
233         # Compare the value of field "connect_flags"
234         imp_val=$(grep "connect_flags" $temp_imp)
235         exp_val=$(grep "connect_flags" $temp_exp)
236         [ "$exp_val" == "$imp_val" ] ||
237                 error "export flags '$exp_val' != import flags '$imp_val'"
238
239         # Compare client versions.  Only compare top-3 fields for compatibility
240         exp_client_version=$(awk '/target_version:/ { print $2 }' $temp_exp)
241         exp_val=$(version_code $(cut -d. -f1,2,3 <<<$exp_client_version))
242         imp_val=$(version_code $(lustre_build_version client | cut -d. -f1,2,3))
243         [ "$exp_val" == "$imp_val" ] ||
244                 error "exp version '$exp_client_version'($exp_val) != " \
245                         "'$(lustre_build_version client)'($imp_val)"
246 }
247 run_test 0d "check export proc ============================="
248
249 test_0e() { # LU-13417
250         (( $MDSCOUNT > 1 )) ||
251                 skip "We need at least 2 MDTs for this test"
252
253         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
254                 skip "Need server version at least 2.14.51"
255
256         local default_lmv_count=$($LFS getdirstripe -D -c $MOUNT)
257         local default_lmv_index=$($LFS getdirstripe -D -i $MOUNT)
258
259         [ $default_lmv_count -eq 1 ] ||
260                 error "$MOUNT default stripe count $default_lmv_count"
261
262         [ $default_lmv_index -eq -1 ] ||
263                 error "$MOUNT default stripe index $default_lmv_index"
264
265         mkdir $MOUNT/$tdir.1 || error "mkdir $MOUNT/$tdir.1 failed"
266         mkdir $MOUNT/$tdir.2 || error "mkdir $MOUNT/$tdir.2 failed"
267
268         local mdt_index1=$($LFS getdirstripe -i $MOUNT/$tdir.1)
269         local mdt_index2=$($LFS getdirstripe -i $MOUNT/$tdir.2)
270
271         [ $mdt_index1 -eq $mdt_index2 ] &&
272                 error "directories are on the same MDT $mdt_index1=$mdt_index2"
273
274         rmdir $MOUNT/$tdir.1 $MOUNT/$tdir.2
275 }
276 run_test 0e "Enable DNE MDT balancing for mkdir in the ROOT"
277
278 test_1() {
279         test_mkdir $DIR/$tdir
280         test_mkdir $DIR/$tdir/d2
281         mkdir $DIR/$tdir/d2 && error "we expect EEXIST, but not returned"
282         $CHECKSTAT -t dir $DIR/$tdir/d2 || error "$tdir/d2 is not a dir"
283         rmdir $DIR/$tdir/d2
284         rmdir $DIR/$tdir
285         $CHECKSTAT -a $DIR/$tdir || error "$tdir was not removed"
286 }
287 run_test 1 "mkdir; remkdir; rmdir"
288
289 test_2() {
290         test_mkdir $DIR/$tdir
291         touch $DIR/$tdir/$tfile || error "touch $tdir/$tfile failed"
292         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "$tdir/$tfile not a file"
293         rm -r $DIR/$tdir
294         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$file is not removed"
295 }
296 run_test 2 "mkdir; touch; rmdir; check file"
297
298 test_3() {
299         test_mkdir $DIR/$tdir
300         $CHECKSTAT -t dir $DIR/$tdir || error "$tdir is not a directory"
301         touch $DIR/$tdir/$tfile
302         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "$tdir/$tfile not a file"
303         rm -r $DIR/$tdir
304         $CHECKSTAT -a $DIR/$tdir || error "$tdir is not removed"
305 }
306 run_test 3 "mkdir; touch; rmdir; check dir"
307
308 # LU-4471 - failed rmdir on remote directories still removes directory on MDT0
309 test_4() {
310         test_mkdir -i 1 $DIR/$tdir
311
312         touch $DIR/$tdir/$tfile ||
313                 error "Create file under remote directory failed"
314
315         rmdir $DIR/$tdir &&
316                 error "Expect error removing in-use dir $DIR/$tdir"
317
318         test -d $DIR/$tdir || error "Remote directory disappeared"
319
320         rm -rf $DIR/$tdir || error "remove remote dir error"
321 }
322 run_test 4 "mkdir; touch dir/file; rmdir; checkdir (expect error)"
323
324 test_5() {
325         test_mkdir $DIR/$tdir
326         test_mkdir $DIR/$tdir/d2
327         chmod 0707 $DIR/$tdir/d2 || error "chmod 0707 $tdir/d2 failed"
328         $CHECKSTAT -t dir -p 0707 $DIR/$tdir/d2 || error "$tdir/d2 not mode 707"
329         $CHECKSTAT -t dir $DIR/$tdir/d2 || error "$tdir/d2 is not a directory"
330 }
331 run_test 5 "mkdir .../d5 .../d5/d2; chmod .../d5/d2"
332
333 test_6a() {
334         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
335         chmod 0666 $DIR/$tfile || error "chmod 0666 $tfile failed"
336         $CHECKSTAT -t file -p 0666 -u \#$UID $DIR/$tfile ||
337                 error "$tfile does not have perm 0666 or UID $UID"
338         $RUNAS chmod 0444 $DIR/$tfile && error "chmod $tfile worked on UID $UID"
339         $CHECKSTAT -t file -p 0666 -u \#$UID $DIR/$tfile ||
340                 error "$tfile should be 0666 and owned by UID $UID"
341 }
342 run_test 6a "touch f6a; chmod f6a; $RUNAS chmod f6a (should return error) =="
343
344 test_6c() {
345         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
346
347         touch $DIR/$tfile
348         chown $RUNAS_ID $DIR/$tfile || error "chown $RUNAS_ID $file failed"
349         $CHECKSTAT -t file -u \#$RUNAS_ID $DIR/$tfile ||
350                 error "$tfile should be owned by UID $RUNAS_ID"
351         $RUNAS chown $UID $DIR/$tfile && error "chown $UID $file succeeded"
352         $CHECKSTAT -t file -u \#$RUNAS_ID $DIR/$tfile ||
353                 error "$tfile should be owned by UID $RUNAS_ID"
354 }
355 run_test 6c "touch f6c; chown f6c; $RUNAS chown f6c (should return error) =="
356
357 test_6e() {
358         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
359
360         touch $DIR/$tfile
361         chgrp $RUNAS_ID $DIR/$tfile || error "chgrp $RUNAS_ID $file failed"
362         $CHECKSTAT -t file -u \#$UID -g \#$RUNAS_ID $DIR/$tfile ||
363                 error "$tfile should be owned by GID $UID"
364         $RUNAS chgrp $UID $DIR/$tfile && error "chgrp $UID $file succeeded"
365         $CHECKSTAT -t file -u \#$UID -g \#$RUNAS_ID $DIR/$tfile ||
366                 error "$tfile should be owned by UID $UID and GID $RUNAS_ID"
367 }
368 run_test 6e "touch+chgrp $tfile; $RUNAS chgrp $tfile (should return error)"
369
370 test_6g() {
371         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
372
373         test_mkdir $DIR/$tdir
374         chmod 777 $DIR/$tdir || error "chmod 0777 $tdir failed"
375         $RUNAS mkdir $DIR/$tdir/d || error "mkdir $tdir/d failed"
376         chmod g+s $DIR/$tdir/d || error "chmod g+s $tdir/d failed"
377         test_mkdir $DIR/$tdir/d/subdir
378         $CHECKSTAT -g \#$RUNAS_GID $DIR/$tdir/d/subdir ||
379                 error "$tdir/d/subdir should be GID $RUNAS_GID"
380         if [[ $MDSCOUNT -gt 1 ]]; then
381                 # check remote dir sgid inherite
382                 $LFS mkdir -i 0 $DIR/$tdir.local ||
383                         error "mkdir $tdir.local failed"
384                 chmod g+s $DIR/$tdir.local ||
385                         error "chmod $tdir.local failed"
386                 chgrp $RUNAS_GID $DIR/$tdir.local ||
387                         error "chgrp $tdir.local failed"
388                 $LFS mkdir -i 1 $DIR/$tdir.local/$tdir.remote ||
389                         error "mkdir $tdir.remote failed"
390                 $CHECKSTAT -g \#$RUNAS_GID $DIR/$tdir.local/$tdir.remote ||
391                         error "$tdir.remote should be owned by $UID.$RUNAS_ID"
392                 $CHECKSTAT -p 02755 $DIR/$tdir.local/$tdir.remote ||
393                         error "$tdir.remote should be mode 02755"
394         fi
395 }
396 run_test 6g "verify new dir in sgid dir inherits group"
397
398 test_6h() { # bug 7331
399         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
400
401         touch $DIR/$tfile || error "touch failed"
402         chown $RUNAS_ID:$RUNAS_GID $DIR/$tfile || error "initial chown failed"
403         $RUNAS -G$RUNAS_GID chown $RUNAS_ID:0 $DIR/$tfile &&
404                 error "chown $RUNAS_ID:0 $tfile worked as GID $RUNAS_GID"
405         $CHECKSTAT -t file -u \#$RUNAS_ID -g \#$RUNAS_GID $DIR/$tfile ||
406                 error "$tdir/$tfile should be UID $RUNAS_UID GID $RUNAS_GID"
407 }
408 run_test 6h "$RUNAS chown RUNAS_ID.0 .../$tfile (should return error)"
409
410 test_7a() {
411         test_mkdir $DIR/$tdir
412         $MCREATE $DIR/$tdir/$tfile
413         chmod 0666 $DIR/$tdir/$tfile
414         $CHECKSTAT -t file -p 0666 $DIR/$tdir/$tfile ||
415                 error "$tdir/$tfile should be mode 0666"
416 }
417 run_test 7a "mkdir .../d7; mcreate .../d7/f; chmod .../d7/f ===="
418
419 test_7b() {
420         if [ ! -d $DIR/$tdir ]; then
421                 test_mkdir $DIR/$tdir
422         fi
423         $MCREATE $DIR/$tdir/$tfile
424         echo -n foo > $DIR/$tdir/$tfile
425         [ "$(cat $DIR/$tdir/$tfile)" = "foo" ] || error "$tdir/$tfile not 'foo'"
426         $CHECKSTAT -t file -s 3 $DIR/$tdir/$tfile || error "$tfile size not 3"
427 }
428 run_test 7b "mkdir .../d7; mcreate d7/f2; echo foo > d7/f2 ====="
429
430 test_8() {
431         test_mkdir $DIR/$tdir
432         touch $DIR/$tdir/$tfile
433         chmod 0666 $DIR/$tdir/$tfile
434         $CHECKSTAT -t file -p 0666 $DIR/$tdir/$tfile ||
435                 error "$tfile mode not 0666"
436 }
437 run_test 8 "mkdir .../d8; touch .../d8/f; chmod .../d8/f ======="
438
439 test_9() {
440         test_mkdir $DIR/$tdir
441         test_mkdir $DIR/$tdir/d2
442         test_mkdir $DIR/$tdir/d2/d3
443         $CHECKSTAT -t dir $DIR/$tdir/d2/d3 || error "$tdir/d2/d3 not a dir"
444 }
445 run_test 9 "mkdir .../d9 .../d9/d2 .../d9/d2/d3 ================"
446
447 test_10() {
448         test_mkdir $DIR/$tdir
449         test_mkdir $DIR/$tdir/d2
450         touch $DIR/$tdir/d2/$tfile
451         $CHECKSTAT -t file $DIR/$tdir/d2/$tfile ||
452                 error "$tdir/d2/$tfile not a file"
453 }
454 run_test 10 "mkdir .../d10 .../d10/d2; touch .../d10/d2/f ======"
455
456 test_11() {
457         test_mkdir $DIR/$tdir
458         test_mkdir $DIR/$tdir/d2
459         chmod 0666 $DIR/$tdir/d2
460         chmod 0705 $DIR/$tdir/d2
461         $CHECKSTAT -t dir -p 0705 $DIR/$tdir/d2 ||
462                 error "$tdir/d2 mode not 0705"
463 }
464 run_test 11 "mkdir .../d11 d11/d2; chmod .../d11/d2 ============"
465
466 test_12() {
467         test_mkdir $DIR/$tdir
468         touch $DIR/$tdir/$tfile
469         chmod 0666 $DIR/$tdir/$tfile
470         chmod 0654 $DIR/$tdir/$tfile
471         $CHECKSTAT -t file -p 0654 $DIR/$tdir/$tfile ||
472                 error "$tdir/d2 mode not 0654"
473 }
474 run_test 12 "touch .../d12/f; chmod .../d12/f .../d12/f ========"
475
476 test_13() {
477         test_mkdir $DIR/$tdir
478         dd if=/dev/zero of=$DIR/$tdir/$tfile count=10
479         >  $DIR/$tdir/$tfile
480         $CHECKSTAT -t file -s 0 $DIR/$tdir/$tfile ||
481                 error "$tdir/$tfile size not 0 after truncate"
482 }
483 run_test 13 "creat .../d13/f; dd .../d13/f; > .../d13/f ========"
484
485 test_14() {
486         test_mkdir $DIR/$tdir
487         touch $DIR/$tdir/$tfile
488         rm $DIR/$tdir/$tfile
489         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$tfile not removed"
490 }
491 run_test 14 "touch .../d14/f; rm .../d14/f; rm .../d14/f ======="
492
493 test_15() {
494         test_mkdir $DIR/$tdir
495         touch $DIR/$tdir/$tfile
496         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}_2
497         $CHECKSTAT -t file $DIR/$tdir/${tfile}_2 ||
498                 error "$tdir/${tfile_2} not a file after rename"
499         rm $DIR/$tdir/${tfile}_2 || error "unlink failed after rename"
500 }
501 run_test 15 "touch .../d15/f; mv .../d15/f .../d15/f2 =========="
502
503 test_16() {
504         test_mkdir $DIR/$tdir
505         touch $DIR/$tdir/$tfile
506         rm -rf $DIR/$tdir/$tfile
507         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$tfile not removed"
508 }
509 run_test 16 "touch .../d16/f; rm -rf .../d16/f"
510
511 test_17a() {
512         test_mkdir $DIR/$tdir
513         touch $DIR/$tdir/$tfile
514         ln -s $DIR/$tdir/$tfile $DIR/$tdir/l-exist
515         ls -l $DIR/$tdir
516         $CHECKSTAT -l $DIR/$tdir/$tfile $DIR/$tdir/l-exist ||
517                 error "$tdir/l-exist not a symlink"
518         $CHECKSTAT -f -t f $DIR/$tdir/l-exist ||
519                 error "$tdir/l-exist not referencing a file"
520         rm -f $DIR/$tdir/l-exist
521         $CHECKSTAT -a $DIR/$tdir/l-exist || error "$tdir/l-exist not removed"
522 }
523 run_test 17a "symlinks: create, remove (real)"
524
525 test_17b() {
526         test_mkdir $DIR/$tdir
527         ln -s no-such-file $DIR/$tdir/l-dangle
528         ls -l $DIR/$tdir
529         $CHECKSTAT -l no-such-file $DIR/$tdir/l-dangle ||
530                 error "$tdir/l-dangle not referencing no-such-file"
531         $CHECKSTAT -fa $DIR/$tdir/l-dangle ||
532                 error "$tdir/l-dangle not referencing non-existent file"
533         rm -f $DIR/$tdir/l-dangle
534         $CHECKSTAT -a $DIR/$tdir/l-dangle || error "$tdir/l-dangle not removed"
535 }
536 run_test 17b "symlinks: create, remove (dangling)"
537
538 test_17c() { # bug 3440 - don't save failed open RPC for replay
539         test_mkdir $DIR/$tdir
540         ln -s foo $DIR/$tdir/$tfile
541         cat $DIR/$tdir/$tfile && error "opened non-existent symlink" || true
542 }
543 run_test 17c "symlinks: open dangling (should return error)"
544
545 test_17d() {
546         test_mkdir $DIR/$tdir
547         ln -s foo $DIR/$tdir/$tfile
548         touch $DIR/$tdir/$tfile || error "creating to new symlink"
549 }
550 run_test 17d "symlinks: create dangling"
551
552 test_17e() {
553         test_mkdir $DIR/$tdir
554         local foo=$DIR/$tdir/$tfile
555         ln -s $foo $foo || error "create symlink failed"
556         ls -l $foo || error "ls -l failed"
557         ls $foo && error "ls not failed" || true
558 }
559 run_test 17e "symlinks: create recursive symlink (should return error)"
560
561 test_17f() {
562         test_mkdir $DIR/$tdir
563         ln -s 1234567890/2234567890/3234567890/4234567890 $DIR/$tdir/111
564         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890 $DIR/$tdir/222
565         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890 $DIR/$tdir/333
566         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890 $DIR/$tdir/444
567         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890/c234567890/d234567890/f234567890 $DIR/$tdir/555
568         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
569         ls -l  $DIR/$tdir
570 }
571 run_test 17f "symlinks: long and very long symlink name"
572
573 # str_repeat(S, N) generate a string that is string S repeated N times
574 str_repeat() {
575         local s=$1
576         local n=$2
577         local ret=''
578         while [ $((n -= 1)) -ge 0 ]; do
579                 ret=$ret$s
580         done
581         echo $ret
582 }
583
584 # Long symlinks and LU-2241
585 test_17g() {
586         test_mkdir $DIR/$tdir
587         local TESTS="59 60 61 4094 4095"
588
589         # Fix for inode size boundary in 2.1.4
590         [ $MDS1_VERSION -lt $(version_code 2.1.4) ] &&
591                 TESTS="4094 4095"
592
593         # Patch not applied to 2.2 or 2.3 branches
594         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
595         [ $MDS1_VERSION -le $(version_code 2.3.55) ] &&
596                 TESTS="4094 4095"
597
598         for i in $TESTS; do
599                 local SYMNAME=$(str_repeat 'x' $i)
600                 ln -s $SYMNAME $DIR/$tdir/f$i || error "failed $i-char symlink"
601                 readlink $DIR/$tdir/f$i || error "failed $i-char readlink"
602         done
603 }
604 run_test 17g "symlinks: really long symlink name and inode boundaries"
605
606 test_17h() { #bug 17378
607         [ $PARALLEL == "yes" ] && skip "skip parallel run"
608         remote_mds_nodsh && skip "remote MDS with nodsh"
609
610         local mdt_idx
611
612         test_mkdir $DIR/$tdir
613         mdt_idx=$($LFS getdirstripe -i $DIR/$tdir)
614         $LFS setstripe -c -1 $DIR/$tdir
615         #define OBD_FAIL_MDS_LOV_PREP_CREATE 0x141
616         do_facet mds$((mdt_idx + 1)) lctl set_param fail_loc=0x80000141
617         touch $DIR/$tdir/$tfile || true
618 }
619 run_test 17h "create objects: lov_free_memmd() doesn't lbug"
620
621 test_17i() { #bug 20018
622         [ $PARALLEL == "yes" ] && skip "skip parallel run"
623         remote_mds_nodsh && skip "remote MDS with nodsh"
624
625         local foo=$DIR/$tdir/$tfile
626         local mdt_idx
627
628         test_mkdir -c1 $DIR/$tdir
629         mdt_idx=$($LFS getdirstripe -i $DIR/$tdir)
630         ln -s $foo $foo || error "create symlink failed"
631 #define OBD_FAIL_MDS_READLINK_EPROTO     0x143
632         do_facet mds$((mdt_idx + 1)) lctl set_param fail_loc=0x80000143
633         ls -l $foo && error "error not detected"
634         return 0
635 }
636 run_test 17i "don't panic on short symlink (should return error)"
637
638 test_17k() { #bug 22301
639         [ $PARALLEL == "yes" ] && skip "skip parallel run"
640         [[ -z "$(which rsync 2>/dev/null)" ]] &&
641                 skip "no rsync command"
642         rsync --help | grep -q xattr ||
643                 skip_env "$(rsync --version | head -n1) does not support xattrs"
644         test_mkdir $DIR/$tdir
645         test_mkdir $DIR/$tdir.new
646         touch $DIR/$tdir/$tfile
647         ln -s $DIR/$tdir/$tfile $DIR/$tdir/$tfile.lnk
648         rsync -av -X $DIR/$tdir/ $DIR/$tdir.new ||
649                 error "rsync failed with xattrs enabled"
650 }
651 run_test 17k "symlinks: rsync with xattrs enabled"
652
653 test_17l() { # LU-279
654         [[ -z "$(which getfattr 2>/dev/null)" ]] &&
655                 skip "no getfattr command"
656
657         test_mkdir $DIR/$tdir
658         touch $DIR/$tdir/$tfile
659         ln -s $DIR/$tdir/$tfile $DIR/$tdir/$tfile.lnk
660         for path in "$DIR/$tdir" "$DIR/$tdir/$tfile" "$DIR/$tdir/$tfile.lnk"; do
661                 # -h to not follow symlinks. -m '' to list all the xattrs.
662                 # grep to remove first line: '# file: $path'.
663                 for xattr in `getfattr -hm '' $path 2>/dev/null | grep -v '^#'`;
664                 do
665                         lgetxattr_size_check $path $xattr ||
666                                 error "lgetxattr_size_check $path $xattr failed"
667                 done
668         done
669 }
670 run_test 17l "Ensure lgetxattr's returned xattr size is consistent"
671
672 # LU-1540
673 test_17m() {
674         [ $PARALLEL == "yes" ] && skip "skip parallel run"
675         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
676         remote_mds_nodsh && skip "remote MDS with nodsh"
677         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
678         [ $MDS1_VERSION -le $(version_code 2.2.93) ] &&
679                 skip "MDS 2.2.0-2.2.93 do not NUL-terminate symlinks"
680
681         local short_sym="0123456789"
682         local wdir=$DIR/$tdir
683         local i
684
685         test_mkdir $wdir
686         long_sym=$short_sym
687         # create a long symlink file
688         for ((i = 0; i < 4; ++i)); do
689                 long_sym=${long_sym}${long_sym}
690         done
691
692         echo "create 512 short and long symlink files under $wdir"
693         for ((i = 0; i < 256; ++i)); do
694                 ln -sf ${long_sym}"a5a5" $wdir/long-$i
695                 ln -sf ${short_sym}"a5a5" $wdir/short-$i
696         done
697
698         echo "erase them"
699         rm -f $wdir/*
700         sync
701         wait_delete_completed
702
703         echo "recreate the 512 symlink files with a shorter string"
704         for ((i = 0; i < 512; ++i)); do
705                 # rewrite the symlink file with a shorter string
706                 ln -sf ${long_sym} $wdir/long-$i || error "long_sym failed"
707                 ln -sf ${short_sym} $wdir/short-$i || error "short_sym failed"
708         done
709
710         local mds_index=$(($($LFS getstripe -m $wdir) + 1))
711
712         echo "stop and checking mds${mds_index}:"
713         # e2fsck should not return error
714         stop mds${mds_index}
715         local devname=$(mdsdevname $mds_index)
716         run_e2fsck $(facet_active_host mds${mds_index}) $devname -n
717         rc=$?
718
719         start mds${mds_index} $devname $MDS_MOUNT_OPTS ||
720                 error "start mds${mds_index} failed"
721         df $MOUNT > /dev/null 2>&1
722         [ $rc -eq 0 ] ||
723                 error "e2fsck detected error for short/long symlink: rc=$rc"
724         rm -f $wdir/*
725 }
726 run_test 17m "run e2fsck against MDT which contains short/long symlink"
727
728 check_fs_consistency_17n() {
729         local mdt_index
730         local rc=0
731
732         # create/unlink in 17n only change 2 MDTs(MDT1/MDT2),
733         # so it only check MDT1/MDT2 instead of all of MDTs.
734         for mdt_index in 1 2; do
735                 # e2fsck should not return error
736                 stop mds${mdt_index}
737                 local devname=$(mdsdevname $mdt_index)
738                 run_e2fsck $(facet_active_host mds$mdt_index) $devname -n ||
739                         rc=$((rc + $?))
740
741                 start mds${mdt_index} $devname $MDS_MOUNT_OPTS ||
742                         error "mount mds$mdt_index failed"
743                 df $MOUNT > /dev/null 2>&1
744         done
745         return $rc
746 }
747
748 test_17n() {
749         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
750         [ $PARALLEL == "yes" ] && skip "skip parallel run"
751         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
752         remote_mds_nodsh && skip "remote MDS with nodsh"
753         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
754         [ $MDS1_VERSION -le $(version_code 2.2.93) ] &&
755                 skip "MDS 2.2.0-2.2.93 do not NUL-terminate symlinks"
756
757         local i
758
759         test_mkdir $DIR/$tdir
760         for ((i=0; i<10; i++)); do
761                 $LFS mkdir -i1 -c2 $DIR/$tdir/remote_dir_${i} ||
762                         error "create remote dir error $i"
763                 createmany -o $DIR/$tdir/remote_dir_${i}/f 10 ||
764                         error "create files under remote dir failed $i"
765         done
766
767         check_fs_consistency_17n ||
768                 error "e2fsck report error after create files under remote dir"
769
770         for ((i = 0; i < 10; i++)); do
771                 rm -rf $DIR/$tdir/remote_dir_${i} ||
772                         error "destroy remote dir error $i"
773         done
774
775         check_fs_consistency_17n ||
776                 error "e2fsck report error after unlink files under remote dir"
777
778         [ $MDS1_VERSION -lt $(version_code 2.4.50) ] &&
779                 skip "lustre < 2.4.50 does not support migrate mv"
780
781         for ((i = 0; i < 10; i++)); do
782                 mkdir -p $DIR/$tdir/remote_dir_${i}
783                 createmany -o $DIR/$tdir/remote_dir_${i}/f 10 ||
784                         error "create files under remote dir failed $i"
785                 $LFS migrate --mdt-index 1 $DIR/$tdir/remote_dir_${i} ||
786                         error "migrate remote dir error $i"
787         done
788         check_fs_consistency_17n || error "e2fsck report error after migration"
789
790         for ((i = 0; i < 10; i++)); do
791                 rm -rf $DIR/$tdir/remote_dir_${i} ||
792                         error "destroy remote dir error $i"
793         done
794
795         check_fs_consistency_17n || error "e2fsck report error after unlink"
796 }
797 run_test 17n "run e2fsck against master/slave MDT which contains remote dir"
798
799 test_17o() {
800         remote_mds_nodsh && skip "remote MDS with nodsh"
801         [ $MDS1_VERSION -lt $(version_code 2.3.64) ] &&
802                 skip "Need MDS version at least 2.3.64"
803
804         local wdir=$DIR/${tdir}o
805         local mdt_index
806         local rc=0
807
808         test_mkdir $wdir
809         touch $wdir/$tfile
810         mdt_index=$($LFS getstripe -m $wdir/$tfile)
811         mdt_index=$((mdt_index + 1))
812
813         cancel_lru_locks mdc
814         #fail mds will wait the failover finish then set
815         #following fail_loc to avoid interfer the recovery process.
816         fail mds${mdt_index}
817
818         #define OBD_FAIL_OSD_LMA_INCOMPAT 0x194
819         do_facet mds${mdt_index} lctl set_param fail_loc=0x194
820         ls -l $wdir/$tfile && rc=1
821         do_facet mds${mdt_index} lctl set_param fail_loc=0
822         [[ $rc -eq 0 ]] || error "stat file should fail"
823 }
824 run_test 17o "stat file with incompat LMA feature"
825
826 test_18() {
827         touch $DIR/$tfile || error "Failed to touch $DIR/$tfile: $?"
828         ls $DIR || error "Failed to ls $DIR: $?"
829 }
830 run_test 18 "touch .../f ; ls ... =============================="
831
832 test_19a() {
833         touch $DIR/$tfile
834         ls -l $DIR
835         rm $DIR/$tfile
836         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
837 }
838 run_test 19a "touch .../f19 ; ls -l ... ; rm .../f19 ==========="
839
840 test_19b() {
841         ls -l $DIR/$tfile && error "ls -l $tfile failed"|| true
842 }
843 run_test 19b "ls -l .../f19 (should return error) =============="
844
845 test_19c() {
846         [ $RUNAS_ID -eq $UID ] &&
847                 skip_env "RUNAS_ID = UID = $UID -- skipping"
848
849         $RUNAS touch $DIR/$tfile && error "create non-root file failed" || true
850 }
851 run_test 19c "$RUNAS touch .../f19 (should return error) =="
852
853 test_19d() {
854         cat $DIR/f19 && error || true
855 }
856 run_test 19d "cat .../f19 (should return error) =============="
857
858 test_20() {
859         touch $DIR/$tfile
860         rm $DIR/$tfile
861         touch $DIR/$tfile
862         rm $DIR/$tfile
863         touch $DIR/$tfile
864         rm $DIR/$tfile
865         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
866 }
867 run_test 20 "touch .../f ; ls -l ..."
868
869 test_21() {
870         test_mkdir $DIR/$tdir
871         [ -f $DIR/$tdir/dangle ] && rm -f $DIR/$tdir/dangle
872         ln -s dangle $DIR/$tdir/link
873         echo foo >> $DIR/$tdir/link
874         cat $DIR/$tdir/dangle
875         $CHECKSTAT -t link $DIR/$tdir/link || error "$tdir/link not a link"
876         $CHECKSTAT -f -t file $DIR/$tdir/link ||
877                 error "$tdir/link not linked to a file"
878 }
879 run_test 21 "write to dangling link"
880
881 test_22() {
882         local wdir=$DIR/$tdir
883         test_mkdir $wdir
884         chown $RUNAS_ID:$RUNAS_GID $wdir
885         (cd $wdir || error "cd $wdir failed";
886                 $RUNAS tar cf - /etc/hosts /etc/sysconfig/network |
887                 $RUNAS tar xf -)
888         ls -lR $wdir/etc || error "ls -lR $wdir/etc failed"
889         $CHECKSTAT -t dir $wdir/etc || error "checkstat -t dir failed"
890         $CHECKSTAT -u \#$RUNAS_ID -g \#$RUNAS_GID $wdir/etc ||
891                 error "checkstat -u failed"
892 }
893 run_test 22 "unpack tar archive as non-root user"
894
895 # was test_23
896 test_23a() {
897         test_mkdir $DIR/$tdir
898         local file=$DIR/$tdir/$tfile
899
900         openfile -f O_CREAT:O_EXCL $file || error "$file create failed"
901         openfile -f O_CREAT:O_EXCL $file &&
902                 error "$file recreate succeeded" || true
903 }
904 run_test 23a "O_CREAT|O_EXCL in subdir"
905
906 test_23b() { # bug 18988
907         test_mkdir $DIR/$tdir
908         local file=$DIR/$tdir/$tfile
909
910         rm -f $file
911         echo foo > $file || error "write filed"
912         echo bar >> $file || error "append filed"
913         $CHECKSTAT -s 8 $file || error "wrong size"
914         rm $file
915 }
916 run_test 23b "O_APPEND check"
917
918 # LU-9409, size with O_APPEND and tiny writes
919 test_23c() {
920         local file=$DIR/$tfile
921
922         # single dd
923         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800
924         $CHECKSTAT -s 6400 $file || error "wrong size, expected 6400"
925         rm -f $file
926
927         # racing tiny writes
928         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800 &
929         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800 &
930         wait
931         $CHECKSTAT -s 12800 $file || error "wrong size, expected 12800"
932         rm -f $file
933
934         #racing tiny & normal writes
935         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=4096 count=4 &
936         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=100 &
937         wait
938         $CHECKSTAT -s 17184 $file || error "wrong size, expected 17184"
939         rm -f $file
940
941         #racing tiny & normal writes 2, ugly numbers
942         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=4099 count=11 &
943         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=17 count=173 &
944         wait
945         $CHECKSTAT -s 48030 $file || error "wrong size, expected 48030"
946         rm -f $file
947 }
948 run_test 23c "O_APPEND size checks for tiny writes"
949
950 # LU-11069 file offset is correct after appending writes
951 test_23d() {
952         local file=$DIR/$tfile
953         local offset
954
955         echo CentaurHauls > $file
956         offset=$($MULTIOP $file oO_WRONLY:O_APPEND:w13Zp)
957         if ((offset != 26)); then
958                 error "wrong offset, expected 26, got '$offset'"
959         fi
960 }
961 run_test 23d "file offset is correct after appending writes"
962
963 # rename sanity
964 test_24a() {
965         echo '-- same directory rename'
966         test_mkdir $DIR/$tdir
967         touch $DIR/$tdir/$tfile.1
968         mv $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
969         $CHECKSTAT -t file $DIR/$tdir/$tfile.2 || error "$tfile.2 not a file"
970 }
971 run_test 24a "rename file to non-existent target"
972
973 test_24b() {
974         test_mkdir $DIR/$tdir
975         touch $DIR/$tdir/$tfile.{1,2}
976         mv $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
977         $CHECKSTAT -a $DIR/$tdir/$tfile.1 || error "$tfile.1 exists"
978         $CHECKSTAT -t file $DIR/$tdir/$tfile.2 || error "$tfile.2 not a file"
979 }
980 run_test 24b "rename file to existing target"
981
982 test_24c() {
983         test_mkdir $DIR/$tdir
984         test_mkdir $DIR/$tdir/d$testnum.1
985         mv $DIR/$tdir/d$testnum.1 $DIR/$tdir/d$testnum.2
986         $CHECKSTAT -a $DIR/$tdir/d$testnum.1 || error "d$testnum.1 exists"
987         $CHECKSTAT -t dir $DIR/$tdir/d$testnum.2 || error "d$testnum.2 not dir"
988 }
989 run_test 24c "rename directory to non-existent target"
990
991 test_24d() {
992         test_mkdir -c1 $DIR/$tdir
993         test_mkdir -c1 $DIR/$tdir/d$testnum.1
994         test_mkdir -c1 $DIR/$tdir/d$testnum.2
995         mrename $DIR/$tdir/d$testnum.1 $DIR/$tdir/d$testnum.2
996         $CHECKSTAT -a $DIR/$tdir/d$testnum.1 || error "d$testnum.1 exists"
997         $CHECKSTAT -t dir $DIR/$tdir/d$testnum.2 || error "d$testnum.2 not dir"
998 }
999 run_test 24d "rename directory to existing target"
1000
1001 test_24e() {
1002         echo '-- cross directory renames --'
1003         test_mkdir $DIR/R5a
1004         test_mkdir $DIR/R5b
1005         touch $DIR/R5a/f
1006         mv $DIR/R5a/f $DIR/R5b/g
1007         $CHECKSTAT -a $DIR/R5a/f || error "$DIR/R5a/f exists"
1008         $CHECKSTAT -t file $DIR/R5b/g || error "$DIR/R5b/g not file type"
1009 }
1010 run_test 24e "touch .../R5a/f; rename .../R5a/f .../R5b/g ======"
1011
1012 test_24f() {
1013         test_mkdir $DIR/R6a
1014         test_mkdir $DIR/R6b
1015         touch $DIR/R6a/f $DIR/R6b/g
1016         mv $DIR/R6a/f $DIR/R6b/g
1017         $CHECKSTAT -a $DIR/R6a/f || error "$DIR/R6a/f exists"
1018         $CHECKSTAT -t file $DIR/R6b/g || error "$DIR/R6b/g not file type"
1019 }
1020 run_test 24f "touch .../R6a/f R6b/g; mv .../R6a/f .../R6b/g ===="
1021
1022 test_24g() {
1023         test_mkdir $DIR/R7a
1024         test_mkdir $DIR/R7b
1025         test_mkdir $DIR/R7a/d
1026         mv $DIR/R7a/d $DIR/R7b/e
1027         $CHECKSTAT -a $DIR/R7a/d || error "$DIR/R7a/d exists"
1028         $CHECKSTAT -t dir $DIR/R7b/e || error "$DIR/R7b/e not dir type"
1029 }
1030 run_test 24g "mkdir .../R7{a,b}/d; mv .../R7a/d .../R7b/e ======"
1031
1032 test_24h() {
1033         test_mkdir -c1 $DIR/R8a
1034         test_mkdir -c1 $DIR/R8b
1035         test_mkdir -c1 $DIR/R8a/d
1036         test_mkdir -c1 $DIR/R8b/e
1037         mrename $DIR/R8a/d $DIR/R8b/e
1038         $CHECKSTAT -a $DIR/R8a/d || error "$DIR/R8a/d exists"
1039         $CHECKSTAT -t dir $DIR/R8b/e || error "$DIR/R8b/e not dir type"
1040 }
1041 run_test 24h "mkdir .../R8{a,b}/{d,e}; rename .../R8a/d .../R8b/e"
1042
1043 test_24i() {
1044         echo "-- rename error cases"
1045         test_mkdir $DIR/R9
1046         test_mkdir $DIR/R9/a
1047         touch $DIR/R9/f
1048         mrename $DIR/R9/f $DIR/R9/a
1049         $CHECKSTAT -t file $DIR/R9/f || error "$DIR/R9/f not file type"
1050         $CHECKSTAT -t dir  $DIR/R9/a || error "$DIR/R9/a not dir type"
1051         $CHECKSTAT -a $DIR/R9/a/f || error "$DIR/R9/a/f exists"
1052 }
1053 run_test 24i "rename file to dir error: touch f ; mkdir a ; rename f a"
1054
1055 test_24j() {
1056         test_mkdir $DIR/R10
1057         mrename $DIR/R10/f $DIR/R10/g
1058         $CHECKSTAT -t dir $DIR/R10 || error "$DIR/R10 not dir type"
1059         $CHECKSTAT -a $DIR/R10/f || error "$DIR/R10/f exists"
1060         $CHECKSTAT -a $DIR/R10/g || error "$DIR/R10/g exists"
1061 }
1062 run_test 24j "source does not exist ============================"
1063
1064 test_24k() {
1065         test_mkdir $DIR/R11a
1066         test_mkdir $DIR/R11a/d
1067         touch $DIR/R11a/f
1068         mv $DIR/R11a/f $DIR/R11a/d
1069         $CHECKSTAT -a $DIR/R11a/f || error "$DIR/R11a/f exists"
1070         $CHECKSTAT -t file $DIR/R11a/d/f || error "$DIR/R11a/d/f not file type"
1071 }
1072 run_test 24k "touch .../R11a/f; mv .../R11a/f .../R11a/d ======="
1073
1074 # bug 2429 - rename foo foo foo creates invalid file
1075 test_24l() {
1076         f="$DIR/f24l"
1077         $MULTIOP $f OcNs || error "rename of ${f} to itself failed"
1078 }
1079 run_test 24l "Renaming a file to itself ========================"
1080
1081 test_24m() {
1082         f="$DIR/f24m"
1083         $MULTIOP $f OcLN ${f}2 ${f}2 || error "link ${f}2 ${f}2 failed"
1084         # on ext3 this does not remove either the source or target files
1085         # though the "expected" operation would be to remove the source
1086         $CHECKSTAT -t file ${f} || error "${f} missing"
1087         $CHECKSTAT -t file ${f}2 || error "${f}2 missing"
1088 }
1089 run_test 24m "Renaming a file to a hard link to itself ========="
1090
1091 test_24n() {
1092     f="$DIR/f24n"
1093     # this stats the old file after it was renamed, so it should fail
1094     touch ${f}
1095     $CHECKSTAT ${f} || error "${f} missing"
1096     mv ${f} ${f}.rename
1097     $CHECKSTAT ${f}.rename || error "${f}.rename missing"
1098     $CHECKSTAT -a ${f} || error "${f} exists"
1099 }
1100 run_test 24n "Statting the old file after renaming (Posix rename 2)"
1101
1102 test_24o() {
1103         test_mkdir $DIR/$tdir
1104         rename_many -s random -v -n 10 $DIR/$tdir
1105 }
1106 run_test 24o "rename of files during htree split"
1107
1108 test_24p() {
1109         test_mkdir $DIR/R12a
1110         test_mkdir $DIR/R12b
1111         DIRINO=`ls -lid $DIR/R12a | awk '{ print $1 }'`
1112         mrename $DIR/R12a $DIR/R12b
1113         $CHECKSTAT -a $DIR/R12a || error "$DIR/R12a exists"
1114         $CHECKSTAT -t dir $DIR/R12b || error "$DIR/R12b not dir type"
1115         DIRINO2=`ls -lid $DIR/R12b | awk '{ print $1 }'`
1116         [ "$DIRINO" = "$DIRINO2" ] || error "R12a $DIRINO != R12b $DIRINO2"
1117 }
1118 run_test 24p "mkdir .../R12{a,b}; rename .../R12a .../R12b"
1119
1120 cleanup_multiop_pause() {
1121         trap 0
1122         kill -USR1 $MULTIPID
1123 }
1124
1125 test_24q() {
1126         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1127
1128         test_mkdir $DIR/R13a
1129         test_mkdir $DIR/R13b
1130         local DIRINO=$(ls -lid $DIR/R13a | awk '{ print $1 }')
1131         multiop_bg_pause $DIR/R13b D_c || error "multiop failed to start"
1132         MULTIPID=$!
1133
1134         trap cleanup_multiop_pause EXIT
1135         mrename $DIR/R13a $DIR/R13b
1136         $CHECKSTAT -a $DIR/R13a || error "R13a still exists"
1137         $CHECKSTAT -t dir $DIR/R13b || error "R13b does not exist"
1138         local DIRINO2=$(ls -lid $DIR/R13b | awk '{ print $1 }')
1139         [ "$DIRINO" = "$DIRINO2" ] || error "R13a $DIRINO != R13b $DIRINO2"
1140         cleanup_multiop_pause
1141         wait $MULTIPID || error "multiop close failed"
1142 }
1143 run_test 24q "mkdir .../R13{a,b}; open R13b rename R13a R13b ==="
1144
1145 test_24r() { #bug 3789
1146         test_mkdir $DIR/R14a
1147         test_mkdir $DIR/R14a/b
1148         mrename $DIR/R14a $DIR/R14a/b && error "rename to subdir worked!"
1149         $CHECKSTAT -t dir $DIR/R14a || error "$DIR/R14a missing"
1150         $CHECKSTAT -t dir $DIR/R14a/b || error "$DIR/R14a/b missing"
1151 }
1152 run_test 24r "mkdir .../R14a/b; rename .../R14a .../R14a/b ====="
1153
1154 test_24s() {
1155         test_mkdir $DIR/R15a
1156         test_mkdir $DIR/R15a/b
1157         test_mkdir $DIR/R15a/b/c
1158         mrename $DIR/R15a $DIR/R15a/b/c && error "rename to sub-subdir worked!"
1159         $CHECKSTAT -t dir $DIR/R15a || error "$DIR/R15a missing"
1160         $CHECKSTAT -t dir $DIR/R15a/b/c || error "$DIR/R15a/b/c missing"
1161 }
1162 run_test 24s "mkdir .../R15a/b/c; rename .../R15a .../R15a/b/c ="
1163
1164 test_24t() {
1165         test_mkdir $DIR/R16a
1166         test_mkdir $DIR/R16a/b
1167         test_mkdir $DIR/R16a/b/c
1168         mrename $DIR/R16a/b/c $DIR/R16a && error "rename to sub-subdir worked!"
1169         $CHECKSTAT -t dir $DIR/R16a || error "$DIR/R16a missing"
1170         $CHECKSTAT -t dir $DIR/R16a/b/c || error "$DIR/R16a/b/c missing"
1171 }
1172 run_test 24t "mkdir .../R16a/b/c; rename .../R16a/b/c .../R16a ="
1173
1174 test_24u() { # bug12192
1175         $MULTIOP $DIR/$tfile C2w$((2048 * 1024))c || error "multiop failed"
1176         $CHECKSTAT -s $((2048 * 1024)) $DIR/$tfile || error "wrong file size"
1177 }
1178 run_test 24u "create stripe file"
1179
1180 simple_cleanup_common() {
1181         local createmany=$1
1182         local rc=0
1183
1184         [[ -z "$DIR" || -z "$tdir" || ! -d "$DIR/$tdir" ]] && return 0
1185
1186         local start=$SECONDS
1187
1188         [[ -n "$createmany" ]] && unlinkmany $DIR/$tdir/$tfile $createmany
1189         rm -rf $DIR/$tdir || error "cleanup $DIR/$tdir failed"
1190         rc=$?
1191         wait_delete_completed
1192         echo "cleanup time $((SECONDS - start))"
1193         return $rc
1194 }
1195
1196 max_pages_per_rpc() {
1197         local mdtname="$(printf "MDT%04x" ${1:-0})"
1198         $LCTL get_param -n mdc.*$mdtname*.max_pages_per_rpc
1199 }
1200
1201 test_24v() {
1202         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1203
1204         local nrfiles=${COUNT:-100000}
1205         local fname="$DIR/$tdir/$tfile"
1206
1207         # Performance issue on ZFS see LU-4072 (c.f. LU-2887)
1208         [ "$mds1_FSTYPE" = "zfs" ] && nrfiles=${COUNT:-10000}
1209
1210         test_mkdir "$(dirname $fname)"
1211         # assume MDT0000 has the fewest inodes
1212         local stripes=$($LFS getdirstripe -c $(dirname $fname))
1213         local free_inodes=$(($(mdt_free_inodes 0) * ${stripes/#0/1}))
1214         [[ $free_inodes -lt $nrfiles ]] && nrfiles=$free_inodes
1215
1216         stack_trap "simple_cleanup_common $nrfiles"
1217
1218         createmany -m "$fname" $nrfiles
1219
1220         cancel_lru_locks mdc
1221         lctl set_param mdc.*.stats clear
1222
1223         # was previously test_24D: LU-6101
1224         # readdir() returns correct number of entries after cursor reload
1225         local num_ls=$(ls $DIR/$tdir | wc -l)
1226         local num_uniq=$(ls $DIR/$tdir | sort -u | wc -l)
1227         local num_all=$(ls -a $DIR/$tdir | wc -l)
1228         if [ $num_ls -ne $nrfiles ] || [ $num_uniq -ne $nrfiles ] ||
1229                 [ $num_all -ne $((nrfiles + 2)) ]; then
1230                         error "Expected $nrfiles files, got $num_ls " \
1231                                 "($num_uniq unique $num_all .&..)"
1232         fi
1233         # LU-5 large readdir
1234         # dirent_size = 32 bytes for sizeof(struct lu_dirent) +
1235         #               N bytes for name (len($nrfiles) rounded to 8 bytes) +
1236         #               8 bytes for luda_type (4 bytes rounded to 8 bytes)
1237         # take into account of overhead in lu_dirpage header and end mark in
1238         # each page, plus one in rpc_num calculation.
1239         local dirent_size=$((32 + (${#tfile} | 7) + 1 + 8))
1240         local page_entries=$(((PAGE_SIZE - 24) / dirent_size))
1241         local mdt_idx=$($LFS getdirstripe -i $(dirname $fname))
1242         local rpc_pages=$(max_pages_per_rpc $mdt_idx)
1243         local rpc_max=$((nrfiles / (page_entries * rpc_pages) + stripes))
1244         local mds_readpage=$(calc_stats mdc.*.stats mds_readpage)
1245         echo "readpages: $mds_readpage rpc_max: $rpc_max-2/+1"
1246         (( $mds_readpage >= $rpc_max - 2 && $mds_readpage <= $rpc_max + 1)) ||
1247                 error "large readdir doesn't take effect: " \
1248                       "$mds_readpage should be about $rpc_max"
1249 }
1250 run_test 24v "list large directory (test hash collision, b=17560)"
1251
1252 test_24w() { # bug21506
1253         SZ1=234852
1254         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=4096 || return 1
1255         dd if=/dev/zero bs=$SZ1 count=1 >> $DIR/$tfile || return 2
1256         dd if=$DIR/$tfile of=$DIR/${tfile}_left bs=1M skip=4097 || return 3
1257         SZ2=`ls -l $DIR/${tfile}_left | awk '{print $5}'`
1258         [[ "$SZ1" -eq "$SZ2" ]] ||
1259                 error "Error reading at the end of the file $tfile"
1260 }
1261 run_test 24w "Reading a file larger than 4Gb"
1262
1263 test_24x() {
1264         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1265         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1266         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1267                 skip "Need MDS version at least 2.7.56"
1268
1269         local MDTIDX=1
1270         local remote_dir=$DIR/$tdir/remote_dir
1271
1272         test_mkdir $DIR/$tdir
1273         $LFS mkdir -i $MDTIDX $remote_dir ||
1274                 error "create remote directory failed"
1275
1276         test_mkdir $DIR/$tdir/src_dir
1277         touch $DIR/$tdir/src_file
1278         test_mkdir $remote_dir/tgt_dir
1279         touch $remote_dir/tgt_file
1280
1281         mrename $DIR/$tdir/src_dir $remote_dir/tgt_dir ||
1282                 error "rename dir cross MDT failed!"
1283
1284         mrename $DIR/$tdir/src_file $remote_dir/tgt_file ||
1285                 error "rename file cross MDT failed!"
1286
1287         touch $DIR/$tdir/ln_file
1288         ln $DIR/$tdir/ln_file $remote_dir/ln_name ||
1289                 error "ln file cross MDT failed"
1290
1291         rm -rf $DIR/$tdir || error "Can not delete directories"
1292 }
1293 run_test 24x "cross MDT rename/link"
1294
1295 test_24y() {
1296         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1297         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1298
1299         local remote_dir=$DIR/$tdir/remote_dir
1300         local mdtidx=1
1301
1302         test_mkdir $DIR/$tdir
1303         $LFS mkdir -i $mdtidx $remote_dir ||
1304                 error "create remote directory failed"
1305
1306         test_mkdir $remote_dir/src_dir
1307         touch $remote_dir/src_file
1308         test_mkdir $remote_dir/tgt_dir
1309         touch $remote_dir/tgt_file
1310
1311         mrename $remote_dir/src_dir $remote_dir/tgt_dir ||
1312                 error "rename subdir in the same remote dir failed!"
1313
1314         mrename $remote_dir/src_file $remote_dir/tgt_file ||
1315                 error "rename files in the same remote dir failed!"
1316
1317         ln $remote_dir/tgt_file $remote_dir/tgt_file1 ||
1318                 error "link files in the same remote dir failed!"
1319
1320         rm -rf $DIR/$tdir || error "Can not delete directories"
1321 }
1322 run_test 24y "rename/link on the same dir should succeed"
1323
1324 test_24z() {
1325         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1326         [[ $MDS1_VERSION -lt $(version_code 2.12.51) ]] &&
1327                 skip "Need MDS version at least 2.12.51"
1328
1329         local index
1330
1331         for index in 0 1; do
1332                 $LFS mkdir -i $index $DIR/$tdir.$index || error "mkdir failed"
1333                 touch $DIR/$tdir.0/$tfile.$index || error "touch failed"
1334         done
1335
1336         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1 || error "mv $tfile.0 failed"
1337
1338         index=$($LFS getstripe -m $DIR/$tdir.1/$tfile.0)
1339         [ $index -eq 0 ] || error "$tfile.0 is on MDT$index"
1340
1341         local mdts=$(comma_list $(mdts_nodes))
1342
1343         do_nodes $mdts $LCTL set_param mdt.*.enable_remote_rename=0
1344         stack_trap "do_nodes $mdts $LCTL \
1345                 set_param mdt.*.enable_remote_rename=1" EXIT
1346
1347         mv $DIR/$tdir.0/$tfile.1 $DIR/$tdir.1 || error "mv $tfile.1 failed"
1348
1349         index=$($LFS getstripe -m $DIR/$tdir.1/$tfile.1)
1350         [ $index -eq 1 ] || error "$tfile.1 is on MDT$index"
1351 }
1352 run_test 24z "cross-MDT rename is done as cp"
1353
1354 test_24A() { # LU-3182
1355         local NFILES=5000
1356
1357         test_mkdir $DIR/$tdir
1358         stack_trap "simple_cleanup_common $NFILES"
1359         createmany -m $DIR/$tdir/$tfile $NFILES
1360         local t=$(ls $DIR/$tdir | wc -l)
1361         local u=$(ls $DIR/$tdir | sort -u | wc -l)
1362         local v=$(ls -ai $DIR/$tdir | sort -u | wc -l)
1363
1364         (( $t == $NFILES && $u == $NFILES && $v == NFILES + 2 )) ||
1365                 error "Expected $NFILES files, got $t ($u unique $v .&..)"
1366 }
1367 run_test 24A "readdir() returns correct number of entries."
1368
1369 test_24B() { # LU-4805
1370         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1371
1372         local count
1373
1374         test_mkdir $DIR/$tdir
1375         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir/ ||
1376                 error "create striped dir failed"
1377
1378         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1379         [ $count -eq 2 ] || error "Expected 2, got $count"
1380
1381         touch $DIR/$tdir/striped_dir/a
1382
1383         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1384         [ $count -eq 3 ] || error "Expected 3, got $count"
1385
1386         touch $DIR/$tdir/striped_dir/.f
1387
1388         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1389         [ $count -eq 4 ] || error "Expected 4, got $count"
1390
1391         rm -rf $DIR/$tdir || error "Can not delete directories"
1392 }
1393 run_test 24B "readdir for striped dir return correct number of entries"
1394
1395 test_24C() {
1396         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1397
1398         mkdir $DIR/$tdir
1399         mkdir $DIR/$tdir/d0
1400         mkdir $DIR/$tdir/d1
1401
1402         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/d0/striped_dir ||
1403                 error "create striped dir failed"
1404
1405         cd $DIR/$tdir/d0/striped_dir
1406
1407         local d0_ino=$(ls -i -l -a $DIR/$tdir | grep "d0" | awk '{print $1}')
1408         local d1_ino=$(ls -i -l -a $DIR/$tdir | grep "d1" | awk '{print $1}')
1409         local parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1410
1411         [ "$d0_ino" = "$parent_ino" ] ||
1412                 error ".. wrong, expect $d0_ino, get $parent_ino"
1413
1414         mv $DIR/$tdir/d0/striped_dir $DIR/$tdir/d1/ ||
1415                 error "mv striped dir failed"
1416
1417         parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1418
1419         [ "$d1_ino" = "$parent_ino" ] ||
1420                 error ".. wrong after mv, expect $d1_ino, get $parent_ino"
1421 }
1422 run_test 24C "check .. in striped dir"
1423
1424 test_24E() {
1425         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
1426         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1427
1428         mkdir -p $DIR/$tdir
1429         mkdir $DIR/$tdir/src_dir
1430         $LFS mkdir -i 1 $DIR/$tdir/src_dir/src_child ||
1431                 error "create remote source failed"
1432
1433         touch $DIR/$tdir/src_dir/src_child/a
1434
1435         $LFS mkdir -i 2 $DIR/$tdir/tgt_dir ||
1436                 error "create remote target dir failed"
1437
1438         $LFS mkdir -i 3 $DIR/$tdir/tgt_dir/tgt_child ||
1439                 error "create remote target child failed"
1440
1441         mrename $DIR/$tdir/src_dir/src_child $DIR/$tdir/tgt_dir/tgt_child ||
1442                 error "rename dir cross MDT failed!"
1443
1444         find $DIR/$tdir
1445
1446         $CHECKSTAT -t dir $DIR/$tdir/src_dir/src_child &&
1447                 error "src_child still exists after rename"
1448
1449         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/tgt_child/a ||
1450                 error "missing file(a) after rename"
1451
1452         rm -rf $DIR/$tdir || error "Can not delete directories"
1453 }
1454 run_test 24E "cross MDT rename/link"
1455
1456 test_24F () {
1457         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
1458
1459         local repeats=1000
1460         [ "$SLOW" = "no" ] && repeats=100
1461
1462         mkdir -p $DIR/$tdir
1463
1464         echo "$repeats repeats"
1465         for ((i = 0; i < repeats; i++)); do
1466                 $LFS mkdir -i0 -c2 $DIR/$tdir/test || error "mkdir fails"
1467                 touch $DIR/$tdir/test/a || error "touch fails"
1468                 mkdir $DIR/$tdir/test/b || error "mkdir fails"
1469                 rm -rf $DIR/$tdir/test || error "rmdir fails"
1470         done
1471
1472         true
1473 }
1474 run_test 24F "hash order vs readdir (LU-11330)"
1475
1476 test_24G () {
1477         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
1478
1479         local ino1
1480         local ino2
1481
1482         $LFS mkdir -i 0 $DIR/$tdir-0 || error "mkdir $tdir-0"
1483         $LFS mkdir -i 1 $DIR/$tdir-1 || error "mkdir $tdir-1"
1484         touch $DIR/$tdir-0/f1 || error "touch f1"
1485         ln -s $DIR/$tdir-0/f1 $DIR/$tdir-0/s1 || error "ln s1"
1486         ino1=$(stat -c%i $DIR/$tdir-0/s1)
1487         mv $DIR/$tdir-0/s1 $DIR/$tdir-1 || error "mv s1"
1488         ino2=$(stat -c%i $DIR/$tdir-1/s1)
1489         [ $ino1 -ne $ino2 ] || error "s1 should be migrated"
1490 }
1491 run_test 24G "migrate symlink in rename"
1492
1493 test_24H() {
1494         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
1495         [[ $(hostname) != $(facet_active_host mds2) ]] ||
1496                 skip "MDT1 should be on another node"
1497
1498         test_mkdir -i 1 -c 1 $DIR/$tdir
1499 #define OBD_FAIL_FLD_QUERY_REQ           0x1103
1500         do_facet mds2 $LCTL set_param fail_loc=0x80001103
1501         touch $DIR/$tdir/$tfile || error "touch failed"
1502 }
1503 run_test 24H "repeat FLD_QUERY rpc"
1504
1505 test_25a() {
1506         echo '== symlink sanity ============================================='
1507
1508         test_mkdir $DIR/d25
1509         ln -s d25 $DIR/s25
1510         touch $DIR/s25/foo ||
1511                 error "File creation in symlinked directory failed"
1512 }
1513 run_test 25a "create file in symlinked directory ==============="
1514
1515 test_25b() {
1516         [ ! -d $DIR/d25 ] && test_25a
1517         $CHECKSTAT -t file $DIR/s25/foo || error "$DIR/s25/foo not file type"
1518 }
1519 run_test 25b "lookup file in symlinked directory ==============="
1520
1521 test_26a() {
1522         test_mkdir $DIR/d26
1523         test_mkdir $DIR/d26/d26-2
1524         ln -s d26/d26-2 $DIR/s26
1525         touch $DIR/s26/foo || error "File creation failed"
1526 }
1527 run_test 26a "multiple component symlink ======================="
1528
1529 test_26b() {
1530         test_mkdir -p $DIR/$tdir/d26-2
1531         ln -s $tdir/d26-2/foo $DIR/s26-2
1532         touch $DIR/s26-2 || error "File creation failed"
1533 }
1534 run_test 26b "multiple component symlink at end of lookup ======"
1535
1536 test_26c() {
1537         test_mkdir $DIR/d26.2
1538         touch $DIR/d26.2/foo
1539         ln -s d26.2 $DIR/s26.2-1
1540         ln -s s26.2-1 $DIR/s26.2-2
1541         ln -s s26.2-2 $DIR/s26.2-3
1542         chmod 0666 $DIR/s26.2-3/foo
1543 }
1544 run_test 26c "chain of symlinks"
1545
1546 # recursive symlinks (bug 439)
1547 test_26d() {
1548         ln -s d26-3/foo $DIR/d26-3
1549 }
1550 run_test 26d "create multiple component recursive symlink"
1551
1552 test_26e() {
1553         [ ! -h $DIR/d26-3 ] && test_26d
1554         rm $DIR/d26-3
1555 }
1556 run_test 26e "unlink multiple component recursive symlink"
1557
1558 # recursive symlinks (bug 7022)
1559 test_26f() {
1560         test_mkdir $DIR/$tdir
1561         test_mkdir $DIR/$tdir/$tfile
1562         cd $DIR/$tdir/$tfile           || error "cd $DIR/$tdir/$tfile failed"
1563         test_mkdir -p lndir/bar1
1564         test_mkdir $DIR/$tdir/$tfile/$tfile
1565         cd $tfile                || error "cd $tfile failed"
1566         ln -s .. dotdot          || error "ln dotdot failed"
1567         ln -s dotdot/lndir lndir || error "ln lndir failed"
1568         cd $DIR/$tdir                 || error "cd $DIR/$tdir failed"
1569         output=`ls $tfile/$tfile/lndir/bar1`
1570         [ "$output" = bar1 ] && error "unexpected output"
1571         rm -r $tfile             || error "rm $tfile failed"
1572         $CHECKSTAT -a $DIR/$tfile || error "$tfile not gone"
1573 }
1574 run_test 26f "rm -r of a directory which has recursive symlink"
1575
1576 test_27a() {
1577         test_mkdir $DIR/$tdir
1578         $LFS getstripe $DIR/$tdir
1579         $LFS setstripe -c 1 $DIR/$tdir/$tfile || error "setstripe failed"
1580         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1581         cp /etc/hosts $DIR/$tdir/$tfile || error "Can't copy to one stripe file"
1582 }
1583 run_test 27a "one stripe file"
1584
1585 test_27b() {
1586         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1587
1588         test_mkdir $DIR/$tdir
1589         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1590         $LFS getstripe -c $DIR/$tdir/$tfile
1591         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
1592                 error "two-stripe file doesn't have two stripes"
1593
1594         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1595 }
1596 run_test 27b "create and write to two stripe file"
1597
1598 # 27c family tests specific striping, setstripe -o
1599 test_27ca() {
1600         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1601         test_mkdir -p $DIR/$tdir
1602         local osts="1"
1603
1604         $LFS setstripe -o $osts $DIR/$tdir/$tfile  || error "setstripe failed"
1605         $LFS getstripe -i $DIR/$tdir/$tfile
1606         [ $($LFS getstripe -i $DIR/$tdir/$tfile ) -eq $osts ] ||
1607                 error "stripe not on specified OST"
1608
1609         dd if=/dev/zero of=$DIR/$tdir/$tfile  bs=1M count=4 || error "dd failed"
1610 }
1611 run_test 27ca "one stripe on specified OST"
1612
1613 test_27cb() {
1614         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1615         test_mkdir -p $DIR/$tdir
1616         local osts="1,0"
1617         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1618         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1619         echo "$getstripe"
1620
1621         # Strip getstripe output to a space separated list of OSTs
1622         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1623                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1624         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1625                 error "stripes not on specified OSTs"
1626
1627         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1628 }
1629 run_test 27cb "two stripes on specified OSTs"
1630
1631 test_27cc() {
1632         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1633         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1634                 skip "server does not support overstriping"
1635
1636         test_mkdir -p $DIR/$tdir
1637         local osts="0,0"
1638         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1639         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1640         echo "$getstripe"
1641
1642         # Strip getstripe output to a space separated list of OSTs
1643         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1644                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1645         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1646                 error "stripes not on specified OSTs"
1647
1648         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1649 }
1650 run_test 27cc "two stripes on the same OST"
1651
1652 test_27cd() {
1653         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1654         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1655                 skip "server does not support overstriping"
1656         test_mkdir -p $DIR/$tdir
1657         local osts="0,1,1,0"
1658         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1659         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1660         echo "$getstripe"
1661
1662         # Strip getstripe output to a space separated list of OSTs
1663         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1664                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1665         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1666                 error "stripes not on specified OSTs"
1667
1668         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1669 }
1670 run_test 27cd "four stripes on two OSTs"
1671
1672 test_27ce() {
1673         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
1674                 skip_env "too many osts, skipping"
1675         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1676                 skip "server does not support overstriping"
1677         # We do one more stripe than we have OSTs
1678         [ $OSTCOUNT -lt 159 ] || large_xattr_enabled ||
1679                 skip_env "ea_inode feature disabled"
1680
1681         test_mkdir -p $DIR/$tdir
1682         local osts=""
1683         for i in $(seq 0 $OSTCOUNT);
1684         do
1685                 osts=$osts"0"
1686                 if [ $i -ne $OSTCOUNT ]; then
1687                         osts=$osts","
1688                 fi
1689         done
1690         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1691         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1692         echo "$getstripe"
1693
1694         # Strip getstripe output to a space separated list of OSTs
1695         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1696                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1697         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1698                 error "stripes not on specified OSTs"
1699
1700         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1701 }
1702 run_test 27ce "more stripes than OSTs with -o"
1703
1704 test_27cf() {
1705         local osp_proc="osp.$FSNAME-OST0000-osc-MDT000*.active"
1706         local pid=0
1707
1708         test_mkdir -p $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
1709         do_facet $SINGLEMDS "$LCTL set_param -n $osp_proc=0"
1710         stack_trap "do_facet $SINGLEMDS $LCTL set_param -n $osp_proc=1" EXIT
1711         wait_update_facet $SINGLEMDS "$LCTL get_param -n $osp_proc | grep 1" ||
1712                 error "failed to set $osp_proc=0"
1713
1714         $LFS setstripe -o 0 $DIR/$tdir/$tfile &
1715         pid=$!
1716         sleep 1
1717         do_facet $SINGLEMDS "$LCTL set_param -n $osp_proc=1"
1718         wait_update_facet $SINGLEMDS "$LCTL get_param -n $osp_proc | grep 0" ||
1719                 error "failed to set $osp_proc=1"
1720         wait $pid
1721         [[ $pid -ne 0 ]] ||
1722                 error "should return error due to $osp_proc=0"
1723 }
1724 run_test 27cf "'setstripe -o' on inactive OSTs should return error"
1725
1726 test_27cg() {
1727         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1728                 skip "server does not support overstriping"
1729         [[ $mds1_FSTYPE != "ldiskfs" ]] && skip_env "ldiskfs only test"
1730         large_xattr_enabled || skip_env "ea_inode feature disabled"
1731
1732         local osts="0"
1733
1734         for ((i=1;i<1000;i++)); do
1735                 osts+=",$((i % OSTCOUNT))"
1736         done
1737
1738         local mdts=$(comma_list $(mdts_nodes))
1739         local before=$(do_nodes $mdts \
1740                 "$LCTL get_param -n osd-ldiskfs.*MDT*.stats" |
1741                 awk '/many credits/{print $3}' |
1742                 calc_sum)
1743
1744         $LFS setstripe -o $osts $DIR/$tfile || error "setstripe failed"
1745         $LFS getstripe $DIR/$tfile | grep stripe
1746
1747         rm -f $DIR/$tfile || error "can't unlink"
1748
1749         after=$(do_nodes $mdts \
1750                 "$LCTL get_param -n osd-ldiskfs.*MDT*.stats" |
1751                 awk '/many credits/{print $3}' |
1752                 calc_sum)
1753
1754         (( before == after )) ||
1755                 error "too many credits happened: $after > $before"
1756 }
1757 run_test 27cg "1000 shouldn't cause too many credits"
1758
1759 test_27d() {
1760         test_mkdir $DIR/$tdir
1761         $LFS setstripe -c 0 -i -1 -S 0 $DIR/$tdir/$tfile ||
1762                 error "setstripe failed"
1763         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1764         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1765 }
1766 run_test 27d "create file with default settings"
1767
1768 test_27e() {
1769         # LU-5839 adds check for existed layout before setting it
1770         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1771                 skip "Need MDS version at least 2.7.56"
1772
1773         test_mkdir $DIR/$tdir
1774         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1775         $LFS setstripe -c 2 $DIR/$tdir/$tfile && error "setstripe worked twice"
1776         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1777 }
1778 run_test 27e "setstripe existing file (should return error)"
1779
1780 test_27f() {
1781         test_mkdir $DIR/$tdir
1782         $LFS setstripe -S 100 -i 0 -c 1 $DIR/$tdir/$tfile &&
1783                 error "$LFS setstripe $DIR/$tdir/$tfile failed"
1784         $CHECKSTAT -t file $DIR/$tdir/$tfile &&
1785                 error "$CHECKSTAT -t file $DIR/$tdir/$tfile should fail"
1786         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1787         $LFS getstripe $DIR/$tdir/$tfile || error "$LFS getstripe failed"
1788 }
1789 run_test 27f "setstripe with bad stripe size (should return error)"
1790
1791 test_27g() {
1792         test_mkdir $DIR/$tdir
1793         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1794         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "no stripe info" ||
1795                 error "$DIR/$tdir/$tfile has object"
1796 }
1797 run_test 27g "$LFS getstripe with no objects"
1798
1799 test_27ga() {
1800         test_mkdir $DIR/$tdir
1801         touch $DIR/$tdir/$tfile || error "touch failed"
1802         ln -s bogus $DIR/$tdir/$tfile.2 || error "ln failed"
1803         $LFS getstripe -m $DIR/$tdir/$tfile $DIR/$tdir/$tfile.2
1804         local rc=$?
1805         (( rc == 2 )) || error "getstripe did not return ENOENT"
1806 }
1807 run_test 27ga "$LFS getstripe with missing file (should return error)"
1808
1809 test_27i() {
1810         test_mkdir $DIR/$tdir
1811         touch $DIR/$tdir/$tfile || error "touch failed"
1812         [[ $($LFS getstripe -c $DIR/$tdir/$tfile) -gt 0 ]] ||
1813                 error "missing objects"
1814 }
1815 run_test 27i "$LFS getstripe with some objects"
1816
1817 test_27j() {
1818         test_mkdir $DIR/$tdir
1819         $LFS setstripe -i $OSTCOUNT $DIR/$tdir/$tfile &&
1820                 error "setstripe failed" || true
1821 }
1822 run_test 27j "setstripe with bad stripe offset (should return error)"
1823
1824 test_27k() { # bug 2844
1825         test_mkdir $DIR/$tdir
1826         local file=$DIR/$tdir/$tfile
1827         local ll_max_blksize=$((4 * 1024 * 1024))
1828         $LFS setstripe -S 67108864 $file || error "setstripe failed"
1829         local blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1830         [ $blksize -le $ll_max_blksize ] || error "1:$blksize > $ll_max_blksize"
1831         dd if=/dev/zero of=$file bs=4k count=1
1832         blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1833         [ $blksize -le $ll_max_blksize ] || error "2:$blksize > $ll_max_blksize"
1834 }
1835 run_test 27k "limit i_blksize for broken user apps"
1836
1837 test_27l() {
1838         mcreate $DIR/$tfile || error "creating file"
1839         $RUNAS $LFS setstripe -c 1 $DIR/$tfile &&
1840                 error "setstripe should have failed" || true
1841 }
1842 run_test 27l "check setstripe permissions (should return error)"
1843
1844 test_27m() {
1845         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1846
1847         [ -n "$RCLIENTS" -o -n "$MOUNT_2" ] &&
1848                 skip_env "multiple clients -- skipping"
1849
1850         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
1851                    head -n1)
1852         if [[ $ORIGFREE -gt $MAXFREE ]]; then
1853                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
1854         fi
1855         stack_trap simple_cleanup_common
1856         test_mkdir $DIR/$tdir
1857         $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.1
1858         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1024 count=$MAXFREE &&
1859                 error "dd should fill OST0"
1860         i=2
1861         while $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.$i; do
1862                 i=$((i + 1))
1863                 [ $i -gt 256 ] && break
1864         done
1865         i=$((i + 1))
1866         touch $DIR/$tdir/$tfile.$i
1867         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1868             awk '{print $1}'| grep -w "0") ] &&
1869                 error "OST0 was full but new created file still use it"
1870         i=$((i + 1))
1871         touch $DIR/$tdir/$tfile.$i
1872         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1873             awk '{print $1}'| grep -w "0") ] &&
1874                 error "OST0 was full but new created file still use it" || true
1875 }
1876 run_test 27m "create file while OST0 was full"
1877
1878 # OSCs keep a NOSPC flag that will be reset after ~5s (qos_maxage)
1879 # if the OST isn't full anymore.
1880 reset_enospc() {
1881         local ostidx=${1:-""}
1882         local delay
1883         local ready
1884         local get_prealloc
1885
1886         local list=$(comma_list $(osts_nodes))
1887         [ "$ostidx" ] && list=$(facet_host ost$((ostidx + 1)))
1888
1889         do_nodes $list lctl set_param fail_loc=0
1890         wait_delete_completed   # initiate all OST_DESTROYs from MDS to OST
1891         delay=$(do_facet $SINGLEMDS lctl get_param -n lov.*.qos_maxage |
1892                 awk '{print $1 * 2;exit;}')
1893         get_prealloc="$LCTL get_param -n osc.*MDT*.prealloc_status |
1894                         grep -v \"^0$\""
1895         wait_update_facet $SINGLEMDS "$get_prealloc" "" $delay
1896 }
1897
1898 test_27n() {
1899         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1900         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1901         remote_mds_nodsh && skip "remote MDS with nodsh"
1902         remote_ost_nodsh && skip "remote OST with nodsh"
1903
1904         reset_enospc
1905         rm -f $DIR/$tdir/$tfile
1906         exhaust_precreations 0 0x80000215
1907         $LFS setstripe -c -1 $DIR/$tdir || error "setstripe failed"
1908         touch $DIR/$tdir/$tfile || error "touch failed"
1909         $LFS getstripe $DIR/$tdir/$tfile
1910         reset_enospc
1911 }
1912 run_test 27n "create file with some full OSTs"
1913
1914 test_27o() {
1915         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1916         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1917         remote_mds_nodsh && skip "remote MDS with nodsh"
1918         remote_ost_nodsh && skip "remote OST with nodsh"
1919
1920         reset_enospc
1921         rm -f $DIR/$tdir/$tfile
1922         exhaust_all_precreations 0x215
1923
1924         touch $DIR/$tdir/$tfile && error "able to create $DIR/$tdir/$tfile"
1925
1926         reset_enospc
1927         rm -rf $DIR/$tdir/*
1928 }
1929 run_test 27o "create file with all full OSTs (should error)"
1930
1931 function create_and_checktime() {
1932         local fname=$1
1933         local loops=$2
1934         local i
1935
1936         for ((i=0; i < $loops; i++)); do
1937                 local start=$SECONDS
1938                 multiop $fname-$i Oc
1939                 ((SECONDS-start < TIMEOUT)) ||
1940                         error "creation took " $((SECONDS-$start)) && return 1
1941         done
1942 }
1943
1944 test_27oo() {
1945         local mdts=$(comma_list $(mdts_nodes))
1946
1947         [ $MDS1_VERSION -lt $(version_code 2.13.57) ] &&
1948                 skip "Need MDS version at least 2.13.57"
1949
1950         local f0=$DIR/${tfile}-0
1951         local f1=$DIR/${tfile}-1
1952
1953         wait_delete_completed
1954
1955         # refill precreated objects
1956         $LFS setstripe -i0 -c1 $f0
1957
1958         saved=$(do_facet mds1 $LCTL get_param -n lov.*0000*.qos_threshold_rr)
1959         # force QoS allocation policy
1960         do_nodes $mdts $LCTL set_param lov.*.qos_threshold_rr=0%
1961         stack_trap "do_nodes $mdts $LCTL set_param \
1962                 lov.*.qos_threshold_rr=$saved" EXIT
1963         sleep_maxage
1964
1965         # one OST is unavailable, but still have few objects preallocated
1966         stop ost1
1967         stack_trap "start ost1 $(ostdevname 1) $OST_MOUNT_OPTS; \
1968                 rm -rf $f1 $DIR/$tdir*" EXIT
1969
1970         for ((i=0; i < 7; i++)); do
1971                 mkdir $DIR/$tdir$i || error "can't create dir"
1972                 $LFS setstripe -c$((OSTCOUNT-1)) $DIR/$tdir$i ||
1973                         error "can't set striping"
1974         done
1975         for ((i=0; i < 7; i++)); do
1976                 create_and_checktime $DIR/$tdir$i/$tfile 100 &
1977         done
1978         wait
1979 }
1980 run_test 27oo "don't let few threads to reserve too many objects"
1981
1982 test_27p() {
1983         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1984         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1985         remote_mds_nodsh && skip "remote MDS with nodsh"
1986         remote_ost_nodsh && skip "remote OST with nodsh"
1987
1988         reset_enospc
1989         rm -f $DIR/$tdir/$tfile
1990         test_mkdir $DIR/$tdir
1991
1992         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1993         $TRUNCATE $DIR/$tdir/$tfile 80000000 || error "truncate failed"
1994         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
1995
1996         exhaust_precreations 0 0x80000215
1997         echo foo >> $DIR/$tdir/$tfile || error "append failed"
1998         $CHECKSTAT -s 80000004 $DIR/$tdir/$tfile || error "checkstat failed"
1999         $LFS getstripe $DIR/$tdir/$tfile
2000
2001         reset_enospc
2002 }
2003 run_test 27p "append to a truncated file with some full OSTs"
2004
2005 test_27q() {
2006         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2007         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2008         remote_mds_nodsh && skip "remote MDS with nodsh"
2009         remote_ost_nodsh && skip "remote OST with nodsh"
2010
2011         reset_enospc
2012         rm -f $DIR/$tdir/$tfile
2013
2014         mkdir_on_mdt0 $DIR/$tdir
2015         $MCREATE $DIR/$tdir/$tfile || error "mcreate $DIR/$tdir/$tfile failed"
2016         $TRUNCATE $DIR/$tdir/$tfile 80000000 ||
2017                 error "truncate $DIR/$tdir/$tfile failed"
2018         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
2019
2020         exhaust_all_precreations 0x215
2021
2022         echo foo >> $DIR/$tdir/$tfile && error "append succeeded"
2023         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat 2 failed"
2024
2025         reset_enospc
2026 }
2027 run_test 27q "append to truncated file with all OSTs full (should error)"
2028
2029 test_27r() {
2030         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2031         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2032         remote_mds_nodsh && skip "remote MDS with nodsh"
2033         remote_ost_nodsh && skip "remote OST with nodsh"
2034
2035         reset_enospc
2036         rm -f $DIR/$tdir/$tfile
2037         exhaust_precreations 0 0x80000215
2038
2039         $LFS setstripe -i 0 -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
2040
2041         reset_enospc
2042 }
2043 run_test 27r "stripe file with some full OSTs (shouldn't LBUG) ="
2044
2045 test_27s() { # bug 10725
2046         test_mkdir $DIR/$tdir
2047         local stripe_size=$((4096 * 1024 * 1024))       # 2^32
2048         local stripe_count=0
2049         [ $OSTCOUNT -eq 1 ] || stripe_count=2
2050         $LFS setstripe -S $stripe_size -c $stripe_count $DIR/$tdir &&
2051                 error "stripe width >= 2^32 succeeded" || true
2052
2053 }
2054 run_test 27s "lsm_xfersize overflow (should error) (bug 10725)"
2055
2056 test_27t() { # bug 10864
2057         WDIR=$(pwd)
2058         WLFS=$(which lfs)
2059         cd $DIR
2060         touch $tfile
2061         $WLFS getstripe $tfile
2062         cd $WDIR
2063 }
2064 run_test 27t "check that utils parse path correctly"
2065
2066 test_27u() { # bug 4900
2067         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2068         remote_mds_nodsh && skip "remote MDS with nodsh"
2069
2070         local index
2071         local list=$(comma_list $(mdts_nodes))
2072
2073 #define OBD_FAIL_MDS_OSC_PRECREATE      0x139
2074         do_nodes $list $LCTL set_param fail_loc=0x139
2075         test_mkdir -p $DIR/$tdir
2076         stack_trap "simple_cleanup_common 1000"
2077         createmany -o $DIR/$tdir/$tfile 1000
2078         do_nodes $list $LCTL set_param fail_loc=0
2079
2080         TLOG=$TMP/$tfile.getstripe
2081         $LFS getstripe $DIR/$tdir > $TLOG
2082         OBJS=$(awk -vobj=0 '($1 == 0) { obj += 1 } END { print obj; }' $TLOG)
2083         [[ $OBJS -gt 0 ]] &&
2084                 error "$OBJS objects created on OST-0. See $TLOG" ||
2085                 rm -f $TLOG
2086 }
2087 run_test 27u "skip object creation on OSC w/o objects"
2088
2089 test_27v() { # bug 4900
2090         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2091         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2092         remote_mds_nodsh && skip "remote MDS with nodsh"
2093         remote_ost_nodsh && skip "remote OST with nodsh"
2094
2095         exhaust_all_precreations 0x215
2096         reset_enospc
2097
2098         $LFS setstripe -c 1 $DIR/$tdir         # 1 stripe / file
2099
2100         touch $DIR/$tdir/$tfile
2101         #define OBD_FAIL_TGT_DELAY_PRECREATE     0x705
2102         # all except ost1
2103         for (( i=1; i < OSTCOUNT; i++ )); do
2104                 do_facet ost$i lctl set_param fail_loc=0x705
2105         done
2106         local START=`date +%s`
2107         createmany -o $DIR/$tdir/$tfile 32
2108
2109         local FINISH=`date +%s`
2110         local TIMEOUT=`lctl get_param -n timeout`
2111         local PROCESS=$((FINISH - START))
2112         [ $PROCESS -ge $((TIMEOUT / 2)) ] && \
2113                error "$FINISH - $START >= $TIMEOUT / 2"
2114         sleep $((TIMEOUT / 2 - PROCESS))
2115         reset_enospc
2116 }
2117 run_test 27v "skip object creation on slow OST"
2118
2119 test_27w() { # bug 10997
2120         test_mkdir $DIR/$tdir
2121         $LFS setstripe -S 65536 $DIR/$tdir/f0 || error "setstripe failed"
2122         [ $($LFS getstripe -S $DIR/$tdir/f0) -ne 65536 ] &&
2123                 error "stripe size $size != 65536" || true
2124         [ $($LFS getstripe -d $DIR/$tdir | grep -c "stripe_count") -eq 0 ] &&
2125                 error "$LFS getstripe -d $DIR/$tdir no 'stripe_count'" || true
2126 }
2127 run_test 27w "check $LFS setstripe -S and getstrip -d options"
2128
2129 test_27wa() {
2130         [[ $OSTCOUNT -lt 2 ]] &&
2131                 skip_env "skipping multiple stripe count/offset test"
2132
2133         test_mkdir $DIR/$tdir
2134         for i in $(seq 1 $OSTCOUNT); do
2135                 offset=$((i - 1))
2136                 $LFS setstripe -c $i -i $offset $DIR/$tdir/f$i ||
2137                         error "setstripe -c $i -i $offset failed"
2138                 count=$($LFS getstripe -c $DIR/$tdir/f$i)
2139                 index=$($LFS getstripe -i $DIR/$tdir/f$i)
2140                 [ $count -ne $i ] && error "stripe count $count != $i" || true
2141                 [ $index -ne $offset ] &&
2142                         error "stripe offset $index != $offset" || true
2143         done
2144 }
2145 run_test 27wa "check $LFS setstripe -c -i options"
2146
2147 test_27x() {
2148         remote_ost_nodsh && skip "remote OST with nodsh"
2149         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2150         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2151
2152         OFFSET=$(($OSTCOUNT - 1))
2153         OSTIDX=0
2154         local OST=$(ostname_from_index $OSTIDX)
2155
2156         test_mkdir $DIR/$tdir
2157         $LFS setstripe -c 1 $DIR/$tdir  # 1 stripe per file
2158         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 1
2159         sleep_maxage
2160         createmany -o $DIR/$tdir/$tfile $OSTCOUNT
2161         for i in $(seq 0 $OFFSET); do
2162                 [ $($LFS getstripe $DIR/$tdir/$tfile$i | grep -A 10 obdidx |
2163                         awk '{print $1}' | grep -w "$OSTIDX") ] &&
2164                 error "OST0 was degraded but new created file still use it"
2165         done
2166         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 0
2167 }
2168 run_test 27x "create files while OST0 is degraded"
2169
2170 test_27y() {
2171         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2172         remote_mds_nodsh && skip "remote MDS with nodsh"
2173         remote_ost_nodsh && skip "remote OST with nodsh"
2174         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2175
2176         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS $FSNAME-OST0000)
2177         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
2178                 osp.$mdtosc.prealloc_last_id)
2179         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
2180                 osp.$mdtosc.prealloc_next_id)
2181         local fcount=$((last_id - next_id))
2182         [[ $fcount -eq 0 ]] && skip "not enough space on OST0"
2183         [[ $fcount -gt $OSTCOUNT ]] && fcount=$OSTCOUNT
2184
2185         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
2186                          awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
2187         local OST_DEACTIVE_IDX=-1
2188         local OSC
2189         local OSTIDX
2190         local OST
2191
2192         for OSC in $MDS_OSCS; do
2193                 OST=$(osc_to_ost $OSC)
2194                 OSTIDX=$(index_from_ostuuid $OST)
2195                 if [ $OST_DEACTIVE_IDX == -1 ]; then
2196                         OST_DEACTIVE_IDX=$OSTIDX
2197                 fi
2198                 if [ $OSTIDX != $OST_DEACTIVE_IDX ]; then
2199                         echo $OSC "is Deactivated:"
2200                         do_facet $SINGLEMDS lctl --device  %$OSC deactivate
2201                 fi
2202         done
2203
2204         OSTIDX=$(index_from_ostuuid $OST)
2205         test_mkdir $DIR/$tdir
2206         $LFS setstripe -c 1 $DIR/$tdir      # 1 stripe / file
2207
2208         for OSC in $MDS_OSCS; do
2209                 OST=$(osc_to_ost $OSC)
2210                 OSTIDX=$(index_from_ostuuid $OST)
2211                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2212                         echo $OST "is degraded:"
2213                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2214                                                 obdfilter.$OST.degraded=1
2215                 fi
2216         done
2217
2218         sleep_maxage
2219         createmany -o $DIR/$tdir/$tfile $fcount
2220
2221         for OSC in $MDS_OSCS; do
2222                 OST=$(osc_to_ost $OSC)
2223                 OSTIDX=$(index_from_ostuuid $OST)
2224                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2225                         echo $OST "is recovered from degraded:"
2226                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2227                                                 obdfilter.$OST.degraded=0
2228                 else
2229                         do_facet $SINGLEMDS lctl --device %$OSC activate
2230                 fi
2231         done
2232
2233         # all osp devices get activated, hence -1 stripe count restored
2234         local stripe_count=0
2235
2236         # sleep 2*lod_qos_maxage seconds waiting for lod qos to notice osp
2237         # devices get activated.
2238         sleep_maxage
2239         $LFS setstripe -c -1 $DIR/$tfile
2240         stripe_count=$($LFS getstripe -c $DIR/$tfile)
2241         rm -f $DIR/$tfile
2242         [ $stripe_count -ne $OSTCOUNT ] &&
2243                 error "Of $OSTCOUNT OSTs, only $stripe_count is available"
2244         return 0
2245 }
2246 run_test 27y "create files while OST0 is degraded and the rest inactive"
2247
2248 check_seq_oid()
2249 {
2250         log "check file $1"
2251
2252         lmm_count=$($LFS getstripe -c $1)
2253         lmm_seq=$($LFS getstripe -v $1 | awk '/lmm_seq/ { print $2 }')
2254         lmm_oid=$($LFS getstripe -v $1 | awk '/lmm_object_id/ { print $2 }')
2255
2256         local old_ifs="$IFS"
2257         IFS=$'[:]'
2258         fid=($($LFS path2fid $1))
2259         IFS="$old_ifs"
2260
2261         log "FID seq ${fid[1]}, oid ${fid[2]} ver ${fid[3]}"
2262         log "LOV seq $lmm_seq, oid $lmm_oid, count: $lmm_count"
2263
2264         # compare lmm_seq and lu_fid->f_seq
2265         [ $lmm_seq = ${fid[1]} ] || { error "SEQ mismatch"; return 1; }
2266         # compare lmm_object_id and lu_fid->oid
2267         [ $lmm_oid = ${fid[2]} ] || { error "OID mismatch"; return 2; }
2268
2269         # check the trusted.fid attribute of the OST objects of the file
2270         local have_obdidx=false
2271         local stripe_nr=0
2272         $LFS getstripe $1 | while read obdidx oid hex seq; do
2273                 # skip lines up to and including "obdidx"
2274                 [ -z "$obdidx" ] && break
2275                 [ "$obdidx" = "obdidx" ] && have_obdidx=true && continue
2276                 $have_obdidx || continue
2277
2278                 local ost=$((obdidx + 1))
2279                 local dev=$(ostdevname $ost)
2280                 local oid_hex
2281
2282                 log "want: stripe:$stripe_nr ost:$obdidx oid:$oid/$hex seq:$seq"
2283
2284                 seq=$(echo $seq | sed -e "s/^0x//g")
2285                 if [ $seq == 0 ] || [ $(facet_fstype ost$ost) == zfs ]; then
2286                         oid_hex=$(echo $oid)
2287                 else
2288                         oid_hex=$(echo $hex | sed -e "s/^0x//g")
2289                 fi
2290                 local obj_file="O/$seq/d$((oid %32))/$oid_hex"
2291
2292                 local ff=""
2293                 #
2294                 # Don't unmount/remount the OSTs if we don't need to do that.
2295                 # LU-2577 changes filter_fid to be smaller, so debugfs needs
2296                 # update too, until that use mount/ll_decode_filter_fid/mount.
2297                 # Re-enable when debugfs will understand new filter_fid.
2298                 #
2299                 if [ $(facet_fstype ost$ost) == ldiskfs ]; then
2300                         ff=$(do_facet ost$ost "$DEBUGFS -c -R 'stat $obj_file' \
2301                                 $dev 2>/dev/null" | grep "parent=")
2302                 fi
2303                 if [ -z "$ff" ]; then
2304                         stop ost$ost
2305                         mount_fstype ost$ost
2306                         ff=$(do_facet ost$ost $LL_DECODE_FILTER_FID \
2307                                 $(facet_mntpt ost$ost)/$obj_file)
2308                         unmount_fstype ost$ost
2309                         start ost$ost $dev $OST_MOUNT_OPTS
2310                         clients_up
2311                 fi
2312
2313                 [ -z "$ff" ] && error "$obj_file: no filter_fid info"
2314
2315                 echo "$ff" | sed -e 's#.*objid=#got: objid=#'
2316
2317                 # /mnt/O/0/d23/23: objid=23 seq=0 parent=[0x200000400:0x1e:0x1]
2318                 # fid: objid=23 seq=0 parent=[0x200000400:0x1e:0x0] stripe=1
2319                 #
2320                 # fid: parent=[0x200000400:0x1e:0x0] stripe=1 stripe_count=2 \
2321                 #       stripe_size=1048576 component_id=1 component_start=0 \
2322                 #       component_end=33554432
2323                 local ff_parent=$(sed -e 's/.*parent=.//' <<<$ff)
2324                 local ff_pseq=$(cut -d: -f1 <<<$ff_parent)
2325                 local ff_poid=$(cut -d: -f2 <<<$ff_parent)
2326                 local ff_pstripe
2327                 if grep -q 'stripe=' <<<$ff; then
2328                         ff_pstripe=$(sed -e 's/.*stripe=//' -e 's/ .*//' <<<$ff)
2329                 else
2330                         # $LL_DECODE_FILTER_FID does not print "stripe="; look
2331                         # into f_ver in this case.  See comment on ff_parent.
2332                         ff_pstripe=$(cut -d: -f3 <<<$ff_parent | sed -e 's/]//')
2333                 fi
2334
2335                 # compare lmm_seq and filter_fid->ff_parent.f_seq
2336                 [ $ff_pseq = $lmm_seq ] ||
2337                         error "FF parent SEQ $ff_pseq != $lmm_seq"
2338                 # compare lmm_object_id and filter_fid->ff_parent.f_oid
2339                 [ $ff_poid = $lmm_oid ] ||
2340                         error "FF parent OID $ff_poid != $lmm_oid"
2341                 (($ff_pstripe == $stripe_nr)) ||
2342                         error "FF stripe $ff_pstripe != $stripe_nr"
2343
2344                 stripe_nr=$((stripe_nr + 1))
2345                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2346                         continue
2347                 if grep -q 'stripe_count=' <<<$ff; then
2348                         local ff_scnt=$(sed -e 's/.*stripe_count=//' \
2349                                             -e 's/ .*//' <<<$ff)
2350                         [ $lmm_count = $ff_scnt ] ||
2351                                 error "FF stripe count $lmm_count != $ff_scnt"
2352                 fi
2353         done
2354 }
2355
2356 test_27z() {
2357         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2358         remote_ost_nodsh && skip "remote OST with nodsh"
2359
2360         test_mkdir $DIR/$tdir
2361         $LFS setstripe -c 1 -i 0 -S 64k $DIR/$tdir/$tfile-1 ||
2362                 { error "setstripe -c -1 failed"; return 1; }
2363         # We need to send a write to every object to get parent FID info set.
2364         # This _should_ also work for setattr, but does not currently.
2365         # touch $DIR/$tdir/$tfile-1 ||
2366         dd if=/dev/zero of=$DIR/$tdir/$tfile-1 bs=1M count=1 ||
2367                 { error "dd $tfile-1 failed"; return 2; }
2368         $LFS setstripe -c -1 -i $((OSTCOUNT - 1)) -S 1M $DIR/$tdir/$tfile-2 ||
2369                 { error "setstripe -c -1 failed"; return 3; }
2370         dd if=/dev/zero of=$DIR/$tdir/$tfile-2 bs=1M count=$OSTCOUNT ||
2371                 { error "dd $tfile-2 failed"; return 4; }
2372
2373         # make sure write RPCs have been sent to OSTs
2374         sync; sleep 5; sync
2375
2376         check_seq_oid $DIR/$tdir/$tfile-1 || return 5
2377         check_seq_oid $DIR/$tdir/$tfile-2 || return 6
2378 }
2379 run_test 27z "check SEQ/OID on the MDT and OST filesystems"
2380
2381 test_27A() { # b=19102
2382         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2383
2384         save_layout_restore_at_exit $MOUNT
2385         $LFS setstripe -c 0 -i -1 -S 0 $MOUNT
2386         wait_update $HOSTNAME "$LFS getstripe -c $MOUNT | sed 's/  *//g'" "1" 20 ||
2387                 error "stripe count $($LFS getstripe -c $MOUNT) != 1"
2388         local default_size=$($LFS getstripe -S $MOUNT)
2389         local default_offset=$($LFS getstripe -i $MOUNT)
2390         local dsize=$(do_facet $SINGLEMDS \
2391                 "$LCTL get_param -n lod.$(facet_svc $SINGLEMDS)*.stripesize")
2392         [ $default_size -eq $dsize ] ||
2393                 error "stripe size $default_size != $dsize"
2394         [ $default_offset -eq -1 ] ||
2395                 error "stripe offset $default_offset != -1"
2396 }
2397 run_test 27A "check filesystem-wide default LOV EA values"
2398
2399 test_27B() { # LU-2523
2400         test_mkdir $DIR/$tdir
2401         rm -f $DIR/$tdir/f0 $DIR/$tdir/f1
2402         touch $DIR/$tdir/f0
2403         # open f1 with O_LOV_DELAY_CREATE
2404         # rename f0 onto f1
2405         # call setstripe ioctl on open file descriptor for f1
2406         # close
2407         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:nB1c \
2408                 $DIR/$tdir/f0
2409
2410         rm -f $DIR/$tdir/f1
2411         # open f1 with O_LOV_DELAY_CREATE
2412         # unlink f1
2413         # call setstripe ioctl on open file descriptor for f1
2414         # close
2415         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:uB1c
2416
2417         # Allow multiop to fail in imitation of NFS's busted semantics.
2418         true
2419 }
2420 run_test 27B "call setstripe on open unlinked file/rename victim"
2421
2422 # 27C family tests full striping and overstriping
2423 test_27Ca() { #LU-2871
2424         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2425
2426         declare -a ost_idx
2427         local index
2428         local found
2429         local i
2430         local j
2431
2432         test_mkdir $DIR/$tdir
2433         cd $DIR/$tdir
2434         for i in $(seq 0 $((OSTCOUNT - 1))); do
2435                 # set stripe across all OSTs starting from OST$i
2436                 $LFS setstripe -i $i -c -1 $tfile$i
2437                 # get striping information
2438                 ost_idx=($($LFS getstripe $tfile$i |
2439                          tail -n $((OSTCOUNT + 1)) | awk '{print $1}'))
2440                 echo "OST Index: ${ost_idx[*]}"
2441
2442                 # check the layout
2443                 [ ${#ost_idx[@]} -eq $OSTCOUNT ] ||
2444                         error "${#ost_idx[@]} != $OSTCOUNT"
2445
2446                 for index in $(seq 0 $((OSTCOUNT - 1))); do
2447                         found=0
2448                         for j in "${ost_idx[@]}"; do
2449                                 if [ $index -eq $j ]; then
2450                                         found=1
2451                                         break
2452                                 fi
2453                         done
2454                         [ $found = 1 ] ||
2455                                 error "Can not find $index in ${ost_idx[*]}"
2456                 done
2457         done
2458 }
2459 run_test 27Ca "check full striping across all OSTs"
2460
2461 test_27Cb() {
2462         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2463                 skip "server does not support overstriping"
2464         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2465                 skip_env "too many osts, skipping"
2466
2467         test_mkdir -p $DIR/$tdir
2468         local setcount=$(($OSTCOUNT * 2))
2469         [ $setcount -lt 160 ] || large_xattr_enabled ||
2470                 skip_env "ea_inode feature disabled"
2471
2472         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2473                 error "setstripe failed"
2474
2475         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2476         [ $count -eq $setcount ] ||
2477                 error "stripe count $count, should be $setcount"
2478
2479         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2480                 error "overstriped should be set in pattern"
2481
2482         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2483                 error "dd failed"
2484 }
2485 run_test 27Cb "more stripes than OSTs with -C"
2486
2487 test_27Cc() {
2488         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2489                 skip "server does not support overstriping"
2490         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2491
2492         test_mkdir -p $DIR/$tdir
2493         local setcount=$(($OSTCOUNT - 1))
2494
2495         [ $setcount -lt 160 ] || large_xattr_enabled ||
2496                 skip_env "ea_inode feature disabled"
2497
2498         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2499                 error "setstripe failed"
2500
2501         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2502         [ $count -eq $setcount ] ||
2503                 error "stripe count $count, should be $setcount"
2504
2505         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" &&
2506                 error "overstriped should not be set in pattern"
2507
2508         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2509                 error "dd failed"
2510 }
2511 run_test 27Cc "fewer stripes than OSTs does not set overstriping"
2512
2513 test_27Cd() {
2514         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2515                 skip "server does not support overstriping"
2516         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2517         large_xattr_enabled || skip_env "ea_inode feature disabled"
2518
2519         force_new_seq_all
2520
2521         test_mkdir -p $DIR/$tdir
2522         local setcount=$LOV_MAX_STRIPE_COUNT
2523
2524         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2525                 error "setstripe failed"
2526
2527         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2528         [ $count -eq $setcount ] ||
2529                 error "stripe count $count, should be $setcount"
2530
2531         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2532                 error "overstriped should be set in pattern"
2533
2534         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2535                 error "dd failed"
2536
2537         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2538 }
2539 run_test 27Cd "test maximum stripe count"
2540
2541 test_27Ce() {
2542         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2543                 skip "server does not support overstriping"
2544         test_mkdir -p $DIR/$tdir
2545
2546         pool_add $TESTNAME || error "Pool creation failed"
2547         pool_add_targets $TESTNAME 0 || error "pool_add_targets failed"
2548
2549         local setcount=8
2550
2551         $LFS setstripe  -C $setcount -p "$TESTNAME" $DIR/$tdir/$tfile ||
2552                 error "setstripe failed"
2553
2554         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2555         [ $count -eq $setcount ] ||
2556                 error "stripe count $count, should be $setcount"
2557
2558         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2559                 error "overstriped should be set in pattern"
2560
2561         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2562                 error "dd failed"
2563
2564         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2565 }
2566 run_test 27Ce "test pool with overstriping"
2567
2568 test_27Cf() {
2569         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2570                 skip "server does not support overstriping"
2571         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2572                 skip_env "too many osts, skipping"
2573
2574         test_mkdir -p $DIR/$tdir
2575
2576         local setcount=$(($OSTCOUNT * 2))
2577         [ $setcount -lt 160 ] || large_xattr_enabled ||
2578                 skip_env "ea_inode feature disabled"
2579
2580         $LFS setstripe  -C $setcount $DIR/$tdir/ ||
2581                 error "setstripe failed"
2582
2583         echo 1 > $DIR/$tdir/$tfile
2584
2585         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2586         [ $count -eq $setcount ] ||
2587                 error "stripe count $count, should be $setcount"
2588
2589         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2590                 error "overstriped should be set in pattern"
2591
2592         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2593                 error "dd failed"
2594
2595         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2596 }
2597 run_test 27Cf "test default inheritance with overstriping"
2598
2599 test_27Cg() {
2600         $LFS setstripe -o 0,$OSTCOUNT $DIR/$tfile
2601         [ $? -ne 0 ] || error "must be an error for not existent OST#"
2602 }
2603 run_test 27Cg "test setstripe with wrong OST idx"
2604
2605 test_27D() {
2606         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2607         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2608         remote_mds_nodsh && skip "remote MDS with nodsh"
2609
2610         local POOL=${POOL:-testpool}
2611         local first_ost=0
2612         local last_ost=$(($OSTCOUNT - 1))
2613         local ost_step=1
2614         local ost_list=$(seq $first_ost $ost_step $last_ost)
2615         local ost_range="$first_ost $last_ost $ost_step"
2616
2617         test_mkdir $DIR/$tdir
2618         pool_add $POOL || error "pool_add failed"
2619         pool_add_targets $POOL $ost_range || error "pool_add_targets failed"
2620
2621         local skip27D
2622         [ $MDS1_VERSION -lt $(version_code 2.8.55) ] &&
2623                 skip27D+="-s 29"
2624         [ $MDS1_VERSION -lt $(version_code 2.9.55) ] ||
2625                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2626                         skip27D+=" -s 30,31"
2627         [[ ! $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ||
2628           $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2629                 skip27D+=" -s 32,33"
2630         [[ $MDS_VERSION -lt $(version_code $SEL_VER) ]] &&
2631                 skip27D+=" -s 34"
2632         llapi_layout_test -d$DIR/$tdir -p$POOL -o$OSTCOUNT $skip27D ||
2633                 error "llapi_layout_test failed"
2634
2635         destroy_test_pools || error "destroy test pools failed"
2636 }
2637 run_test 27D "validate llapi_layout API"
2638
2639 # Verify that default_easize is increased from its initial value after
2640 # accessing a widely striped file.
2641 test_27E() {
2642         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2643         [ $CLIENT_VERSION -lt $(version_code 2.5.57) ] &&
2644                 skip "client does not have LU-3338 fix"
2645
2646         # 72 bytes is the minimum space required to store striping
2647         # information for a file striped across one OST:
2648         # (sizeof(struct lov_user_md_v3) +
2649         #  sizeof(struct lov_user_ost_data_v1))
2650         local min_easize=72
2651         $LCTL set_param -n llite.*.default_easize $min_easize ||
2652                 error "lctl set_param failed"
2653         local easize=$($LCTL get_param -n llite.*.default_easize)
2654
2655         [ $easize -eq $min_easize ] ||
2656                 error "failed to set default_easize"
2657
2658         $LFS setstripe -c $OSTCOUNT $DIR/$tfile ||
2659                 error "setstripe failed"
2660         # In order to ensure stat() call actually talks to MDS we need to
2661         # do something drastic to this file to shake off all lock, e.g.
2662         # rename it (kills lookup lock forcing cache cleaning)
2663         mv $DIR/$tfile $DIR/${tfile}-1
2664         ls -l $DIR/${tfile}-1
2665         rm $DIR/${tfile}-1
2666
2667         easize=$($LCTL get_param -n llite.*.default_easize)
2668
2669         [ $easize -gt $min_easize ] ||
2670                 error "default_easize not updated"
2671 }
2672 run_test 27E "check that default extended attribute size properly increases"
2673
2674 test_27F() { # LU-5346/LU-7975
2675         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2676         [[ $OSTCOUNT -lt 2 ]] && skip "needs >= 2 OSTs"
2677         [[ $MDS1_VERSION -lt $(version_code 2.8.51) ]] &&
2678                 skip "Need MDS version at least 2.8.51"
2679         remote_ost_nodsh && skip "remote OST with nodsh"
2680
2681         test_mkdir $DIR/$tdir
2682         rm -f $DIR/$tdir/f0
2683         $LFS setstripe -c 2 $DIR/$tdir
2684
2685         # stop all OSTs to reproduce situation for LU-7975 ticket
2686         for num in $(seq $OSTCOUNT); do
2687                 stop ost$num
2688         done
2689
2690         # open/create f0 with O_LOV_DELAY_CREATE
2691         # truncate f0 to a non-0 size
2692         # close
2693         multiop $DIR/$tdir/f0 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T1050000c
2694
2695         $CHECKSTAT -s 1050000 $DIR/$tdir/f0 || error "checkstat failed"
2696         # open/write it again to force delayed layout creation
2697         cat /etc/hosts > $DIR/$tdir/f0 &
2698         catpid=$!
2699
2700         # restart OSTs
2701         for num in $(seq $OSTCOUNT); do
2702                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS ||
2703                         error "ost$num failed to start"
2704         done
2705
2706         wait $catpid || error "cat failed"
2707
2708         cmp /etc/hosts $DIR/$tdir/f0 || error "cmp failed"
2709         [[ $($LFS getstripe -c $DIR/$tdir/f0) == 2 ]] ||
2710                 error "wrong stripecount"
2711
2712 }
2713 run_test 27F "Client resend delayed layout creation with non-zero size"
2714
2715 test_27G() { #LU-10629
2716         [ $MDS1_VERSION -lt $(version_code 2.11.51) ] &&
2717                 skip "Need MDS version at least 2.11.51"
2718         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2719         remote_mds_nodsh && skip "remote MDS with nodsh"
2720         local POOL=${POOL:-testpool}
2721         local ostrange="0 0 1"
2722
2723         test_mkdir $DIR/$tdir
2724         touch $DIR/$tdir/$tfile.nopool
2725         pool_add $POOL || error "pool_add failed"
2726         pool_add_targets $POOL $ostrange || error "pool_add_targets failed"
2727         $LFS setstripe -p $POOL $DIR/$tdir
2728
2729         local pool=$($LFS getstripe -p $DIR/$tdir)
2730
2731         [ "$pool" = "$POOL" ] || error "Striping failed got '$pool' not '$POOL'"
2732         touch $DIR/$tdir/$tfile.default
2733         $LFS setstripe -E 1M --pool $POOL -c 1 -E eof -c 1 $DIR/$tdir/$tfile.pfl
2734         $LFS find $DIR/$tdir -type f --pool $POOL
2735         local found=$($LFS find $DIR/$tdir -type f --pool $POOL | wc -l)
2736         [[ "$found" == "2" ]] ||
2737                 error "found $found != 2 files in '$DIR/$tdir' in '$POOL'"
2738
2739         $LFS setstripe -d $DIR/$tdir
2740
2741         pool=$($LFS getstripe -p -d $DIR/$tdir)
2742
2743         [[ "$pool" != "$POOL" ]] || error "$DIR/$tdir is still '$pool'"
2744 }
2745 run_test 27G "Clear OST pool from stripe"
2746
2747 test_27H() {
2748         [[ $MDS1_VERSION -le $(version_code 2.11.54) ]] &&
2749                 skip "Need MDS version newer than 2.11.54"
2750         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
2751         test_mkdir $DIR/$tdir
2752         $LFS setstripe -o 0 -o 2 $DIR/$tdir || error "setstripe failed"
2753         touch $DIR/$tdir/$tfile
2754         $LFS getstripe -c $DIR/$tdir/$tfile
2755         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
2756                 error "two-stripe file doesn't have two stripes"
2757
2758         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
2759         $LFS getstripe -y $DIR/$tdir/$tfile
2760         (( $($LFS getstripe -y $DIR/$tdir/$tfile |
2761              egrep -c "l_ost_idx: [02]$") == "2" )) ||
2762                 error "expected l_ost_idx: [02]$ not matched"
2763
2764         # make sure ost list has been cleared
2765         local stripesize=$($LFS getstripe -S $DIR/$tdir)
2766         $LFS setstripe -S $((stripesize * 4)) -i 1 \
2767                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
2768         touch $DIR/$tdir/f3
2769         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
2770 }
2771 run_test 27H "Set specific OSTs stripe"
2772
2773 test_27I() {
2774         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2775         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2776         [[ $MDS1_VERSION -gt $(version_code 2.12.52) ]] ||
2777                 skip "Need MDS version newer than 2.12.52"
2778         local pool=$TESTNAME
2779         local ostrange="1 1 1"
2780
2781         save_layout_restore_at_exit $MOUNT
2782         $LFS setstripe -c 2 -i 0 $MOUNT
2783         pool_add $pool || error "pool_add failed"
2784         pool_add_targets $pool $ostrange ||
2785                 error "pool_add_targets failed"
2786         test_mkdir $DIR/$tdir
2787         $LFS setstripe -p $pool $DIR/$tdir
2788         $MULTIOP $DIR/$tdir/$tfile Oc || error "multiop failed"
2789         $LFS getstripe $DIR/$tdir/$tfile
2790 }
2791 run_test 27I "check that root dir striping does not break parent dir one"
2792
2793 test_27J() {
2794         [[ $MDS1_VERSION -le $(version_code 2.12.51) ]] &&
2795                 skip "Need MDS version newer than 2.12.51"
2796
2797         test_mkdir $DIR/$tdir
2798         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2799         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2800
2801         # create foreign file (raw way)
2802         ! $LFS setstripe --flags 0xda08 $DIR/$tdir/$tfile ||
2803                 error "creating $tfile w/ hex flags w/o --foreign should fail"
2804
2805         ! $LFS setstripe --foreign --flags foo \
2806                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tfile ||
2807                         error "creating $tfile with '--flags foo' should fail"
2808
2809         ! $LFS setstripe --foreign --flags 0xffffffff \
2810                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tfile ||
2811                         error "creating $tfile w/ 0xffffffff flags should fail"
2812
2813         create_foreign_file -f $DIR/$tdir/$tfile -x "${uuid1}@${uuid2}" \
2814                 -t 1 -F 0xda08 || error "create_foreign_file failed"
2815
2816         # verify foreign file (raw way)
2817         parse_foreign_file -f $DIR/$tdir/$tfile |
2818                 grep "lov_foreign_magic: 0x0BD70BD0" ||
2819                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign magic"
2820         parse_foreign_file -f $DIR/$tdir/$tfile | grep "lov_xattr_size: 89" ||
2821                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2822         parse_foreign_file -f $DIR/$tdir/$tfile |
2823                 grep "lov_foreign_size: 73" ||
2824                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2825         parse_foreign_file -f $DIR/$tdir/$tfile |
2826                 grep "lov_foreign_type: 1" ||
2827                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign type"
2828         parse_foreign_file -f $DIR/$tdir/$tfile |
2829                 grep "lov_foreign_flags: 0x0000DA08" ||
2830                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign flags"
2831         local lov=$(parse_foreign_file -f $DIR/$tdir/$tfile |
2832                 grep "lov_foreign_value: 0x" |
2833                 sed -e 's/lov_foreign_value: 0x//')
2834         local lov2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160)
2835         [[ $lov = ${lov2// /} ]] ||
2836                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign value"
2837
2838         # create foreign file (lfs + API)
2839         $LFS setstripe --foreign=none --flags 0xda08 \
2840                 -x "${uuid1}@${uuid2}" $DIR/$tdir/${tfile}2 ||
2841                 error "$DIR/$tdir/${tfile}2: create failed"
2842
2843         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2844                 grep "lfm_magic:.*0x0BD70BD0" ||
2845                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign magic"
2846         # lfm_length is LOV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2847         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_length:.*73" ||
2848                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign size"
2849         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_type:.*none" ||
2850                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign type"
2851         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2852                 grep "lfm_flags:.*0x0000DA08" ||
2853                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign flags"
2854         $LFS getstripe $DIR/$tdir/${tfile}2 |
2855                 grep "lfm_value:.*${uuid1}@${uuid2}" ||
2856                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign value"
2857
2858         # modify striping should fail
2859         $LFS setstripe -c 2 $DIR/$tdir/$tfile &&
2860                 error "$DIR/$tdir/$tfile: setstripe should fail"
2861         $LFS setstripe -c 2 $DIR/$tdir/${tfile}2 &&
2862                 error "$DIR/$tdir/${tfile}2: setstripe should fail"
2863
2864         # R/W should fail
2865         cat $DIR/$tdir/$tfile && error "$DIR/$tdir/$tfile: read should fail"
2866         cat $DIR/$tdir/${tfile}2 &&
2867                 error "$DIR/$tdir/${tfile}2: read should fail"
2868         cat /etc/passwd > $DIR/$tdir/$tfile &&
2869                 error "$DIR/$tdir/$tfile: write should fail"
2870         cat /etc/passwd > $DIR/$tdir/${tfile}2 &&
2871                 error "$DIR/$tdir/${tfile}2: write should fail"
2872
2873         # chmod should work
2874         chmod 222 $DIR/$tdir/$tfile ||
2875                 error "$DIR/$tdir/$tfile: chmod failed"
2876         chmod 222 $DIR/$tdir/${tfile}2 ||
2877                 error "$DIR/$tdir/${tfile}2: chmod failed"
2878
2879         # chown should work
2880         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tfile ||
2881                 error "$DIR/$tdir/$tfile: chown failed"
2882         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tfile}2 ||
2883                 error "$DIR/$tdir/${tfile}2: chown failed"
2884
2885         # rename should work
2886         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}.new ||
2887                 error "$DIR/$tdir/$tfile: rename of foreign file has failed"
2888         mv $DIR/$tdir/${tfile}2 $DIR/$tdir/${tfile}2.new ||
2889                 error "$DIR/$tdir/${tfile}2: rename of foreign file has failed"
2890
2891         #remove foreign file
2892         rm $DIR/$tdir/${tfile}.new ||
2893                 error "$DIR/$tdir/${tfile}.new: remove of foreign file has failed"
2894         rm $DIR/$tdir/${tfile}2.new ||
2895                 error "$DIR/$tdir/${tfile}2.new: remove of foreign file has failed"
2896 }
2897 run_test 27J "basic ops on file with foreign LOV"
2898
2899 test_27K() {
2900         [[ $MDS1_VERSION -le $(version_code 2.12.49) ]] &&
2901                 skip "Need MDS version newer than 2.12.49"
2902
2903         test_mkdir $DIR/$tdir
2904         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2905         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2906
2907         # create foreign dir (raw way)
2908         ! $LFS setdirstripe --flags 0xda08 $DIR/$tdir/$tdir ||
2909                 error "creating $tdir w/ hex flags w/o --foreign should fail"
2910
2911         ! $LFS setdirstripe --foreign --flags foo \
2912                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tdir ||
2913                         error "creating $tdir with '--flags foo' should fail"
2914
2915         ! $LFS setdirstripe --foreign --flags 0xffffffff \
2916                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tdir ||
2917                         error "creating $tdir w/ 0xffffffff flags should fail"
2918
2919         create_foreign_dir -d $DIR/$tdir/$tdir -x "${uuid1}@${uuid2}" -t 1 ||
2920                 error "create_foreign_dir FAILED"
2921
2922         # verify foreign dir (raw way)
2923         parse_foreign_dir -d $DIR/$tdir/$tdir |
2924                 grep "lmv_foreign_magic:.*0xcd50cd0" ||
2925                 error "$DIR/$tdir/$tfile: invalid LMV EA magic"
2926         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_xattr_size:.*89$" ||
2927                 error "$DIR/$tdir/$tdir: invalid LMV EA size"
2928         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_foreign_type: 1$" ||
2929                 error "$DIR/$tdir/$tdir: invalid LMV EA type"
2930         parse_foreign_dir -d $DIR/$tdir/$tdir |
2931                 grep "lmv_foreign_flags: 55813$" ||
2932                 error "$DIR/$tdir/$tdir: invalid LMV EA flags"
2933         local lmv=$(parse_foreign_dir -d $DIR/$tdir/$tdir |
2934                 grep "lmv_foreign_value: 0x" |
2935                 sed 's/lmv_foreign_value: 0x//')
2936         local lmv2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160 |
2937                 sed 's/ //g')
2938         [[ $lmv == $lmv2 ]] || error "$DIR/$tdir/$tdir: invalid LMV EA value"
2939
2940         # create foreign dir (lfs + API)
2941         $LFS mkdir --foreign=none --xattr="${uuid1}@${uuid2}" --flags=0xda05 \
2942                 $DIR/$tdir/${tdir}2 ||
2943                 error "$DIR/$tdir/${tdir}2: create failed"
2944
2945         $LFS getdirstripe -v $DIR/$tdir/${tdir}2
2946
2947         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2948                 grep "lfm_magic:.*0x0CD50CD0" ||
2949                 error "$DIR/$tdir/${tdir}2: invalid LMV EA magic"
2950         # lfm_length is LMV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2951         # - sizeof(lfm_type) - sizeof(lfm_flags)
2952         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_length:.*73" ||
2953                 error "$DIR/$tdir/${tdir}2: invalid LMV EA size"
2954         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_type:.*none" ||
2955                 error "$DIR/$tdir/${tdir}2: invalid LMV EA type"
2956         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2957                 grep "lfm_flags:.*0x0000DA05" ||
2958                 error "$DIR/$tdir/${tdir}2: invalid LMV EA flags"
2959         $LFS getdirstripe $DIR/$tdir/${tdir}2 |
2960                 grep "lfm_value.*${uuid1}@${uuid2}" ||
2961                 error "$DIR/$tdir/${tdir}2: invalid LMV EA value"
2962
2963         # file create in dir should fail
2964         touch $DIR/$tdir/$tdir/$tfile && error "$DIR/$tdir: file create should fail"
2965         touch $DIR/$tdir/${tdir}2/$tfile &&
2966                 error "$DIR/${tdir}2: file create should fail"
2967
2968         # chmod should work
2969         chmod 777 $DIR/$tdir/$tdir ||
2970                 error "$DIR/$tdir: chmod failed"
2971         chmod 777 $DIR/$tdir/${tdir}2 ||
2972                 error "$DIR/${tdir}2: chmod failed"
2973
2974         # chown should work
2975         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tdir ||
2976                 error "$DIR/$tdir: chown failed"
2977         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tdir}2 ||
2978                 error "$DIR/${tdir}2: chown failed"
2979
2980         # rename should work
2981         mv $DIR/$tdir/$tdir $DIR/$tdir/${tdir}.new ||
2982                 error "$DIR/$tdir/$tdir: rename of foreign dir has failed"
2983         mv $DIR/$tdir/${tdir}2 $DIR/$tdir/${tdir}2.new ||
2984                 error "$DIR/$tdir/${tdir}2: rename of foreign dir has failed"
2985
2986         #remove foreign dir
2987         rmdir $DIR/$tdir/${tdir}.new ||
2988                 error "$DIR/$tdir/${tdir}.new: remove of foreign dir has failed"
2989         rmdir $DIR/$tdir/${tdir}2.new ||
2990                 error "$DIR/$tdir/${tdir}2.new: remove of foreign dir has failed"
2991 }
2992 run_test 27K "basic ops on dir with foreign LMV"
2993
2994 test_27L() {
2995         remote_mds_nodsh && skip "remote MDS with nodsh"
2996
2997         local POOL=${POOL:-$TESTNAME}
2998
2999         pool_add $POOL || error "pool_add failed"
3000
3001         lfs pool_list $MOUNT | grep -Fx "${FSNAME}.${POOL}" ||
3002                  error "pool_list does not contain ${FSNAME}.${POOL}:" \
3003                        "$(lfs pool_list $MOUNT | grep -F "${POOL}")"
3004 }
3005 run_test 27L "lfs pool_list gives correct pool name"
3006
3007 test_27M() {
3008         [[ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.12.57) ]] &&
3009                 skip "Need MDS version >= than 2.12.57"
3010         remote_mds_nodsh && skip "remote MDS with nodsh"
3011         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
3012
3013         # Set default striping on directory
3014         local setcount=4
3015         local stripe_opt
3016         local mdts=$(comma_list $(mdts_nodes))
3017
3018         # if we run against a 2.12 server which lacks overstring support
3019         # then the connect_flag will not report overstriping, even if client
3020         # is 2.14+
3021         if [[ $($LCTL get_param mdc.*.connect_flags) =~ overstriping ]]; then
3022                 stripe_opt="-C $setcount"
3023         elif (( $OSTCOUNT >= $setcount )); then
3024                 stripe_opt="-c $setcount"
3025         else
3026                 skip "server does not support overstriping"
3027         fi
3028
3029         test_mkdir $DIR/$tdir
3030
3031         # Validate existing append_* params and ensure restore
3032         local pool=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_pool)
3033         [[ "$pool" == "" ]] || error "expected append_pool == '', got '$pool'"
3034         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_pool=none"
3035
3036         local orig_count=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_stripe_count)
3037         ((orig_count == 1)) || error "expected append_stripe_count == 1, got $orig_count"
3038         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=1"
3039
3040         $LFS setstripe $stripe_opt $DIR/$tdir
3041
3042         echo 1 > $DIR/$tdir/${tfile}.1
3043         local count=$($LFS getstripe -c $DIR/$tdir/${tfile}.1)
3044         [ $count -eq $setcount ] ||
3045                 error "(1) stripe count $count, should be $setcount"
3046
3047         local appendcount=$orig_count
3048         echo 1 >> $DIR/$tdir/${tfile}.2_append
3049         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.2_append)
3050         [ $count -eq $appendcount ] ||
3051                 error "(2)stripe count $count, should be $appendcount for append"
3052
3053         # Disable O_APPEND striping, verify it works
3054         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
3055
3056         # Should now get the default striping, which is 4
3057         setcount=4
3058         echo 1 >> $DIR/$tdir/${tfile}.3_append
3059         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.3_append)
3060         [ $count -eq $setcount ] ||
3061                 error "(3) stripe count $count, should be $setcount"
3062
3063         # Try changing the stripe count for append files
3064         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=2
3065
3066         # Append striping is now 2 (directory default is still 4)
3067         appendcount=2
3068         echo 1 >> $DIR/$tdir/${tfile}.4_append
3069         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.4_append)
3070         [ $count -eq $appendcount ] ||
3071                 error "(4) stripe count $count, should be $appendcount for append"
3072
3073         # Test append stripe count of -1
3074         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=-1
3075         appendcount=$OSTCOUNT
3076         echo 1 >> $DIR/$tdir/${tfile}.5
3077         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.5)
3078         [ $count -eq $appendcount ] ||
3079                 error "(5) stripe count $count, should be $appendcount for append"
3080
3081         # Set append striping back to default of 1
3082         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=1
3083
3084         # Try a new default striping, PFL + DOM
3085         $LFS setstripe -L mdt -E 1M -E -1 -c 2 $DIR/$tdir
3086
3087         # Create normal DOM file, DOM returns stripe count == 0
3088         setcount=0
3089         touch $DIR/$tdir/${tfile}.6
3090         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.6)
3091         [ $count -eq $setcount ] ||
3092                 error "(6) stripe count $count, should be $setcount"
3093
3094         # Show
3095         appendcount=1
3096         echo 1 >> $DIR/$tdir/${tfile}.7_append
3097         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.7_append)
3098         [ $count -eq $appendcount ] ||
3099                 error "(7) stripe count $count, should be $appendcount for append"
3100
3101         # Clean up DOM layout
3102         $LFS setstripe -d $DIR/$tdir
3103
3104         save_layout_restore_at_exit $MOUNT
3105         # Now test that append striping works when layout is from root
3106         $LFS setstripe -c 2 $MOUNT
3107         # Make a special directory for this
3108         mkdir $DIR/${tdir}/${tdir}.2
3109
3110         # Verify for normal file
3111         setcount=2
3112         echo 1 > $DIR/${tdir}/${tdir}.2/${tfile}.8
3113         count=$($LFS getstripe -c $DIR/$tdir/${tdir}.2/${tfile}.8)
3114         [ $count -eq $setcount ] ||
3115                 error "(8) stripe count $count, should be $setcount"
3116
3117         appendcount=1
3118         echo 1 >> $DIR/${tdir}/${tdir}.2/${tfile}.9_append
3119         count=$($LFS getstripe -c $DIR/${tdir}/${tdir}.2/${tfile}.9_append)
3120         [ $count -eq $appendcount ] ||
3121                 error "(9) stripe count $count, should be $appendcount for append"
3122
3123         # Now test O_APPEND striping with pools
3124         pool_add $TESTNAME || error "pool creation failed"
3125         pool_add_targets $TESTNAME 0 1 || error "Pool add targets failed"
3126         do_nodes $mdts $LCTL set_param mdd.*.append_pool="$TESTNAME"
3127
3128         echo 1 >> $DIR/$tdir/${tfile}.10_append
3129
3130         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.10_append)
3131         [ "$pool" = "$TESTNAME" ] || error "(10) incorrect pool: $pool"
3132
3133         # Check that count is still correct
3134         appendcount=1
3135         echo 1 >> $DIR/$tdir/${tfile}.11_append
3136         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.11_append)
3137         [ $count -eq $appendcount ] ||
3138                 error "(11) stripe count $count, should be $appendcount for append"
3139
3140         # Disable O_APPEND stripe count, verify pool works separately
3141         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
3142
3143         echo 1 >> $DIR/$tdir/${tfile}.12_append
3144
3145         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.12_append)
3146         [ "$pool" = "$TESTNAME" ] || error "(12) incorrect pool: $pool"
3147
3148         # Remove pool setting, verify it's not applied
3149         do_nodes $mdts $LCTL set_param mdd.*.append_pool='none'
3150
3151         echo 1 >> $DIR/$tdir/${tfile}.13_append
3152
3153         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.13_append)
3154         [ "$pool" = "" ] || error "(13) pool found: $pool"
3155 }
3156 run_test 27M "test O_APPEND striping"
3157
3158 test_27N() {
3159         combined_mgs_mds && skip "needs separate MGS/MDT"
3160
3161         pool_add $TESTNAME || error "pool_add failed"
3162         do_facet mgs "$LCTL pool_list $FSNAME" |
3163                 grep -Fx "${FSNAME}.${TESTNAME}" ||
3164                 error "lctl pool_list on MGS failed"
3165 }
3166 run_test 27N "lctl pool_list on separate MGS gives correct pool name"
3167
3168 clean_foreign_symlink() {
3169         trap 0
3170         lctl set_param llite/$FSNAME-*/foreign_symlink_enable=0
3171         for i in $DIR/$tdir/* ; do
3172                 $LFS unlink_foreign $i || true
3173         done
3174 }
3175
3176 test_27O() {
3177         [[ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.12.51) ]] &&
3178                 skip "Need MDS version newer than 2.12.51"
3179
3180         test_mkdir $DIR/$tdir
3181         local uuid1=$(cat /proc/sys/kernel/random/uuid)
3182         local uuid2=$(cat /proc/sys/kernel/random/uuid)
3183
3184         trap clean_foreign_symlink EXIT
3185
3186         # enable foreign_symlink behaviour
3187         $LCTL set_param llite/$FSNAME-*/foreign_symlink_enable=1
3188
3189         # foreign symlink LOV format is a partial path by default
3190
3191         # create foreign file (lfs + API)
3192         $LFS setstripe --foreign=symlink --flags 0xda05 \
3193                 -x "${uuid1}/${uuid2}" --mode 0600 $DIR/$tdir/${tfile} ||
3194                 error "$DIR/$tdir/${tfile}: create failed"
3195
3196         $LFS getstripe -v $DIR/$tdir/${tfile} |
3197                 grep "lfm_magic:.*0x0BD70BD0" ||
3198                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign magic"
3199         $LFS getstripe -v $DIR/$tdir/${tfile} | grep "lfm_type:.*symlink" ||
3200                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign type"
3201         $LFS getstripe -v $DIR/$tdir/${tfile} |
3202                 grep "lfm_flags:.*0x0000DA05" ||
3203                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign flags"
3204         $LFS getstripe $DIR/$tdir/${tfile} |
3205                 grep "lfm_value:.*${uuid1}/${uuid2}" ||
3206                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign value"
3207
3208         # modify striping should fail
3209         $LFS setstripe -c 2 $DIR/$tdir/$tfile &&
3210                 error "$DIR/$tdir/$tfile: setstripe should fail"
3211
3212         # R/W should fail ("/{foreign_symlink_prefix}/${uuid1}/" missing)
3213         cat $DIR/$tdir/$tfile && error "$DIR/$tdir/$tfile: read should fail"
3214         cat /etc/passwd > $DIR/$tdir/$tfile &&
3215                 error "$DIR/$tdir/$tfile: write should fail"
3216
3217         # rename should succeed
3218         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}.new ||
3219                 error "$DIR/$tdir/$tfile: rename has failed"
3220
3221         #remove foreign_symlink file should fail
3222         rm $DIR/$tdir/${tfile}.new &&
3223                 error "$DIR/$tdir/${tfile}.new: remove of foreign_symlink file should fail"
3224
3225         #test fake symlink
3226         mkdir /tmp/${uuid1} ||
3227                 error "/tmp/${uuid1}: mkdir has failed"
3228         echo FOOFOO > /tmp/${uuid1}/${uuid2} ||
3229                 error "/tmp/${uuid1}/${uuid2}: echo has failed"
3230         $LCTL set_param llite/$FSNAME-*/foreign_symlink_prefix=/tmp/
3231         $CHECKSTAT -t link -l /tmp/${uuid1}/${uuid2} $DIR/$tdir/${tfile}.new ||
3232                 error "$DIR/$tdir/${tfile}.new: not seen as a symlink"
3233         #read should succeed now
3234         cat $DIR/$tdir/${tfile}.new | grep FOOFOO ||
3235                 error "$DIR/$tdir/${tfile}.new: symlink resolution has failed"
3236         #write should succeed now
3237         cat /etc/passwd > $DIR/$tdir/${tfile}.new ||
3238                 error "$DIR/$tdir/${tfile}.new: write should succeed"
3239         diff /etc/passwd $DIR/$tdir/${tfile}.new ||
3240                 error "$DIR/$tdir/${tfile}.new: diff has failed"
3241         diff /etc/passwd /tmp/${uuid1}/${uuid2} ||
3242                 error "/tmp/${uuid1}/${uuid2}: diff has failed"
3243
3244         #check that getstripe still works
3245         $LFS getstripe $DIR/$tdir/${tfile}.new ||
3246                 error "$DIR/$tdir/${tfile}.new: getstripe should still work with foreign_symlink enabled"
3247
3248         # chmod should still succeed
3249         chmod 644 $DIR/$tdir/${tfile}.new ||
3250                 error "$DIR/$tdir/${tfile}.new: chmod has failed"
3251
3252         # chown should still succeed
3253         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tfile}.new ||
3254                 error "$DIR/$tdir/${tfile}.new: chown has failed"
3255
3256         # rename should still succeed
3257         mv $DIR/$tdir/${tfile}.new $DIR/$tdir/${tfile} ||
3258                 error "$DIR/$tdir/${tfile}.new: rename has failed"
3259
3260         #remove foreign_symlink file should still fail
3261         rm $DIR/$tdir/${tfile} &&
3262                 error "$DIR/$tdir/${tfile}: remove of foreign_symlink file should fail"
3263
3264         #use special ioctl() to unlink foreign_symlink file
3265         $LFS unlink_foreign $DIR/$tdir/${tfile} ||
3266                 error "$DIR/$tdir/$tfile: unlink/ioctl failed"
3267
3268 }
3269 run_test 27O "basic ops on foreign file of symlink type"
3270
3271 test_27P() {
3272         [[ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.12.49) ]] &&
3273                 skip "Need MDS version newer than 2.12.49"
3274
3275         test_mkdir $DIR/$tdir
3276         local uuid1=$(cat /proc/sys/kernel/random/uuid)
3277         local uuid2=$(cat /proc/sys/kernel/random/uuid)
3278
3279         trap clean_foreign_symlink EXIT
3280
3281         # enable foreign_symlink behaviour
3282         $LCTL set_param llite/$FSNAME-*/foreign_symlink_enable=1
3283
3284         # foreign symlink LMV format is a partial path by default
3285
3286         # create foreign dir (lfs + API)
3287         $LFS mkdir --foreign=symlink --xattr="${uuid1}/${uuid2}" \
3288                 --flags=0xda05 --mode 0750 $DIR/$tdir/${tdir} ||
3289                 error "$DIR/$tdir/${tdir}: create failed"
3290
3291         $LFS getdirstripe -v $DIR/$tdir/${tdir}
3292
3293         $LFS getdirstripe -v $DIR/$tdir/${tdir} |
3294                 grep "lfm_magic:.*0x0CD50CD0" ||
3295                 error "$DIR/$tdir/${tdir}: invalid LMV EA magic"
3296         $LFS getdirstripe -v $DIR/$tdir/${tdir} | grep "lfm_type:.*symlink" ||
3297                 error "$DIR/$tdir/${tdir}: invalid LMV EA type"
3298         $LFS getdirstripe -v $DIR/$tdir/${tdir} |
3299                 grep "lfm_flags:.*0x0000DA05" ||
3300                 error "$DIR/$tdir/${tdir}: invalid LMV EA flags"
3301         $LFS getdirstripe $DIR/$tdir/${tdir} |
3302                 grep "lfm_value.*${uuid1}/${uuid2}" ||
3303                 error "$DIR/$tdir/${tdir}: invalid LMV EA value"
3304
3305         # file create in dir should fail
3306         # ("/{foreign_symlink_prefix}/${uuid1}/${uuid2}/" missing)
3307         touch $DIR/$tdir/$tdir/$tfile && error "$DIR/$tdir: file create should fail"
3308
3309         # rename should succeed
3310         mv $DIR/$tdir/$tdir $DIR/$tdir/${tdir}.new ||
3311                 error "$DIR/$tdir/$tdir: rename of foreign_symlink dir has failed"
3312
3313         #remove foreign_symlink dir should fail
3314         rmdir $DIR/$tdir/${tdir}.new &&
3315                 error "$DIR/$tdir/${tdir}.new: remove of foreign_symlink dir should fail"
3316
3317         #test fake symlink
3318         mkdir -p /tmp/${uuid1}/${uuid2} ||
3319                 error "/tmp/${uuid1}/${uuid2}: mkdir has failed"
3320         echo FOOFOO > /tmp/${uuid1}/${uuid2}/foo ||
3321                 error "/tmp/${uuid1}/${uuid2}/foo: echo has failed"
3322         $LCTL set_param llite/$FSNAME-*/foreign_symlink_prefix=/tmp/
3323         $CHECKSTAT -t link -l /tmp/${uuid1}/${uuid2} $DIR/$tdir/${tdir}.new ||
3324                 error "$DIR/$tdir/${tdir}.new: not seen as a symlink"
3325         cat $DIR/$tdir/${tdir}.new/foo | grep FOOFOO ||
3326                 error "$DIR/$tdir/${tdir}.new: symlink resolution has failed"
3327
3328         #check that getstripe fails now that foreign_symlink enabled
3329         $LFS getdirstripe $DIR/$tdir/${tdir}.new ||
3330                 error "$DIR/$tdir/${tdir}.new: getdirstripe should still work with foreign_symlink enabled"
3331
3332         # file create in dir should work now
3333         cp /etc/passwd $DIR/$tdir/${tdir}.new/$tfile ||
3334                 error "$DIR/$tdir/${tdir}.new/$tfile: file create should fail"
3335         diff /etc/passwd $DIR/$tdir/${tdir}.new/$tfile ||
3336                 error "$DIR/$tdir/${tdir}.new/$tfile: diff has failed"
3337         diff /etc/passwd /tmp/${uuid1}/${uuid2}/$tfile ||
3338                 error "/tmp/${uuid1}/${uuid2}/$tfile: diff has failed"
3339
3340         # chmod should still succeed
3341         chmod 755 $DIR/$tdir/${tdir}.new ||
3342                 error "$DIR/$tdir/${tdir}.new: chmod has failed"
3343
3344         # chown should still succeed
3345         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tdir}.new ||
3346                 error "$DIR/$tdir/${tdir}.new: chown has failed"
3347
3348         # rename should still succeed
3349         mv $DIR/$tdir/${tdir}.new $DIR/$tdir/${tdir} ||
3350                 error "$DIR/$tdir/${tdir}.new: rename of foreign_symlink dir has failed"
3351
3352         #remove foreign_symlink dir should still fail
3353         rmdir $DIR/$tdir/${tdir} &&
3354                 error "$DIR/$tdir/${tdir}: remove of foreign_symlink dir should fail"
3355
3356         #use special ioctl() to unlink foreign_symlink file
3357         $LFS unlink_foreign $DIR/$tdir/${tdir} ||
3358                 error "$DIR/$tdir/$tdir: unlink/ioctl failed"
3359
3360         #created file should still exist
3361         [[ -f /tmp/${uuid1}/${uuid2}/$tfile ]] ||
3362                 error "/tmp/${uuid1}/${uuid2}/$tfile has been removed"
3363         diff /etc/passwd /tmp/${uuid1}/${uuid2}/$tfile ||
3364                 error "/tmp/${uuid1}/${uuid2}/$tfile: diff has failed"
3365 }
3366 run_test 27P "basic ops on foreign dir of foreign_symlink type"
3367
3368 test_27Q() {
3369         rm -f $TMP/$tfile $TMP/$tfile.loop $TMP/$tfile.none $TMP/$tfile.broken
3370         stack_trap "rm -f $TMP/$tfile*"
3371
3372         test_mkdir $DIR/$tdir-1
3373         test_mkdir $DIR/$tdir-2
3374
3375         echo 'It is what it is' > $DIR/$tdir-1/$tfile
3376         lov_getstripe_old $DIR/$tdir-1/$tfile || error "$DIR/$tdir-1/$tfile: rc = $?"
3377
3378         ln -s $DIR/$tdir-1/$tfile $DIR/$tdir-2/$tfile
3379         lov_getstripe_old $DIR/$tdir-2/$tfile || error "$DIR/$tdir-2/$tfile: rc = $?"
3380
3381         ln -s $DIR/$tdir-1/$tfile $TMP/$tfile
3382         lov_getstripe_old $TMP/$tfile || error "$TMP/$tfile: rc = $?"
3383
3384         # Create some bad symlinks and ensure that we don't loop
3385         # forever or something. These should return ELOOP (40) and
3386         # ENOENT (2) but I don't want to test for that because there's
3387         # always some weirdo architecture that needs to ruin
3388         # everything by defining these error numbers differently.
3389
3390         ln -s $TMP/$tfile.loop $TMP/$tfile.loop
3391         lov_getstripe_old $TMP/$tfile.loop && error "$TMP/$tfile.loop: rc = $?"
3392
3393         ln -s $TMP/$tfile.none $TMP/$tfile.broken
3394         lov_getstripe_old $TMP/$tfile.broken && error "$TMP/$tfile.broken: rc = $?"
3395
3396         return 0
3397 }
3398 run_test 27Q "llapi_file_get_stripe() works on symlinks"
3399
3400 test_27R() {
3401         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
3402                 skip "need MDS 2.14.55 or later"
3403         (( $OSTCOUNT >= 2 )) || skip_env "needs at least 2 OSTs"
3404
3405         local testdir="$DIR/$tdir"
3406         test_mkdir -p $testdir
3407         stack_trap "rm -rf $testdir"
3408         $LFS setstripe -c -1 $testdir || error "setstripe failed"
3409
3410         local f1="$testdir/f1"
3411         touch $f1 || error "failed to touch $f1"
3412         local count=$($LFS getstripe -c $f1)
3413         (( $count == $OSTCOUNT )) || error "wrong stripe count"
3414
3415         do_facet $SINGLEMDS $LCTL set_param lod.*.max_stripecount=-1
3416         (( $? == 34 )) || error "setting max_stripecount to -1 should fail and return ERANGE"
3417
3418         local maxcount=$(($OSTCOUNT - 1))
3419         local mdts=$(comma_list $(mdts_nodes))
3420         do_nodes $mdts $LCTL set_param lod.*.max_stripecount=$maxcount
3421         stack_trap "do_nodes $mdts $LCTL set_param lod.*.max_stripecount=0"
3422
3423         local f2="$testdir/f2"
3424         touch $f2 || error "failed to touch $f2"
3425         local count=$($LFS getstripe -c $f2)
3426         (( $count == $maxcount )) || error "wrong stripe count"
3427 }
3428 run_test 27R "test max_stripecount limitation when stripe count is set to -1"
3429
3430 test_27T() {
3431         [ $(facet_host client) == $(facet_host ost1) ] &&
3432                 skip "need ost1 and client on different nodes"
3433
3434 #define OBD_FAIL_OSC_NO_GRANT            0x411
3435         $LCTL set_param fail_loc=0x20000411 fail_val=1
3436 #define OBD_FAIL_OST_ENOSPC              0x215
3437         do_facet ost1 "$LCTL set_param fail_loc=0x80000215"
3438         $LFS setstripe -i 0 -c 1 $DIR/$tfile
3439         $MULTIOP $DIR/$tfile oO_WRONLY:P$((4 * 1024 * 1024 + 10 * 4096))c ||
3440                 error "multiop failed"
3441 }
3442 run_test 27T "no eio on close on partial write due to enosp"
3443
3444 test_27U() {
3445         local dir=$DIR/$tdir
3446         local file=$dir/$tfile
3447         local append_pool=${TESTNAME}-append
3448         local normal_pool=${TESTNAME}-normal
3449         local pool
3450         local stripe_count
3451         local stripe_count2
3452         local mdts=$(comma_list $(mdts_nodes))
3453
3454         (( $MDS1_VERSION >= $(version_code 2.15.51) )) ||
3455                 skip "Need MDS version at least 2.15.51 for append pool feature"
3456
3457         # Validate existing append_* params and ensure restore
3458         pool=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_pool)
3459         [[ "$pool" == "" ]] || error "expected append_pool == '', got '$pool'"
3460         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_pool=none"
3461
3462         stripe_count=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_stripe_count)
3463         ((stripe_count == 1)) || error "expected append_stripe_count != 0, got $stripe_count"
3464         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=$stripe_count"
3465
3466         pool_add $append_pool || error "pool creation failed"
3467         pool_add_targets $append_pool 0 1 || error "Pool add targets failed"
3468
3469         pool_add $normal_pool || error "pool creation failed"
3470         pool_add_targets $normal_pool 0 1 || error "Pool add targets failed"
3471
3472         test_mkdir $dir
3473         $LFS setstripe -E 1M -c 1 -p $normal_pool -E 2M -c 2 -p $normal_pool -E eof -c -1 $dir
3474
3475         echo XXX >> $file.1
3476         $LFS getstripe $file.1
3477
3478         pool=$($LFS getstripe -p $file.1)
3479         [[ "$pool" == "$normal_pool" ]] || error "got pool '$pool', expected '$normal_pool'"
3480
3481         stripe_count2=$($LFS getstripe -c $file.1)
3482         ((stripe_count2 == stripe_count)) ||
3483                 error "got stripe_count '$stripe_count2', expected '$stripe_count'"
3484
3485         do_nodes $mdts $LCTL set_param mdd.*.append_pool=$append_pool
3486
3487         echo XXX >> $file.2
3488         $LFS getstripe $file.2
3489
3490         pool=$($LFS getstripe -p $file.2)
3491         [[ "$pool" == "$append_pool" ]] || error "got pool '$pool', expected '$append_pool'"
3492
3493         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=2
3494
3495         echo XXX >> $file.3
3496         $LFS getstripe $file.3
3497
3498         stripe_count2=$($LFS getstripe -c $file.3)
3499         ((stripe_count2 == 2)) || error "got stripe_count '$stripe_count2', expected 2"
3500 }
3501 run_test 27U "append pool and stripe count work with composite default layout"
3502
3503 # createtest also checks that device nodes are created and
3504 # then visible correctly (#2091)
3505 test_28() { # bug 2091
3506         test_mkdir $DIR/d28
3507         $CREATETEST $DIR/d28/ct || error "createtest failed"
3508 }
3509 run_test 28 "create/mknod/mkdir with bad file types ============"
3510
3511 test_29() {
3512         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3513
3514         [ $MDS1_VERSION -ge $(version_code 2.14.51) ] && {
3515                 disable_opencache
3516                 stack_trap "restore_opencache"
3517         }
3518
3519         sync; sleep 1; sync # flush out any dirty pages from previous tests
3520         cancel_lru_locks
3521         test_mkdir $DIR/d29
3522         touch $DIR/d29/foo
3523         log 'first d29'
3524         ls -l $DIR/d29
3525
3526         declare -i LOCKCOUNTORIG=0
3527         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
3528                 let LOCKCOUNTORIG=$LOCKCOUNTORIG+$lock_count
3529         done
3530         [ $LOCKCOUNTORIG -eq 0 ] && error "No mdc lock count" && return 1
3531
3532         declare -i LOCKUNUSEDCOUNTORIG=0
3533         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3534                 let LOCKUNUSEDCOUNTORIG=$LOCKUNUSEDCOUNTORIG+$unused_count
3535         done
3536
3537         log 'second d29'
3538         ls -l $DIR/d29
3539         log 'done'
3540
3541         declare -i LOCKCOUNTCURRENT=0
3542         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
3543                 let LOCKCOUNTCURRENT=$LOCKCOUNTCURRENT+$lock_count
3544         done
3545
3546         declare -i LOCKUNUSEDCOUNTCURRENT=0
3547         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3548                 let LOCKUNUSEDCOUNTCURRENT=$LOCKUNUSEDCOUNTCURRENT+$unused_count
3549         done
3550
3551         if [[ $LOCKCOUNTCURRENT -gt $LOCKCOUNTORIG ]]; then
3552                 $LCTL set_param -n ldlm.dump_namespaces ""
3553                 error "CURRENT: $LOCKCOUNTCURRENT > $LOCKCOUNTORIG"
3554                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3555                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3556                 return 2
3557         fi
3558         if [[ $LOCKUNUSEDCOUNTCURRENT -gt $LOCKUNUSEDCOUNTORIG ]]; then
3559                 error "UNUSED: $LOCKUNUSEDCOUNTCURRENT > $LOCKUNUSEDCOUNTORIG"
3560                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3561                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3562                 return 3
3563         fi
3564 }
3565 run_test 29 "IT_GETATTR regression  ============================"
3566
3567 test_30a() { # was test_30
3568         cp $(which ls) $DIR || cp /bin/ls $DIR
3569         $DIR/ls / || error "Can't execute binary from lustre"
3570         rm $DIR/ls
3571 }
3572 run_test 30a "execute binary from Lustre (execve) =============="
3573
3574 test_30b() {
3575         cp `which ls` $DIR || cp /bin/ls $DIR
3576         chmod go+rx $DIR/ls
3577         $RUNAS $DIR/ls / || error "Can't execute binary from lustre as non-root"
3578         rm $DIR/ls
3579 }
3580 run_test 30b "execute binary from Lustre as non-root ==========="
3581
3582 test_30c() { # b=22376
3583         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3584
3585         cp $(which ls) $DIR || cp /bin/ls $DIR
3586         chmod a-rw $DIR/ls
3587         cancel_lru_locks mdc
3588         cancel_lru_locks osc
3589         $RUNAS $DIR/ls / || error "Can't execute binary from lustre"
3590         rm -f $DIR/ls
3591 }
3592 run_test 30c "execute binary from Lustre without read perms ===="
3593
3594 test_30d() {
3595         cp $(which dd) $DIR || error "failed to copy dd to $DIR/dd"
3596
3597         for i in {1..10}; do
3598                 $DIR/dd bs=1M count=128 if=/dev/zero of=$DIR/$tfile &
3599                 local PID=$!
3600                 sleep 1
3601                 $LCTL set_param ldlm.namespaces.*MDT*.lru_size=clear
3602                 wait $PID || error "executing dd from Lustre failed"
3603                 rm -f $DIR/$tfile
3604         done
3605
3606         rm -f $DIR/dd
3607 }
3608 run_test 30d "execute binary from Lustre while clear locks"
3609
3610 test_31a() {
3611         $OPENUNLINK $DIR/f31 $DIR/f31 || error "openunlink failed"
3612         $CHECKSTAT -a $DIR/f31 || error "$DIR/f31 exists"
3613 }
3614 run_test 31a "open-unlink file =================================="
3615
3616 test_31b() {
3617         touch $DIR/f31 || error "touch $DIR/f31 failed"
3618         ln $DIR/f31 $DIR/f31b || error "ln failed"
3619         $MULTIOP $DIR/f31b Ouc || error "multiop failed"
3620         $CHECKSTAT -t file $DIR/f31 || error "$DIR/f31 not file type"
3621 }
3622 run_test 31b "unlink file with multiple links while open ======="
3623
3624 test_31c() {
3625         touch $DIR/f31 || error "touch $DIR/f31 failed"
3626         ln $DIR/f31 $DIR/f31c || error "ln failed"
3627         multiop_bg_pause $DIR/f31 O_uc ||
3628                 error "multiop_bg_pause for $DIR/f31 failed"
3629         MULTIPID=$!
3630         $MULTIOP $DIR/f31c Ouc
3631         kill -USR1 $MULTIPID
3632         wait $MULTIPID
3633 }
3634 run_test 31c "open-unlink file with multiple links ============="
3635
3636 test_31d() {
3637         opendirunlink $DIR/d31d $DIR/d31d || error "opendirunlink failed"
3638         $CHECKSTAT -a $DIR/d31d || error "$DIR/d31d exists"
3639 }
3640 run_test 31d "remove of open directory ========================="
3641
3642 test_31e() { # bug 2904
3643         openfilleddirunlink $DIR/d31e || error "openfilleddirunlink failed"
3644 }
3645 run_test 31e "remove of open non-empty directory ==============="
3646
3647 test_31f() { # bug 4554
3648         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3649
3650         set -vx
3651         test_mkdir $DIR/d31f
3652         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3653         cp /etc/hosts $DIR/d31f
3654         ls -l $DIR/d31f
3655         $LFS getstripe $DIR/d31f/hosts
3656         multiop_bg_pause $DIR/d31f D_c || return 1
3657         MULTIPID=$!
3658
3659         rm -rv $DIR/d31f || error "first of $DIR/d31f"
3660         test_mkdir $DIR/d31f
3661         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3662         cp /etc/hosts $DIR/d31f
3663         ls -l $DIR/d31f
3664         $LFS getstripe $DIR/d31f/hosts
3665         multiop_bg_pause $DIR/d31f D_c || return 1
3666         MULTIPID2=$!
3667
3668         kill -USR1 $MULTIPID || error "first opendir $MULTIPID not running"
3669         wait $MULTIPID || error "first opendir $MULTIPID failed"
3670
3671         sleep 6
3672
3673         kill -USR1 $MULTIPID2 || error "second opendir $MULTIPID not running"
3674         wait $MULTIPID2 || error "second opendir $MULTIPID2 failed"
3675         set +vx
3676 }
3677 run_test 31f "remove of open directory with open-unlink file ==="
3678
3679 test_31g() {
3680         echo "-- cross directory link --"
3681         test_mkdir -c1 $DIR/${tdir}ga
3682         test_mkdir -c1 $DIR/${tdir}gb
3683         touch $DIR/${tdir}ga/f
3684         ln $DIR/${tdir}ga/f $DIR/${tdir}gb/g
3685         $CHECKSTAT -t file $DIR/${tdir}ga/f || error "source"
3686         [ `stat -c%h $DIR/${tdir}ga/f` == '2' ] || error "source nlink"
3687         $CHECKSTAT -t file $DIR/${tdir}gb/g || error "target"
3688         [ `stat -c%h $DIR/${tdir}gb/g` == '2' ] || error "target nlink"
3689 }
3690 run_test 31g "cross directory link==============="
3691
3692 test_31h() {
3693         echo "-- cross directory link --"
3694         test_mkdir -c1 $DIR/${tdir}
3695         test_mkdir -c1 $DIR/${tdir}/dir
3696         touch $DIR/${tdir}/f
3697         ln $DIR/${tdir}/f $DIR/${tdir}/dir/g
3698         $CHECKSTAT -t file $DIR/${tdir}/f || error "source"
3699         [ `stat -c%h $DIR/${tdir}/f` == '2' ] || error "source nlink"
3700         $CHECKSTAT -t file $DIR/${tdir}/dir/g || error "target"
3701         [ `stat -c%h $DIR/${tdir}/dir/g` == '2' ] || error "target nlink"
3702 }
3703 run_test 31h "cross directory link under child==============="
3704
3705 test_31i() {
3706         echo "-- cross directory link --"
3707         test_mkdir -c1 $DIR/$tdir
3708         test_mkdir -c1 $DIR/$tdir/dir
3709         touch $DIR/$tdir/dir/f
3710         ln $DIR/$tdir/dir/f $DIR/$tdir/g
3711         $CHECKSTAT -t file $DIR/$tdir/dir/f || error "source"
3712         [ `stat -c%h $DIR/$tdir/dir/f` == '2' ] || error "source nlink"
3713         $CHECKSTAT -t file $DIR/$tdir/g || error "target"
3714         [ `stat -c%h $DIR/$tdir/g` == '2' ] || error "target nlink"
3715 }
3716 run_test 31i "cross directory link under parent==============="
3717
3718 test_31j() {
3719         test_mkdir -c1 -p $DIR/$tdir
3720         test_mkdir -c1 -p $DIR/$tdir/dir1
3721         ln $DIR/$tdir/dir1 $DIR/$tdir/dir2 && error "ln for dir"
3722         link $DIR/$tdir/dir1 $DIR/$tdir/dir3 && error "link for dir"
3723         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir4 && error "mlink for dir"
3724         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir1 && error "mlink to the same dir"
3725         return 0
3726 }
3727 run_test 31j "link for directory==============="
3728
3729 test_31k() {
3730         test_mkdir -c1 -p $DIR/$tdir
3731         touch $DIR/$tdir/s
3732         touch $DIR/$tdir/exist
3733         mlink $DIR/$tdir/s $DIR/$tdir/t || error "mlink"
3734         mlink $DIR/$tdir/s $DIR/$tdir/exist && error "mlink to exist file"
3735         mlink $DIR/$tdir/s $DIR/$tdir/s && error "mlink to the same file"
3736         mlink $DIR/$tdir/s $DIR/$tdir && error "mlink to parent dir"
3737         mlink $DIR/$tdir $DIR/$tdir/s && error "mlink parent dir to target"
3738         mlink $DIR/$tdir/not-exist $DIR/$tdir/foo && error "mlink non-existing to new"
3739         mlink $DIR/$tdir/not-exist $DIR/$tdir/s && error "mlink non-existing to exist"
3740         return 0
3741 }
3742 run_test 31k "link to file: the same, non-existing, dir==============="
3743
3744 test_31l() {
3745         local ln_ver=$(ln --version | awk '/coreutils/ { print $4 }')
3746
3747         (( $(version_code $ln_ver) < $(version_code 8.31) )) ||
3748         (( $(version_code $(uname -r)) >= $(version_code 5.18) )) ||
3749                 skip "need coreutils < 8.31 or kernel >= 5.18 for ln"
3750
3751         touch $DIR/$tfile || error "create failed"
3752         mkdir $DIR/$tdir || error "mkdir failed"
3753         ln $DIR/$tfile $DIR/$tdir/ || error "ln to '$tdir/' failed"
3754 }
3755 run_test 31l "link to file: target dir has trailing slash"
3756
3757 test_31m() {
3758         mkdir $DIR/d31m
3759         touch $DIR/d31m/s
3760         mkdir $DIR/d31m2
3761         touch $DIR/d31m2/exist
3762         mlink $DIR/d31m/s $DIR/d31m2/t || error "mlink"
3763         mlink $DIR/d31m/s $DIR/d31m2/exist && error "mlink to exist file"
3764         mlink $DIR/d31m/s $DIR/d31m2 && error "mlink to parent dir"
3765         mlink $DIR/d31m2 $DIR/d31m/s && error "mlink parent dir to target"
3766         mlink $DIR/d31m/not-exist $DIR/d31m2/foo && error "mlink non-existing to new"
3767         mlink $DIR/d31m/not-exist $DIR/d31m2/s && error "mlink non-existing to exist"
3768         return 0
3769 }
3770 run_test 31m "link to file: the same, non-existing, dir==============="
3771
3772 test_31n() {
3773         touch $DIR/$tfile || error "cannot create '$DIR/$tfile'"
3774         nlink=$(stat --format=%h $DIR/$tfile)
3775         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3776         local fd=$(free_fd)
3777         local cmd="exec $fd<$DIR/$tfile"
3778         eval $cmd
3779         cmd="exec $fd<&-"
3780         trap "eval $cmd" EXIT
3781         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3782         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3783         rm $DIR/$tfile || error "cannot remove '$DIR/$tfile'"
3784         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3785         [ ${nlink:--1} -eq 0 ] || error "nlink is $nlink, expected 0"
3786         eval $cmd
3787 }
3788 run_test 31n "check link count of unlinked file"
3789
3790 link_one() {
3791         local tempfile=$(mktemp $1_XXXXXX)
3792         mlink $tempfile $1 2> /dev/null &&
3793                 echo "$BASHPID: link $tempfile to $1 succeeded"
3794         munlink $tempfile
3795 }
3796
3797 test_31o() { # LU-2901
3798         test_mkdir $DIR/$tdir
3799         for LOOP in $(seq 100); do
3800                 rm -f $DIR/$tdir/$tfile*
3801                 for THREAD in $(seq 8); do
3802                         link_one $DIR/$tdir/$tfile.$LOOP &
3803                 done
3804                 wait
3805                 local LINKS=$(ls -1 $DIR/$tdir | grep -c $tfile.$LOOP)
3806                 [[ $LINKS -gt 1 ]] && ls $DIR/$tdir &&
3807                         error "$LINKS duplicate links to $tfile.$LOOP" &&
3808                         break || true
3809         done
3810 }
3811 run_test 31o "duplicate hard links with same filename"
3812
3813 test_31p() {
3814         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3815
3816         test_mkdir $DIR/$tdir
3817         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3818         $LFS setdirstripe -D -c2 -H all_char $DIR/$tdir/striped_dir
3819
3820         opendirunlink $DIR/$tdir/striped_dir/test1 ||
3821                 error "open unlink test1 failed"
3822         opendirunlink $DIR/$tdir/striped_dir/test2 ||
3823                 error "open unlink test2 failed"
3824
3825         $CHECKSTAT -a $DIR/$tdir/striped_dir/test1 ||
3826                 error "test1 still exists"
3827         $CHECKSTAT -a $DIR/$tdir/striped_dir/test2 ||
3828                 error "test2 still exists"
3829 }
3830 run_test 31p "remove of open striped directory"
3831
3832 test_31q() {
3833         [ $MDSCOUNT -lt 3 ] && skip_env "needs >= 3 MDTs"
3834
3835         $LFS mkdir -i 3,1 $DIR/$tdir || error "mkdir failed"
3836         index=$($LFS getdirstripe -i $DIR/$tdir)
3837         [ $index -eq 3 ] || error "first stripe index $index != 3"
3838         index=$($LFS getdirstripe $DIR/$tdir | tail -1 | awk '{print $1}')
3839         [ $index -eq 1 ] || error "second stripe index $index != 1"
3840
3841         # when "-c <stripe_count>" is set, the number of MDTs specified after
3842         # "-i" should equal to the stripe count
3843         $LFS mkdir -i 3,1 -c 3 $DIR/$tdir.2 && error "mkdir should fail" || true
3844 }
3845 run_test 31q "create striped directory on specific MDTs"
3846
3847 #LU-14949
3848 test_31r() {
3849         touch $DIR/$tfile.target
3850         touch $DIR/$tfile.source
3851
3852         #OBD_FAIL_LLITE_OPEN_DELAY 0x1419
3853         $LCTL set_param fail_loc=0x1419 fail_val=3
3854         cat $DIR/$tfile.target &
3855         CATPID=$!
3856
3857         # Guarantee open is waiting before we get here
3858         sleep 1
3859         mv $DIR/$tfile.source $DIR/$tfile.target
3860
3861         wait $CATPID
3862         RC=$?
3863         if [[ $RC -ne 0 ]]; then
3864                 error "open with cat failed, rc=$RC"
3865         fi
3866 }
3867 run_test 31r "open-rename(replace) race"
3868
3869 cleanup_test32_mount() {
3870         local rc=0
3871         trap 0
3872         local loopdev=$(losetup -a | grep $EXT2_DEV | sed -ne 's/:.*$//p')
3873         $UMOUNT $DIR/$tdir/ext2-mountpoint || rc=$?
3874         losetup -d $loopdev || true
3875         rm -rf $DIR/$tdir
3876         return $rc
3877 }
3878
3879 test_32a() {
3880         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3881
3882         echo "== more mountpoints and symlinks ================="
3883         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3884         trap cleanup_test32_mount EXIT
3885         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3886         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3887                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3888         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/.. ||
3889                 error "$DIR/$tdir/ext2-mountpoint/.. not dir type"
3890         cleanup_test32_mount
3891 }
3892 run_test 32a "stat d32a/ext2-mountpoint/.. ====================="
3893
3894 test_32b() {
3895         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3896
3897         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3898         trap cleanup_test32_mount EXIT
3899         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3900         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3901                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3902         ls -al $DIR/$tdir/ext2-mountpoint/.. ||
3903                 error "Can't list $DIR/$tdir/ext2-mountpoint/.."
3904         cleanup_test32_mount
3905 }
3906 run_test 32b "open d32b/ext2-mountpoint/.. ====================="
3907
3908 test_32c() {
3909         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3910
3911         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3912         trap cleanup_test32_mount EXIT
3913         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3914         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3915                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3916         test_mkdir -p $DIR/$tdir/d2/test_dir
3917         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3918                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_dir not dir type"
3919         cleanup_test32_mount
3920 }
3921 run_test 32c "stat d32c/ext2-mountpoint/../d2/test_dir ========="
3922
3923 test_32d() {
3924         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3925
3926         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3927         trap cleanup_test32_mount EXIT
3928         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3929         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3930                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3931         test_mkdir -p $DIR/$tdir/d2/test_dir
3932         ls -al $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3933                 error "Can't list $DIR/$tdir/ext2-mountpoint/../d2/test_dir"
3934         cleanup_test32_mount
3935 }
3936 run_test 32d "open d32d/ext2-mountpoint/../d2/test_dir"
3937
3938 test_32e() {
3939         rm -fr $DIR/$tdir
3940         test_mkdir -p $DIR/$tdir/tmp
3941         local tmp_dir=$DIR/$tdir/tmp
3942         ln -s $DIR/$tdir $tmp_dir/symlink11
3943         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3944         $CHECKSTAT -t link $DIR/$tdir/tmp/symlink11 || error "symlink11 bad"
3945         $CHECKSTAT -t link $DIR/$tdir/symlink01 || error "symlink01 bad"
3946 }
3947 run_test 32e "stat d32e/symlink->tmp/symlink->lustre-subdir"
3948
3949 test_32f() {
3950         rm -fr $DIR/$tdir
3951         test_mkdir -p $DIR/$tdir/tmp
3952         local tmp_dir=$DIR/$tdir/tmp
3953         ln -s $DIR/$tdir $tmp_dir/symlink11
3954         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3955         ls $DIR/$tdir/tmp/symlink11  || error "symlink11 bad"
3956         ls $DIR/$tdir/symlink01 || error "symlink01 bad"
3957 }
3958 run_test 32f "open d32f/symlink->tmp/symlink->lustre-subdir"
3959
3960 test_32g() {
3961         local tmp_dir=$DIR/$tdir/tmp
3962         test_mkdir -p $tmp_dir
3963         test_mkdir $DIR/${tdir}2
3964         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3965         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3966         $CHECKSTAT -t link $tmp_dir/symlink12 || error "symlink12 not a link"
3967         $CHECKSTAT -t link $DIR/$tdir/symlink02 || error "symlink02 not a link"
3968         $CHECKSTAT -t dir -f $tmp_dir/symlink12 || error "symlink12 not a dir"
3969         $CHECKSTAT -t dir -f $DIR/$tdir/symlink02 || error "symlink12 not a dir"
3970 }
3971 run_test 32g "stat d32g/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3972
3973 test_32h() {
3974         rm -fr $DIR/$tdir $DIR/${tdir}2
3975         tmp_dir=$DIR/$tdir/tmp
3976         test_mkdir -p $tmp_dir
3977         test_mkdir $DIR/${tdir}2
3978         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3979         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3980         ls $tmp_dir/symlink12 || error "listing symlink12"
3981         ls $DIR/$tdir/symlink02  || error "listing symlink02"
3982 }
3983 run_test 32h "open d32h/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3984
3985 test_32i() {
3986         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3987
3988         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3989         trap cleanup_test32_mount EXIT
3990         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3991         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3992                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3993         touch $DIR/$tdir/test_file
3994         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../test_file ||
3995                 error "$DIR/$tdir/ext2-mountpoint/../test_file not file type"
3996         cleanup_test32_mount
3997 }
3998 run_test 32i "stat d32i/ext2-mountpoint/../test_file ==========="
3999
4000 test_32j() {
4001         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4002
4003         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
4004         trap cleanup_test32_mount EXIT
4005         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4006         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4007                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4008         touch $DIR/$tdir/test_file
4009         cat $DIR/$tdir/ext2-mountpoint/../test_file ||
4010                 error "Can't open $DIR/$tdir/ext2-mountpoint/../test_file"
4011         cleanup_test32_mount
4012 }
4013 run_test 32j "open d32j/ext2-mountpoint/../test_file ==========="
4014
4015 test_32k() {
4016         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4017
4018         rm -fr $DIR/$tdir
4019         trap cleanup_test32_mount EXIT
4020         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4021         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4022                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4023         test_mkdir -p $DIR/$tdir/d2
4024         touch $DIR/$tdir/d2/test_file || error "touch failed"
4025         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
4026                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_file not file type"
4027         cleanup_test32_mount
4028 }
4029 run_test 32k "stat d32k/ext2-mountpoint/../d2/test_file ========"
4030
4031 test_32l() {
4032         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4033
4034         rm -fr $DIR/$tdir
4035         trap cleanup_test32_mount EXIT
4036         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4037         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4038                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4039         test_mkdir -p $DIR/$tdir/d2
4040         touch $DIR/$tdir/d2/test_file || error "touch failed"
4041         cat  $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
4042                 error "Can't open $DIR/$tdir/ext2-mountpoint/../d2/test_file"
4043         cleanup_test32_mount
4044 }
4045 run_test 32l "open d32l/ext2-mountpoint/../d2/test_file ========"
4046
4047 test_32m() {
4048         rm -fr $DIR/d32m
4049         test_mkdir -p $DIR/d32m/tmp
4050         TMP_DIR=$DIR/d32m/tmp
4051         ln -s $DIR $TMP_DIR/symlink11
4052         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
4053         $CHECKSTAT -t link $DIR/d32m/tmp/symlink11 ||
4054                 error "symlink11 not a link"
4055         $CHECKSTAT -t link $DIR/d32m/symlink01 ||
4056                 error "symlink01 not a link"
4057 }
4058 run_test 32m "stat d32m/symlink->tmp/symlink->lustre-root ======"
4059
4060 test_32n() {
4061         rm -fr $DIR/d32n
4062         test_mkdir -p $DIR/d32n/tmp
4063         TMP_DIR=$DIR/d32n/tmp
4064         ln -s $DIR $TMP_DIR/symlink11
4065         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
4066         ls -l $DIR/d32n/tmp/symlink11  || error "listing symlink11"
4067         ls -l $DIR/d32n/symlink01 || error "listing symlink01"
4068 }
4069 run_test 32n "open d32n/symlink->tmp/symlink->lustre-root ======"
4070
4071 test_32o() {
4072         touch $DIR/$tfile
4073         test_mkdir -p $DIR/d32o/tmp
4074         TMP_DIR=$DIR/d32o/tmp
4075         ln -s $DIR/$tfile $TMP_DIR/symlink12
4076         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
4077         $CHECKSTAT -t link $DIR/d32o/tmp/symlink12 ||
4078                 error "symlink12 not a link"
4079         $CHECKSTAT -t link $DIR/d32o/symlink02 || error "symlink02 not a link"
4080         $CHECKSTAT -t file -f $DIR/d32o/tmp/symlink12 ||
4081                 error "$DIR/d32o/tmp/symlink12 not file type"
4082         $CHECKSTAT -t file -f $DIR/d32o/symlink02 ||
4083                 error "$DIR/d32o/symlink02 not file type"
4084 }
4085 run_test 32o "stat d32o/symlink->tmp/symlink->lustre-root/$tfile"
4086
4087 test_32p() {
4088         log 32p_1
4089         rm -fr $DIR/d32p
4090         log 32p_2
4091         rm -f $DIR/$tfile
4092         log 32p_3
4093         touch $DIR/$tfile
4094         log 32p_4
4095         test_mkdir -p $DIR/d32p/tmp
4096         log 32p_5
4097         TMP_DIR=$DIR/d32p/tmp
4098         log 32p_6
4099         ln -s $DIR/$tfile $TMP_DIR/symlink12
4100         log 32p_7
4101         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
4102         log 32p_8
4103         cat $DIR/d32p/tmp/symlink12 ||
4104                 error "Can't open $DIR/d32p/tmp/symlink12"
4105         log 32p_9
4106         cat $DIR/d32p/symlink02 || error "Can't open $DIR/d32p/symlink02"
4107         log 32p_10
4108 }
4109 run_test 32p "open d32p/symlink->tmp/symlink->lustre-root/$tfile"
4110
4111 test_32q() {
4112         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4113
4114         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
4115         trap cleanup_test32_mount EXIT
4116         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4117         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
4118         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4119                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4120         ls $DIR/$tdir/ext2-mountpoint | grep "\<under_the_mount\>" && error
4121         cleanup_test32_mount
4122 }
4123 run_test 32q "stat follows mountpoints in Lustre (should return error)"
4124
4125 test_32r() {
4126         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4127
4128         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
4129         trap cleanup_test32_mount EXIT
4130         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4131         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
4132         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4133                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4134         ls $DIR/$tdir/ext2-mountpoint | grep -q under_the_mount && error || true
4135         cleanup_test32_mount
4136 }
4137 run_test 32r "opendir follows mountpoints in Lustre (should return error)"
4138
4139 test_33aa() {
4140         rm -f $DIR/$tfile
4141         touch $DIR/$tfile
4142         chmod 444 $DIR/$tfile
4143         chown $RUNAS_ID $DIR/$tfile
4144         log 33_1
4145         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
4146         log 33_2
4147 }
4148 run_test 33aa "write file with mode 444 (should return error)"
4149
4150 test_33a() {
4151         rm -fr $DIR/$tdir
4152         test_mkdir $DIR/$tdir
4153         chown $RUNAS_ID $DIR/$tdir
4154         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile ||
4155                 error "$RUNAS create $tdir/$tfile failed"
4156         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile &&
4157                 error "open RDWR" || true
4158 }
4159 run_test 33a "test open file(mode=0444) with O_RDWR (should return error)"
4160
4161 test_33b() {
4162         rm -fr $DIR/$tdir
4163         test_mkdir $DIR/$tdir
4164         chown $RUNAS_ID $DIR/$tdir
4165         $RUNAS $OPENFILE -f 1286739555 $DIR/$tdir/$tfile || true
4166 }
4167 run_test 33b "test open file with malformed flags (No panic)"
4168
4169 test_33c() {
4170         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4171         remote_ost_nodsh && skip "remote OST with nodsh"
4172
4173         local ostnum
4174         local ostname
4175         local write_bytes
4176         local all_zeros
4177
4178         all_zeros=true
4179         test_mkdir $DIR/$tdir
4180         # Read: 0, Write: 4, create/destroy: 2/0, stat: 1, punch: 0
4181
4182         sync
4183         for ostnum in $(seq $OSTCOUNT); do
4184                 # test-framework's OST numbering is one-based, while Lustre's
4185                 # is zero-based
4186                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4187                 # check if at least some write_bytes stats are counted
4188                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
4189                               obdfilter.$ostname.stats |
4190                               awk '/^write_bytes/ {print $7}' )
4191                 echo "baseline_write_bytes@ost$ostnum/$ostname=$write_bytes"
4192                 if (( ${write_bytes:-0} > 0 )); then
4193                         all_zeros=false
4194                         break
4195                 fi
4196         done
4197
4198         $all_zeros || return 0
4199
4200         # Write four bytes
4201         echo foo > $DIR/$tdir/bar
4202         # Really write them
4203         sync
4204
4205         # Total up write_bytes after writing.  We'd better find non-zeros.
4206         for ostnum in $(seq $OSTCOUNT); do
4207                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4208                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
4209                               obdfilter/$ostname/stats |
4210                               awk '/^write_bytes/ {print $7}' )
4211                 echo "write_bytes@ost$ostnum/$ostname=$write_bytes"
4212                 if (( ${write_bytes:-0} > 0 )); then
4213                         all_zeros=false
4214                         break
4215                 fi
4216         done
4217
4218         if $all_zeros; then
4219                 for ostnum in $(seq $OSTCOUNT); do
4220                         ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4221                         echo "Check write_bytes is in obdfilter.*.stats:"
4222                         do_facet ost$ostnum lctl get_param -n \
4223                                 obdfilter.$ostname.stats
4224                 done
4225                 error "OST not keeping write_bytes stats (b=22312)"
4226         fi
4227 }
4228 run_test 33c "test write_bytes stats"
4229
4230 test_33d() {
4231         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
4232         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4233
4234         local MDTIDX=1
4235         local remote_dir=$DIR/$tdir/remote_dir
4236
4237         test_mkdir $DIR/$tdir
4238         $LFS mkdir -i $MDTIDX $remote_dir ||
4239                 error "create remote directory failed"
4240
4241         touch $remote_dir/$tfile
4242         chmod 444 $remote_dir/$tfile
4243         chown $RUNAS_ID $remote_dir/$tfile
4244
4245         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
4246
4247         chown $RUNAS_ID $remote_dir
4248         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 ||
4249                                         error "create" || true
4250         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 &&
4251                                     error "open RDWR" || true
4252         $RUNAS $OPENFILE -f 1286739555 $remote_dir/f33 || true
4253 }
4254 run_test 33d "openfile with 444 modes and malformed flags under remote dir"
4255
4256 test_33e() {
4257         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4258
4259         mkdir $DIR/$tdir
4260
4261         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4262         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4263         mkdir $DIR/$tdir/local_dir
4264
4265         local s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4266         local s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4267         local l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4268
4269         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4270                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode"
4271
4272         rmdir $DIR/$tdir/* || error "rmdir failed"
4273
4274         umask 777
4275         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4276         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4277         mkdir $DIR/$tdir/local_dir
4278
4279         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4280         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4281         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4282
4283         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4284                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 777"
4285
4286         rmdir $DIR/$tdir/* || error "rmdir(umask 777) failed"
4287
4288         umask 000
4289         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4290         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4291         mkdir $DIR/$tdir/local_dir
4292
4293         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4294         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4295         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4296
4297         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4298                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 0"
4299 }
4300 run_test 33e "mkdir and striped directory should have same mode"
4301
4302 cleanup_33f() {
4303         trap 0
4304         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=0
4305 }
4306
4307 test_33f() {
4308         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4309         remote_mds_nodsh && skip "remote MDS with nodsh"
4310
4311         mkdir $DIR/$tdir
4312         chmod go+rwx $DIR/$tdir
4313         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=-1
4314         trap cleanup_33f EXIT
4315
4316         $RUNAS lfs mkdir -i 0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
4317                 error "cannot create striped directory"
4318
4319         $RUNAS touch $DIR/$tdir/striped_dir/{0..16} ||
4320                 error "cannot create files in striped directory"
4321
4322         $RUNAS rm $DIR/$tdir/striped_dir/{0..16} ||
4323                 error "cannot remove files in striped directory"
4324
4325         $RUNAS rmdir $DIR/$tdir/striped_dir ||
4326                 error "cannot remove striped directory"
4327
4328         cleanup_33f
4329 }
4330 run_test 33f "nonroot user can create, access, and remove a striped directory"
4331
4332 test_33g() {
4333         mkdir -p $DIR/$tdir/dir2
4334
4335         local err=$($RUNAS mkdir $DIR/$tdir/dir2 2>&1)
4336         echo $err
4337         [[ $err =~ "exists" ]] || error "Not exists error"
4338 }
4339 run_test 33g "nonroot user create already existing root created file"
4340
4341 sub_33h() {
4342         local hash_type=$1
4343         local count=250
4344
4345         test_mkdir -c $MDSCOUNT -H $hash_type $DIR/$tdir ||
4346                 error "lfs mkdir -H $hash_type $tdir failed"
4347         touch $DIR/$tdir/$tfile || error "touch $tfile failed"
4348
4349         local index=$($LFS getstripe -m $DIR/$tdir/$tfile)
4350         local index2
4351         local fname
4352
4353         for fname in $DIR/$tdir/$tfile.bak \
4354                      $DIR/$tdir/$tfile.SAV \
4355                      $DIR/$tdir/$tfile.orig \
4356                      $DIR/$tdir/$tfile~; do
4357                 touch $fname || error "touch $fname failed"
4358                 index2=$($LFS getstripe -m $fname)
4359                 (( $index == $index2 )) ||
4360                         error "$fname MDT index mismatch $index != $index2"
4361         done
4362
4363         local failed=0
4364         local patterns=(".$tfile.XXXXXX" "$tfile.XXXXXXXX")
4365         local pattern
4366
4367         for pattern in ${patterns[*]}; do
4368                 echo "pattern $pattern"
4369                 fname=$DIR/$tdir/$pattern
4370                 for (( i = 0; i < $count; i++ )); do
4371                         fname=$(mktemp $DIR/$tdir/$pattern) ||
4372                                 error "mktemp $DIR/$tdir/$pattern failed"
4373                         index2=$($LFS getstripe -m $fname)
4374                         (( $index == $index2 )) && continue
4375
4376                         failed=$((failed + 1))
4377                         echo "$fname MDT index mismatch $index != $index2"
4378                 done
4379         done
4380
4381         echo "$failed/$count MDT index mismatches, expect ~2-4"
4382         (( failed < 10 )) || error "MDT index mismatch $failed/$count times"
4383
4384         local same=0
4385         local expect
4386
4387         # verify that "crush" is still broken with all files on same MDT,
4388         # crush2 should have about 1/MDSCOUNT files on each MDT, with margin
4389         [[ "$hash_type" == "crush" ]] && expect=$count ||
4390                 expect=$((count / MDSCOUNT))
4391
4392         # crush2 doesn't put all-numeric suffixes on the same MDT,
4393         # filename like $tfile.12345678 should *not* be considered temp
4394         for pattern in ${patterns[*]}; do
4395                 local base=${pattern%%X*}
4396                 local suff=${pattern#$base}
4397
4398                 echo "pattern $pattern"
4399                 for (( i = 0; i < $count; i++ )); do
4400                         fname=$DIR/$tdir/$base$((${suff//X/1} + i))
4401                         touch $fname || error "touch $fname failed"
4402                         index2=$($LFS getstripe -m $fname)
4403                         (( $index != $index2 )) && continue
4404
4405                         same=$((same + 1))
4406                 done
4407         done
4408
4409         # the number of "bad" hashes is random, as it depends on the random
4410         # filenames generated by "mktemp".  Allow some margin in the results.
4411         echo "$((same/${#patterns[*]}))/$count matches, expect ~$expect for $1"
4412         (( same / ${#patterns[*]} <= expect * 9 / 7 &&
4413            same / ${#patterns[*]} > expect * 5 / 7 )) ||
4414                 error "MDT index match $((same / ${#patterns[*]}))/$count times"
4415         same=0
4416
4417         # crush2 doesn't put suffixes with special characters on the same MDT
4418         # filename like $tfile.txt.1234 should *not* be considered temp
4419         for pattern in ${patterns[*]}; do
4420                 local base=${pattern%%X*}
4421                 local suff=${pattern#$base}
4422
4423                 pattern=$base...${suff/XXX}
4424                 echo "pattern=$pattern"
4425                 for (( i = 0; i < $count; i++ )); do
4426                         fname=$(mktemp $DIR/$tdir/$pattern) ||
4427                                 error "touch $fname failed"
4428                         index2=$($LFS getstripe -m $fname)
4429                         (( $index != $index2 )) && continue
4430
4431                         same=$((same + 1))
4432                 done
4433         done
4434
4435         # the number of "bad" hashes is random, as it depends on the random
4436         # filenames generated by "mktemp".  Allow some margin in the results.
4437         echo "$((same/${#patterns[*]}))/$count matches, expect ~$expect for $1"
4438         (( same / ${#patterns[*]} <= expect * 9 / 7 &&
4439            same / ${#patterns[*]} > expect * 5 / 7 )) ||
4440                 error "MDT index match $((same / ${#patterns[*]}))/$count times"
4441 }
4442
4443 test_33h() {
4444         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
4445         (( $MDS1_VERSION >= $(version_code 2.13.50) )) ||
4446                 skip "Need MDS version at least 2.13.50"
4447
4448         sub_33h crush
4449 }
4450 run_test 33h "temp file is located on the same MDT as target (crush)"
4451
4452 test_33hh() {
4453         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
4454         echo "MDS1_VERSION=$MDS1_VERSION version_code=$(version_code 2.15.0)"
4455         (( $MDS1_VERSION > $(version_code 2.15.0) )) ||
4456                 skip "Need MDS version at least 2.15.0 for crush2"
4457
4458         sub_33h crush2
4459 }
4460 run_test 33hh "temp file is located on the same MDT as target (crush2)"
4461
4462 test_33i()
4463 {
4464         (( MDSCOUNT < 2 )) && skip "needs >= 2 MDTs"
4465
4466         local FNAME=$(str_repeat 'f' 250)
4467
4468         test_mkdir -i 0 -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
4469         createmany -o $DIR/$tdir/$FNAME 1000 || error "createmany failed"
4470
4471         local count
4472         local total
4473
4474         count=$($LFS getstripe -m $DIR/$tdir/* | grep -cw 1)
4475
4476         local MDC=$(lctl dl | awk '/MDT0001-mdc-[^M]/ { print $4 }')
4477
4478         lctl --device %$MDC deactivate
4479         stack_trap "lctl --device %$MDC activate"
4480         ls $DIR/$tdir > /dev/null && error "ls should return an error"
4481         total=$(\ls -l $DIR/$tdir | wc -l)
4482         # "ls -l" will list total in the first line
4483         total=$((total - 1))
4484         (( total + count == 1000 )) ||
4485                 error "ls list $total files, $count files on MDT1"
4486 }
4487 run_test 33i "striped directory can be accessed when one MDT is down"
4488
4489 test_33j() {
4490         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
4491
4492         mkdir -p $DIR/$tdir/
4493
4494         $LFS setdirstripe -D -i0,1 $DIR/$tdir/striped_dir_a &&
4495                 error "setdirstripe -D -i0,1 incorrectly succeeded"
4496
4497         $LFS setdirstripe -D -i0,1 -c1 $DIR/$tdir/striped_dir_b &&
4498                 error "setdirstripe -D -i0,1 -c1 incorrectly succeeded"
4499
4500         $LFS setdirstripe -D -i0,1 -c3 $DIR/$tdir/striped_dir_c &&
4501                 error "setdirstripe -D -i0,1 -c3 incorrectly succeeded"
4502
4503         $LFS setdirstripe -i0,1 $DIR/$tdir/striped_dir_e ||
4504                 error "-D was not specified, but still failed"
4505 }
4506 run_test 33j "lfs setdirstripe -D -i x,y,x should fail"
4507
4508 TEST_34_SIZE=${TEST_34_SIZE:-2000000000000}
4509 test_34a() {
4510         rm -f $DIR/f34
4511         $MCREATE $DIR/f34 || error "mcreate failed"
4512         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4513                 error "getstripe failed"
4514         $TRUNCATE $DIR/f34 $TEST_34_SIZE || error "truncate failed"
4515         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4516                 error "getstripe failed"
4517         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4518                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4519 }
4520 run_test 34a "truncate file that has not been opened ==========="
4521
4522 test_34b() {
4523         [ ! -f $DIR/f34 ] && test_34a
4524         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4525                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4526         $OPENFILE -f O_RDONLY $DIR/f34
4527         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4528                 error "getstripe failed"
4529         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4530                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4531 }
4532 run_test 34b "O_RDONLY opening file doesn't create objects ====="
4533
4534 test_34c() {
4535         [ ! -f $DIR/f34 ] && test_34a
4536         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4537                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4538         $OPENFILE -f O_RDWR $DIR/f34
4539         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" &&
4540                 error "$LFS getstripe failed"
4541         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4542                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4543 }
4544 run_test 34c "O_RDWR opening file-with-size works =============="
4545
4546 test_34d() {
4547         [ ! -f $DIR/f34 ] && test_34a
4548         dd if=/dev/zero of=$DIR/f34 conv=notrunc bs=4k count=1 ||
4549                 error "dd failed"
4550         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4551                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4552         rm $DIR/f34
4553 }
4554 run_test 34d "write to sparse file ============================="
4555
4556 test_34e() {
4557         rm -f $DIR/f34e
4558         $MCREATE $DIR/f34e || error "mcreate failed"
4559         $TRUNCATE $DIR/f34e 1000 || error "truncate failed"
4560         $CHECKSTAT -s 1000 $DIR/f34e ||
4561                 error "Size of $DIR/f34e not equal to 1000 bytes"
4562         $OPENFILE -f O_RDWR $DIR/f34e
4563         $CHECKSTAT -s 1000 $DIR/f34e ||
4564                 error "Size of $DIR/f34e not equal to 1000 bytes"
4565 }
4566 run_test 34e "create objects, some with size and some without =="
4567
4568 test_34f() { # bug 6242, 6243
4569         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4570
4571         SIZE34F=48000
4572         rm -f $DIR/f34f
4573         $MCREATE $DIR/f34f || error "mcreate failed"
4574         $TRUNCATE $DIR/f34f $SIZE34F || error "truncating $DIR/f3f to $SIZE34F"
4575         dd if=$DIR/f34f of=$TMP/f34f
4576         $CHECKSTAT -s $SIZE34F $TMP/f34f || error "$TMP/f34f not $SIZE34F bytes"
4577         dd if=/dev/zero of=$TMP/f34fzero bs=$SIZE34F count=1
4578         cmp $DIR/f34f $TMP/f34fzero || error "$DIR/f34f not all zero"
4579         cmp $TMP/f34f $TMP/f34fzero || error "$TMP/f34f not all zero"
4580         rm $TMP/f34f $TMP/f34fzero $DIR/f34f
4581 }
4582 run_test 34f "read from a file with no objects until EOF ======="
4583
4584 test_34g() {
4585         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4586
4587         dd if=/dev/zero of=$DIR/$tfile bs=1 count=100 seek=$TEST_34_SIZE ||
4588                 error "dd failed"
4589         $TRUNCATE $DIR/$tfile $((TEST_34_SIZE / 2))|| error "truncate failed"
4590         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
4591                 error "Size of $DIR/$tfile not equal to $((TEST_34_SIZE / 2))"
4592         cancel_lru_locks osc
4593         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
4594                 error "wrong size after lock cancel"
4595
4596         $TRUNCATE $DIR/$tfile $TEST_34_SIZE || error "truncate failed"
4597         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
4598                 error "expanding truncate failed"
4599         cancel_lru_locks osc
4600         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
4601                 error "wrong expanded size after lock cancel"
4602 }
4603 run_test 34g "truncate long file ==============================="
4604
4605 test_34h() {
4606         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4607
4608         local gid=10
4609         local sz=1000
4610
4611         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 || error "dd failed"
4612         sync # Flush the cache so that multiop below does not block on cache
4613              # flush when getting the group lock
4614         $MULTIOP $DIR/$tfile OG${gid}T${sz}g${gid}c &
4615         MULTIPID=$!
4616
4617         # Since just timed wait is not good enough, let's do a sync write
4618         # that way we are sure enough time for a roundtrip + processing
4619         # passed + 2 seconds of extra margin.
4620         dd if=/dev/zero of=$DIR/${tfile}-1 bs=$PAGE_SIZE oflag=direct count=1
4621         rm $DIR/${tfile}-1
4622         sleep 2
4623
4624         if [[ `ps h -o comm -p $MULTIPID` == "multiop" ]]; then
4625                 error "Multiop blocked on ftruncate, pid=$MULTIPID"
4626                 kill -9 $MULTIPID
4627         fi
4628         wait $MULTIPID
4629         local nsz=`stat -c %s $DIR/$tfile`
4630         [[ $nsz == $sz ]] || error "New size wrong $nsz != $sz"
4631 }
4632 run_test 34h "ftruncate file under grouplock should not block"
4633
4634 test_35a() {
4635         cp /bin/sh $DIR/f35a
4636         chmod 444 $DIR/f35a
4637         chown $RUNAS_ID $DIR/f35a
4638         $RUNAS $DIR/f35a && error || true
4639         rm $DIR/f35a
4640 }
4641 run_test 35a "exec file with mode 444 (should return and not leak)"
4642
4643 test_36a() {
4644         rm -f $DIR/f36
4645         utime $DIR/f36 || error "utime failed for MDS"
4646 }
4647 run_test 36a "MDS utime check (mknod, utime)"
4648
4649 test_36b() {
4650         echo "" > $DIR/f36
4651         utime $DIR/f36 || error "utime failed for OST"
4652 }
4653 run_test 36b "OST utime check (open, utime)"
4654
4655 test_36c() {
4656         rm -f $DIR/d36/f36
4657         test_mkdir $DIR/d36
4658         chown $RUNAS_ID $DIR/d36
4659         $RUNAS utime $DIR/d36/f36 || error "utime failed for MDS as non-root"
4660 }
4661 run_test 36c "non-root MDS utime check (mknod, utime)"
4662
4663 test_36d() {
4664         [ ! -d $DIR/d36 ] && test_36c
4665         echo "" > $DIR/d36/f36
4666         $RUNAS utime $DIR/d36/f36 || error "utime failed for OST as non-root"
4667 }
4668 run_test 36d "non-root OST utime check (open, utime)"
4669
4670 test_36e() {
4671         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID -- skipping"
4672
4673         test_mkdir $DIR/$tdir
4674         touch $DIR/$tdir/$tfile
4675         $RUNAS utime $DIR/$tdir/$tfile &&
4676                 error "utime worked, expected failure" || true
4677 }
4678 run_test 36e "utime on non-owned file (should return error)"
4679
4680 subr_36fh() {
4681         local fl="$1"
4682         local LANG_SAVE=$LANG
4683         local LC_LANG_SAVE=$LC_LANG
4684         export LANG=C LC_LANG=C # for date language
4685
4686         DATESTR="Dec 20  2000"
4687         test_mkdir $DIR/$tdir
4688         lctl set_param fail_loc=$fl
4689         date; date +%s
4690         cp /etc/hosts $DIR/$tdir/$tfile
4691         sync & # write RPC generated with "current" inode timestamp, but delayed
4692         sleep 1
4693         touch --date="$DATESTR" $DIR/$tdir/$tfile # setattr timestamp in past
4694         LS_BEFORE="`ls -l $DIR/$tdir/$tfile`" # old timestamp from client cache
4695         cancel_lru_locks $OSC
4696         LS_AFTER="`ls -l $DIR/$tdir/$tfile`"  # timestamp from OST object
4697         date; date +%s
4698         [ "$LS_BEFORE" != "$LS_AFTER" ] && \
4699                 echo "BEFORE: $LS_BEFORE" && \
4700                 echo "AFTER : $LS_AFTER" && \
4701                 echo "WANT  : $DATESTR" && \
4702                 error "$DIR/$tdir/$tfile timestamps changed" || true
4703
4704         export LANG=$LANG_SAVE LC_LANG=$LC_LANG_SAVE
4705 }
4706
4707 test_36f() {
4708         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4709
4710         #define OBD_FAIL_OST_BRW_PAUSE_BULK 0x214
4711         subr_36fh "0x80000214"
4712 }
4713 run_test 36f "utime on file racing with OST BRW write =========="
4714
4715 test_36g() {
4716         remote_ost_nodsh && skip "remote OST with nodsh"
4717         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4718         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
4719                 skip "Need MDS version at least 2.12.51"
4720
4721         local fmd_max_age
4722         local fmd
4723         local facet="ost1"
4724         local tgt="obdfilter"
4725
4726         [[ $OSC == "mdc" ]] && tgt="mdt" && facet="mds1"
4727
4728         test_mkdir $DIR/$tdir
4729         fmd_max_age=$(do_facet $facet \
4730                 "lctl get_param -n $tgt.*.tgt_fmd_seconds 2> /dev/null | \
4731                 head -n 1")
4732
4733         echo "FMD max age: ${fmd_max_age}s"
4734         touch $DIR/$tdir/$tfile
4735         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4736                 gawk '{cnt=cnt+$1}  END{print cnt}')
4737         echo "FMD before: $fmd"
4738         [[ $fmd == 0 ]] &&
4739                 error "FMD wasn't create by touch"
4740         sleep $((fmd_max_age + 12))
4741         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4742                 gawk '{cnt=cnt+$1}  END{print cnt}')
4743         echo "FMD after: $fmd"
4744         [[ $fmd == 0 ]] ||
4745                 error "FMD wasn't expired by ping"
4746 }
4747 run_test 36g "FMD cache expiry ====================="
4748
4749 test_36h() {
4750         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4751
4752         #define OBD_FAIL_OST_BRW_PAUSE_BULK2 0x227
4753         subr_36fh "0x80000227"
4754 }
4755 run_test 36h "utime on file racing with OST BRW write =========="
4756
4757 test_36i() {
4758         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4759
4760         test_mkdir $DIR/$tdir
4761         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir
4762
4763         local mtime=$(stat -c%Y $DIR/$tdir/striped_dir)
4764         local new_mtime=$((mtime + 200))
4765
4766         #change Modify time of striped dir
4767         touch -m -d @$new_mtime $DIR/$tdir/striped_dir ||
4768                         error "change mtime failed"
4769
4770         local got=$(stat -c%Y $DIR/$tdir/striped_dir)
4771
4772         [ "$new_mtime" = "$got" ] || error "expect $new_mtime got $got"
4773 }
4774 run_test 36i "change mtime on striped directory"
4775
4776 # test_37 - duplicate with tests 32q 32r
4777
4778 test_38() {
4779         local file=$DIR/$tfile
4780         touch $file
4781         openfile -f O_DIRECTORY $file
4782         local RC=$?
4783         local ENOTDIR=20
4784         [ $RC -eq 0 ] && error "opened file $file with O_DIRECTORY" || true
4785         [ $RC -eq $ENOTDIR ] || error "error $RC should be ENOTDIR ($ENOTDIR)"
4786 }
4787 run_test 38 "open a regular file with O_DIRECTORY should return -ENOTDIR ==="
4788
4789 test_39a() { # was test_39
4790         touch $DIR/$tfile
4791         touch $DIR/${tfile}2
4792 #       ls -l  $DIR/$tfile $DIR/${tfile}2
4793 #       ls -lu  $DIR/$tfile $DIR/${tfile}2
4794 #       ls -lc  $DIR/$tfile $DIR/${tfile}2
4795         sleep 2
4796         $OPENFILE -f O_CREAT:O_TRUNC:O_WRONLY $DIR/${tfile}2
4797         if [ ! $DIR/${tfile}2 -nt $DIR/$tfile ]; then
4798                 echo "mtime"
4799                 ls -l --full-time $DIR/$tfile $DIR/${tfile}2
4800                 echo "atime"
4801                 ls -lu --full-time $DIR/$tfile $DIR/${tfile}2
4802                 echo "ctime"
4803                 ls -lc --full-time $DIR/$tfile $DIR/${tfile}2
4804                 error "O_TRUNC didn't change timestamps"
4805         fi
4806 }
4807 run_test 39a "mtime changed on create"
4808
4809 test_39b() {
4810         test_mkdir -c1 $DIR/$tdir
4811         cp -p /etc/passwd $DIR/$tdir/fopen
4812         cp -p /etc/passwd $DIR/$tdir/flink
4813         cp -p /etc/passwd $DIR/$tdir/funlink
4814         cp -p /etc/passwd $DIR/$tdir/frename
4815         ln $DIR/$tdir/funlink $DIR/$tdir/funlink2
4816
4817         sleep 1
4818         echo "aaaaaa" >> $DIR/$tdir/fopen
4819         echo "aaaaaa" >> $DIR/$tdir/flink
4820         echo "aaaaaa" >> $DIR/$tdir/funlink
4821         echo "aaaaaa" >> $DIR/$tdir/frename
4822
4823         local open_new=`stat -c %Y $DIR/$tdir/fopen`
4824         local link_new=`stat -c %Y $DIR/$tdir/flink`
4825         local unlink_new=`stat -c %Y $DIR/$tdir/funlink`
4826         local rename_new=`stat -c %Y $DIR/$tdir/frename`
4827
4828         cat $DIR/$tdir/fopen > /dev/null
4829         ln $DIR/$tdir/flink $DIR/$tdir/flink2
4830         rm -f $DIR/$tdir/funlink2
4831         mv -f $DIR/$tdir/frename $DIR/$tdir/frename2
4832
4833         for (( i=0; i < 2; i++ )) ; do
4834                 local open_new2=`stat -c %Y $DIR/$tdir/fopen`
4835                 local link_new2=`stat -c %Y $DIR/$tdir/flink`
4836                 local unlink_new2=`stat -c %Y $DIR/$tdir/funlink`
4837                 local rename_new2=`stat -c %Y $DIR/$tdir/frename2`
4838
4839                 [ $open_new2 -eq $open_new ] || error "open file reverses mtime"
4840                 [ $link_new2 -eq $link_new ] || error "link file reverses mtime"
4841                 [ $unlink_new2 -eq $unlink_new ] || error "unlink file reverses mtime"
4842                 [ $rename_new2 -eq $rename_new ] || error "rename file reverses mtime"
4843
4844                 cancel_lru_locks $OSC
4845                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4846         done
4847 }
4848 run_test 39b "mtime change on open, link, unlink, rename  ======"
4849
4850 # this should be set to past
4851 TEST_39_MTIME=`date -d "1 year ago" +%s`
4852
4853 # bug 11063
4854 test_39c() {
4855         touch $DIR1/$tfile
4856         sleep 2
4857         local mtime0=`stat -c %Y $DIR1/$tfile`
4858
4859         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4860         local mtime1=`stat -c %Y $DIR1/$tfile`
4861         [ "$mtime1" = $TEST_39_MTIME ] || \
4862                 error "mtime is not set to past: $mtime1, should be $TEST_39_MTIME"
4863
4864         local d1=`date +%s`
4865         echo hello >> $DIR1/$tfile
4866         local d2=`date +%s`
4867         local mtime2=`stat -c %Y $DIR1/$tfile`
4868         [ "$mtime2" -ge "$d1" ] && [ "$mtime2" -le "$d2" ] || \
4869                 error "mtime is not updated on write: $d1 <= $mtime2 <= $d2"
4870
4871         mv $DIR1/$tfile $DIR1/$tfile-1
4872
4873         for (( i=0; i < 2; i++ )) ; do
4874                 local mtime3=`stat -c %Y $DIR1/$tfile-1`
4875                 [ "$mtime2" = "$mtime3" ] || \
4876                         error "mtime ($mtime2) changed (to $mtime3) on rename"
4877
4878                 cancel_lru_locks $OSC
4879                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4880         done
4881 }
4882 run_test 39c "mtime change on rename ==========================="
4883
4884 # bug 21114
4885 test_39d() {
4886         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4887
4888         touch $DIR1/$tfile
4889         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4890
4891         for (( i=0; i < 2; i++ )) ; do
4892                 local mtime=`stat -c %Y $DIR1/$tfile`
4893                 [ $mtime = $TEST_39_MTIME ] || \
4894                         error "mtime($mtime) is not set to $TEST_39_MTIME"
4895
4896                 cancel_lru_locks $OSC
4897                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4898         done
4899 }
4900 run_test 39d "create, utime, stat =============================="
4901
4902 # bug 21114
4903 test_39e() {
4904         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4905
4906         touch $DIR1/$tfile
4907         local mtime1=`stat -c %Y $DIR1/$tfile`
4908
4909         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4910
4911         for (( i=0; i < 2; i++ )) ; do
4912                 local mtime2=`stat -c %Y $DIR1/$tfile`
4913                 [ $mtime2 = $TEST_39_MTIME ] || \
4914                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4915
4916                 cancel_lru_locks $OSC
4917                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4918         done
4919 }
4920 run_test 39e "create, stat, utime, stat ========================"
4921
4922 # bug 21114
4923 test_39f() {
4924         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4925
4926         touch $DIR1/$tfile
4927         mtime1=`stat -c %Y $DIR1/$tfile`
4928
4929         sleep 2
4930         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4931
4932         for (( i=0; i < 2; i++ )) ; do
4933                 local mtime2=`stat -c %Y $DIR1/$tfile`
4934                 [ $mtime2 = $TEST_39_MTIME ] || \
4935                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4936
4937                 cancel_lru_locks $OSC
4938                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4939         done
4940 }
4941 run_test 39f "create, stat, sleep, utime, stat ================="
4942
4943 # bug 11063
4944 test_39g() {
4945         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4946
4947         echo hello >> $DIR1/$tfile
4948         local mtime1=`stat -c %Y $DIR1/$tfile`
4949
4950         sleep 2
4951         chmod o+r $DIR1/$tfile
4952
4953         for (( i=0; i < 2; i++ )) ; do
4954                 local mtime2=`stat -c %Y $DIR1/$tfile`
4955                 [ "$mtime1" = "$mtime2" ] || \
4956                         error "lost mtime: $mtime2, should be $mtime1"
4957
4958                 cancel_lru_locks $OSC
4959                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4960         done
4961 }
4962 run_test 39g "write, chmod, stat ==============================="
4963
4964 # bug 11063
4965 test_39h() {
4966         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4967
4968         touch $DIR1/$tfile
4969         sleep 1
4970
4971         local d1=`date`
4972         echo hello >> $DIR1/$tfile
4973         local mtime1=`stat -c %Y $DIR1/$tfile`
4974
4975         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4976         local d2=`date`
4977         if [ "$d1" != "$d2" ]; then
4978                 echo "write and touch not within one second"
4979         else
4980                 for (( i=0; i < 2; i++ )) ; do
4981                         local mtime2=`stat -c %Y $DIR1/$tfile`
4982                         [ "$mtime2" = $TEST_39_MTIME ] || \
4983                                 error "lost mtime: $mtime2, should be $TEST_39_MTIME"
4984
4985                         cancel_lru_locks $OSC
4986                         if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4987                 done
4988         fi
4989 }
4990 run_test 39h "write, utime within one second, stat ============="
4991
4992 test_39i() {
4993         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4994
4995         touch $DIR1/$tfile
4996         sleep 1
4997
4998         echo hello >> $DIR1/$tfile
4999         local mtime1=`stat -c %Y $DIR1/$tfile`
5000
5001         mv $DIR1/$tfile $DIR1/$tfile-1
5002
5003         for (( i=0; i < 2; i++ )) ; do
5004                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
5005
5006                 [ "$mtime1" = "$mtime2" ] || \
5007                         error "lost mtime: $mtime2, should be $mtime1"
5008
5009                 cancel_lru_locks $OSC
5010                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
5011         done
5012 }
5013 run_test 39i "write, rename, stat =============================="
5014
5015 test_39j() {
5016         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5017
5018         start_full_debug_logging
5019         touch $DIR1/$tfile
5020         sleep 1
5021
5022         #define OBD_FAIL_OSC_DELAY_SETTIME       0x412
5023         lctl set_param fail_loc=0x80000412
5024         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c ||
5025                 error "multiop failed"
5026         local multipid=$!
5027         local mtime1=`stat -c %Y $DIR1/$tfile`
5028
5029         mv $DIR1/$tfile $DIR1/$tfile-1
5030
5031         kill -USR1 $multipid
5032         wait $multipid || error "multiop close failed"
5033
5034         for (( i=0; i < 2; i++ )) ; do
5035                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
5036                 [ "$mtime1" = "$mtime2" ] ||
5037                         error "mtime is lost on close: $mtime2, " \
5038                               "should be $mtime1"
5039
5040                 cancel_lru_locks
5041                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
5042         done
5043         lctl set_param fail_loc=0
5044         stop_full_debug_logging
5045 }
5046 run_test 39j "write, rename, close, stat ======================="
5047
5048 test_39k() {
5049         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5050
5051         touch $DIR1/$tfile
5052         sleep 1
5053
5054         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c || error "multiop failed"
5055         local multipid=$!
5056         local mtime1=`stat -c %Y $DIR1/$tfile`
5057
5058         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
5059
5060         kill -USR1 $multipid
5061         wait $multipid || error "multiop close failed"
5062
5063         for (( i=0; i < 2; i++ )) ; do
5064                 local mtime2=`stat -c %Y $DIR1/$tfile`
5065
5066                 [ "$mtime2" = $TEST_39_MTIME ] || \
5067                         error "mtime is lost on close: $mtime2, should be $TEST_39_MTIME"
5068
5069                 cancel_lru_locks
5070                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
5071         done
5072 }
5073 run_test 39k "write, utime, close, stat ========================"
5074
5075 # this should be set to future
5076 TEST_39_ATIME=`date -d "1 year" +%s`
5077
5078 test_39l() {
5079         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5080         remote_mds_nodsh && skip "remote MDS with nodsh"
5081
5082         local atime_diff=$(do_facet $SINGLEMDS \
5083                                 lctl get_param -n mdd.*MDT0000*.atime_diff)
5084         rm -rf $DIR/$tdir
5085         mkdir_on_mdt0 $DIR/$tdir
5086
5087         # test setting directory atime to future
5088         touch -a -d @$TEST_39_ATIME $DIR/$tdir
5089         local atime=$(stat -c %X $DIR/$tdir)
5090         [ "$atime" = $TEST_39_ATIME ] ||
5091                 error "atime is not set to future: $atime, $TEST_39_ATIME"
5092
5093         # test setting directory atime from future to now
5094         local now=$(date +%s)
5095         touch -a -d @$now $DIR/$tdir
5096
5097         atime=$(stat -c %X $DIR/$tdir)
5098         [ "$atime" -eq "$now"  ] ||
5099                 error "atime is not updated from future: $atime, $now"
5100
5101         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=2
5102         sleep 3
5103
5104         # test setting directory atime when now > dir atime + atime_diff
5105         local d1=$(date +%s)
5106         ls $DIR/$tdir
5107         local d2=$(date +%s)
5108         cancel_lru_locks mdc
5109         atime=$(stat -c %X $DIR/$tdir)
5110         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
5111                 error "atime is not updated  : $atime, should be $d2"
5112
5113         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=60
5114         sleep 3
5115
5116         # test not setting directory atime when now < dir atime + atime_diff
5117         ls $DIR/$tdir
5118         cancel_lru_locks mdc
5119         atime=$(stat -c %X $DIR/$tdir)
5120         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
5121                 error "atime is updated to $atime, should remain $d1<atime<$d2"
5122
5123         do_facet $SINGLEMDS \
5124                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
5125 }
5126 run_test 39l "directory atime update ==========================="
5127
5128 test_39m() {
5129         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5130
5131         touch $DIR1/$tfile
5132         sleep 2
5133         local far_past_mtime=$(date -d "May 29 1953" +%s)
5134         local far_past_atime=$(date -d "Dec 17 1903" +%s)
5135
5136         touch -m -d @$far_past_mtime $DIR1/$tfile
5137         touch -a -d @$far_past_atime $DIR1/$tfile
5138
5139         for (( i=0; i < 2; i++ )) ; do
5140                 local timestamps=$(stat -c "%X %Y" $DIR1/$tfile)
5141                 [ "$timestamps" = "$far_past_atime $far_past_mtime" ] || \
5142                         error "atime or mtime set incorrectly"
5143
5144                 cancel_lru_locks $OSC
5145                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
5146         done
5147 }
5148 run_test 39m "test atime and mtime before 1970"
5149
5150 test_39n() { # LU-3832
5151         remote_mds_nodsh && skip "remote MDS with nodsh"
5152
5153         local atime_diff=$(do_facet $SINGLEMDS \
5154                 lctl get_param -n mdd.*MDT0000*.atime_diff)
5155         local atime0
5156         local atime1
5157         local atime2
5158
5159         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=1
5160
5161         rm -rf $DIR/$tfile
5162         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 status=noxfer
5163         atime0=$(stat -c %X $DIR/$tfile)
5164
5165         sleep 5
5166         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
5167         atime1=$(stat -c %X $DIR/$tfile)
5168
5169         sleep 5
5170         cancel_lru_locks mdc
5171         cancel_lru_locks osc
5172         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
5173         atime2=$(stat -c %X $DIR/$tfile)
5174
5175         do_facet $SINGLEMDS \
5176                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
5177
5178         [ "$atime0" -eq "$atime1" ] || error "atime0 $atime0 != atime1 $atime1"
5179         [ "$atime1" -eq "$atime2" ] || error "atime0 $atime0 != atime1 $atime1"
5180 }
5181 run_test 39n "check that O_NOATIME is honored"
5182
5183 test_39o() {
5184         TESTDIR=$DIR/$tdir/$tfile
5185         [ -e $TESTDIR ] && rm -rf $TESTDIR
5186         mkdir -p $TESTDIR
5187         cd $TESTDIR
5188         links1=2
5189         ls
5190         mkdir a b
5191         ls
5192         links2=$(stat -c %h .)
5193         [ $(($links1 + 2)) != $links2 ] &&
5194                 error "wrong links count $(($links1 + 2)) != $links2"
5195         rmdir b
5196         links3=$(stat -c %h .)
5197         [ $(($links1 + 1)) != $links3 ] &&
5198                 error "wrong links count $links1 != $links3"
5199         return 0
5200 }
5201 run_test 39o "directory cached attributes updated after create"
5202
5203 test_39p() {
5204         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
5205
5206         local MDTIDX=1
5207         TESTDIR=$DIR/$tdir/$tdir
5208         [ -e $TESTDIR ] && rm -rf $TESTDIR
5209         test_mkdir -p $TESTDIR
5210         cd $TESTDIR
5211         links1=2
5212         ls
5213         test_mkdir -i $MDTIDX $TESTDIR/remote_dir1
5214         test_mkdir -i $MDTIDX $TESTDIR/remote_dir2
5215         ls
5216         links2=$(stat -c %h .)
5217         [ $(($links1 + 2)) != $links2 ] &&
5218                 error "wrong links count $(($links1 + 2)) != $links2"
5219         rmdir remote_dir2
5220         links3=$(stat -c %h .)
5221         [ $(($links1 + 1)) != $links3 ] &&
5222                 error "wrong links count $links1 != $links3"
5223         return 0
5224 }
5225 run_test 39p "remote directory cached attributes updated after create ========"
5226
5227 test_39r() {
5228         [ $OST1_VERSION -ge $(version_code 2.13.52) ] ||
5229                 skip "no atime update on old OST"
5230         if [ "$ost1_FSTYPE" != ldiskfs ]; then
5231                 skip_env "ldiskfs only test"
5232         fi
5233
5234         local saved_adiff
5235         saved_adiff=$(do_facet ost1 \
5236                 lctl get_param -n obdfilter.*OST0000.atime_diff)
5237         stack_trap "do_facet ost1 \
5238                 lctl set_param obdfilter.*.atime_diff=$saved_adiff"
5239
5240         do_facet ost1 "lctl set_param obdfilter.*.atime_diff=5"
5241
5242         $LFS setstripe -i 0 $DIR/$tfile
5243         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 ||
5244                 error "can't write initial file"
5245         cancel_lru_locks osc
5246
5247         # exceed atime_diff and access file
5248         sleep 10
5249         dd if=$DIR/$tfile of=/dev/null bs=4k count=1 ||
5250                 error "can't udpate atime"
5251
5252         local atime_cli=$(stat -c %X $DIR/$tfile)
5253         echo "client atime: $atime_cli"
5254         # allow atime update to be written to device
5255         do_facet ost1 "$LCTL set_param -n osd*.*OST*.force_sync 1"
5256         sleep 5
5257
5258         local ostdev=$(ostdevname 1)
5259         local fid=($($LFS getstripe $DIR/$tfile | grep 0x))
5260         local seq=${fid[3]#0x}
5261         local oid=${fid[1]}
5262         local oid_hex
5263
5264         if [ $seq == 0 ]; then
5265                 oid_hex=${fid[1]}
5266         else
5267                 oid_hex=${fid[2]#0x}
5268         fi
5269         local objpath="O/$seq/d$(($oid % 32))/$oid_hex"
5270         local cmd="debugfs -c -R \\\"stat $objpath\\\" $ostdev"
5271
5272         echo "OST atime: $(do_facet ost1 "$cmd" |& grep atime)"
5273         local atime_ost=$(do_facet ost1 "$cmd" |&
5274                           awk -F'[: ]' '/atime:/ { print $4 }')
5275         (( atime_cli == atime_ost )) ||
5276                 error "atime on client $atime_cli != ost $atime_ost"
5277 }
5278 run_test 39r "lazy atime update on OST"
5279
5280 test_39q() { # LU-8041
5281         local testdir=$DIR/$tdir
5282         mkdir -p $testdir
5283         multiop_bg_pause $testdir D_c || error "multiop failed"
5284         local multipid=$!
5285         cancel_lru_locks mdc
5286         kill -USR1 $multipid
5287         local atime=$(stat -c %X $testdir)
5288         [ "$atime" -ne 0 ] || error "atime is zero"
5289 }
5290 run_test 39q "close won't zero out atime"
5291
5292 test_39s() {
5293         local atime0
5294         local atime1
5295         local atime2
5296         local atime3
5297         local atime4
5298
5299         umount_client $MOUNT
5300         mount_client $MOUNT relatime
5301
5302         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 status=noxfer conv=fsync
5303         atime0=$(stat -c %X $DIR/$tfile)
5304
5305         # First read updates atime
5306         sleep 1
5307         cat $DIR/$tfile >/dev/null
5308         atime1=$(stat -c %X $DIR/$tfile) # (atime = atime0 + 1)
5309
5310         # Next reads do not update atime
5311         sleep 1
5312         cat $DIR/$tfile >/dev/null
5313         atime2=$(stat -c %X $DIR/$tfile) # (atime = atime0 + 1)
5314
5315         # If mtime is greater than atime, atime is updated
5316         sleep 1
5317         touch -m $DIR/$tfile # (mtime = now)
5318         sleep 1
5319         cat $DIR/$tfile >/dev/null # (atime is updated because atime < mtime)
5320         atime3=$(stat -c %X $DIR/$tfile) # (atime = mtime = atime0 + 3)
5321
5322         # Next reads do not update atime
5323         sleep 1
5324         cat $DIR/$tfile >/dev/null
5325         atime4=$(stat -c %X $DIR/$tfile)
5326
5327         # Remount the client to clear 'relatime' option
5328         remount_client $MOUNT
5329
5330         (( atime0 < atime1 )) ||
5331                 error "atime $atime0 should be smaller than $atime1"
5332         (( atime1 == atime2 )) ||
5333                 error "atime $atime1 was updated to $atime2"
5334         (( atime1 < atime3 )) || error "atime1 $atime1 != atime3 $atime3"
5335         (( atime3 == atime4 )) || error "atime3 $atime3 != atime4 $atime4"
5336 }
5337 run_test 39s "relatime is supported"
5338
5339 test_40() {
5340         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
5341         $RUNAS $OPENFILE -f O_WRONLY:O_TRUNC $DIR/$tfile &&
5342                 error "openfile O_WRONLY:O_TRUNC $tfile failed"
5343         $CHECKSTAT -t file -s 4096 $DIR/$tfile ||
5344                 error "$tfile is not 4096 bytes in size"
5345 }
5346 run_test 40 "failed open(O_TRUNC) doesn't truncate ============="
5347
5348 test_41() {
5349         # bug 1553
5350         small_write $DIR/f41 18
5351 }
5352 run_test 41 "test small file write + fstat ====================="
5353
5354 count_ost_writes() {
5355         lctl get_param -n ${OSC}.*.stats |
5356                 awk -vwrites=0 '/ost_write/ { writes += $2 } \
5357                         END { printf("%0.0f", writes) }'
5358 }
5359
5360 # decent default
5361 WRITEBACK_SAVE=500
5362 DIRTY_RATIO_SAVE=40
5363 MAX_DIRTY_RATIO=50
5364 BG_DIRTY_RATIO_SAVE=10
5365 MAX_BG_DIRTY_RATIO=25
5366
5367 start_writeback() {
5368         trap 0
5369         # in 2.6, restore /proc/sys/vm/dirty_writeback_centisecs,
5370         # dirty_ratio, dirty_background_ratio
5371         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
5372                 sysctl -w vm.dirty_writeback_centisecs=$WRITEBACK_SAVE
5373                 sysctl -w vm.dirty_background_ratio=$BG_DIRTY_RATIO_SAVE
5374                 sysctl -w vm.dirty_ratio=$DIRTY_RATIO_SAVE
5375         else
5376                 # if file not here, we are a 2.4 kernel
5377                 kill -CONT `pidof kupdated`
5378         fi
5379 }
5380
5381 stop_writeback() {
5382         # setup the trap first, so someone cannot exit the test at the
5383         # exact wrong time and mess up a machine
5384         trap start_writeback EXIT
5385         # in 2.6, save and 0 /proc/sys/vm/dirty_writeback_centisecs
5386         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
5387                 WRITEBACK_SAVE=`sysctl -n vm.dirty_writeback_centisecs`
5388                 sysctl -w vm.dirty_writeback_centisecs=0
5389                 sysctl -w vm.dirty_writeback_centisecs=0
5390                 # save and increase /proc/sys/vm/dirty_ratio
5391                 DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_ratio`
5392                 sysctl -w vm.dirty_ratio=$MAX_DIRTY_RATIO
5393                 # save and increase /proc/sys/vm/dirty_background_ratio
5394                 BG_DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_background_ratio`
5395                 sysctl -w vm.dirty_background_ratio=$MAX_BG_DIRTY_RATIO
5396         else
5397                 # if file not here, we are a 2.4 kernel
5398                 kill -STOP `pidof kupdated`
5399         fi
5400 }
5401
5402 # ensure that all stripes have some grant before we test client-side cache
5403 setup_test42() {
5404         for i in `seq -f $DIR/f42-%g 1 $OSTCOUNT`; do
5405                 dd if=/dev/zero of=$i bs=4k count=1
5406                 rm $i
5407         done
5408 }
5409
5410 # Tests 42* verify that our behaviour is correct WRT caching, file closure,
5411 # file truncation, and file removal.
5412 test_42a() {
5413         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5414
5415         setup_test42
5416         cancel_lru_locks $OSC
5417         stop_writeback
5418         sync; sleep 1; sync # just to be safe
5419         BEFOREWRITES=`count_ost_writes`
5420         lctl get_param -n osc.*[oO][sS][cC][_-]*.cur_grant_bytes | grep "[0-9]"
5421         dd if=/dev/zero of=$DIR/f42a bs=1024 count=100
5422         AFTERWRITES=`count_ost_writes`
5423         [ $BEFOREWRITES -eq $AFTERWRITES ] || \
5424                 error "$BEFOREWRITES < $AFTERWRITES"
5425         start_writeback
5426 }
5427 run_test 42a "ensure that we don't flush on close"
5428
5429 test_42b() {
5430         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5431
5432         setup_test42
5433         cancel_lru_locks $OSC
5434         stop_writeback
5435         sync
5436         dd if=/dev/zero of=$DIR/f42b bs=1024 count=100
5437         BEFOREWRITES=$(count_ost_writes)
5438         $MUNLINK $DIR/f42b || error "$MUNLINK $DIR/f42b: $?"
5439         AFTERWRITES=$(count_ost_writes)
5440         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
5441                 error "$BEFOREWRITES < $AFTERWRITES on unlink"
5442         fi
5443         BEFOREWRITES=$(count_ost_writes)
5444         sync || error "sync: $?"
5445         AFTERWRITES=$(count_ost_writes)
5446         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
5447                 error "$BEFOREWRITES < $AFTERWRITES on sync"
5448         fi
5449         dmesg | grep 'error from obd_brw_async' && error 'error writing back'
5450         start_writeback
5451         return 0
5452 }
5453 run_test 42b "test destroy of file with cached dirty data ======"
5454
5455 # if these tests just want to test the effect of truncation,
5456 # they have to be very careful.  consider:
5457 # - the first open gets a {0,EOF}PR lock
5458 # - the first write conflicts and gets a {0, count-1}PW
5459 # - the rest of the writes are under {count,EOF}PW
5460 # - the open for truncate tries to match a {0,EOF}PR
5461 #   for the filesize and cancels the PWs.
5462 # any number of fixes (don't get {0,EOF} on open, match
5463 # composite locks, do smarter file size management) fix
5464 # this, but for now we want these tests to verify that
5465 # the cancellation with truncate intent works, so we
5466 # start the file with a full-file pw lock to match against
5467 # until the truncate.
5468 trunc_test() {
5469         test=$1
5470         file=$DIR/$test
5471         offset=$2
5472         cancel_lru_locks $OSC
5473         stop_writeback
5474         # prime the file with 0,EOF PW to match
5475         touch $file
5476         $TRUNCATE $file 0
5477         sync; sync
5478         # now the real test..
5479         dd if=/dev/zero of=$file bs=1024 count=100
5480         BEFOREWRITES=`count_ost_writes`
5481         $TRUNCATE $file $offset
5482         cancel_lru_locks $OSC
5483         AFTERWRITES=`count_ost_writes`
5484         start_writeback
5485 }
5486
5487 test_42c() {
5488         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5489
5490         trunc_test 42c 1024
5491         [ $BEFOREWRITES -eq $AFTERWRITES ] &&
5492                 error "beforewrites $BEFOREWRITES == afterwrites $AFTERWRITES on truncate"
5493         rm $file
5494 }
5495 run_test 42c "test partial truncate of file with cached dirty data"
5496
5497 test_42d() {
5498         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5499
5500         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
5501         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
5502         $LCTL set_param debug=+cache
5503
5504         trunc_test 42d 0
5505         [ $BEFOREWRITES -eq $AFTERWRITES ] ||
5506                 error "beforewrites $BEFOREWRITES != afterwrites $AFTERWRITES on truncate"
5507         rm $file
5508 }
5509 run_test 42d "test complete truncate of file with cached dirty data"
5510
5511 test_42e() { # bug22074
5512         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5513
5514         local TDIR=$DIR/${tdir}e
5515         local pages=16 # hardcoded 16 pages, don't change it.
5516         local files=$((OSTCOUNT * 500)) # hopefully 500 files on each OST
5517         local proc_osc0="osc.${FSNAME}-OST0000-osc-[^MDT]*"
5518         local max_dirty_mb
5519         local warmup_files
5520
5521         test_mkdir $DIR/${tdir}e
5522         $LFS setstripe -c 1 $TDIR
5523         createmany -o $TDIR/f $files
5524
5525         max_dirty_mb=$($LCTL get_param -n $proc_osc0/max_dirty_mb)
5526
5527         # we assume that with $OSTCOUNT files, at least one of them will
5528         # be allocated on OST0.
5529         warmup_files=$((OSTCOUNT * max_dirty_mb))
5530         createmany -o $TDIR/w $warmup_files
5531
5532         # write a large amount of data into one file and sync, to get good
5533         # avail_grant number from OST.
5534         for ((i=0; i<$warmup_files; i++)); do
5535                 idx=$($LFS getstripe -i $TDIR/w$i)
5536                 [ $idx -ne 0 ] && continue
5537                 dd if=/dev/zero of=$TDIR/w$i bs="$max_dirty_mb"M count=1
5538                 break
5539         done
5540         [[ $i -gt $warmup_files ]] && error "OST0 is still cold"
5541         sync
5542         $LCTL get_param $proc_osc0/cur_dirty_bytes
5543         $LCTL get_param $proc_osc0/cur_grant_bytes
5544
5545         # create as much dirty pages as we can while not to trigger the actual
5546         # RPCs directly. but depends on the env, VFS may trigger flush during this
5547         # period, hopefully we are good.
5548         for ((i=0; i<$warmup_files; i++)); do
5549                 idx=$($LFS getstripe -i $TDIR/w$i)
5550                 [ $idx -ne 0 ] && continue
5551                 dd if=/dev/zero of=$TDIR/w$i bs=1M count=1 2>/dev/null
5552         done
5553         $LCTL get_param $proc_osc0/cur_dirty_bytes
5554         $LCTL get_param $proc_osc0/cur_grant_bytes
5555
5556         # perform the real test
5557         $LCTL set_param $proc_osc0/rpc_stats 0
5558         for ((;i<$files; i++)); do
5559                 [ $($LFS getstripe -i $TDIR/f$i) -eq 0 ] || continue
5560                 dd if=/dev/zero of=$TDIR/f$i bs=$PAGE_SIZE count=$pages 2>/dev/null
5561         done
5562         sync
5563         $LCTL get_param $proc_osc0/rpc_stats
5564
5565         local percent=0
5566         local have_ppr=false
5567         $LCTL get_param $proc_osc0/rpc_stats |
5568                 while read PPR RRPC RPCT RCUM BAR WRPC WPCT WCUM; do
5569                         # skip lines until we are at the RPC histogram data
5570                         [ "$PPR" == "pages" ] && have_ppr=true && continue
5571                         $have_ppr || continue
5572
5573                         # we only want the percent stat for < 16 pages
5574                         [[ $(echo $PPR | tr -d ':') -ge $pages ]] && break
5575
5576                         percent=$((percent + WPCT))
5577                         if [[ $percent -gt 15 ]]; then
5578                                 error "less than 16-pages write RPCs" \
5579                                       "$percent% > 15%"
5580                                 break
5581                         fi
5582                 done
5583         rm -rf $TDIR
5584 }
5585 run_test 42e "verify sub-RPC writes are not done synchronously"
5586
5587 test_43A() { # was test_43
5588         test_mkdir $DIR/$tdir
5589         cp -p /bin/ls $DIR/$tdir/$tfile
5590         $MULTIOP $DIR/$tdir/$tfile Ow_c &
5591         pid=$!
5592         # give multiop a chance to open
5593         sleep 1
5594
5595         $DIR/$tdir/$tfile && error "execute $DIR/$tdir/$tfile succeeded" || true
5596         kill -USR1 $pid
5597         # Wait for multiop to exit
5598         wait $pid
5599 }
5600 run_test 43A "execution of file opened for write should return -ETXTBSY"
5601
5602 test_43a() {
5603         test_mkdir $DIR/$tdir
5604         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
5605         $DIR/$tdir/sleep 60 &
5606         SLEEP_PID=$!
5607         # Make sure exec of $tdir/sleep wins race with truncate
5608         sleep 1
5609         $MULTIOP $DIR/$tdir/sleep Oc && error "expected error, got success"
5610         kill $SLEEP_PID
5611 }
5612 run_test 43a "open(RDWR) of file being executed should return -ETXTBSY"
5613
5614 test_43b() {
5615         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5616
5617         test_mkdir $DIR/$tdir
5618         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
5619         $DIR/$tdir/sleep 60 &
5620         SLEEP_PID=$!
5621         # Make sure exec of $tdir/sleep wins race with truncate
5622         sleep 1
5623         $TRUNCATE $DIR/$tdir/sleep 0 && error "expected error, got success"
5624         kill $SLEEP_PID
5625 }
5626 run_test 43b "truncate of file being executed should return -ETXTBSY"
5627
5628 test_43c() {
5629         local testdir="$DIR/$tdir"
5630         test_mkdir $testdir
5631         cp $SHELL $testdir/
5632         ( cd $(dirname $SHELL) && md5sum $(basename $SHELL) ) |
5633                 ( cd $testdir && md5sum -c )
5634 }
5635 run_test 43c "md5sum of copy into lustre"
5636
5637 test_44A() { # was test_44
5638         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5639
5640         dd if=/dev/zero of=$DIR/f1 bs=4k count=1 seek=1023
5641         dd if=$DIR/f1 bs=4k count=1 > /dev/null
5642 }
5643 run_test 44A "zero length read from a sparse stripe"
5644
5645 test_44a() {
5646         local nstripe=$($LFS getstripe -c -d $DIR)
5647         [ -z "$nstripe" ] && skip "can't get stripe info"
5648         [[ $nstripe -gt $OSTCOUNT ]] &&
5649                 skip "Wrong default stripe_count: $nstripe OSTCOUNT: $OSTCOUNT"
5650
5651         local stride=$($LFS getstripe -S -d $DIR)
5652         if [[ $nstripe -eq 0 || $nstripe -eq -1 ]]; then
5653                 nstripe=$($LFS df $DIR | grep OST: | wc -l)
5654         fi
5655
5656         OFFSETS="0 $((stride/2)) $((stride-1))"
5657         for offset in $OFFSETS; do
5658                 for i in $(seq 0 $((nstripe-1))); do
5659                         local GLOBALOFFSETS=""
5660                         # size in Bytes
5661                         local size=$((((i + 2 * $nstripe )*$stride + $offset)))
5662                         local myfn=$DIR/d44a-$size
5663                         echo "--------writing $myfn at $size"
5664                         ll_sparseness_write $myfn $size ||
5665                                 error "ll_sparseness_write"
5666                         GLOBALOFFSETS="$GLOBALOFFSETS $size"
5667                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
5668                                 error "ll_sparseness_verify $GLOBALOFFSETS"
5669
5670                         for j in $(seq 0 $((nstripe-1))); do
5671                                 # size in Bytes
5672                                 size=$((((j + $nstripe )*$stride + $offset)))
5673                                 ll_sparseness_write $myfn $size ||
5674                                         error "ll_sparseness_write"
5675                                 GLOBALOFFSETS="$GLOBALOFFSETS $size"
5676                         done
5677                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
5678                                 error "ll_sparseness_verify $GLOBALOFFSETS"
5679                         rm -f $myfn
5680                 done
5681         done
5682 }
5683 run_test 44a "test sparse pwrite ==============================="
5684
5685 dirty_osc_total() {
5686         tot=0
5687         for d in `lctl get_param -n ${OSC}.*.cur_dirty_bytes`; do
5688                 tot=$(($tot + $d))
5689         done
5690         echo $tot
5691 }
5692 do_dirty_record() {
5693         before=`dirty_osc_total`
5694         echo executing "\"$*\""
5695         eval $*
5696         after=`dirty_osc_total`
5697         echo before $before, after $after
5698 }
5699 test_45() {
5700         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5701
5702         f="$DIR/f45"
5703         # Obtain grants from OST if it supports it
5704         echo blah > ${f}_grant
5705         stop_writeback
5706         sync
5707         do_dirty_record "echo blah > $f"
5708         [[ $before -eq $after ]] && error "write wasn't cached"
5709         do_dirty_record "> $f"
5710         [[ $before -gt $after ]] || error "truncate didn't lower dirty count"
5711         do_dirty_record "echo blah > $f"
5712         [[ $before -eq $after ]] && error "write wasn't cached"
5713         do_dirty_record "sync"
5714         [[ $before -gt $after ]] || error "writeback didn't lower dirty count"
5715         do_dirty_record "echo blah > $f"
5716         [[ $before -eq $after ]] && error "write wasn't cached"
5717         do_dirty_record "cancel_lru_locks osc"
5718         [[ $before -gt $after ]] ||
5719                 error "lock cancellation didn't lower dirty count"
5720         start_writeback
5721 }
5722 run_test 45 "osc io page accounting ============================"
5723
5724 # in a 2 stripe file (lov.sh), page 1023 maps to page 511 in its object.  this
5725 # test tickles a bug where re-dirtying a page was failing to be mapped to the
5726 # objects offset and an assert hit when an rpc was built with 1023's mapped
5727 # offset 511 and 511's raw 511 offset. it also found general redirtying bugs.
5728 test_46() {
5729         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5730
5731         f="$DIR/f46"
5732         stop_writeback
5733         sync
5734         dd if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5735         sync
5736         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=1023 count=1
5737         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5738         sync
5739         start_writeback
5740 }
5741 run_test 46 "dirtying a previously written page ================"
5742
5743 # test_47 is removed "Device nodes check" is moved to test_28
5744
5745 test_48a() { # bug 2399
5746         [ "$mds1_FSTYPE" = "zfs" ] &&
5747         [ $MDS1_VERSION -lt $(version_code 2.3.63) ] &&
5748                 skip "MDS prior to 2.3.63 handle ZFS dir .. incorrectly"
5749
5750         test_mkdir $DIR/$tdir
5751         cd $DIR/$tdir
5752         mv $DIR/$tdir $DIR/$tdir.new || error "move directory failed"
5753         test_mkdir $DIR/$tdir
5754         touch foo || error "'touch foo' failed after recreating cwd"
5755         test_mkdir bar
5756         touch .foo || error "'touch .foo' failed after recreating cwd"
5757         test_mkdir .bar
5758         ls . > /dev/null || error "'ls .' failed after recreating cwd"
5759         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5760         cd . || error "'cd .' failed after recreating cwd"
5761         mkdir . && error "'mkdir .' worked after recreating cwd"
5762         rmdir . && error "'rmdir .' worked after recreating cwd"
5763         ln -s . baz || error "'ln -s .' failed after recreating cwd"
5764         cd .. || error "'cd ..' failed after recreating cwd"
5765 }
5766 run_test 48a "Access renamed working dir (should return errors)="
5767
5768 test_48b() { # bug 2399
5769         rm -rf $DIR/$tdir
5770         test_mkdir $DIR/$tdir
5771         cd $DIR/$tdir
5772         rmdir $DIR/$tdir || error "remove cwd $DIR/$tdir failed"
5773         touch foo && error "'touch foo' worked after removing cwd"
5774         mkdir foo && error "'mkdir foo' worked after removing cwd"
5775         touch .foo && error "'touch .foo' worked after removing cwd"
5776         mkdir .foo && error "'mkdir .foo' worked after removing cwd"
5777         ls . > /dev/null && error "'ls .' worked after removing cwd"
5778         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5779         mkdir . && error "'mkdir .' worked after removing cwd"
5780         rmdir . && error "'rmdir .' worked after removing cwd"
5781         ln -s . foo && error "'ln -s .' worked after removing cwd"
5782         cd .. || echo "'cd ..' failed after removing cwd `pwd`"  #bug 3517
5783 }
5784 run_test 48b "Access removed working dir (should return errors)="
5785
5786 test_48c() { # bug 2350
5787         #lctl set_param debug=-1
5788         #set -vx
5789         rm -rf $DIR/$tdir
5790         test_mkdir -p $DIR/$tdir/dir
5791         cd $DIR/$tdir/dir
5792         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5793         $TRACE touch foo && error "touch foo worked after removing cwd"
5794         $TRACE mkdir foo && error "'mkdir foo' worked after removing cwd"
5795         touch .foo && error "touch .foo worked after removing cwd"
5796         mkdir .foo && error "mkdir .foo worked after removing cwd"
5797         $TRACE ls . && error "'ls .' worked after removing cwd"
5798         $TRACE ls .. || error "'ls ..' failed after removing cwd"
5799         $TRACE mkdir . && error "'mkdir .' worked after removing cwd"
5800         $TRACE rmdir . && error "'rmdir .' worked after removing cwd"
5801         $TRACE ln -s . foo && error "'ln -s .' worked after removing cwd"
5802         $TRACE cd .. || echo "'cd ..' failed after removing cwd `pwd`" #bug 3415
5803 }
5804 run_test 48c "Access removed working subdir (should return errors)"
5805
5806 test_48d() { # bug 2350
5807         #lctl set_param debug=-1
5808         #set -vx
5809         rm -rf $DIR/$tdir
5810         test_mkdir -p $DIR/$tdir/dir
5811         cd $DIR/$tdir/dir
5812         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5813         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5814         $TRACE touch foo && error "'touch foo' worked after removing parent"
5815         $TRACE mkdir foo && error "mkdir foo worked after removing parent"
5816         touch .foo && error "'touch .foo' worked after removing parent"
5817         mkdir .foo && error "mkdir .foo worked after removing parent"
5818         $TRACE ls . && error "'ls .' worked after removing parent"
5819         $TRACE ls .. && error "'ls ..' worked after removing parent"
5820         $TRACE mkdir . && error "'mkdir .' worked after removing parent"
5821         $TRACE rmdir . && error "'rmdir .' worked after removing parent"
5822         $TRACE ln -s . foo && error "'ln -s .' worked after removing parent"
5823         true
5824 }
5825 run_test 48d "Access removed parent subdir (should return errors)"
5826
5827 test_48e() { # bug 4134
5828         #lctl set_param debug=-1
5829         #set -vx
5830         rm -rf $DIR/$tdir
5831         test_mkdir -p $DIR/$tdir/dir
5832         cd $DIR/$tdir/dir
5833         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5834         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5835         $TRACE touch $DIR/$tdir || error "'touch $DIR/$tdir' failed"
5836         $TRACE chmod +x $DIR/$tdir || error "'chmod +x $DIR/$tdir' failed"
5837         # On a buggy kernel addition of "touch foo" after cd .. will
5838         # produce kernel oops in lookup_hash_it
5839         touch ../foo && error "'cd ..' worked after recreate parent"
5840         cd $DIR
5841         $TRACE rm $DIR/$tdir || error "rm '$DIR/$tdir' failed"
5842 }
5843 run_test 48e "Access to recreated parent subdir (should return errors)"
5844
5845 test_48f() {
5846         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
5847                 skip "need MDS >= 2.13.55"
5848         [[ $MDSCOUNT -ge 2 ]] || skip "needs >= 2 MDTs"
5849         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] ||
5850                 skip "needs different host for mdt1 mdt2"
5851         [[ $(facet_fstype mds1) == ldiskfs ]] || skip "ldiskfs only"
5852
5853         $LFS mkdir -i0 $DIR/$tdir
5854         $LFS mkdir -i 1 $DIR/$tdir/sub1 $DIR/$tdir/sub2 $DIR/$tdir/sub3
5855
5856         for d in sub1 sub2 sub3; do
5857                 #define OBD_FAIL_OSD_REF_DEL    0x19c
5858                 do_facet mds1 $LCTL set_param fail_loc=0x8000019c
5859                 rm -rf $DIR/$tdir/$d && error "rm $d should fail"
5860         done
5861
5862         rm -d --interactive=never $DIR/$tdir || error "rm $tdir fail"
5863 }
5864 run_test 48f "non-zero nlink dir unlink won't LBUG()"
5865
5866 test_49() { # LU-1030
5867         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5868         remote_ost_nodsh && skip "remote OST with nodsh"
5869
5870         # get ost1 size - $FSNAME-OST0000
5871         ost1_size=$(do_facet ost1 $LFS df | grep ${ost1_svc} |
5872                 awk '{ print $4 }')
5873         # write 800M at maximum
5874         [[ $ost1_size -lt 2 ]] && ost1_size=2
5875         [[ $ost1_size -gt 819200 ]] && ost1_size=819200
5876
5877         $LFS setstripe -c 1 -i 0 $DIR/$tfile
5878         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((ost1_size >> 2)) &
5879         local dd_pid=$!
5880
5881         # change max_pages_per_rpc while writing the file
5882         local osc1_mppc=osc.$(get_osc_import_name client ost1).max_pages_per_rpc
5883         local orig_mppc=$($LCTL get_param -n $osc1_mppc)
5884         # loop until dd process exits
5885         while ps ax -opid | grep -wq $dd_pid; do
5886                 $LCTL set_param $osc1_mppc=$((RANDOM % 256 + 1))
5887                 sleep $((RANDOM % 5 + 1))
5888         done
5889         # restore original max_pages_per_rpc
5890         $LCTL set_param $osc1_mppc=$orig_mppc
5891         rm $DIR/$tfile || error "rm $DIR/$tfile failed"
5892 }
5893 run_test 49 "Change max_pages_per_rpc won't break osc extent"
5894
5895 test_50() {
5896         # bug 1485
5897         test_mkdir $DIR/$tdir
5898         cd $DIR/$tdir
5899         ls /proc/$$/cwd || error "ls /proc/$$/cwd failed"
5900 }
5901 run_test 50 "special situations: /proc symlinks  ==============="
5902
5903 test_51a() {    # was test_51
5904         # bug 1516 - create an empty entry right after ".." then split dir
5905         test_mkdir -c1 $DIR/$tdir
5906         touch $DIR/$tdir/foo
5907         $MCREATE $DIR/$tdir/bar
5908         rm $DIR/$tdir/foo
5909         createmany -m $DIR/$tdir/longfile 201
5910         FNUM=202
5911         while [[ $(ls -sd $DIR/$tdir | awk '{ print $1 }') -eq 4 ]]; do
5912                 $MCREATE $DIR/$tdir/longfile$FNUM
5913                 FNUM=$(($FNUM + 1))
5914                 echo -n "+"
5915         done
5916         echo
5917         ls -l $DIR/$tdir > /dev/null || error "ls -l $DIR/$tdir failed"
5918 }
5919 run_test 51a "special situations: split htree with empty entry =="
5920
5921 cleanup_print_lfs_df () {
5922         trap 0
5923         $LFS df
5924         $LFS df -i
5925 }
5926
5927 test_51b() {
5928         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5929
5930         local dir=$DIR/$tdir
5931         local nrdirs=$((65536 + 100))
5932
5933         # cleanup the directory
5934         rm -fr $dir
5935
5936         mkdir_on_mdt -i $((RANDOM % MDSCOUNT)) $dir
5937
5938         $LFS df
5939         $LFS df -i
5940         local mdtidx=$(printf "%04x" $($LFS getstripe -m $dir))
5941         local numfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.filesfree)
5942         [[ $numfree -lt $nrdirs ]] &&
5943                 skip "not enough free inodes ($numfree) on MDT$mdtidx"
5944
5945         # need to check free space for the directories as well
5946         local blkfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.kbytesavail)
5947         numfree=$(( blkfree / $(fs_inode_ksize) ))
5948         [[ $numfree -lt $nrdirs ]] && skip "not enough blocks ($numfree)"
5949
5950         trap cleanup_print_lfs_df EXIT
5951
5952         # create files
5953         createmany -d $dir/d $nrdirs || {
5954                 unlinkmany $dir/d $nrdirs
5955                 error "failed to create $nrdirs subdirs in MDT$mdtidx:$dir"
5956         }
5957
5958         # really created :
5959         nrdirs=$(ls -U $dir | wc -l)
5960
5961         # unlink all but 100 subdirectories, then check it still works
5962         local left=100
5963         local delete=$((nrdirs - left))
5964
5965         $LFS df
5966         $LFS df -i
5967
5968         # for ldiskfs the nlink count should be 1, but this is OSD specific
5969         # and so this is listed for informational purposes only
5970         echo "nlink before: $(stat -c %h $dir), created before: $nrdirs"
5971         unlinkmany -d $dir/d $delete ||
5972                 error "unlink of first $delete subdirs failed"
5973
5974         echo "nlink between: $(stat -c %h $dir)"
5975         local found=$(ls -U $dir | wc -l)
5976         [ $found -ne $left ] &&
5977                 error "can't find subdirs: found only $found, expected $left"
5978
5979         unlinkmany -d $dir/d $delete $left ||
5980                 error "unlink of second $left subdirs failed"
5981         # regardless of whether the backing filesystem tracks nlink accurately
5982         # or not, the nlink count shouldn't be more than "." and ".." here
5983         local after=$(stat -c %h $dir)
5984         [[ $after -gt 2 ]] && error "nlink after: $after > 2" ||
5985                 echo "nlink after: $after"
5986
5987         cleanup_print_lfs_df
5988 }
5989 run_test 51b "exceed 64k subdirectory nlink limit on create, verify unlink"
5990
5991 test_51d_sub() {
5992         local stripecount=$1
5993         local nfiles=$2
5994
5995         log "create files with stripecount=$stripecount"
5996         $LFS setstripe -C $stripecount $DIR/$tdir
5997         createmany -o $DIR/$tdir/t- $nfiles
5998         $LFS getstripe $DIR/$tdir > $TMP/$tfile
5999         for ((n = 0; n < $OSTCOUNT; n++)); do
6000                 objs[$n]=$(awk -vobjs=0 '($1 == '$n') { objs += 1 } \
6001                            END { printf("%0.0f", objs) }' $TMP/$tfile)
6002                 objs0[$n]=$(grep -A 1 idx $TMP/$tfile | awk -vobjs=0 \
6003                             '($1 == '$n') { objs += 1 } \
6004                             END { printf("%0.0f", objs) }')
6005                 log "OST$n has ${objs[$n]} objects, ${objs0[$n]} are index 0"
6006         done
6007         unlinkmany $DIR/$tdir/t- $nfiles
6008         rm  -f $TMP/$tfile
6009
6010         local nlast
6011         local min=4
6012         local max=6 # allow variance of (1 - $min/$max) = 33% by default
6013
6014         # For some combinations of stripecount and OSTCOUNT current code
6015         # is not ideal, and allocates 50% fewer *first* objects to some OSTs
6016         # than others. Rather than skipping this test entirely, check that
6017         # and keep testing to ensure imbalance does not get worse. LU-15282
6018         (( (OSTCOUNT == 6 && stripecount == 4) ||
6019            (OSTCOUNT == 10 && (stripecount == 4 || stripecount == 8)) ||
6020            (OSTCOUNT == 12 && (stripecount == 8 || stripecount == 9)))) && max=9
6021         for ((nlast=0, n = 1; n < $OSTCOUNT; nlast=n,n++)); do
6022                 (( ${objs[$n]} > ${objs[$nlast]} * 4 / 5 )) ||
6023                         { $LFS df && $LFS df -i &&
6024                         error "stripecount=$stripecount: " \
6025                               "OST $n has fewer objects vs. OST $nlast " \
6026                               "(${objs[$n]} < ${objs[$nlast]} x 4/5)"; }
6027                 (( ${objs[$n]} < ${objs[$nlast]} * 5 / 4 )) ||
6028                         { $LFS df && $LFS df -i &&
6029                         error "stripecount=$stripecount: " \
6030                               "OST $n has more objects vs. OST $nlast " \
6031                               "(${objs[$n]} > ${objs[$nlast]} x 5/4)"; }
6032
6033                 (( ${objs0[$n]} > ${objs0[$nlast]} * $min / $max )) ||
6034                         { $LFS df && $LFS df -i &&
6035                         error "stripecount=$stripecount: " \
6036                               "OST $n has fewer #0 objects vs. OST $nlast " \
6037                               "(${objs0[$n]} < ${objs0[$nlast]} x $min/$max)"; }
6038                 (( ${objs0[$n]} < ${objs0[$nlast]} * $max / $min )) ||
6039                         { $LFS df && $LFS df -i &&
6040                         error "stripecount=$stripecount: " \
6041                               "OST $n has more #0 objects vs. OST $nlast " \
6042                               "(${objs0[$n]} > ${objs0[$nlast]} x $max/$min)"; }
6043         done
6044 }
6045
6046 test_51d() {
6047         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6048         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
6049
6050         local stripecount
6051         local per_ost=100
6052         local nfiles=$((per_ost * OSTCOUNT))
6053         local mdts=$(comma_list $(mdts_nodes))
6054         local param="osp.*.create_count"
6055         local qos_old=$(do_facet mds1 \
6056                 "$LCTL get_param -n lod.$FSNAME-*.qos_threshold_rr" | head -n 1)
6057
6058         do_nodes $mdts \
6059                 "$LCTL set_param lod.$FSNAME-*.qos_threshold_rr=100"
6060         stack_trap "do_nodes $mdts \
6061                 '$LCTL set_param lod.$FSNAME-*.qos_threshold_rr=${qos_old%%%}'"
6062
6063         test_mkdir $DIR/$tdir
6064         local dirstripes=$(lfs getdirstripe -c $DIR/$tdir)
6065         (( dirstripes > 0 )) || dirstripes=1
6066
6067         # Ensure enough OST objects precreated for tests to pass without
6068         # running out of objects.  This is an LOV r-r OST algorithm test,
6069         # not an OST object precreation test.
6070         local old=$(do_facet mds1 "$LCTL get_param -n $param" | head -n 1)
6071         (( old >= nfiles )) ||
6072         {
6073                 local create_count=$((nfiles * OSTCOUNT / dirstripes))
6074
6075                 do_nodes $mdts "$LCTL set_param $param=$create_count"
6076                 stack_trap "do_nodes $mdts $LCTL set_param $param=$old"
6077
6078                 # trigger precreation from all MDTs for all OSTs
6079                 for ((i = 0; i < $MDSCOUNT * 2; i++ )); do
6080                         $LFS setstripe -c -1 $DIR/$tdir/wide.$i
6081                 done
6082         }
6083
6084         for ((stripecount = 3; stripecount <= $OSTCOUNT; stripecount++)); do
6085                 sleep 8  # allow object precreation to catch up
6086                 test_51d_sub $stripecount $nfiles
6087         done
6088 }
6089 run_test 51d "check LOV round-robin OST object distribution"
6090
6091 test_51e() {
6092         if [ "$mds1_FSTYPE" != ldiskfs ]; then
6093                 skip_env "ldiskfs only test"
6094         fi
6095
6096         test_mkdir -c1 $DIR/$tdir
6097         test_mkdir -c1 $DIR/$tdir/d0
6098
6099         touch $DIR/$tdir/d0/foo
6100         createmany -l $DIR/$tdir/d0/foo $DIR/$tdir/d0/f- 65001 &&
6101                 error "file exceed 65000 nlink limit!"
6102         unlinkmany $DIR/$tdir/d0/f- 65001
6103         return 0
6104 }
6105 run_test 51e "check file nlink limit"
6106
6107 test_51f() {
6108         test_mkdir $DIR/$tdir
6109
6110         local max=100000
6111         local ulimit_old=$(ulimit -n)
6112         local spare=20 # number of spare fd's for scripts/libraries, etc.
6113         local mdt=$($LFS getstripe -m $DIR/$tdir)
6114         local numfree=$($LFS df -i $DIR/$tdir | awk '/MDT:'$mdt'/ { print $4 }')
6115
6116         echo "MDT$mdt numfree=$numfree, max=$max"
6117         [[ $numfree -gt $max ]] && numfree=$max || numfree=$((numfree * 7 / 8))
6118         if [ $((numfree + spare)) -gt $ulimit_old ]; then
6119                 while ! ulimit -n $((numfree + spare)); do
6120                         numfree=$((numfree * 3 / 4))
6121                 done
6122                 echo "changed ulimit from $ulimit_old to $((numfree + spare))"
6123         else
6124                 echo "left ulimit at $ulimit_old"
6125         fi
6126
6127         createmany -o -k -t 120 $DIR/$tdir/f $numfree || {
6128                 unlinkmany $DIR/$tdir/f $numfree
6129                 error "create+open $numfree files in $DIR/$tdir failed"
6130         }
6131         ulimit -n $ulimit_old
6132
6133         # if createmany exits at 120s there will be fewer than $numfree files
6134         unlinkmany $DIR/$tdir/f $numfree || true
6135 }
6136 run_test 51f "check many open files limit"
6137
6138 test_52a() {
6139         [ -f $DIR/$tdir/foo ] && chattr -a $DIR/$tdir/foo
6140         test_mkdir $DIR/$tdir
6141         touch $DIR/$tdir/foo
6142         chattr +a $DIR/$tdir/foo || error "chattr +a failed"
6143         echo bar >> $DIR/$tdir/foo || error "append bar failed"
6144         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
6145         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
6146         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
6147                                         error "link worked"
6148         echo foo >> $DIR/$tdir/foo || error "append foo failed"
6149         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
6150         lsattr $DIR/$tdir/foo | egrep -q "^-+a[-e]+ $DIR/$tdir/foo" ||
6151                                                      error "lsattr"
6152         chattr -a $DIR/$tdir/foo || error "chattr -a failed"
6153         cp -r $DIR/$tdir $TMP/
6154         rm -fr $DIR/$tdir $TMP/$tdir || error "cleanup rm failed"
6155 }
6156 run_test 52a "append-only flag test (should return errors)"
6157
6158 test_52b() {
6159         [ -f $DIR/$tdir/foo ] && chattr -i $DIR/$tdir/foo
6160         test_mkdir $DIR/$tdir
6161         touch $DIR/$tdir/foo
6162         chattr +i $DIR/$tdir/foo || error "chattr +i failed"
6163         cat test > $DIR/$tdir/foo && error "cat test worked"
6164         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
6165         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
6166         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
6167                                         error "link worked"
6168         echo foo >> $DIR/$tdir/foo && error "echo worked"
6169         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
6170         [ -f $DIR/$tdir/foo ] || error "$tdir/foo is not a file"
6171         [ -f $DIR/$tdir/foo_ren ] && error "$tdir/foo_ren is not a file"
6172         lsattr $DIR/$tdir/foo | egrep -q "^-+i[-e]+ $DIR/$tdir/foo" ||
6173                                                         error "lsattr"
6174         chattr -i $DIR/$tdir/foo || error "chattr failed"
6175
6176         rm -fr $DIR/$tdir || error "unable to remove $DIR/$tdir"
6177 }
6178 run_test 52b "immutable flag test (should return errors) ======="
6179
6180 test_53() {
6181         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6182         remote_mds_nodsh && skip "remote MDS with nodsh"
6183         remote_ost_nodsh && skip "remote OST with nodsh"
6184
6185         local param
6186         local param_seq
6187         local ostname
6188         local mds_last
6189         local mds_last_seq
6190         local ost_last
6191         local ost_last_seq
6192         local ost_last_id
6193         local ostnum
6194         local node
6195         local found=false
6196         local support_last_seq=true
6197
6198         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
6199                 support_last_seq=false
6200
6201         # only test MDT0000
6202         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS)
6203         local value
6204         for value in $(do_facet $SINGLEMDS \
6205                        $LCTL get_param osp.$mdtosc.prealloc_last_id) ; do
6206                 param=$(echo ${value[0]} | cut -d "=" -f1)
6207                 ostname=$(echo $param | cut -d "." -f2 | cut -d - -f 1-2)
6208
6209                 if $support_last_seq; then
6210                         param_seq=$(echo $param |
6211                                 sed -e s/prealloc_last_id/prealloc_last_seq/g)
6212                         mds_last_seq=$(do_facet $SINGLEMDS \
6213                                        $LCTL get_param -n $param_seq)
6214                 fi
6215                 mds_last=$(do_facet $SINGLEMDS $LCTL get_param -n $param)
6216
6217                 ostnum=$(index_from_ostuuid ${ostname}_UUID)
6218                 node=$(facet_active_host ost$((ostnum+1)))
6219                 param="obdfilter.$ostname.last_id"
6220                 for ost_last in $(do_node $node $LCTL get_param -n $param) ; do
6221                         echo "$ostname.last_id=$ost_last; MDS.last_id=$mds_last"
6222                         ost_last_id=$ost_last
6223
6224                         if $support_last_seq; then
6225                                 ost_last_id=$(echo $ost_last |
6226                                               awk -F':' '{print $2}' |
6227                                               sed -e "s/^0x//g")
6228                                 ost_last_seq=$(echo $ost_last |
6229                                                awk -F':' '{print $1}')
6230                                 [[ $ost_last_seq = $mds_last_seq ]] || continue
6231                         fi
6232
6233                         if [[ $ost_last_id != $mds_last ]]; then
6234                                 error "$ost_last_id != $mds_last"
6235                         else
6236                                 found=true
6237                                 break
6238                         fi
6239                 done
6240         done
6241         $found || error "can not match last_seq/last_id for $mdtosc"
6242         return 0
6243 }
6244 run_test 53 "verify that MDS and OSTs agree on pre-creation ===="
6245
6246 test_54a() {
6247         LANG=C perl -MSocket -e ';' || skip "no Socket perl module installed"
6248
6249         LANG=C $SOCKETSERVER $DIR/socket ||
6250                 error "$SOCKETSERVER $DIR/socket failed: $?"
6251         LANG=C $SOCKETCLIENT $DIR/socket ||
6252                 error "$SOCKETCLIENT $DIR/socket failed: $?"
6253         $MUNLINK $DIR/socket || error "$MUNLINK $DIR/socket failed: $?"
6254 }
6255 run_test 54a "unix domain socket test =========================="
6256
6257 test_54b() {
6258         f="$DIR/f54b"
6259         mknod $f c 1 3
6260         chmod 0666 $f
6261         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1
6262 }
6263 run_test 54b "char device works in lustre ======================"
6264
6265 find_loop_dev() {
6266         [ -b /dev/loop/0 ] && LOOPBASE=/dev/loop/
6267         [ -b /dev/loop0 ] && LOOPBASE=/dev/loop
6268         [ -z "$LOOPBASE" ] && echo "/dev/loop/0 and /dev/loop0 gone?" && return
6269
6270         for i in $(seq 3 7); do
6271                 losetup $LOOPBASE$i > /dev/null 2>&1 && continue
6272                 LOOPDEV=$LOOPBASE$i
6273                 LOOPNUM=$i
6274                 break
6275         done
6276 }
6277
6278 cleanup_54c() {
6279         local rc=0
6280         loopdev="$DIR/loop54c"
6281
6282         trap 0
6283         $UMOUNT $DIR/$tdir || rc=$?
6284         losetup -d $loopdev || true
6285         losetup -d $LOOPDEV || true
6286         rm -rf $loopdev $DIR/$tfile $DIR/$tdir
6287         return $rc
6288 }
6289
6290 test_54c() {
6291         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6292
6293         loopdev="$DIR/loop54c"
6294
6295         find_loop_dev
6296         [ -z "$LOOPNUM" ] && skip_env "couldn't find empty loop device"
6297         trap cleanup_54c EXIT
6298         mknod $loopdev b 7 $LOOPNUM
6299         echo "make a loop file system with $DIR/$tfile on $loopdev ($LOOPNUM)."
6300         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE seek=1024 count=1 > /dev/null
6301         losetup $loopdev $DIR/$tfile ||
6302                 error "can't set up $loopdev for $DIR/$tfile"
6303         mkfs.ext2 $loopdev || error "mke2fs on $loopdev"
6304         test_mkdir $DIR/$tdir
6305         mount -t ext2 $loopdev $DIR/$tdir ||
6306                 error "error mounting $loopdev on $DIR/$tdir"
6307         dd if=/dev/zero of=$DIR/$tdir/tmp bs=$PAGE_SIZE count=30 ||
6308                 error "dd write"
6309         df $DIR/$tdir
6310         dd if=$DIR/$tdir/tmp of=/dev/zero bs=$PAGE_SIZE count=30 ||
6311                 error "dd read"
6312         cleanup_54c
6313 }
6314 run_test 54c "block device works in lustre ====================="
6315
6316 test_54d() {
6317         local pipe="$DIR/$tfile.pipe"
6318         local string="aaaaaa"
6319
6320         mknod $pipe p
6321         echo -n "$string" > $pipe &
6322         local result=$(cat $pipe)
6323         [[ "$result" == "$string" ]] || error "$result != $string"
6324 }
6325 run_test 54d "fifo device works in lustre ======================"
6326
6327 test_54e() {
6328         f="$DIR/f54e"
6329         string="aaaaaa"
6330         cp -aL /dev/console $f
6331         echo $string > $f || error "echo $string to $f failed"
6332 }
6333 run_test 54e "console/tty device works in lustre ======================"
6334
6335 test_56a() {
6336         local numfiles=3
6337         local numdirs=2
6338         local dir=$DIR/$tdir
6339
6340         rm -rf $dir
6341         test_mkdir -p $dir/dir
6342         for i in $(seq $numfiles); do
6343                 touch $dir/file$i
6344                 touch $dir/dir/file$i
6345         done
6346
6347         local numcomp=$($LFS getstripe --component-count $dir)
6348
6349         [[ $numcomp == 0 ]] && numcomp=1
6350
6351         # test lfs getstripe with --recursive
6352         local filenum=$($LFS getstripe -r $dir | egrep -c "obdidx|l_ost_idx")
6353
6354         [[ $filenum -eq $((numfiles * 2)) ]] ||
6355                 error "$LFS getstripe -r: found $filenum != $((numfiles * 2))"
6356         filenum=$($LFS getstripe $dir | egrep -c "obdidx|l_ost_idx")
6357         [[ $filenum -eq $numfiles ]] ||
6358                 error "$LFS getstripe $dir: found $filenum, not $numfiles"
6359         echo "$LFS getstripe showed obdidx or l_ost_idx"
6360
6361         # test lfs getstripe with file instead of dir
6362         filenum=$($LFS getstripe $dir/file1 | egrep -c "obdidx|l_ost_idx")
6363         [[ $filenum -eq 1 ]] ||
6364                 error "$LFS getstripe $dir/file1: found $filenum, not 1"
6365         echo "$LFS getstripe file1 passed"
6366
6367         #test lfs getstripe with --verbose
6368         filenum=$($LFS getstripe --verbose $dir | grep -c lmm_magic)
6369         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
6370                 error "$LFS getstripe --verbose $dir: "\
6371                       "got $filenum want $((numfiles * numcomp)) lmm_magic"
6372         [[ $($LFS getstripe $dir | grep -c lmm_magic) -eq 0 ]] ||
6373                 error "$LFS getstripe $dir: showed lmm_magic"
6374
6375         #test lfs getstripe with -v prints lmm_fid
6376         filenum=$($LFS getstripe -v $dir | grep -c lmm_fid)
6377         local countfids=$((numdirs + numfiles * numcomp))
6378         [[ $filenum -eq $countfids ]] ||
6379                 error "$LFS getstripe -v $dir: "\
6380                       "got $filenum want $countfids lmm_fid"
6381         [[ $($LFS getstripe $dir | grep -c lmm_fid) -eq 0 ]] ||
6382                 error "$LFS getstripe $dir: showed lmm_fid by default"
6383         echo "$LFS getstripe --verbose passed"
6384
6385         #check for FID information
6386         local fid1=$($LFS getstripe --fid $dir/file1)
6387         local fid2=$($LFS getstripe --verbose $dir/file1 |
6388                      awk '/lmm_fid: / { print $2; exit; }')
6389         local fid3=$($LFS path2fid $dir/file1)
6390
6391         [ "$fid1" != "$fid2" ] &&
6392                 error "getstripe --fid '$fid1' != getstripe --verbose '$fid2'"
6393         [ "$fid1" != "$fid3" ] &&
6394                 error "getstripe --fid '$fid1' != lfs path2fid '$fid3'"
6395         echo "$LFS getstripe --fid passed"
6396
6397         #test lfs getstripe with --obd
6398         $LFS getstripe --obd wrong_uuid $dir 2>&1 | grep -q "unknown obduuid" ||
6399                 error "$LFS getstripe --obd wrong_uuid: should return error"
6400
6401         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6402
6403         local ostidx=1
6404         local obduuid=$(ostuuid_from_index $ostidx)
6405         local found=$($LFS getstripe -r --obd $obduuid $dir |
6406                 grep 'lmm_stripe_offset:' | grep -c " $ostidx\$")
6407
6408         filenum=$($LFS getstripe -ir $dir | grep -c "^$ostidx\$")
6409         [[ $($LFS getstripe -id $dir) -ne $ostidx ]] ||
6410                 ((filenum--))
6411         [[ $($LFS getstripe -id $dir/dir) -ne $ostidx ]] ||
6412                 ((filenum--))
6413
6414         [[ $found -eq $filenum ]] ||
6415                 error "$LFS getstripe --obd: found $found expect $filenum"
6416         [[ $($LFS getstripe -r -v --obd $obduuid $dir |
6417                 sed '/^[         ]*'${ostidx}'[  ]/d' |
6418                 sed -n '/^[      ]*[0-9][0-9]*[  ]/p' | wc -l) -eq 0 ]] ||
6419                 error "$LFS getstripe --obd: should not show file on other obd"
6420         echo "$LFS getstripe --obd passed"
6421 }
6422 run_test 56a "check $LFS getstripe"
6423
6424 test_56b() {
6425         local dir=$DIR/$tdir
6426         local numdirs=3
6427
6428         test_mkdir $dir
6429         for i in $(seq $numdirs); do
6430                 test_mkdir $dir/dir$i
6431         done
6432
6433         # test lfs getdirstripe default mode is non-recursion, which is
6434         # different from lfs getstripe
6435         local dircnt=$($LFS getdirstripe $dir | grep -c lmv_stripe_count)
6436
6437         [[ $dircnt -eq 1 ]] ||
6438                 error "$LFS getdirstripe: found $dircnt, not 1"
6439         dircnt=$($LFS getdirstripe --recursive $dir |
6440                 grep -c lmv_stripe_count)
6441         [[ $dircnt -eq $((numdirs + 1)) ]] ||
6442                 error "$LFS getdirstripe -r: $dircnt, != $((numdirs + 1))"
6443 }
6444 run_test 56b "check $LFS getdirstripe"
6445
6446 test_56bb() {
6447         verify_yaml_available || skip_env "YAML verification not installed"
6448         local output_file=$DIR/$tfile.out
6449
6450         $LFS getdirstripe -v -D -y $DIR 1> $output_file
6451
6452         cat $output_file
6453         cat $output_file | verify_yaml || error "layout is not valid YAML"
6454 }
6455 run_test 56bb "check $LFS getdirstripe layout is YAML"
6456
6457 test_56c() {
6458         remote_ost_nodsh && skip "remote OST with nodsh"
6459
6460         local ost_idx=0
6461         local ost_name=$(ostname_from_index $ost_idx)
6462         local old_status=$(ost_dev_status $ost_idx)
6463         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
6464
6465         [[ -z "$old_status" ]] ||
6466                 skip_env "OST $ost_name is in $old_status status"
6467
6468         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=1
6469         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
6470                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=1
6471         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
6472                 save_lustre_params ost1 osd-*.$ost_name.nonrotational > $p
6473                 do_facet ost1 $LCTL set_param -n osd-*.$ost_name.nonrotational=1
6474         fi
6475
6476         [[ $($LFS df -v $MOUNT |& grep -c "inactive device") -eq 0 ]] ||
6477                 error "$LFS df -v showing inactive devices"
6478         sleep_maxage
6479
6480         local new_status=$(ost_dev_status $ost_idx $MOUNT -v)
6481
6482         [[ "$new_status" =~ "D" ]] ||
6483                 error "$ost_name status is '$new_status', missing 'D'"
6484         if [[ $OST1_VERSION -ge $(version_code 2.12.55) ]]; then
6485                 [[ "$new_status" =~ "N" ]] ||
6486                         error "$ost_name status is '$new_status', missing 'N'"
6487         fi
6488         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
6489                 [[ "$new_status" =~ "f" ]] ||
6490                         error "$ost_name status is '$new_status', missing 'f'"
6491         fi
6492
6493         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=0
6494         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
6495                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=0
6496         [[ -z "$p" ]] && restore_lustre_params < $p || true
6497         sleep_maxage
6498
6499         new_status=$(ost_dev_status $ost_idx)
6500         [[ ! "$new_status" =~ "D" && ! "$new_status" =~ "N" ]] ||
6501                 error "$ost_name status is '$new_status', has 'D' and/or 'N'"
6502         # can't check 'f' as devices may actually be on flash
6503 }
6504 run_test 56c "check 'lfs df' showing device status"
6505
6506 test_56d() {
6507         local mdts=$($LFS df -v $MOUNT | grep -c MDT)
6508         local osts=$($LFS df -v $MOUNT | grep -c OST)
6509
6510         $LFS df $MOUNT
6511
6512         (( mdts == MDSCOUNT )) ||
6513                 error "lfs df -v showed $mdts MDTs, not $MDSCOUNT"
6514         (( osts == OSTCOUNT )) ||
6515                 error "lfs df -v showed $osts OSTs, not $OSTCOUNT"
6516 }
6517 run_test 56d "'lfs df -v' prints only configured devices"
6518
6519 test_56e() {
6520         err_enoent=2 # No such file or directory
6521         err_eopnotsupp=95 # Operation not supported
6522
6523         enoent_mnt=/pmt1 # Invalid dentry. Path not present
6524         notsup_mnt=/tmp  # Valid dentry, but Not a lustreFS
6525
6526         # Check for handling of path not exists
6527         output=$($LFS df $enoent_mnt 2>&1)
6528         ret=$?
6529
6530         fs=$(echo $output | awk -F: '{print $2}' | awk '{print $3}' | tr -d \')
6531         [[ $fs = $enoent_mnt && $ret -eq $err_enoent ]] ||
6532                 error "expect failure $err_enoent, not $ret"
6533
6534         # Check for handling of non-Lustre FS
6535         output=$($LFS df $notsup_mnt)
6536         ret=$?
6537
6538         fs=$(echo $output | awk '{print $1}' | awk -F: '{print $2}')
6539         [[ $fs = $notsup_mnt && $ret -eq $err_eopnotsupp ]] ||
6540                 error "expect success $err_eopnotsupp, not $ret"
6541
6542         # Check for multiple LustreFS argument
6543         output=$($LFS df $MOUNT $MOUNT $MOUNT | grep -c "filesystem_summary:")
6544         ret=$?
6545
6546         [[ $output -eq 3 && $ret -eq 0 ]] ||
6547                 error "expect success 3, not $output, rc = $ret"
6548
6549         # Check for correct non-Lustre FS handling among multiple
6550         # LustreFS argument
6551         output=$($LFS df $MOUNT $notsup_mnt $MOUNT |
6552                 grep -c "filesystem_summary:"; exit ${PIPESTATUS[0]})
6553         ret=$?
6554
6555         [[ $output -eq 2 && $ret -eq $err_eopnotsupp ]] ||
6556                 error "expect success 2, not $output, rc = $ret"
6557 }
6558 run_test 56e "'lfs df' Handle non LustreFS & multiple LustreFS"
6559
6560 NUMFILES=3
6561 NUMDIRS=3
6562 setup_56() {
6563         local local_tdir="$1"
6564         local local_numfiles="$2"
6565         local local_numdirs="$3"
6566         local dir_params="$4"
6567         local dir_stripe_params="$5"
6568
6569         if [ ! -d "$local_tdir" ] ; then
6570                 test_mkdir -p $dir_stripe_params $local_tdir
6571                 [ "$dir_params" ] && $LFS setstripe $dir_params $local_tdir
6572                 for i in $(seq $local_numfiles) ; do
6573                         touch $local_tdir/file$i
6574                 done
6575                 for i in $(seq $local_numdirs) ; do
6576                         test_mkdir $dir_stripe_params $local_tdir/dir$i
6577                         for j in $(seq $local_numfiles) ; do
6578                                 touch $local_tdir/dir$i/file$j
6579                         done
6580                 done
6581         fi
6582 }
6583
6584 setup_56_special() {
6585         local local_tdir=$1
6586         local local_numfiles=$2
6587         local local_numdirs=$3
6588
6589         setup_56 $local_tdir $local_numfiles $local_numdirs
6590
6591         if [ ! -e "$local_tdir/loop${local_numfiles}b" ] ; then
6592                 for i in $(seq $local_numfiles) ; do
6593                         mknod $local_tdir/loop${i}b b 7 $i
6594                         mknod $local_tdir/null${i}c c 1 3
6595                         ln -s $local_tdir/file1 $local_tdir/link${i}
6596                 done
6597                 for i in $(seq $local_numdirs) ; do
6598                         mknod $local_tdir/dir$i/loop${i}b b 7 $i
6599                         mknod $local_tdir/dir$i/null${i}c c 1 3
6600                         ln -s $local_tdir/dir$i/file1 $local_tdir/dir$i/link${i}
6601                 done
6602         fi
6603 }
6604
6605 test_56g() {
6606         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6607         local expected=$(($NUMDIRS + 2))
6608
6609         setup_56 $dir $NUMFILES $NUMDIRS
6610
6611         # test lfs find with -name
6612         for i in $(seq $NUMFILES) ; do
6613                 local nums=$($LFS find -name "*$i" $dir | wc -l)
6614
6615                 [ $nums -eq $expected ] ||
6616                         error "lfs find -name '*$i' $dir wrong: "\
6617                               "found $nums, expected $expected"
6618         done
6619 }
6620 run_test 56g "check lfs find -name"
6621
6622 test_56h() {
6623         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6624         local expected=$(((NUMDIRS + 1) * (NUMFILES - 1) + NUMFILES))
6625
6626         setup_56 $dir $NUMFILES $NUMDIRS
6627
6628         # test lfs find with ! -name
6629         for i in $(seq $NUMFILES) ; do
6630                 local nums=$($LFS find ! -name "*$i" $dir | wc -l)
6631
6632                 [ $nums -eq $expected ] ||
6633                         error "lfs find ! -name '*$i' $dir wrong: "\
6634                               "found $nums, expected $expected"
6635         done
6636 }
6637 run_test 56h "check lfs find ! -name"
6638
6639 test_56i() {
6640         local dir=$DIR/$tdir
6641
6642         test_mkdir $dir
6643
6644         local cmd="$LFS find -ost $(ostuuid_from_index 0 $dir) $dir"
6645         local out=$($cmd)
6646
6647         [ -z "$out" ] || error "'$cmd' returned directory '$out'"
6648 }
6649 run_test 56i "check 'lfs find -ost UUID' skips directories"
6650
6651 test_56j() {
6652         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6653
6654         setup_56_special $dir $NUMFILES $NUMDIRS
6655
6656         local expected=$((NUMDIRS + 1))
6657         local cmd="$LFS find -type d $dir"
6658         local nums=$($cmd | wc -l)
6659
6660         [ $nums -eq $expected ] ||
6661                 error "'$cmd' wrong: found $nums, expected $expected"
6662 }
6663 run_test 56j "check lfs find -type d"
6664
6665 test_56k() {
6666         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6667
6668         setup_56_special $dir $NUMFILES $NUMDIRS
6669
6670         local expected=$(((NUMDIRS + 1) * NUMFILES))
6671         local cmd="$LFS find -type f $dir"
6672         local nums=$($cmd | wc -l)
6673
6674         [ $nums -eq $expected ] ||
6675                 error "'$cmd' wrong: found $nums, expected $expected"
6676 }
6677 run_test 56k "check lfs find -type f"
6678
6679 test_56l() {
6680         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6681
6682         setup_56_special $dir $NUMFILES $NUMDIRS
6683
6684         local expected=$((NUMDIRS + NUMFILES))
6685         local cmd="$LFS find -type b $dir"
6686         local nums=$($cmd | wc -l)
6687
6688         [ $nums -eq $expected ] ||
6689                 error "'$cmd' wrong: found $nums, expected $expected"
6690 }
6691 run_test 56l "check lfs find -type b"
6692
6693 test_56m() {
6694         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6695
6696         setup_56_special $dir $NUMFILES $NUMDIRS
6697
6698         local expected=$((NUMDIRS + NUMFILES))
6699         local cmd="$LFS find -type c $dir"
6700         local nums=$($cmd | wc -l)
6701         [ $nums -eq $expected ] ||
6702                 error "'$cmd' wrong: found $nums, expected $expected"
6703 }
6704 run_test 56m "check lfs find -type c"
6705
6706 test_56n() {
6707         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6708         setup_56_special $dir $NUMFILES $NUMDIRS
6709
6710         local expected=$((NUMDIRS + NUMFILES))
6711         local cmd="$LFS find -type l $dir"
6712         local nums=$($cmd | wc -l)
6713
6714         [ $nums -eq $expected ] ||
6715                 error "'$cmd' wrong: found $nums, expected $expected"
6716 }
6717 run_test 56n "check lfs find -type l"
6718
6719 test_56o() {
6720         local dir=$DIR/$tdir
6721
6722         setup_56 $dir $NUMFILES $NUMDIRS
6723         utime $dir/file1 > /dev/null || error "utime (1)"
6724         utime $dir/file2 > /dev/null || error "utime (2)"
6725         utime $dir/dir1 > /dev/null || error "utime (3)"
6726         utime $dir/dir2 > /dev/null || error "utime (4)"
6727         utime $dir/dir1/file1 > /dev/null || error "utime (5)"
6728         dd if=/dev/zero count=1 >> $dir/dir1/file1 && sync
6729
6730         local expected=4
6731         local nums=$($LFS find -mtime +0 $dir | wc -l)
6732
6733         [ $nums -eq $expected ] ||
6734                 error "lfs find -mtime +0 $dir: found $nums expect $expected"
6735
6736         expected=12
6737         cmd="$LFS find -mtime 0 $dir"
6738         nums=$($cmd | wc -l)
6739         [ $nums -eq $expected ] ||
6740                 error "'$cmd' wrong: found $nums, expected $expected"
6741 }
6742 run_test 56o "check lfs find -mtime for old files"
6743
6744 test_56ob() {
6745         local dir=$DIR/$tdir
6746         local expected=1
6747         local count=0
6748
6749         # just to make sure there is something that won't be found
6750         test_mkdir $dir
6751         touch $dir/$tfile.now
6752
6753         for age in year week day hour min; do
6754                 count=$((count + 1))
6755
6756                 touch $dir/$tfile-a.$age $dir/$tfile-m.$age
6757                 touch --date="$count $age ago" -a $dir/$tfile-a.$age
6758                 touch --date="$count $age ago" -m $dir/$tfile-m.$age
6759
6760                 local cmd="$LFS find $dir -mtime $count${age:0:1}"
6761                 local nums=$($cmd | wc -l)
6762                 [ $nums -eq $expected ] ||
6763                         error "'$cmd' wrong: found $nums, expected $expected"
6764
6765                 cmd="$LFS find $dir -atime $count${age:0:1}"
6766                 nums=$($cmd | wc -l)
6767                 [ $nums -eq $expected ] ||
6768                         error "'$cmd' wrong: found $nums, expected $expected"
6769         done
6770
6771         sleep 2
6772         cmd="$LFS find $dir -ctime +1s -type f"
6773         nums=$($cmd | wc -l)
6774         (( $nums == $count * 2 + 1)) ||
6775                 error "'$cmd' wrong: found $nums, expected $((count * 2 + 1))"
6776 }
6777 run_test 56ob "check lfs find -atime -mtime -ctime with units"
6778
6779 test_newerXY_base() {
6780         local x=$1
6781         local y=$2
6782         local dir=$DIR/$tdir
6783         local ref
6784         local negref
6785
6786         if [ $y == "t" ]; then
6787                 if [ $x == "b" ]; then
6788                         ref=\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\"
6789                 else
6790                         ref=\"$(date +"%Y-%m-%d %H:%M:%S")\"
6791                 fi
6792         else
6793                 ref=$DIR/$tfile.newer.$x$y
6794                 touch $ref || error "touch $ref failed"
6795         fi
6796
6797         echo "before = $ref"
6798         sleep 2
6799         setup_56 $dir $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6800         sleep 2
6801         if [ $y == "t" ]; then
6802                 if [ $x == "b" ]; then
6803                         negref=\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\"
6804                 else
6805                         negref=\"$(date +"%Y-%m-%d %H:%M:%S")\"
6806                 fi
6807         else
6808                 negref=$DIR/$tfile.negnewer.$x$y
6809                 touch $negref || error "touch $negref failed"
6810         fi
6811
6812         echo "after = $negref"
6813         local cmd="$LFS find $dir -newer$x$y $ref"
6814         local nums=$(eval $cmd | wc -l)
6815         local expected=$(((NUMFILES + 2) * NUMDIRS + 1))
6816
6817         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6818                 error "'$cmd' wrong: found $nums newer, expected $expected"  ; }
6819
6820         cmd="$LFS find $dir ! -newer$x$y $negref"
6821         nums=$(eval $cmd | wc -l)
6822         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6823                 error "'$cmd' wrong: found $nums older, expected $expected"  ; }
6824
6825         cmd="$LFS find $dir -newer$x$y $ref ! -newer$x$y $negref"
6826         nums=$(eval $cmd | wc -l)
6827         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6828                 error "'$cmd' wrong: found $nums between, expected $expected"; }
6829
6830         rm -rf $DIR/*
6831 }
6832
6833 test_56oc() {
6834         test_newerXY_base "a" "a"
6835         test_newerXY_base "a" "m"
6836         test_newerXY_base "a" "c"
6837         test_newerXY_base "m" "a"
6838         test_newerXY_base "m" "m"
6839         test_newerXY_base "m" "c"
6840         test_newerXY_base "c" "a"
6841         test_newerXY_base "c" "m"
6842         test_newerXY_base "c" "c"
6843
6844         test_newerXY_base "a" "t"
6845         test_newerXY_base "m" "t"
6846         test_newerXY_base "c" "t"
6847
6848         [[ $MDS1_VERSION -lt $(version_code 2.13.54) ||
6849            $CLIENT_VERSION -lt $(version_code 2.13.54) ]] &&
6850                 ! btime_supported && echo "btime unsupported" && return 0
6851
6852         test_newerXY_base "b" "b"
6853         test_newerXY_base "b" "t"
6854 }
6855 run_test 56oc "check lfs find -newerXY work"
6856
6857 btime_supported() {
6858         local dir=$DIR/$tdir
6859         local rc
6860
6861         mkdir -p $dir
6862         touch $dir/$tfile
6863         $LFS find $dir -btime -1d -type f
6864         rc=$?
6865         rm -rf $dir
6866         return $rc
6867 }
6868
6869 test_56od() {
6870         [ $MDS1_VERSION -lt $(version_code 2.13.53) ] &&
6871                 ! btime_supported && skip "btime unsupported on MDS"
6872
6873         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
6874                 ! btime_supported && skip "btime unsupported on clients"
6875
6876         local dir=$DIR/$tdir
6877         local ref=$DIR/$tfile.ref
6878         local negref=$DIR/$tfile.negref
6879
6880         mkdir $dir || error "mkdir $dir failed"
6881         touch $dir/$tfile.n1 || error "touch $dir/$tfile.n1 failed"
6882         touch $dir/$tfile.n2 || error "touch $dir/$tfile.n2 failed"
6883         mkdir $dir/$tdir.n1 || error "mkdir $dir/$tdir.n1 failed"
6884         mkdir $dir/$tdir.n2 || error "mkdir $dir/$tdir.n2 failed"
6885         touch $ref || error "touch $ref failed"
6886         # sleep 3 seconds at least
6887         sleep 3
6888
6889         local before=$(do_facet mds1 date +%s)
6890         local skew=$(($(date +%s) - before + 1))
6891
6892         if (( skew < 0 && skew > -5 )); then
6893                 sleep $((0 - skew + 1))
6894                 skew=0
6895         fi
6896
6897         # Set the dir stripe params to limit files all on MDT0,
6898         # otherwise we need to calc the max clock skew between
6899         # the client and MDTs.
6900         setup_56 $dir/d.btime $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6901         sleep 2
6902         touch $negref || error "touch $negref failed"
6903
6904         local cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type f"
6905         local nums=$($cmd | wc -l)
6906         local expected=$(((NUMFILES + 1) * NUMDIRS))
6907
6908         [ $nums -eq $expected ] ||
6909                 error "'$cmd' wrong: found $nums, expected $expected"
6910
6911         cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type d"
6912         nums=$($cmd | wc -l)
6913         expected=$((NUMFILES + 1))
6914         [ $nums -eq $expected ] ||
6915                 error "'$cmd' wrong: found $nums, expected $expected"
6916
6917         [ $skew -lt 0 ] && return
6918
6919         local after=$(do_facet mds1 date +%s)
6920         local age=$((after - before + 1 + skew))
6921
6922         cmd="$LFS find $dir -btime -${age}s -type f"
6923         nums=$($cmd | wc -l)
6924         expected=$(((NUMFILES + 1) * NUMDIRS))
6925
6926         echo "Clock skew between client and server: $skew, age:$age"
6927         [ $nums -eq $expected ] ||
6928                 error "'$cmd' wrong: found $nums, expected $expected"
6929
6930         expected=$(($NUMDIRS + 1))
6931         cmd="$LFS find $dir -btime -${age}s -type d"
6932         nums=$($cmd | wc -l)
6933         [ $nums -eq $expected ] ||
6934                 error "'$cmd' wrong: found $nums, expected $expected"
6935         rm -f $ref $negref || error "Failed to remove $ref $negref"
6936 }
6937 run_test 56od "check lfs find -btime with units"
6938
6939 test_56p() {
6940         [ $RUNAS_ID -eq $UID ] &&
6941                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6942
6943         local dir=$DIR/$tdir
6944
6945         setup_56 $dir $NUMFILES $NUMDIRS
6946         chown $RUNAS_ID $dir/file* || error "chown $DIR/${tdir}g/file$i failed"
6947
6948         local expected=$NUMFILES
6949         local cmd="$LFS find -uid $RUNAS_ID $dir"
6950         local nums=$($cmd | wc -l)
6951
6952         [ $nums -eq $expected ] ||
6953                 error "'$cmd' wrong: found $nums, expected $expected"
6954
6955         expected=$(((NUMFILES + 1) * NUMDIRS + 1))
6956         cmd="$LFS find ! -uid $RUNAS_ID $dir"
6957         nums=$($cmd | wc -l)
6958         [ $nums -eq $expected ] ||
6959                 error "'$cmd' wrong: found $nums, expected $expected"
6960 }
6961 run_test 56p "check lfs find -uid and ! -uid"
6962
6963 test_56q() {
6964         [ $RUNAS_ID -eq $UID ] &&
6965                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6966
6967         local dir=$DIR/$tdir
6968
6969         setup_56 $dir $NUMFILES $NUMDIRS
6970         chgrp $RUNAS_GID $dir/file* || error "chown $dir/file$i failed"
6971
6972         local expected=$NUMFILES
6973         local cmd="$LFS find -gid $RUNAS_GID $dir"
6974         local nums=$($cmd | wc -l)
6975
6976         [ $nums -eq $expected ] ||
6977                 error "'$cmd' wrong: found $nums, expected $expected"
6978
6979         expected=$(( ($NUMFILES+1) * $NUMDIRS + 1))
6980         cmd="$LFS find ! -gid $RUNAS_GID $dir"
6981         nums=$($cmd | wc -l)
6982         [ $nums -eq $expected ] ||
6983                 error "'$cmd' wrong: found $nums, expected $expected"
6984 }
6985 run_test 56q "check lfs find -gid and ! -gid"
6986
6987 test_56r() {
6988         local dir=$DIR/$tdir
6989
6990         setup_56 $dir $NUMFILES $NUMDIRS
6991
6992         local expected=12
6993         local cmd="$LFS find -size 0 -type f -lazy $dir"
6994         local nums=$($cmd | wc -l)
6995
6996         [ $nums -eq $expected ] ||
6997                 error "'$cmd' wrong: found $nums, expected $expected"
6998         cmd="$LFS find -size 0 -type f $dir"
6999         nums=$($cmd | wc -l)
7000         [ $nums -eq $expected ] ||
7001                 error "'$cmd' wrong: found $nums, expected $expected"
7002
7003         expected=0
7004         cmd="$LFS find ! -size 0 -type f -lazy $dir"
7005         nums=$($cmd | wc -l)
7006         [ $nums -eq $expected ] ||
7007                 error "'$cmd' wrong: found $nums, expected $expected"
7008         cmd="$LFS find ! -size 0 -type f $dir"
7009         nums=$($cmd | wc -l)
7010         [ $nums -eq $expected ] ||
7011                 error "'$cmd' wrong: found $nums, expected $expected"
7012
7013         echo "test" > $dir/$tfile
7014         echo "test2" > $dir/$tfile.2 && sync
7015         expected=1
7016         cmd="$LFS find -size 5 -type f -lazy $dir"
7017         nums=$($cmd | wc -l)
7018         [ $nums -eq $expected ] ||
7019                 error "'$cmd' wrong: found $nums, expected $expected"
7020         cmd="$LFS find -size 5 -type f $dir"
7021         nums=$($cmd | wc -l)
7022         [ $nums -eq $expected ] ||
7023                 error "'$cmd' wrong: found $nums, expected $expected"
7024
7025         expected=1
7026         cmd="$LFS find -size +5 -type f -lazy $dir"
7027         nums=$($cmd | wc -l)
7028         [ $nums -eq $expected ] ||
7029                 error "'$cmd' wrong: found $nums, expected $expected"
7030         cmd="$LFS find -size +5 -type f $dir"
7031         nums=$($cmd | wc -l)
7032         [ $nums -eq $expected ] ||
7033                 error "'$cmd' wrong: found $nums, expected $expected"
7034
7035         expected=2
7036         cmd="$LFS find -size +0 -type f -lazy $dir"
7037         nums=$($cmd | wc -l)
7038         [ $nums -eq $expected ] ||
7039                 error "'$cmd' wrong: found $nums, expected $expected"
7040         cmd="$LFS find -size +0 -type f $dir"
7041         nums=$($cmd | wc -l)
7042         [ $nums -eq $expected ] ||
7043                 error "'$cmd' wrong: found $nums, expected $expected"
7044
7045         expected=2
7046         cmd="$LFS find ! -size -5 -type f -lazy $dir"
7047         nums=$($cmd | wc -l)
7048         [ $nums -eq $expected ] ||
7049                 error "'$cmd' wrong: found $nums, expected $expected"
7050         cmd="$LFS find ! -size -5 -type f $dir"
7051         nums=$($cmd | wc -l)
7052         [ $nums -eq $expected ] ||
7053                 error "'$cmd' wrong: found $nums, expected $expected"
7054
7055         expected=12
7056         cmd="$LFS find -size -5 -type f -lazy $dir"
7057         nums=$($cmd | wc -l)
7058         [ $nums -eq $expected ] ||
7059                 error "'$cmd' wrong: found $nums, expected $expected"
7060         cmd="$LFS find -size -5 -type f $dir"
7061         nums=$($cmd | wc -l)
7062         [ $nums -eq $expected ] ||
7063                 error "'$cmd' wrong: found $nums, expected $expected"
7064 }
7065 run_test 56r "check lfs find -size works"
7066
7067 test_56ra_sub() {
7068         local expected=$1
7069         local glimpses=$2
7070         local cmd="$3"
7071
7072         cancel_lru_locks $OSC
7073
7074         local rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
7075         local nums=$($cmd | wc -l)
7076
7077         [ $nums -eq $expected ] ||
7078                 error "'$cmd' wrong: found $nums, expected $expected"
7079
7080         local rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
7081
7082         if (( rpcs_before + glimpses != rpcs_after )); then
7083                 echo "Before: $rpcs_before After: $rpcs_after $NUMFILES"
7084                 $LCTL get_param osc.*.stats | grep ldlm_glimpse_enqueue
7085
7086                 if [[ $glimpses == 0 ]]; then
7087                         error "'$cmd' should not send glimpse RPCs to OST"
7088                 else
7089                         error "'$cmd' should send $glimpses glimpse RPCs to OST"
7090                 fi
7091         fi
7092 }
7093
7094 test_56ra() {
7095         [[ $MDS1_VERSION -gt $(version_code 2.12.58) ]] ||
7096                 skip "MDS < 2.12.58 doesn't return LSOM data"
7097         local dir=$DIR/$tdir
7098         local old_agl=$($LCTL get_param -n llite.*.statahead_agl)
7099
7100         [[ $OSC == "mdc" ]] && skip "statahead not needed for DoM files"
7101
7102         # statahead_agl may cause extra glimpse which confuses results. LU-13017
7103         $LCTL set_param -n llite.*.statahead_agl=0
7104         stack_trap "$LCTL set_param -n llite.*.statahead_agl=$old_agl"
7105
7106         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
7107         # open and close all files to ensure LSOM is updated
7108         cancel_lru_locks $OSC
7109         find $dir -type f | xargs cat > /dev/null
7110
7111         #   expect_found  glimpse_rpcs  command_to_run
7112         test_56ra_sub 12  0 "$LFS find -size 0 -type f -lazy $dir"
7113         test_56ra_sub 12 12 "$LFS find -size 0 -type f $dir"
7114         test_56ra_sub  0  0 "$LFS find ! -size 0 -type f -lazy $dir"
7115         test_56ra_sub  0 12 "$LFS find ! -size 0 -type f $dir"
7116
7117         echo "test" > $dir/$tfile
7118         echo "test2" > $dir/$tfile.2 && sync
7119         cancel_lru_locks $OSC
7120         cat $dir/$tfile $dir/$tfile.2 > /dev/null
7121
7122         test_56ra_sub  1  0 "$LFS find -size 5 -type f -lazy $dir"
7123         test_56ra_sub  1 14 "$LFS find -size 5 -type f $dir"
7124         test_56ra_sub  1  0 "$LFS find -size +5 -type f -lazy $dir"
7125         test_56ra_sub  1 14 "$LFS find -size +5 -type f $dir"
7126
7127         test_56ra_sub  2  0 "$LFS find -size +0 -type f -lazy $dir"
7128         test_56ra_sub  2 14 "$LFS find -size +0 -type f $dir"
7129         test_56ra_sub  2  0 "$LFS find ! -size -5 -type f -lazy $dir"
7130         test_56ra_sub  2 14 "$LFS find ! -size -5 -type f $dir"
7131         test_56ra_sub 12  0 "$LFS find -size -5 -type f -lazy $dir"
7132         test_56ra_sub 12 14 "$LFS find -size -5 -type f $dir"
7133 }
7134 run_test 56ra "check lfs find -size -lazy works for data on OSTs"
7135
7136 test_56rb() {
7137         local dir=$DIR/$tdir
7138         local tmp=$TMP/$tfile.log
7139         local mdt_idx;
7140
7141         test_mkdir -p $dir || error "failed to mkdir $dir"
7142         $LFS setstripe -c 1 -i 0 $dir/$tfile ||
7143                 error "failed to setstripe $dir/$tfile"
7144         mdt_idx=$($LFS getdirstripe -i $dir)
7145         dd if=/dev/zero of=$dir/$tfile bs=1M count=1
7146
7147         stack_trap "rm -f $tmp" EXIT
7148         $LFS find --size +100K --ost 0 $dir |& tee $tmp
7149         ! grep -q obd_uuid $tmp ||
7150                 error "failed to find --size +100K --ost 0 $dir"
7151         $LFS find --size +100K --mdt $mdt_idx $dir |& tee $tmp
7152         ! grep -q obd_uuid $tmp ||
7153                 error "failed to find --size +100K --mdt $mdt_idx $dir"
7154 }
7155 run_test 56rb "check lfs find --size --ost/--mdt works"
7156
7157 test_56rc() {
7158         (( MDSCOUNT >= 2 )) || skip "needs at least 2 MDTs"
7159         local dir=$DIR/$tdir
7160         local found
7161
7162         test_mkdir -c 2 -H all_char $dir || error "failed to mkdir $dir"
7163         $LFS mkdir -c 2 --mdt-hash all_char $dir/$tdir-all{1..10}
7164         (( $MDSCOUNT > 2 )) &&
7165                 $LFS mkdir -c 3 --mdt-hash fnv_1a_64 $dir/$tdir-fnv{1..10}
7166         mkdir $dir/$tdir-{1..10}
7167         touch $dir/$tfile-{1..10}
7168
7169         found=$($LFS find $dir --mdt-count 2 | wc -l)
7170         expect=11
7171         (( $found == $expect )) || error "found $found 2-stripe, expect $expect"
7172
7173         found=$($LFS find $dir -T +1 | wc -l)
7174         (( $MDSCOUNT > 2 )) && expect=$((expect + 10))
7175         (( $found == $expect )) || error "found $found 2+stripe, expect $expect"
7176
7177         found=$($LFS find $dir --mdt-hash all_char | wc -l)
7178         expect=11
7179         (( $found == $expect )) || error "found $found all_char, expect $expect"
7180
7181         found=$($LFS find $dir --mdt-hash fnv_1a_64 | wc -l)
7182         (( $MDSCOUNT > 2 )) && expect=10 || expect=0
7183         (( $found == $expect )) || error "found $found all_char, expect $expect"
7184 }
7185 run_test 56rc "check lfs find --mdt-count/--mdt-hash works"
7186
7187 test_56s() { # LU-611 #LU-9369
7188         [[ $OSTCOUNT -lt 2 ]] && skip_env "need at least 2 OSTs"
7189
7190         local dir=$DIR/$tdir
7191         local onestripe=$(((NUMDIRS + 1) * NUMFILES))
7192
7193         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
7194         for i in $(seq $NUMDIRS); do
7195                 $LFS setstripe -c $((OSTCOUNT + 1)) $dir/dir$i/$tfile
7196         done
7197
7198         local expected=$NUMDIRS
7199         local cmd="$LFS find -c $OSTCOUNT $dir"
7200         local nums=$($cmd | wc -l)
7201
7202         [ $nums -eq $expected ] || {
7203                 $LFS getstripe -R $dir
7204                 error "'$cmd' wrong: found $nums, expected $expected"
7205         }
7206
7207         expected=$((NUMDIRS + onestripe))
7208         cmd="$LFS find -stripe-count +0 -type f $dir"
7209         nums=$($cmd | wc -l)
7210         [ $nums -eq $expected ] || {
7211                 $LFS getstripe -R $dir
7212                 error "'$cmd' wrong: found $nums, expected $expected"
7213         }
7214
7215         expected=$onestripe
7216         cmd="$LFS find -stripe-count 1 -type f $dir"
7217         nums=$($cmd | wc -l)
7218         [ $nums -eq $expected ] || {
7219                 $LFS getstripe -R $dir
7220                 error "'$cmd' wrong: found $nums, expected $expected"
7221         }
7222
7223         cmd="$LFS find -stripe-count -2 -type f $dir"
7224         nums=$($cmd | wc -l)
7225         [ $nums -eq $expected ] || {
7226                 $LFS getstripe -R $dir
7227                 error "'$cmd' wrong: found $nums, expected $expected"
7228         }
7229
7230         expected=0
7231         cmd="$LFS find -stripe-count $((OSTCOUNT + 1)) -type f $dir"
7232         nums=$($cmd | wc -l)
7233         [ $nums -eq $expected ] || {
7234                 $LFS getstripe -R $dir
7235                 error "'$cmd' wrong: found $nums, expected $expected"
7236         }
7237 }
7238 run_test 56s "check lfs find -stripe-count works"
7239
7240 test_56t() { # LU-611 #LU-9369
7241         local dir=$DIR/$tdir
7242
7243         setup_56 $dir 0 $NUMDIRS
7244         for i in $(seq $NUMDIRS); do
7245                 $LFS setstripe -S 8M $dir/dir$i/$tfile
7246         done
7247
7248         local expected=$NUMDIRS
7249         local cmd="$LFS find -S 8M $dir"
7250         local nums=$($cmd | wc -l)
7251
7252         [ $nums -eq $expected ] || {
7253                 $LFS getstripe -R $dir
7254                 error "'$cmd' wrong: found $nums, expected $expected"
7255         }
7256         rm -rf $dir
7257
7258         setup_56 $dir $NUMFILES $NUMDIRS "--stripe-size 512k"
7259
7260         $LFS setstripe -S 256k $dir/$tfile.{0,1,2,3}
7261
7262         expected=$(((NUMDIRS + 1) * NUMFILES))
7263         cmd="$LFS find -stripe-size 512k -type f $dir"
7264         nums=$($cmd | wc -l)
7265         [ $nums -eq $expected ] ||
7266                 error "'$cmd' wrong: found $nums, expected $expected"
7267
7268         cmd="$LFS find -stripe-size +320k -type f $dir"
7269         nums=$($cmd | wc -l)
7270         [ $nums -eq $expected ] ||
7271                 error "'$cmd' wrong: found $nums, expected $expected"
7272
7273         expected=$(((NUMDIRS + 1) * NUMFILES + 4))
7274         cmd="$LFS find -stripe-size +200k -type f $dir"
7275         nums=$($cmd | wc -l)
7276         [ $nums -eq $expected ] ||
7277                 error "'$cmd' wrong: found $nums, expected $expected"
7278
7279         cmd="$LFS find -stripe-size -640k -type f $dir"
7280         nums=$($cmd | wc -l)
7281         [ $nums -eq $expected ] ||
7282                 error "'$cmd' wrong: found $nums, expected $expected"
7283
7284         expected=4
7285         cmd="$LFS find -stripe-size 256k -type f $dir"
7286         nums=$($cmd | wc -l)
7287         [ $nums -eq $expected ] ||
7288                 error "'$cmd' wrong: found $nums, expected $expected"
7289
7290         cmd="$LFS find -stripe-size -320k -type f $dir"
7291         nums=$($cmd | wc -l)
7292         [ $nums -eq $expected ] ||
7293                 error "'$cmd' wrong: found $nums, expected $expected"
7294
7295         expected=0
7296         cmd="$LFS find -stripe-size 1024k -type f $dir"
7297         nums=$($cmd | wc -l)
7298         [ $nums -eq $expected ] ||
7299                 error "'$cmd' wrong: found $nums, expected $expected"
7300 }
7301 run_test 56t "check lfs find -stripe-size works"
7302
7303 test_56u() { # LU-611
7304         local dir=$DIR/$tdir
7305
7306         setup_56 $dir $NUMFILES $NUMDIRS "-i 0 -c 1"
7307
7308         if [[ $OSTCOUNT -gt 1 ]]; then
7309                 $LFS setstripe -i 1 -c 1 $dir/$tfile.{0,1,2,3}
7310                 onestripe=4
7311         else
7312                 onestripe=0
7313         fi
7314
7315         local expected=$(((NUMDIRS + 1) * NUMFILES))
7316         local cmd="$LFS find -stripe-index 0 -type f $dir"
7317         local nums=$($cmd | wc -l)
7318
7319         [ $nums -eq $expected ] ||
7320                 error "'$cmd' wrong: found $nums, expected $expected"
7321
7322         expected=$onestripe
7323         cmd="$LFS find -stripe-index 1 -type f $dir"
7324         nums=$($cmd | wc -l)
7325         [ $nums -eq $expected ] ||
7326                 error "'$cmd' wrong: found $nums, expected $expected"
7327
7328         cmd="$LFS find ! -stripe-index 0 -type f $dir"
7329         nums=$($cmd | wc -l)
7330         [ $nums -eq $expected ] ||
7331                 error "'$cmd' wrong: found $nums, expected $expected"
7332
7333         expected=0
7334         # This should produce an error and not return any files
7335         cmd="$LFS find -stripe-index $OSTCOUNT -type f $dir"
7336         nums=$($cmd 2>/dev/null | wc -l)
7337         [ $nums -eq $expected ] ||
7338                 error "'$cmd' wrong: found $nums, expected $expected"
7339
7340         if [[ $OSTCOUNT -gt 1 ]]; then
7341                 expected=$(((NUMDIRS + 1) * NUMFILES + onestripe))
7342                 cmd="$LFS find -stripe-index 0,1 -type f $dir"
7343                 nums=$($cmd | wc -l)
7344                 [ $nums -eq $expected ] ||
7345                         error "'$cmd' wrong: found $nums, expected $expected"
7346         fi
7347 }
7348 run_test 56u "check lfs find -stripe-index works"
7349
7350 test_56v() {
7351         local mdt_idx=0
7352         local dir=$DIR/$tdir
7353
7354         setup_56 $dir $NUMFILES $NUMDIRS
7355
7356         UUID=$(mdtuuid_from_index $mdt_idx $dir)
7357         [ -z "$UUID" ] && error "mdtuuid_from_index cannot find MDT $mdt_idx"
7358
7359         for file in $($LFS find -m $UUID $dir); do
7360                 file_midx=$($LFS getstripe -m $file)
7361                 [ $file_midx -eq $mdt_idx ] ||
7362                         error "lfs find -m $UUID != getstripe -m $file_midx"
7363         done
7364 }
7365 run_test 56v "check 'lfs find -m match with lfs getstripe -m'"
7366
7367 test_56wa() {
7368         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
7369         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7370
7371         local dir=$DIR/$tdir
7372
7373         setup_56 $dir $NUMFILES $NUMDIRS "-c $OSTCOUNT" "-c1"
7374         stack_trap "rm -rf $dir"
7375
7376         local stripe_size=$($LFS getstripe -S -d $dir) ||
7377                 error "$LFS getstripe -S -d $dir failed"
7378         stripe_size=${stripe_size%% *}
7379
7380         local file_size=$((stripe_size * OSTCOUNT))
7381         local file_num=$((NUMDIRS * NUMFILES + NUMFILES))
7382         local required_space=$((file_num * file_size))
7383         local free_space=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
7384                            head -n1)
7385         (( free_space >= required_space / 1024 )) ||
7386                 skip_env "need $required_space, have $free_space kbytes"
7387
7388         local dd_bs=65536
7389         local dd_count=$((file_size / dd_bs))
7390
7391         # write data into the files
7392         local i
7393         local j
7394         local file
7395
7396         for ((i = 1; i <= NUMFILES; i++ )); do
7397                 file=$dir/file$i
7398                 yes | dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
7399                         error "write data into $file failed"
7400         done
7401         for ((i = 1; i <= NUMDIRS; i++ )); do
7402                 for ((j = 1; j <= NUMFILES; j++ )); do
7403                         file=$dir/dir$i/file$j
7404                         yes|dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
7405                                 error "write data into $file failed"
7406                 done
7407         done
7408
7409         # $LFS_MIGRATE will fail if hard link migration is unsupported
7410         if (( MDS1_VERSION > $(version_code 2.5.55) )); then
7411                 createmany -l$dir/dir1/file1 $dir/dir1/link 200 ||
7412                         error "creating links to $dir/dir1/file1 failed"
7413         fi
7414
7415         local expected=-1
7416
7417         (( OSTCOUNT <= 1 )) || expected=$((OSTCOUNT - 1))
7418
7419         # lfs_migrate file
7420         local cmd="$LFS_MIGRATE -y -c $expected $dir/file1"
7421
7422         echo "$cmd"
7423         eval $cmd || error "$cmd failed"
7424
7425         check_stripe_count $dir/file1 $expected
7426
7427         if (( $MDS1_VERSION >= $(version_code 2.6.90) )); then
7428                 # lfs_migrate file onto OST 0 if it is on OST 1, or onto
7429                 # OST 1 if it is on OST 0. This file is small enough to
7430                 # be on only one stripe.
7431                 file=$dir/migr_1_ost
7432                 dd bs=$dd_bs count=1 if=/dev/urandom of=$file >/dev/null 2>&1 ||
7433                         error "write data into $file failed"
7434                 local obdidx=$($LFS getstripe -i $file)
7435                 local oldmd5=$(md5sum $file)
7436                 local newobdidx=0
7437
7438                 (( obdidx != 0 )) || newobdidx=1
7439                 cmd="$LFS migrate -i $newobdidx $file"
7440                 echo $cmd
7441                 eval $cmd || error "$cmd failed"
7442
7443                 local realobdix=$($LFS getstripe -i $file)
7444                 local newmd5=$(md5sum $file)
7445
7446                 (( $newobdidx == $realobdix )) ||
7447                         error "new OST is different (was=$obdidx, wanted=$newobdidx, got=$realobdix)"
7448                 [[ "$oldmd5" == "$newmd5" ]] ||
7449                         error "md5sum differ: $oldmd5, $newmd5"
7450         fi
7451
7452         # lfs_migrate dir
7453         cmd="$LFS_MIGRATE -y -c $expected $dir/dir1"
7454         echo "$cmd"
7455         eval $cmd || error "$cmd failed"
7456
7457         for (( j = 1; j <= NUMFILES; j++ )); do
7458                 check_stripe_count $dir/dir1/file$j $expected
7459         done
7460
7461         # lfs_migrate works with lfs find
7462         cmd="$LFS find -stripe_count $OSTCOUNT -type f $dir |
7463              $LFS_MIGRATE -y -c $expected"
7464         echo "$cmd"
7465         eval $cmd || error "$cmd failed"
7466
7467         for (( i = 2; i <= NUMFILES; i++ )); do
7468                 check_stripe_count $dir/file$i $expected
7469         done
7470         for (( i = 2; i <= NUMDIRS; i++ )); do
7471                 for (( j = 1; j <= NUMFILES; j++ )); do
7472                         check_stripe_count $dir/dir$i/file$j $expected
7473                 done
7474         done
7475 }
7476 run_test 56wa "check lfs_migrate -c stripe_count works"
7477
7478 test_56wb() {
7479         local file1=$DIR/$tdir/file1
7480         local create_pool=false
7481         local initial_pool=$($LFS getstripe -p $DIR)
7482         local pool_list=()
7483         local pool=""
7484
7485         echo -n "Creating test dir..."
7486         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
7487         echo "done."
7488
7489         echo -n "Creating test file..."
7490         touch $file1 || error "cannot create file"
7491         echo "done."
7492
7493         echo -n "Detecting existing pools..."
7494         pool_list=($($LFS pool_list $FSNAME | grep "$FSNAME\." | cut -d. -f2))
7495
7496         if [ ${#pool_list[@]} -gt 0 ]; then
7497                 echo "${pool_list[@]}"
7498                 for thispool in "${pool_list[@]}"; do
7499                         if [[ -z "$initial_pool" ||
7500                               "$initial_pool" != "$thispool" ]]; then
7501                                 pool="$thispool"
7502                                 echo "Using existing pool '$pool'"
7503                                 break
7504                         fi
7505                 done
7506         else
7507                 echo "none detected."
7508         fi
7509         if [ -z "$pool" ]; then
7510                 pool=${POOL:-testpool}
7511                 [ "$initial_pool" = "$pool" ] && pool="testpool2"
7512                 echo -n "Creating pool '$pool'..."
7513                 create_pool=true
7514                 pool_add $pool &> /dev/null ||
7515                         error "pool_add failed"
7516                 echo "done."
7517
7518                 echo -n "Adding target to pool..."
7519                 pool_add_targets $pool 0 0 1 &> /dev/null ||
7520                         error "pool_add_targets failed"
7521                 echo "done."
7522         fi
7523
7524         echo -n "Setting pool using -p option..."
7525         $LFS_MIGRATE -y -q --no-rsync -p $pool $file1 &> /dev/null ||
7526                 error "migrate failed rc = $?"
7527         echo "done."
7528
7529         echo -n "Verifying test file is in pool after migrating..."
7530         [ "$($LFS getstripe -p $file1)" = $pool ] ||
7531                 error "file was not migrated to pool $pool"
7532         echo "done."
7533
7534         echo -n "Removing test file from pool '$pool'..."
7535         # "lfs migrate $file" won't remove the file from the pool
7536         # until some striping information is changed.
7537         $LFS migrate -c 1 $file1 &> /dev/null ||
7538                 error "cannot remove from pool"
7539         [ "$($LFS getstripe -p $file1)" ] &&
7540                 error "pool still set"
7541         echo "done."
7542
7543         echo -n "Setting pool using --pool option..."
7544         $LFS_MIGRATE -y -q --no-rsync --pool $pool $file1 &> /dev/null ||
7545                 error "migrate failed rc = $?"
7546         echo "done."
7547
7548         # Clean up
7549         rm -f $file1
7550         if $create_pool; then
7551                 destroy_test_pools 2> /dev/null ||
7552                         error "destroy test pools failed"
7553         fi
7554 }
7555 run_test 56wb "check lfs_migrate pool support"
7556
7557 test_56wc() {
7558         local file1="$DIR/$tdir/$tfile"
7559         local md5
7560         local parent_ssize
7561         local parent_scount
7562         local cur_ssize
7563         local cur_scount
7564         local orig_ssize
7565         local new_scount
7566         local cur_comp
7567
7568         echo -n "Creating test dir..."
7569         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
7570         $LFS setstripe -S 1M -c 1 "$DIR/$tdir" &> /dev/null ||
7571                 error "cannot set stripe by '-S 1M -c 1'"
7572         echo "done"
7573
7574         echo -n "Setting initial stripe for test file..."
7575         $LFS setstripe -S 512K -c 1 "$file1" &> /dev/null ||
7576                 error "cannot set stripe"
7577         cur_ssize=$($LFS getstripe -S "$file1")
7578         (( cur_ssize == 524288 )) || error "setstripe -S $cur_ssize != 524288"
7579         echo "done."
7580
7581         dd if=/dev/urandom of=$file1 bs=1M count=12 || error "dd $file1 failed"
7582         stack_trap "rm -f $file1"
7583         md5="$(md5sum $file1)"
7584
7585         # File currently set to -S 512K -c 1
7586
7587         # Ensure -c and -S options are rejected when -R is set
7588         echo -n "Verifying incompatible options are detected..."
7589         $LFS_MIGRATE -R -c 1 "$file1" &&
7590                 error "incompatible -R and -c options not detected"
7591         $LFS_MIGRATE -R -S 1M "$file1" &&
7592                 error "incompatible -R and -S options not detected"
7593         $LFS_MIGRATE -R -p pool "$file1" &&
7594                 error "incompatible -R and -p options not detected"
7595         $LFS_MIGRATE -R -E eof -c 1 "$file1" &&
7596                 error "incompatible -R and -E options not detected"
7597         $LFS_MIGRATE -R -A "$file1" &&
7598                 error "incompatible -R and -A options not detected"
7599         $LFS_MIGRATE -A -c 1 "$file1" &&
7600                 error "incompatible -A and -c options not detected"
7601         $LFS_MIGRATE -A -S 1M "$file1" &&
7602                 error "incompatible -A and -S options not detected"
7603         $LFS_MIGRATE -A -p pool "$file1" &&
7604                 error "incompatible -A and -p options not detected"
7605         $LFS_MIGRATE -A -E eof -c 1 "$file1" &&
7606                 error "incompatible -A and -E options not detected"
7607         echo "done."
7608
7609         # Ensure unrecognized options are passed through to 'lfs migrate'
7610         echo -n "Verifying -S option is passed through to lfs migrate..."
7611         $LFS_MIGRATE -y -S 1M "$file1" || error "migration failed"
7612         cur_ssize=$($LFS getstripe -S "$file1")
7613         (( cur_ssize == 1048576 )) || error "migrate -S $cur_ssize != 1048576"
7614         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (1)"
7615         echo "done."
7616
7617         # File currently set to -S 1M -c 1
7618
7619         # Ensure long options are supported
7620         echo -n "Verifying long options supported..."
7621         $LFS_MIGRATE --non-block "$file1" ||
7622                 error "long option without argument not supported"
7623         $LFS_MIGRATE --stripe-size 512K "$file1" ||
7624                 error "long option with argument not supported"
7625         cur_ssize=$($LFS getstripe -S "$file1")
7626         (( cur_ssize == 524288 )) ||
7627                 error "migrate --stripe-size $cur_ssize != 524288"
7628         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (2)"
7629         echo "done."
7630
7631         # File currently set to -S 512K -c 1
7632
7633         if (( OSTCOUNT > 1 )); then
7634                 echo -n "Verifying explicit stripe count can be set..."
7635                 $LFS_MIGRATE -c 2 "$file1" || error "migrate failed"
7636                 cur_scount=$($LFS getstripe -c "$file1")
7637                 (( cur_scount == 2 )) || error "migrate -c $cur_scount != 2"
7638                 [[ "$(md5sum $file1)" == "$md5" ]] ||
7639                         error "file data has changed (3)"
7640                 echo "done."
7641         fi
7642
7643         # File currently set to -S 512K -c 1 or -S 512K -c 2
7644
7645         # Ensure parent striping is used if -R is set, and no stripe
7646         # count or size is specified
7647         echo -n "Setting stripe for parent directory..."
7648         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
7649                 error "cannot set stripe '-S 2M -c 1'"
7650         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (4)"
7651         echo "done."
7652
7653         echo -n "Verifying restripe option uses parent stripe settings..."
7654         parent_ssize=$($LFS getstripe -S $DIR/$tdir 2>/dev/null)
7655         parent_scount=$($LFS getstripe -c $DIR/$tdir 2>/dev/null)
7656         $LFS_MIGRATE -R "$file1" || error "migrate failed"
7657         cur_ssize=$($LFS getstripe -S "$file1")
7658         (( cur_ssize == parent_ssize )) ||
7659                 error "migrate -R stripe_size $cur_ssize != $parent_ssize"
7660         cur_scount=$($LFS getstripe -c "$file1")
7661         (( cur_scount == parent_scount )) ||
7662                 error "migrate -R stripe_count $cur_scount != $parent_scount"
7663         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (5)"
7664         echo "done."
7665
7666         # File currently set to -S 1M -c 1
7667
7668         # Ensure striping is preserved if -R is not set, and no stripe
7669         # count or size is specified
7670         echo -n "Verifying striping size preserved when not specified..."
7671         orig_ssize=$($LFS getstripe -S "$file1" 2>/dev/null)
7672         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
7673                 error "cannot set stripe on parent directory"
7674         $LFS_MIGRATE "$file1" || error "migrate failed"
7675         cur_ssize=$($LFS getstripe -S "$file1")
7676         (( cur_ssize == orig_ssize )) ||
7677                 error "migrate by default $cur_ssize != $orig_ssize"
7678         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (6)"
7679         echo "done."
7680
7681         # Ensure file name properly detected when final option has no argument
7682         echo -n "Verifying file name properly detected..."
7683         $LFS_MIGRATE "$file1" ||
7684                 error "file name interpreted as option argument"
7685         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (7)"
7686         echo "done."
7687
7688         # Ensure PFL arguments are passed through properly
7689         echo -n "Verifying PFL options passed through..."
7690         new_scount=$(((OSTCOUNT + 1) / 2))
7691         $LFS_MIGRATE -E 1M -c 1 -E 16M -c $new_scount -E eof -c -1 "$file1" ||
7692                 error "migrate PFL arguments failed"
7693         cur_comp=$($LFS getstripe --comp-count $file1)
7694         (( cur_comp == 3 )) || error "component count '$cur_comp' != 3"
7695         cur_scount=$($LFS getstripe --stripe-count $file1)
7696         (( cur_scount == new_scount)) ||
7697                 error "PFL stripe count $cur_scount != $new_scount"
7698         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (8)"
7699         echo "done."
7700 }
7701 run_test 56wc "check unrecognized options for lfs_migrate are passed through"
7702
7703 test_56wd() {
7704         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
7705
7706         local file1=$DIR/$tdir/$tfile
7707
7708         echo -n "Creating test dir..."
7709         test_mkdir $DIR/$tdir || error "cannot create dir"
7710         echo "done."
7711
7712         echo -n "Creating test file..."
7713         echo "$tfile" > $file1
7714         echo "done."
7715
7716         # Ensure 'lfs migrate' will fail by using a non-existent option,
7717         # and make sure rsync is not called to recover
7718         echo -n "Make sure --no-rsync option works..."
7719         $LFS_MIGRATE -y --no-rsync --invalid-opt $file1 2>&1 |
7720                 grep -q 'refusing to fall back to rsync' ||
7721                 error "rsync was called with --no-rsync set"
7722         echo "done."
7723
7724         # Ensure rsync is called without trying 'lfs migrate' first
7725         echo -n "Make sure --rsync option works..."
7726         $LFS_MIGRATE -y --rsync --invalid-opt $file1 2>&1 |
7727                 grep -q 'falling back to rsync' &&
7728                 error "lfs migrate was called with --rsync set"
7729         echo "done."
7730 }
7731 run_test 56wd "check lfs_migrate --rsync and --no-rsync work"
7732
7733 test_56we() {
7734         local td=$DIR/$tdir
7735         local tf=$td/$tfile
7736
7737         test_mkdir $td || error "cannot create $td"
7738         touch $tf || error "cannot touch $tf"
7739
7740         echo -n "Make sure --non-direct|-D works..."
7741         $LFS_MIGRATE -y --non-direct -v $tf 2>&1 |
7742                 grep -q "lfs migrate --non-direct" ||
7743                 error "--non-direct option cannot work correctly"
7744         $LFS_MIGRATE -y -D -v $tf 2>&1 |
7745                 grep -q "lfs migrate -D" ||
7746                 error "-D option cannot work correctly"
7747         echo "done."
7748 }
7749 run_test 56we "check lfs_migrate --non-direct|-D support"
7750
7751 test_56x() {
7752         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7753         check_swap_layouts_support
7754
7755         local dir=$DIR/$tdir
7756         local ref1=/etc/passwd
7757         local file1=$dir/file1
7758
7759         test_mkdir $dir || error "creating dir $dir"
7760         $LFS setstripe -c 2 $file1
7761         cp $ref1 $file1
7762         $LFS migrate -c 1 $file1 || error "migrate failed rc = $?"
7763         stripe=$($LFS getstripe -c $file1)
7764         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
7765         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
7766
7767         # clean up
7768         rm -f $file1
7769 }
7770 run_test 56x "lfs migration support"
7771
7772 test_56xa() {
7773         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7774         check_swap_layouts_support
7775
7776         local dir=$DIR/$tdir/$testnum
7777
7778         test_mkdir -p $dir
7779
7780         local ref1=/etc/passwd
7781         local file1=$dir/file1
7782
7783         $LFS setstripe -c 2 $file1
7784         cp $ref1 $file1
7785         $LFS migrate --block -c 1 $file1 || error "migrate failed rc = $?"
7786
7787         local stripe=$($LFS getstripe -c $file1)
7788
7789         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
7790         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
7791
7792         # clean up
7793         rm -f $file1
7794 }
7795 run_test 56xa "lfs migration --block support"
7796
7797 check_migrate_links() {
7798         [[ "$1" == "--rsync" ]] && local opts="--rsync -y" && shift
7799         local dir="$1"
7800         local file1="$dir/file1"
7801         local begin="$2"
7802         local count="$3"
7803         local runas="$4"
7804         local total_count=$(($begin + $count - 1))
7805         local symlink_count=10
7806         local uniq_count=10
7807
7808         if [ ! -f "$file1" ]; then
7809                 echo -n "creating initial file..."
7810                 $LFS setstripe -c 1 -S "512k" "$file1" ||
7811                         error "cannot setstripe initial file"
7812                 echo "done"
7813
7814                 echo -n "creating symlinks..."
7815                 for s in $(seq 1 $symlink_count); do
7816                         ln -s "$file1" "$dir/slink$s" ||
7817                                 error "cannot create symlinks"
7818                 done
7819                 echo "done"
7820
7821                 echo -n "creating nonlinked files..."
7822                 createmany -o "$dir/uniq" 1 10 &> /dev/null ||
7823                         error "cannot create nonlinked files"
7824                 echo "done"
7825         fi
7826
7827         # create hard links
7828         if [ ! -f "$dir/file$total_count" ]; then
7829                 echo -n "creating hard links $begin:$total_count..."
7830                 createmany -l"$file1" "$dir/file" "$begin" "$count" &>  \
7831                         /dev/null || error "cannot create hard links"
7832                 echo "done"
7833         fi
7834
7835         echo -n "checking number of hard links listed in xattrs..."
7836         local fid=$($LFS getstripe -F "$file1")
7837         local paths=($($LFS fid2path "$MOUNT" "$fid" 2> /dev/null))
7838
7839         echo "${#paths[*]}"
7840         if [ ${#paths[*]} -lt $total_count -a "$begin" -eq 2  ]; then
7841                         skip "hard link list has unexpected size, skipping test"
7842         fi
7843         if [ ${#paths[*]} -ge $total_count -a "$begin" -ne 2  ]; then
7844                         error "link names should exceed xattrs size"
7845         fi
7846
7847         echo -n "migrating files..."
7848         local migrate_out=$($runas $LFS_MIGRATE $opts -S '1m' $dir)
7849         local rc=$?
7850         [ $rc -eq 0 ] || error "migrate failed rc = $rc"
7851         echo "done"
7852
7853         # make sure all links have been properly migrated
7854         echo -n "verifying files..."
7855         fid=$($LFS getstripe -F "$file1") ||
7856                 error "cannot get fid for file $file1"
7857         for i in $(seq 2 $total_count); do
7858                 local fid2=$($LFS getstripe -F $dir/file$i)
7859
7860                 [ "$fid2" == "$fid" ] ||
7861                         error "migrated hard link has mismatched FID"
7862         done
7863
7864         # make sure hard links were properly detected, and migration was
7865         # performed only once for the entire link set; nonlinked files should
7866         # also be migrated
7867         local actual=$(grep -c 'done' <<< "$migrate_out")
7868         local expected=$(($uniq_count + 1))
7869
7870         [ "$actual" -eq  "$expected" ] ||
7871                 error "hard links individually migrated ($actual != $expected)"
7872
7873         # make sure the correct number of hard links are present
7874         local hardlinks=$(stat -c '%h' "$file1")
7875
7876         [ $hardlinks -eq $total_count ] ||
7877                 error "num hard links $hardlinks != $total_count"
7878         echo "done"
7879
7880         return 0
7881 }
7882
7883 test_56xb() {
7884         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
7885                 skip "Need MDS version at least 2.10.55"
7886
7887         local dir="$DIR/$tdir"
7888
7889         test_mkdir "$dir" || error "cannot create dir $dir"
7890
7891         echo "testing lfs migrate mode when all links fit within xattrs"
7892         check_migrate_links "$dir" 2 99
7893
7894         echo "testing rsync mode when all links fit within xattrs"
7895         check_migrate_links --rsync "$dir" 2 99
7896
7897         echo "testing lfs migrate mode when all links do not fit within xattrs"
7898         check_migrate_links "$dir" 101 100
7899
7900         echo "testing rsync mode when all links do not fit within xattrs"
7901         check_migrate_links --rsync "$dir" 101 100
7902
7903         chown -R $RUNAS_ID $dir
7904         echo "testing non-root lfs migrate mode when not all links are in xattr"
7905         check_migrate_links "$dir" 101 100 "$RUNAS"
7906
7907         # clean up
7908         rm -rf $dir
7909 }
7910 run_test 56xb "lfs migration hard link support"
7911
7912 test_56xc() {
7913         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7914
7915         local dir="$DIR/$tdir"
7916
7917         test_mkdir "$dir" || error "cannot create dir $dir"
7918
7919         # Test 1: ensure file < 1 GB is always migrated with 1 stripe
7920         echo -n "Setting initial stripe for 20MB test file..."
7921         $LFS setstripe -c 2 -i 0 "$dir/20mb" ||
7922                 error "cannot setstripe 20MB file"
7923         echo "done"
7924         echo -n "Sizing 20MB test file..."
7925         $TRUNCATE "$dir/20mb" 20971520 || error "cannot create 20MB test file"
7926         echo "done"
7927         echo -n "Verifying small file autostripe count is 1..."
7928         $LFS_MIGRATE -y -A -C 1 "$dir/20mb" ||
7929                 error "cannot migrate 20MB file"
7930         local stripe_count=$($LFS getstripe -c "$dir/20mb") ||
7931                 error "cannot get stripe for $dir/20mb"
7932         [ $stripe_count -eq 1 ] ||
7933                 error "unexpected stripe count $stripe_count for 20MB file"
7934         rm -f "$dir/20mb"
7935         echo "done"
7936
7937         # Test 2: File is small enough to fit within the available space on
7938         # sqrt(size_in_gb) + 1 OSTs but is larger than 1GB.  The file must
7939         # have at least an additional 1KB for each desired stripe for test 3
7940         echo -n "Setting stripe for 1GB test file..."
7941         $LFS setstripe -c 1 -i 0 "$dir/1gb" || error "cannot setstripe 1GB file"
7942         echo "done"
7943         echo -n "Sizing 1GB test file..."
7944         # File size is 1GB + 3KB
7945         $TRUNCATE "$dir/1gb" 1073744896 || error "cannot create 1GB test file"
7946         echo "done"
7947
7948         # need at least 512MB per OST for 1GB file to fit in 2 stripes
7949         local avail=$($LCTL get_param -n llite.$FSNAME*.kbytesavail)
7950         if (( avail > 524288 * OSTCOUNT )); then
7951                 echo -n "Migrating 1GB file..."
7952                 $LFS_MIGRATE -y -A -C 1 "$dir/1gb" ||
7953                         error "cannot migrate 1GB file"
7954                 echo "done"
7955                 echo -n "Verifying autostripe count is sqrt(n) + 1..."
7956                 stripe_count=$($LFS getstripe -c "$dir/1gb") ||
7957                         error "cannot getstripe for 1GB file"
7958                 [ $stripe_count -eq 2 ] ||
7959                         error "unexpected stripe count $stripe_count != 2"
7960                 echo "done"
7961         fi
7962
7963         # Test 3: File is too large to fit within the available space on
7964         # sqrt(n) + 1 OSTs.  Simulate limited available space with -X
7965         if [ $OSTCOUNT -ge 3 ]; then
7966                 # The required available space is calculated as
7967                 # file size (1GB + 3KB) / OST count (3).
7968                 local kb_per_ost=349526
7969
7970                 echo -n "Migrating 1GB file with limit..."
7971                 $LFS_MIGRATE -y -A -C 1 -X $kb_per_ost "$dir/1gb" ||
7972                         error "cannot migrate 1GB file with limit"
7973                 echo "done"
7974
7975                 stripe_count=$($LFS getstripe -c "$dir/1gb")
7976                 echo -n "Verifying 1GB autostripe count with limited space..."
7977                 [ "$stripe_count" -a $stripe_count -ge 3 ] ||
7978                         error "unexpected stripe count $stripe_count (min 3)"
7979                 echo "done"
7980         fi
7981
7982         # clean up
7983         rm -rf $dir
7984 }
7985 run_test 56xc "lfs migration autostripe"
7986
7987 test_56xd() {
7988         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7989
7990         local dir=$DIR/$tdir
7991         local f_mgrt=$dir/$tfile.mgrt
7992         local f_yaml=$dir/$tfile.yaml
7993         local f_copy=$dir/$tfile.copy
7994         local layout_yaml="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
7995         local layout_copy="-c 2 -S 2M -i 1"
7996         local yamlfile=$dir/yamlfile
7997         local layout_before;
7998         local layout_after;
7999
8000         test_mkdir "$dir" || error "cannot create dir $dir"
8001         stack_trap "rm -rf $dir"
8002         $LFS setstripe $layout_yaml $f_yaml ||
8003                 error "cannot setstripe $f_yaml with layout $layout_yaml"
8004         $LFS getstripe --yaml $f_yaml > $yamlfile
8005         $LFS setstripe $layout_copy $f_copy ||
8006                 error "cannot setstripe $f_copy with layout $layout_copy"
8007         touch $f_mgrt
8008         dd if=/dev/zero of=$f_mgrt bs=1M count=4
8009
8010         # 1. test option --yaml
8011         $LFS_MIGRATE -y --yaml $yamlfile $f_mgrt ||
8012                 error "cannot migrate $f_mgrt with --yaml $yamlfile"
8013         layout_before=$(get_layout_param $f_yaml)
8014         layout_after=$(get_layout_param $f_mgrt)
8015         [ "$layout_after" == "$layout_before" ] ||
8016                 error "lfs_migrate --yaml: $layout_after != $layout_before"
8017
8018         # 2. test option --copy
8019         $LFS_MIGRATE -y --copy $f_copy $f_mgrt ||
8020                 error "cannot migrate $f_mgrt with --copy $f_copy"
8021         layout_before=$(SKIP_INDEX=yes get_layout_param $f_copy)
8022         layout_after=$(SKIP_INDEX=yes get_layout_param $f_mgrt)
8023         [ "$layout_after" == "$layout_before" ] ||
8024                 error "lfs_migrate --copy: $layout_after != $layout_before"
8025 }
8026 run_test 56xd "check lfs_migrate --yaml and --copy support"
8027
8028 test_56xe() {
8029         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8030
8031         local dir=$DIR/$tdir
8032         local f_comp=$dir/$tfile
8033         local layout="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
8034         local layout_before=""
8035         local layout_after=""
8036
8037         test_mkdir "$dir" || error "cannot create dir $dir"
8038         stack_trap "rm -rf $dir"
8039         $LFS setstripe $layout $f_comp ||
8040                 error "cannot setstripe $f_comp with layout $layout"
8041         layout_before=$(SKIP_INDEX=yes get_layout_param $f_comp)
8042         dd if=/dev/zero of=$f_comp bs=1M count=4
8043
8044         # 1. migrate a comp layout file by lfs_migrate
8045         $LFS_MIGRATE -y $f_comp || error "cannot migrate $f_comp by lfs_migrate"
8046         layout_after=$(SKIP_INDEX=yes get_layout_param $f_comp)
8047         [ "$layout_before" == "$layout_after" ] ||
8048                 error "lfs_migrate: $layout_before != $layout_after"
8049
8050         # 2. migrate a comp layout file by lfs migrate
8051         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
8052         layout_after=$(SKIP_INDEX=yes get_layout_param $f_comp)
8053         [ "$layout_before" == "$layout_after" ] ||
8054                 error "lfs migrate: $layout_before != $layout_after"
8055 }
8056 run_test 56xe "migrate a composite layout file"
8057
8058 test_56xf() {
8059         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
8060
8061         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
8062                 skip "Need server version at least 2.13.53"
8063
8064         local dir=$DIR/$tdir
8065         local f_comp=$dir/$tfile
8066         local layout="-E 1M -c1 -E -1 -c2"
8067         local fid_before=""
8068         local fid_after=""
8069
8070         test_mkdir "$dir" || error "cannot create dir $dir"
8071         stack_trap "rm -rf $dir"
8072         $LFS setstripe $layout $f_comp ||
8073                 error "cannot setstripe $f_comp with layout $layout"
8074         fid_before=$($LFS getstripe --fid $f_comp)
8075         dd if=/dev/zero of=$f_comp bs=1M count=4
8076
8077         # 1. migrate a comp layout file to a comp layout
8078         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
8079         fid_after=$($LFS getstripe --fid $f_comp)
8080         [ "$fid_before" == "$fid_after" ] ||
8081                 error "comp-to-comp migrate: $fid_before != $fid_after"
8082
8083         # 2. migrate a comp layout file to a plain layout
8084         $LFS migrate -c2 $f_comp ||
8085                 error "cannot migrate $f_comp by lfs migrate"
8086         fid_after=$($LFS getstripe --fid $f_comp)
8087         [ "$fid_before" == "$fid_after" ] ||
8088                 error "comp-to-plain migrate: $fid_before != $fid_after"
8089
8090         # 3. migrate a plain layout file to a comp layout
8091         $LFS migrate $layout $f_comp ||
8092                 error "cannot migrate $f_comp by lfs migrate"
8093         fid_after=$($LFS getstripe --fid $f_comp)
8094         [ "$fid_before" == "$fid_after" ] ||
8095                 error "plain-to-comp migrate: $fid_before != $fid_after"
8096 }
8097 run_test 56xf "FID is not lost during migration of a composite layout file"
8098
8099 check_file_ost_range() {
8100         local file="$1"
8101         shift
8102         local range="$*"
8103         local -a file_range
8104         local idx
8105
8106         file_range=($($LFS getstripe -y "$file" |
8107                 awk '/l_ost_idx:/ { print $NF }'))
8108
8109         if [[ "${#file_range[@]}" = 0 ]]; then
8110                 echo "No osts found for $file"
8111                 return 1
8112         fi
8113
8114         for idx in "${file_range[@]}"; do
8115                 [[ " $range " =~ " $idx " ]] ||
8116                         return 1
8117         done
8118
8119         return 0
8120 }
8121
8122 sub_test_56xg() {
8123         local stripe_opt="$1"
8124         local pool="$2"
8125         shift 2
8126         local pool_ostidx="$(seq $* | tr '\n' ' ')"
8127
8128         $LFS migrate $stripe_opt -p $pool $DIR/$tfile ||
8129                 error "Fail to migrate $tfile on $pool"
8130         [[ "$($LFS getstripe -p $DIR/$tfile)" = "$pool" ]] ||
8131                 error "$tfile is not in pool $pool"
8132         check_file_ost_range "$DIR/$tfile" $pool_ostidx ||
8133                 error "$tfile osts mismatch with pool $pool (osts $pool_ostidx)"
8134 }
8135
8136 test_56xg() {
8137         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
8138         [[ $OSTCOUNT -ge 2 ]] || skip "needs >= 2 OSTs"
8139         [[ $MDS1_VERSION -gt $(version_code 2.14.52) ]] ||
8140                 skip "Need MDS version newer than 2.14.52"
8141
8142         local -a pool_names=("${TESTNAME}_0" "${TESTNAME}_1" "${TESTNAME}_2")
8143         local -a pool_ranges=("0 0" "1 1" "0 1")
8144
8145         # init pools
8146         for i in "${!pool_names[@]}"; do
8147                 pool_add ${pool_names[$i]} ||
8148                         error "pool_add failed (pool: ${pool_names[$i]})"
8149                 pool_add_targets ${pool_names[$i]} ${pool_ranges[$i]} ||
8150                         error "pool_add_targets failed (pool: ${pool_names[$i]})"
8151         done
8152
8153         # init the file to migrate
8154         $LFS setstripe -c1 -i1 $DIR/$tfile ||
8155                 error "Unable to create $tfile on OST1"
8156         stack_trap "rm -f $DIR/$tfile"
8157         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=4 status=none ||
8158                 error "Unable to write on $tfile"
8159
8160         echo "1. migrate $tfile on pool ${pool_names[0]}"
8161         sub_test_56xg "-c-1" "${pool_names[0]}" ${pool_ranges[0]}
8162
8163         echo "2. migrate $tfile on pool ${pool_names[2]}"
8164         sub_test_56xg "-c-1 -S2M" "${pool_names[2]}" ${pool_ranges[2]}
8165
8166         echo "3. migrate $tfile on pool ${pool_names[1]}"
8167         sub_test_56xg "-n -c-1" "${pool_names[1]}" ${pool_ranges[1]}
8168
8169         echo "4. migrate $tfile on pool ${pool_names[2]} with default stripe parameters"
8170         sub_test_56xg "" "${pool_names[2]}" ${pool_ranges[2]}
8171         echo
8172
8173         # Clean pools
8174         destroy_test_pools ||
8175                 error "pool_destroy failed"
8176 }
8177 run_test 56xg "lfs migrate pool support"
8178
8179 test_56xh() {
8180         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
8181
8182         local size_mb=25
8183         local file1=$DIR/$tfile
8184         local tmp1=$TMP/$tfile.tmp
8185
8186         $LFS setstripe -c 2 $file1
8187
8188         stack_trap "rm -f $file1 $tmp1"
8189         dd if=/dev/urandom of=$tmp1 bs=1M count=$size_mb ||
8190                         error "error creating $tmp1"
8191         ls -lsh $tmp1
8192         cp $tmp1 $file1
8193
8194         local start=$SECONDS
8195
8196         $LFS migrate --stats --stats-interval=1 -W 1M -c 1 $file1 ||
8197                 error "migrate failed rc = $?"
8198
8199         local elapsed=$((SECONDS - start))
8200
8201         # with 1MB/s, elapsed should equal size_mb
8202         (( elapsed >= size_mb * 95 / 100 )) ||
8203                 error "'lfs migrate -W' too fast ($elapsed < 0.95 * $size_mb)?"
8204
8205         (( elapsed <= size_mb * 120 / 100 )) ||
8206                 error_not_in_vm "'lfs migrate -W' slow ($elapsed > 1.2 * $size_mb)"
8207
8208         (( elapsed <= size_mb * 350 / 100 )) ||
8209                 error "'lfs migrate -W' too slow in VM ($elapsed > 3.5 * $size_mb)"
8210
8211         stripe=$($LFS getstripe -c $file1)
8212         (( $stripe == 1 )) || error "stripe of $file1 is $stripe != 1"
8213         cmp $file1 $tmp1 || error "content mismatch $file1 differs from $tmp1"
8214
8215         # Clean up file (since it is multiple MB)
8216         rm -f $file1 $tmp1
8217 }
8218 run_test 56xh "lfs migrate bandwidth limitation support"
8219
8220 test_56xi() {
8221         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
8222         verify_yaml_available || skip_env "YAML verification not installed"
8223
8224         local size_mb=5
8225         local file1=$DIR/$tfile.1
8226         local file2=$DIR/$tfile.2
8227         local file3=$DIR/$tfile.3
8228         local output_file=$DIR/$tfile.out
8229         local tmp1=$TMP/$tfile.tmp
8230
8231         $LFS setstripe -c 2 $file1
8232         $LFS setstripe -c 2 $file2
8233         $LFS setstripe -c 2 $file3
8234
8235         stack_trap "rm -f $file1 $file2 $file3 $tmp1 $output_file"
8236         dd if=/dev/urandom of=$tmp1 bs=1M count=$size_mb ||
8237                         error "error creating $tmp1"
8238         ls -lsh $tmp1
8239         cp $tmp1 $file1
8240         cp $tmp1 $file2
8241         cp $tmp1 $file3
8242
8243         $LFS migrate --stats --stats-interval=1 \
8244                 -c 1 $file1 $file2 $file3 1> $output_file ||
8245                 error "migrate failed rc = $?"
8246
8247         cat $output_file
8248         cat $output_file | verify_yaml || error "rename_stats is not valid YAML"
8249
8250         # Clean up file (since it is multiple MB)
8251         rm -f $file1 $file2 $file3 $tmp1 $output_file
8252 }
8253 run_test 56xi "lfs migrate stats support"
8254
8255 test_56xj() { # LU-16571 "lfs migrate -b" can cause thread starvation on OSS
8256         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
8257
8258         local file=$DIR/$tfile
8259         local linkdir=$DIR/$tdir
8260
8261         test_mkdir $linkdir || error "fail to create $linkdir"
8262         $LFS setstripe -i 0 -c 1 -S1M $file
8263         stack_trap "rm -rf $file $linkdir"
8264         dd if=/dev/urandom of=$file bs=1M count=10 ||
8265                 error "fail to create $file"
8266
8267         # Create file links
8268         local cpts
8269         local threads_max
8270         local nlinks
8271
8272         thread_max=$(do_facet ost1 "$LCTL get_param -n ost.OSS.ost.threads_max")
8273         cpts=$(do_facet ost1 "$LCTL get_param -n cpu_partition_table | wc -l")
8274         (( nlinks = thread_max * 3 / 2 / cpts))
8275
8276         echo "create $nlinks hard links of $file"
8277         createmany -l $file $linkdir/link $nlinks
8278
8279         # Parallel migrates (should not block)
8280         local i
8281         for ((i = 0; i < nlinks; i++)); do
8282                 echo $linkdir/link$i
8283         done | xargs -n1 -P $nlinks $LFS migrate -c2
8284
8285         local stripe_count
8286         stripe_count=$($LFS getstripe -c $file) ||
8287                 error "fail to get stripe count on $file"
8288
8289         ((stripe_count == 2)) ||
8290                 error "fail to migrate $file (stripe_count = $stripe_count)"
8291 }
8292 run_test 56xj "lfs migrate -b should not cause starvation of threads on OSS"
8293
8294 test_56y() {
8295         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
8296                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
8297
8298         local res=""
8299         local dir=$DIR/$tdir
8300         local f1=$dir/file1
8301         local f2=$dir/file2
8302
8303         test_mkdir -p $dir || error "creating dir $dir"
8304         touch $f1 || error "creating std file $f1"
8305         $MULTIOP $f2 H2c || error "creating released file $f2"
8306
8307         # a directory can be raid0, so ask only for files
8308         res=$($LFS find $dir -L raid0 -type f | wc -l)
8309         [[ $res == 2 ]] || error "search raid0: found $res files != 2"
8310
8311         res=$($LFS find $dir \! -L raid0 -type f | wc -l)
8312         [[ $res == 0 ]] || error "search !raid0: found $res files != 0"
8313
8314         # only files can be released, so no need to force file search
8315         res=$($LFS find $dir -L released)
8316         [[ $res == $f2 ]] || error "search released: found $res != $f2"
8317
8318         res=$($LFS find $dir -type f \! -L released)
8319         [[ $res == $f1 ]] || error "search !released: found $res != $f1"
8320 }
8321 run_test 56y "lfs find -L raid0|released"
8322
8323 test_56z() { # LU-4824
8324         # This checks to make sure 'lfs find' continues after errors
8325         # There are two classes of errors that should be caught:
8326         # - If multiple paths are provided, all should be searched even if one
8327         #   errors out
8328         # - If errors are encountered during the search, it should not terminate
8329         #   early
8330         local dir=$DIR/$tdir
8331         local i
8332
8333         test_mkdir $dir
8334         for i in d{0..9}; do
8335                 test_mkdir $dir/$i
8336                 touch $dir/$i/$tfile
8337         done
8338         $LFS find $DIR/non_existent_dir $dir &&
8339                 error "$LFS find did not return an error"
8340         # Make a directory unsearchable. This should NOT be the last entry in
8341         # directory order.  Arbitrarily pick the 6th entry
8342         chmod 700 $($LFS find $dir -type d | sed '6!d')
8343
8344         $RUNAS $LFS find $DIR/non_existent $dir
8345         local count=$($RUNAS $LFS find $DIR/non_existent $dir | wc -l)
8346
8347         # The user should be able to see 10 directories and 9 files
8348         (( count == 19 )) ||
8349                 error "$LFS find found $count != 19 entries after error"
8350 }
8351 run_test 56z "lfs find should continue after an error"
8352
8353 test_56aa() { # LU-5937
8354         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
8355
8356         local dir=$DIR/$tdir
8357
8358         mkdir $dir
8359         $LFS setdirstripe -c$MDSCOUNT $dir/striped_dir
8360
8361         createmany -o $dir/striped_dir/${tfile}- 1024
8362         local dirs=$($LFS find --size +8k $dir/)
8363
8364         [ -n "$dirs" ] || error "lfs find --size wrong under striped dir"
8365 }
8366 run_test 56aa "lfs find --size under striped dir"
8367
8368 test_56ab() { # LU-10705
8369         test_mkdir $DIR/$tdir
8370         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=8k count=1 seek=2k
8371         dd if=/dev/zero of=$DIR/$tdir/$tfile.2 bs=4k count=1 seek=4k
8372         dd if=/dev/zero of=$DIR/$tdir/$tfile.3 bs=1M count=2 seek=16
8373         # Flush writes to ensure valid blocks.  Need to be more thorough for
8374         # ZFS, since blocks are not allocated/returned to client immediately.
8375         sync_all_data
8376         wait_zfs_commit ost1 2
8377         cancel_lru_locks osc
8378         ls -ls $DIR/$tdir
8379
8380         local files=$($LFS find --size +16M $DIR/$tdir | wc -l)
8381
8382         [[ $files == 3 ]] || error ">16M size files $files isn't 3 as expected"
8383
8384         files=$($LFS find --blocks +1M $DIR/$tdir | wc -l)
8385         [[ $files == 1 ]] || error ">1M blocks files $files isn't 1 as expected"
8386
8387         rm -f $DIR/$tdir/$tfile.[123]
8388 }
8389 run_test 56ab "lfs find --blocks"
8390
8391 # LU-11188
8392 test_56aca() {
8393         local dir="$DIR/$tdir"
8394         local perms=(001 002 003 004 005 006 007
8395                      010 020 030 040 050 060 070
8396                      100 200 300 400 500 600 700
8397                      111 222 333 444 555 666 777)
8398         local perm_minus=(8 8 4 8 4 4 2
8399                           8 8 4 8 4 4 2
8400                           8 8 4 8 4 4 2
8401                           4 4 2 4 2 2 1)
8402         local perm_slash=(8  8 12  8 12 12 14
8403                           8  8 12  8 12 12 14
8404                           8  8 12  8 12 12 14
8405                          16 16 24 16 24 24 28)
8406
8407         test_mkdir "$dir"
8408         for perm in ${perms[*]}; do
8409                 touch "$dir/$tfile.$perm"
8410                 chmod $perm "$dir/$tfile.$perm"
8411         done
8412
8413         for ((i = 0; i < ${#perms[*]}; i++)); do
8414                 local num=$($LFS find $dir -perm ${perms[i]} | wc -l)
8415                 (( $num == 1 )) ||
8416                         error "lfs find -perm ${perms[i]}:"\
8417                               "$num != 1"
8418
8419                 num=$($LFS find $dir -perm -${perms[i]} -type f| wc -l)
8420                 (( $num == ${perm_minus[i]} )) ||
8421                         error "lfs find -perm -${perms[i]}:"\
8422                               "$num != ${perm_minus[i]}"
8423
8424                 num=$($LFS find $dir -perm /${perms[i]} -type f| wc -l)
8425                 (( $num == ${perm_slash[i]} )) ||
8426                         error "lfs find -perm /${perms[i]}:"\
8427                               "$num != ${perm_slash[i]}"
8428         done
8429 }
8430 run_test 56aca "check lfs find -perm with octal representation"
8431
8432 test_56acb() {
8433         local dir=$DIR/$tdir
8434         # p is the permission of write and execute for user, group and other
8435         # without the umask. It is used to test +wx.
8436         local p=$(printf "%o" "$((0333 & ~$(umask)))")
8437         local perms=(1000 000 2000 4000 $p 644 111 110 100 004)
8438         local symbolic=(+t  a+t u+t g+t o+t
8439                         g+s u+s o+s +s o+sr
8440                         o=r,ug+o,u+w
8441                         u+ g+ o+ a+ ugo+
8442                         u- g- o- a- ugo-
8443                         u= g= o= a= ugo=
8444                         o=r,ug+o,u+w u=r,a+u,u+w
8445                         g=r,ugo=g,u+w u+x,+X +X
8446                         u+x,u+X u+X u+x,g+X o+r,+X
8447                         u+x,go+X +wx +rwx)
8448
8449         test_mkdir $dir
8450         for perm in ${perms[*]}; do
8451                 touch "$dir/$tfile.$perm"
8452                 chmod $perm "$dir/$tfile.$perm"
8453         done
8454
8455         for (( i = 0; i < ${#symbolic[*]}; i++ )); do
8456                 local num=$($LFS find $dir -perm ${symbolic[i]} | wc -l)
8457
8458                 (( $num == 1 )) ||
8459                         error "lfs find $dir -perm ${symbolic[i]}: $num != 1"
8460         done
8461 }
8462 run_test 56acb "check lfs find -perm with symbolic representation"
8463
8464 test_56acc() {
8465         local dir=$DIR/$tdir
8466         local tests="17777 787 789 abcd
8467                 ug=uu ug=a ug=gu uo=ou urw
8468                 u+xg+x a=r,u+x,"
8469
8470         test_mkdir $dir
8471         for err in $tests; do
8472                 if $LFS find $dir -perm $err 2>/dev/null; then
8473                         error "lfs find -perm $err: parsing should have failed"
8474                 fi
8475         done
8476 }
8477 run_test 56acc "check parsing error for lfs find -perm"
8478
8479 test_56ba() {
8480         [ $MDS1_VERSION -lt $(version_code 2.10.50) ] &&
8481                 skip "Need MDS version at least 2.10.50"
8482
8483         # Create composite files with one component
8484         local dir=$DIR/$tdir
8485
8486         setup_56 $dir/1Mfiles 5 1 "-S 1M --component-end 1M"
8487         # Create composite files with three components
8488         setup_56 $dir/2Mfiles 5 2 "-E 2M -S 1M -E 4M -E 6M"
8489         # Create non-composite files
8490         createmany -o $dir/${tfile}- 10
8491
8492         local nfiles=$($LFS find --component-end 1M --type f $dir | wc -l)
8493
8494         [[ $nfiles == 10 ]] ||
8495                 error "lfs find -E 1M found $nfiles != 10 files"
8496
8497         nfiles=$($LFS find ! -E 1M --type f $dir | wc -l)
8498         [[ $nfiles == 25 ]] ||
8499                 error "lfs find ! -E 1M found $nfiles != 25 files"
8500
8501         # All files have a component that starts at 0
8502         nfiles=$($LFS find --component-start 0 --type f $dir | wc -l)
8503         [[ $nfiles == 35 ]] ||
8504                 error "lfs find --component-start 0 - $nfiles != 35 files"
8505
8506         nfiles=$($LFS find --component-start 2M --type f $dir | wc -l)
8507         [[ $nfiles == 15 ]] ||
8508                 error "lfs find --component-start 2M - $nfiles != 15 files"
8509
8510         # All files created here have a componenet that does not starts at 2M
8511         nfiles=$($LFS find ! --component-start 2M --type f $dir | wc -l)
8512         [[ $nfiles == 35 ]] ||
8513                 error "lfs find ! --component-start 2M - $nfiles != 35 files"
8514
8515         # Find files with a specified number of components
8516         local nfiles=$($LFS find --component-count 3 --type f $dir | wc -l)
8517         [[ $nfiles == 15 ]] ||
8518                 error "lfs find --component-count 3 - $nfiles != 15 files"
8519
8520         # Remember non-composite files have a component count of zero
8521         local nfiles=$($LFS find --component-count 0 --type f $dir | wc -l)
8522         [[ $nfiles == 10 ]] ||
8523                 error "lfs find --component-count 0 - $nfiles != 10 files"
8524
8525         nfiles=$($LFS find ! --component-count 3 --type f $dir | wc -l)
8526         [[ $nfiles == 20 ]] ||
8527                 error "lfs find ! --component-count 3 - $nfiles != 20 files"
8528
8529         # All files have a flag called "init"
8530         local nfiles=$($LFS find --component-flags init --type f $dir | wc -l)
8531         [[ $nfiles == 35 ]] ||
8532                 error "lfs find --component-flags init - $nfiles != 35 files"
8533
8534         # Multi-component files will have a component not initialized
8535         local nfiles=$($LFS find ! --component-flags init --type f $dir | wc -l)
8536         [[ $nfiles == 15 ]] ||
8537                 error "lfs find !--component-flags init - $nfiles != 15 files"
8538
8539         rm -rf $dir
8540
8541 }
8542 run_test 56ba "test lfs find --component-end, -start, -count, and -flags"
8543
8544 test_56ca() {
8545         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
8546                 skip "Need MDS version at least 2.10.57"
8547
8548         local td=$DIR/$tdir
8549         local tf=$td/$tfile
8550         local dir
8551         local nfiles
8552         local cmd
8553         local i
8554         local j
8555
8556         # create mirrored directories and mirrored files
8557         mkdir $td || error "mkdir $td failed"
8558         $LFS mirror create -N3 $td || error "create mirrored dir $td failed"
8559         createmany -o $tf- 10 || error "create $tf- failed"
8560
8561         for i in $(seq 2); do
8562                 dir=$td/dir$i
8563                 mkdir $dir || error "mkdir $dir failed"
8564                 $LFS mirror create -N$((3 + i)) $dir ||
8565                         error "create mirrored dir $dir failed"
8566                 createmany -o $dir/$tfile- 10 ||
8567                         error "create $dir/$tfile- failed"
8568         done
8569
8570         # change the states of some mirrored files
8571         echo foo > $tf-6
8572         for i in $(seq 2); do
8573                 dir=$td/dir$i
8574                 for j in $(seq 4 9); do
8575                         echo foo > $dir/$tfile-$j
8576                 done
8577         done
8578
8579         # find mirrored files with specific mirror count
8580         cmd="$LFS find --mirror-count 3 --type f $td"
8581         nfiles=$($cmd | wc -l)
8582         [[ $nfiles = 10 ]] || error "$cmd: $nfiles != 10 files"
8583
8584         cmd="$LFS find ! --mirror-count 3 --type f $td"
8585         nfiles=$($cmd | wc -l)
8586         [[ $nfiles = 20 ]] || error "$cmd: $nfiles != 20 files"
8587
8588         cmd="$LFS find --mirror-count +2 --type f $td"
8589         nfiles=$($cmd | wc -l)
8590         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8591
8592         cmd="$LFS find --mirror-count -6 --type f $td"
8593         nfiles=$($cmd | wc -l)
8594         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8595
8596         # find mirrored files with specific file state
8597         cmd="$LFS find --maxdepth 1 --mirror-state=^ro --type f $td"
8598         [[ $($cmd) = $tf-6 ]] || error "$cmd: didn't return $tf-6"
8599
8600         cmd="$LFS find --mirror-state=ro --type f $td"
8601         nfiles=$($cmd | wc -l)
8602         [[ $nfiles = 17 ]] || error "$cmd: $nfiles != 17 files"
8603
8604         cmd="$LFS find ! --mirror-state=ro --type f $td"
8605         nfiles=$($cmd | wc -l)
8606         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
8607
8608         cmd="$LFS find --mirror-state=wp --type f $td"
8609         nfiles=$($cmd | wc -l)
8610         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
8611
8612         cmd="$LFS find ! --mirror-state=sp --type f $td"
8613         nfiles=$($cmd | wc -l)
8614         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8615 }
8616 run_test 56ca "check lfs find --mirror-count|-N and --mirror-state"
8617
8618 test_56da() { # LU-14179
8619         local path=$DIR/$tdir
8620
8621         test_mkdir $path
8622         cd $path
8623
8624         local longdir=$(str_repeat 'a' 255)
8625
8626         for i in {1..15}; do
8627                 path=$path/$longdir
8628                 test_mkdir $longdir
8629                 cd $longdir
8630         done
8631
8632         local len=${#path}
8633         local lastdir=$(str_repeat 'a' $((4096 - 1 - $len - 1)))
8634
8635         test_mkdir $lastdir
8636         cd $lastdir
8637         # PATH_MAX-1
8638         (( ${#PWD} == 4095 )) || error "bad PWD length ${#PWD}, expect 4095"
8639
8640         # NAME_MAX
8641         touch $(str_repeat 'f' 255)
8642
8643         $LFS find $DIR/$tdir --type d |& grep "lfs find: error" &&
8644                 error "lfs find reported an error"
8645
8646         rm -rf $DIR/$tdir
8647 }
8648 run_test 56da "test lfs find with long paths"
8649
8650 test_56ea() { #LU-10378
8651         local path=$DIR/$tdir
8652         local pool=$TESTNAME
8653
8654         # Create ost pool
8655         pool_add $pool || error "pool_add $pool failed"
8656         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
8657                 error "adding targets to $pool failed"
8658
8659         # Set default pool on directory before creating file
8660         mkdir $path || error "mkdir $path failed"
8661         $LFS setstripe -p $pool $path ||
8662                 error "set OST pool on $pool failed"
8663         touch $path/$tfile || error "touch $path/$tfile failed"
8664
8665         # Compare basic file attributes from -printf and stat
8666         local attr_printf=$($LFS find $path/$tfile -printf "%A@ %T@ %C@ %U %G %n")
8667         local attr_stat=$(stat -c "%X %Y %Z %u %g %h" $path/$tfile)
8668
8669         [[ "${attr_printf}" == "${attr_stat}" ]] ||
8670                 error "Attrs from lfs find and stat don't match"
8671
8672         # Compare Lustre attributes from lfs find and lfs getstripe
8673         local lattr_printf=$($LFS find $path/$tfile -printf "%Lc %LS %Li %Lp")
8674         local str_cnt=$($LFS getstripe --stripe-count $path/$tfile)
8675         local str_size=$($LFS getstripe --stripe-size $path/$tfile)
8676         local str_idx=$($LFS getstripe --stripe-index $path/$tfile)
8677         local fpool=$($LFS getstripe --pool $path/$tfile)
8678         local lattr_getstr="${str_cnt} ${str_size} ${str_idx} ${fpool}"
8679
8680         [[ "${lattr_printf}" == "${lattr_getstr}" ]] ||
8681                 error "Attrs from lfs find and lfs getstripe don't match"
8682
8683         # Verify behavior for unknown escape/format sequences
8684         local esc_printf=$($LFS find $path/$tfile -printf '\\ %% \Q %Q')
8685
8686         [[ "${esc_printf}" == '\ % \Q %Q' ]] ||
8687                 error "Escape/format codes don't match"
8688 }
8689 run_test 56ea "test lfs find -printf option"
8690
8691 test_56eb() {
8692         local dir=$DIR/$tdir
8693         local subdir_1=$dir/subdir_1
8694
8695         test_mkdir -p $subdir_1
8696         ln -s subdir_1 $dir/link_1
8697
8698         $LFS getstripe $dir | grep "^$dir/link_1$" -A1 ||
8699                 error "symlink is not followed"
8700
8701         $LFS getstripe --no-follow $dir |
8702                 grep "^$dir/link_1 has no stripe info$" ||
8703                 error "symlink should not have stripe info"
8704
8705         touch $dir/testfile
8706         ln -s testfile $dir/file_link_2
8707
8708         $LFS getstripe $dir | grep "^$dir/file_link_2$" -A1 ||
8709                 error "symlink is not followed"
8710
8711         $LFS getstripe --no-follow $dir |
8712                 grep "^$dir/file_link_2 has no stripe info$" ||
8713                 error "symlink should not have stripe info"
8714 }
8715 run_test 56eb "check lfs getstripe on symlink"
8716
8717 test_56ec() {
8718         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8719         local dir=$DIR/$tdir
8720         local srcfile=$dir/srcfile
8721         local srcyaml=$dir/srcyaml
8722         local destfile=$dir/destfile
8723
8724         test_mkdir -p $dir
8725
8726         $LFS setstripe -i 1 $srcfile
8727         $LFS getstripe --hex-idx --yaml $srcfile > $srcyaml
8728         # if the setstripe yaml parsing fails for any reason, the command can
8729         # randomly assign the correct OST index, leading to an erroneous
8730         # success. but the chance of false success is low enough that a
8731         # regression should still be quickly caught.
8732         $LFS setstripe --yaml=$srcyaml $destfile
8733
8734         local srcindex=$($LFS getstripe -i $srcfile)
8735         local destindex=$($LFS getstripe -i $destfile)
8736
8737         if [[ ! $srcindex -eq $destindex ]]; then
8738                 error "setstripe did not set OST index correctly"
8739         fi
8740 }
8741 run_test 56ec "check lfs getstripe,setstripe --hex --yaml"
8742
8743 test_56eda() {
8744         local dir=$DIR/$tdir
8745         local subdir=$dir/subdir
8746         local file1=$dir/$tfile
8747         local file2=$dir/$tfile\2
8748         local link=$dir/$tfile-link
8749         local nfiles
8750
8751         test_mkdir -p $dir
8752         $LFS setdirstripe -c1 $subdir
8753         touch $file1
8754         touch $file2
8755         ln $file2 $link
8756
8757         nfiles=$($LFS find --links 1 $dir | wc -l)
8758         (( $nfiles == 1 )) ||
8759                 error "lfs find --links expected 1 file, got $nfiles"
8760
8761         nfiles=$($LFS find --type f --links 2 $dir | wc -l)
8762         (( $nfiles == 2 )) ||
8763                 error "lfs find --links expected 2 files, got $nfiles"
8764
8765         nfiles=$($LFS find --type d --links 2 $dir | wc -l)
8766         (( $nfiles == 1 )) ||
8767                 error "lfs find --links expected 1 directory, got $nfiles"
8768 }
8769 run_test 56eda "check lfs find --links"
8770
8771 test_56edb() {
8772         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
8773
8774         local dir=$DIR/$tdir
8775         local stripedir=$dir/stripedir
8776         local nfiles
8777
8778         test_mkdir -p $dir
8779
8780         $LFS setdirstripe -c2 $stripedir
8781
8782         $LFS getdirstripe $stripedir
8783
8784         nfiles=$($LFS find --type d --links 2 $stripedir | wc -l)
8785         (( $nfiles == 1 )) ||
8786                 error "lfs find --links expected 1 directory, got $nfiles"
8787 }
8788 run_test 56edb "check lfs find --links for directory striped on multiple MDTs"
8789
8790 test_57a() {
8791         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8792         # note test will not do anything if MDS is not local
8793         if [ "$mds1_FSTYPE" != ldiskfs ]; then
8794                 skip_env "ldiskfs only test"
8795         fi
8796         remote_mds_nodsh && skip "remote MDS with nodsh"
8797
8798         local MNTDEV="osd*.*MDT*.mntdev"
8799         DEV=$(do_facet $SINGLEMDS lctl get_param -n $MNTDEV)
8800         [ -z "$DEV" ] && error "can't access $MNTDEV"
8801         for DEV in $(do_facet $SINGLEMDS lctl get_param -n $MNTDEV); do
8802                 do_facet $SINGLEMDS $DUMPE2FS -h $DEV > $TMP/t57a.dump ||
8803                         error "can't access $DEV"
8804                 DEVISIZE=$(awk '/Inode size:/ { print $3 }' $TMP/t57a.dump)
8805                 [[ $DEVISIZE -gt 128 ]] || error "inode size $DEVISIZE"
8806                 rm $TMP/t57a.dump
8807         done
8808 }
8809 run_test 57a "verify MDS filesystem created with large inodes =="
8810
8811 test_57b() {
8812         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8813         if [ "$mds1_FSTYPE" != ldiskfs ]; then
8814                 skip_env "ldiskfs only test"
8815         fi
8816         remote_mds_nodsh && skip "remote MDS with nodsh"
8817
8818         local dir=$DIR/$tdir
8819         local filecount=100
8820         local file1=$dir/f1
8821         local fileN=$dir/f$filecount
8822
8823         rm -rf $dir || error "removing $dir"
8824         test_mkdir -c1 $dir
8825         local mdtidx=$($LFS getstripe -m $dir)
8826         local mdtname=MDT$(printf %04x $mdtidx)
8827         local facet=mds$((mdtidx + 1))
8828
8829         echo "mcreating $filecount files"
8830         createmany -m $dir/f 1 $filecount || error "creating files in $dir"
8831
8832         # verify that files do not have EAs yet
8833         $LFS getstripe $file1 2>&1 | grep -q "no stripe" ||
8834                 error "$file1 has an EA"
8835         $LFS getstripe $fileN 2>&1 | grep -q "no stripe" ||
8836                 error "$fileN has an EA"
8837
8838         sync
8839         sleep 1
8840         df $dir  #make sure we get new statfs data
8841         local mdsfree=$(do_facet $facet \
8842                         lctl get_param -n osd*.*$mdtname.kbytesfree)
8843         local mdcfree=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
8844         local file
8845
8846         echo "opening files to create objects/EAs"
8847         for file in $(seq -f $dir/f%g 1 $filecount); do
8848                 $OPENFILE -f O_RDWR $file > /dev/null 2>&1 ||
8849                         error "opening $file"
8850         done
8851
8852         # verify that files have EAs now
8853         $LFS getstripe $file1 | grep -q "obdidx" || error "$file1 missing EA"
8854         $LFS getstripe $fileN | grep -q "obdidx" || error "$fileN missing EA"
8855
8856         sleep 1  #make sure we get new statfs data
8857         df $dir
8858         local mdsfree2=$(do_facet $facet \
8859                          lctl get_param -n osd*.*$mdtname.kbytesfree)
8860         local mdcfree2=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
8861
8862         if [[ $mdcfree2 -lt $((mdcfree - 16)) ]]; then
8863                 if [ "$mdsfree" != "$mdsfree2" ]; then
8864                         error "MDC before $mdcfree != after $mdcfree2"
8865                 else
8866                         echo "MDC before $mdcfree != after $mdcfree2"
8867                         echo "unable to confirm if MDS has large inodes"
8868                 fi
8869         fi
8870         rm -rf $dir
8871 }
8872 run_test 57b "default LOV EAs are stored inside large inodes ==="
8873
8874 test_58() {
8875         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8876         [ -z "$(which wiretest 2>/dev/null)" ] &&
8877                         skip_env "could not find wiretest"
8878
8879         wiretest
8880 }
8881 run_test 58 "verify cross-platform wire constants =============="
8882
8883 test_59() {
8884         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8885
8886         echo "touch 130 files"
8887         createmany -o $DIR/f59- 130
8888         echo "rm 130 files"
8889         unlinkmany $DIR/f59- 130
8890         sync
8891         # wait for commitment of removal
8892         wait_delete_completed
8893 }
8894 run_test 59 "verify cancellation of llog records async ========="
8895
8896 TEST60_HEAD="test_60 run $RANDOM"
8897 test_60a() {
8898         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8899         remote_mgs_nodsh && skip "remote MGS with nodsh"
8900         do_facet mgs "! which run-llog.sh &> /dev/null" &&
8901                 do_facet mgs "! ls run-llog.sh &> /dev/null" &&
8902                         skip_env "missing subtest run-llog.sh"
8903
8904         log "$TEST60_HEAD - from kernel mode"
8905         do_facet mgs "$LCTL dk > /dev/null"
8906         do_facet mgs "bash run-llog.sh" || error "run-llog.sh failed"
8907         do_facet mgs $LCTL dk > $TMP/$tfile
8908
8909         # LU-6388: test llog_reader
8910         local llog_reader=$(do_facet mgs "which llog_reader 2> /dev/null")
8911         llog_reader=${llog_reader:-$LUSTRE/utils/llog_reader}
8912         [ -z $(do_facet mgs ls -d $llog_reader 2> /dev/null) ] &&
8913                         skip_env "missing llog_reader"
8914         local fstype=$(facet_fstype mgs)
8915         [ $fstype != ldiskfs -a $fstype != zfs ] &&
8916                 skip_env "Only for ldiskfs or zfs type mgs"
8917
8918         local mntpt=$(facet_mntpt mgs)
8919         local mgsdev=$(mgsdevname 1)
8920         local fid_list
8921         local fid
8922         local rec_list
8923         local rec
8924         local rec_type
8925         local obj_file
8926         local path
8927         local seq
8928         local oid
8929         local pass=true
8930
8931         #get fid and record list
8932         fid_list=($(awk '/9_sub.*record/ { print $NF }' $TMP/$tfile |
8933                 tail -n 4))
8934         rec_list=($(awk '/9_sub.*record/ { print $((NF-3)) }' $TMP/$tfile |
8935                 tail -n 4))
8936         #remount mgs as ldiskfs or zfs type
8937         stop mgs || error "stop mgs failed"
8938         mount_fstype mgs || error "remount mgs failed"
8939         for ((i = 0; i < ${#fid_list[@]}; i++)); do
8940                 fid=${fid_list[i]}
8941                 rec=${rec_list[i]}
8942                 seq=$(echo $fid | awk -F ':' '{ print $1 }' | sed -e "s/^0x//g")
8943                 oid=$(echo $fid | awk -F ':' '{ print $2 }' | sed -e "s/^0x//g")
8944                 oid=$((16#$oid))
8945
8946                 case $fstype in
8947                         ldiskfs )
8948                                 obj_file=$mntpt/O/$seq/d$((oid%32))/$oid ;;
8949                         zfs )
8950                                 obj_file=$mntpt/oi.$(($((16#$seq))&127))/$fid ;;
8951                 esac
8952                 echo "obj_file is $obj_file"
8953                 do_facet mgs $llog_reader $obj_file
8954
8955                 rec_type=$(do_facet mgs $llog_reader $obj_file | grep "type=" |
8956                         awk '{ print $3 }' | sed -e "s/^type=//g")
8957                 if [ $rec_type != $rec ]; then
8958                         echo "FAILED test_60a wrong record type $rec_type," \
8959                               "should be $rec"
8960                         pass=false
8961                         break
8962                 fi
8963
8964                 #check obj path if record type is LLOG_LOGID_MAGIC
8965                 if [ "$rec" == "1064553b" ]; then
8966                         path=$(do_facet mgs $llog_reader $obj_file |
8967                                 grep "path=" | awk '{ print $NF }' |
8968                                 sed -e "s/^path=//g")
8969                         if [ $obj_file != $mntpt/$path ]; then
8970                                 echo "FAILED test_60a wrong obj path" \
8971                                       "$montpt/$path, should be $obj_file"
8972                                 pass=false
8973                                 break
8974                         fi
8975                 fi
8976         done
8977         rm -f $TMP/$tfile
8978         #restart mgs before "error", otherwise it will block the next test
8979         stop mgs || error "stop mgs failed"
8980         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
8981         $pass || error "test failed, see FAILED test_60a messages for specifics"
8982 }
8983 run_test 60a "llog_test run from kernel module and test llog_reader"
8984
8985 test_60b() { # bug 6411
8986         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8987
8988         dmesg > $DIR/$tfile
8989         LLOG_COUNT=$(do_facet mgs dmesg |
8990                      awk "/$TEST60_HEAD/ { marker = 1; from_marker = 0; }
8991                           /llog_[a-z]*.c:[0-9]/ {
8992                                 if (marker)
8993                                         from_marker++
8994                                 from_begin++
8995                           }
8996                           END {
8997                                 if (marker)
8998                                         print from_marker
8999                                 else
9000                                         print from_begin
9001                           }")
9002
9003         [[ $LLOG_COUNT -gt 120 ]] &&
9004                 error "CDEBUG_LIMIT not limiting messages ($LLOG_COUNT)" || true
9005 }
9006 run_test 60b "limit repeated messages from CERROR/CWARN"
9007
9008 test_60c() {
9009         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9010
9011         echo "create 5000 files"
9012         createmany -o $DIR/f60c- 5000
9013 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED  0x137
9014         lctl set_param fail_loc=0x80000137
9015         unlinkmany $DIR/f60c- 5000
9016         lctl set_param fail_loc=0
9017 }
9018 run_test 60c "unlink file when mds full"
9019
9020 test_60d() {
9021         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9022
9023         SAVEPRINTK=$(lctl get_param -n printk)
9024         # verify "lctl mark" is even working"
9025         MESSAGE="test message ID $RANDOM $$"
9026         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
9027         dmesg | grep -q "$MESSAGE" || error "didn't find debug marker in log"
9028
9029         lctl set_param printk=0 || error "set lnet.printk failed"
9030         lctl get_param -n printk | grep emerg || error "lnet.printk dropped emerg"
9031         MESSAGE="new test message ID $RANDOM $$"
9032         # Assume here that libcfs_debug_mark_buffer() uses D_WARNING
9033         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
9034         dmesg | grep -q "$MESSAGE" && error "D_WARNING wasn't masked" || true
9035
9036         lctl set_param -n printk="$SAVEPRINTK"
9037 }
9038 run_test 60d "test printk console message masking"
9039
9040 test_60e() {
9041         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9042         remote_mds_nodsh && skip "remote MDS with nodsh"
9043
9044         touch $DIR/$tfile
9045 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED2  0x15b
9046         do_facet mds1 lctl set_param fail_loc=0x15b
9047         rm $DIR/$tfile
9048 }
9049 run_test 60e "no space while new llog is being created"
9050
9051 test_60f() {
9052         local old_path=$($LCTL get_param -n debug_path)
9053
9054         stack_trap "$LCTL set_param debug_path=$old_path"
9055         stack_trap "rm -f $TMP/$tfile*"
9056         rm -f $TMP/$tfile* 2> /dev/null
9057         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
9058         $LCTL set_param debug_path=$TMP/$tfile fail_loc=0x8000050e
9059         test_mkdir $DIR/$tdir
9060         # retry in case the open is cached and not released
9061         for (( i = 0; i < 100 && $(ls $TMP/$tfile* | wc -l) == 0; i++ )); do
9062                 echo $i > $DIR/$tdir/$tfile.$i && cat $DIR/$tdir/$tfile.$i
9063                 sleep 0.1
9064         done
9065         ls $TMP/$tfile*
9066         (( $(ls $TMP/$tfile* | wc -l) > 0 )) || error "$TMP/$tfile not dumped"
9067 }
9068 run_test 60f "change debug_path works"
9069
9070 test_60g() {
9071         local pid
9072         local i
9073
9074         test_mkdir -c $MDSCOUNT $DIR/$tdir
9075
9076         (
9077                 local index=0
9078                 while true; do
9079                         $LFS setdirstripe -i $(($index % $MDSCOUNT)) \
9080                                 -c $MDSCOUNT $DIR/$tdir/subdir$index \
9081                                 2>/dev/null
9082                         mkdir $DIR/$tdir/subdir$index 2>/dev/null
9083                         rmdir $DIR/$tdir/subdir$index 2>/dev/null
9084                         index=$((index + 1))
9085                 done
9086         ) &
9087
9088         pid=$!
9089
9090         for i in {0..100}; do
9091                 # define OBD_FAIL_OSD_TXN_START    0x19a
9092                 local index=$((i % MDSCOUNT + 1))
9093
9094                 do_facet mds$index $LCTL set_param fail_loc=0x8000019a \
9095                         > /dev/null
9096                 sleep 0.01
9097         done
9098
9099         kill -9 $pid
9100
9101         for i in $(seq $MDSCOUNT); do
9102                 do_facet mds$i $LCTL set_param fail_loc=0 > /dev/null
9103         done
9104
9105         mkdir $DIR/$tdir/new || error "mkdir failed"
9106         rmdir $DIR/$tdir/new || error "rmdir failed"
9107
9108         do_facet mds1 $LCTL lfsck_start -M $(facet_svc mds1) -A -C \
9109                 -t namespace
9110         for i in $(seq $MDSCOUNT); do
9111                 wait_update_facet mds$i "$LCTL get_param -n \
9112                         mdd.$(facet_svc mds$i).lfsck_namespace |
9113                         awk '/^status/ { print \\\$2 }'" "completed"
9114         done
9115
9116         ls -R $DIR/$tdir
9117         rm -rf $DIR/$tdir || error "rmdir failed"
9118 }
9119 run_test 60g "transaction abort won't cause MDT hung"
9120
9121 test_60h() {
9122         [ $MDS1_VERSION -le $(version_code 2.12.52) ] &&
9123                 skip "Need MDS version at least 2.12.52"
9124         [ $MDSCOUNT -lt 2 ] && skip "Need at least 2 MDTs"
9125
9126         local f
9127
9128         #define OBD_FAIL_MDS_STRIPE_CREATE       0x188
9129         #define OBD_FAIL_MDS_STRIPE_FID          0x189
9130         for fail_loc in 0x80000188 0x80000189; do
9131                 do_facet mds1 "$LCTL set_param fail_loc=$fail_loc"
9132                 $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir-$fail_loc ||
9133                         error "mkdir $dir-$fail_loc failed"
9134                 for i in {0..10}; do
9135                         # create may fail on missing stripe
9136                         echo $i > $DIR/$tdir-$fail_loc/$i
9137                 done
9138                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
9139                         error "getdirstripe $tdir-$fail_loc failed"
9140                 $LFS migrate -m 1 $DIR/$tdir-$fail_loc ||
9141                         error "migrate $tdir-$fail_loc failed"
9142                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
9143                         error "getdirstripe $tdir-$fail_loc failed"
9144                 pushd $DIR/$tdir-$fail_loc
9145                 for f in *; do
9146                         echo $f | cmp $f - || error "$f data mismatch"
9147                 done
9148                 popd
9149                 rm -rf $DIR/$tdir-$fail_loc
9150         done
9151 }
9152 run_test 60h "striped directory with missing stripes can be accessed"
9153
9154 function t60i_load() {
9155         mkdir $DIR/$tdir
9156         #define OBD_FAIL_LLOG_PAUSE_AFTER_PAD               0x131c
9157         $LCTL set_param fail_loc=0x131c fail_val=1
9158         for ((i=0; i<5000; i++)); do
9159                 touch $DIR/$tdir/f$i
9160         done
9161 }
9162
9163 test_60i() {
9164         changelog_register || error "changelog_register failed"
9165         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
9166         changelog_users $SINGLEMDS | grep -q $cl_user ||
9167                 error "User $cl_user not found in changelog_users"
9168         changelog_chmask "ALL"
9169         t60i_load &
9170         local PID=$!
9171         for((i=0; i<100; i++)); do
9172                 changelog_dump >/dev/null ||
9173                         error "can't read changelog"
9174         done
9175         kill $PID
9176         wait $PID
9177         changelog_deregister || error "changelog_deregister failed"
9178         $LCTL set_param fail_loc=0
9179 }
9180 run_test 60i "llog: new record vs reader race"
9181
9182 test_60j() {
9183         (( $MDS1_VERSION >= $(version_code 2.15.50) )) ||
9184                 skip "need MDS version at least 2.15.50"
9185         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
9186         remote_mds_nodsh && skip "remote MDS with nodsh"
9187         [[ "$mds1_FSTYPE" == "ldiskfs" ]] || skip "ldiskfs only test"
9188
9189         changelog_users $SINGLEMDS | grep "^cl" &&
9190                 skip "active changelog user"
9191
9192         local llog_reader=$(do_facet $SINGLEMDS "which llog_reader 2> /dev/null")
9193
9194         [[ -z $(do_facet $SINGLEMDS ls -d $llog_reader 2> /dev/null) ]] &&
9195                 skip_env "missing llog_reader"
9196
9197         mkdir_on_mdt0 $DIR/$tdir
9198
9199         local f=$DIR/$tdir/$tfile
9200         local mdt_dev
9201         local tmpfile
9202         local plain
9203
9204         changelog_register || error "cannot register changelog user"
9205
9206         # set changelog_mask to ALL
9207         changelog_chmask "ALL"
9208         changelog_clear
9209
9210         createmany -o ${f}- 100 || error "createmany failed as $RUNAS_ID"
9211         unlinkmany ${f}- 100 || error "unlinkmany failed"
9212
9213         tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
9214         mdt_dev=$(facet_device $SINGLEMDS)
9215
9216         do_facet $SINGLEMDS sync
9217         plain=$(do_facet $SINGLEMDS "$DEBUGFS -c -R 'dump changelog_catalog \
9218                 $tmpfile' $mdt_dev; $llog_reader $tmpfile" |
9219                 awk '{match($0,"path=([^ ]+)",a)}END{print a[1]}')
9220
9221         stack_trap "do_facet $SINGLEMDS rm -f $tmpfile"
9222
9223         # if $tmpfile is not on EXT3 filesystem for some reason
9224         [[ ${plain:0:1} == 'O' ]] ||
9225                 skip "path $plain is not in 'O/1/d<n>/<n>' format"
9226
9227         size=$(do_facet $SINGLEMDS "$DEBUGFS -c -R 'dump $plain $tmpfile' \
9228                 $mdt_dev; stat -c %s $tmpfile")
9229         echo "Truncate llog from $size to $((size - size % 8192))"
9230         size=$((size - size % 8192))
9231         do_facet $SINGLEMDS $TRUNCATE $tmpfile $size
9232         errs=$(do_facet $SINGLEMDS "$llog_reader $tmpfile" |
9233                 grep -c 'in bitmap only')
9234         (( $errs > 0 )) || error "llog_reader didn't find lost records"
9235
9236         size=$((size - 9000))
9237         echo "Corrupt llog in the middle at $size"
9238         do_facet $SINGLEMDS dd if=/dev/urandom of=$tmpfile bs=1 seek=$size \
9239                 count=333 conv=notrunc
9240         errs=$(do_facet $SINGLEMDS "$llog_reader $tmpfile" |
9241                 grep -c 'next chunk')
9242         (( $errs > 0 )) || error "llog_reader didn't skip bad chunk"
9243 }
9244 run_test 60j "llog_reader reports corruptions"
9245
9246 test_61a() {
9247         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9248
9249         f="$DIR/f61"
9250         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1 || error "dd $f failed"
9251         cancel_lru_locks osc
9252         $MULTIOP $f OSMWUc || error "$MULTIOP $f failed"
9253         sync
9254 }
9255 run_test 61a "mmap() writes don't make sync hang ================"
9256
9257 test_61b() {
9258         mmap_mknod_test $DIR/$tfile || error "mmap_mknod_test failed"
9259 }
9260 run_test 61b "mmap() of unstriped file is successful"
9261
9262 # bug 2330 - insufficient obd_match error checking causes LBUG
9263 test_62() {
9264         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9265
9266         f="$DIR/f62"
9267         echo foo > $f
9268         cancel_lru_locks osc
9269         lctl set_param fail_loc=0x405
9270         cat $f && error "cat succeeded, expect -EIO"
9271         lctl set_param fail_loc=0
9272 }
9273 # This test is now irrelevant (as of bug 10718 inclusion), we no longer
9274 # match every page all of the time.
9275 #run_test 62 "verify obd_match failure doesn't LBUG (should -EIO)"
9276
9277 # bug 2319 - oig_wait() interrupted causes crash because of invalid waitq.
9278 # Though this test is irrelevant anymore, it helped to reveal some
9279 # other grant bugs (LU-4482), let's keep it.
9280 test_63a() {   # was test_63
9281         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9282
9283         MAX_DIRTY_MB=$(lctl get_param -n osc.*.max_dirty_mb | head -n 1)
9284
9285         for i in `seq 10` ; do
9286                 dd if=/dev/zero of=$DIR/f63 bs=8k &
9287                 sleep 5
9288                 kill $!
9289                 sleep 1
9290         done
9291
9292         rm -f $DIR/f63 || true
9293 }
9294 run_test 63a "Verify oig_wait interruption does not crash ======="
9295
9296 # bug 2248 - async write errors didn't return to application on sync
9297 # bug 3677 - async write errors left page locked
9298 test_63b() {
9299         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9300
9301         debugsave
9302         lctl set_param debug=-1
9303
9304         # ensure we have a grant to do async writes
9305         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1
9306         rm $DIR/$tfile
9307
9308         sync    # sync lest earlier test intercept the fail_loc
9309
9310         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
9311         lctl set_param fail_loc=0x80000406
9312         $MULTIOP $DIR/$tfile Owy && \
9313                 error "sync didn't return ENOMEM"
9314         sync; sleep 2; sync     # do a real sync this time to flush page
9315         lctl get_param -n llite.*.dump_page_cache | grep locked && \
9316                 error "locked page left in cache after async error" || true
9317         debugrestore
9318 }
9319 run_test 63b "async write errors should be returned to fsync ==="
9320
9321 test_64a () {
9322         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9323
9324         lfs df $DIR
9325         lctl get_param osc.*[oO][sS][cC][_-]*.cur* | grep "=[1-9]"
9326 }
9327 run_test 64a "verify filter grant calculations (in kernel) ====="
9328
9329 test_64b () {
9330         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9331
9332         bash oos.sh $MOUNT || error "oos.sh failed: $?"
9333 }
9334 run_test 64b "check out-of-space detection on client"
9335
9336 test_64c() {
9337         $LCTL set_param osc.*OST0000-osc-[^mM]*.cur_grant_bytes=0
9338 }
9339 run_test 64c "verify grant shrink"
9340
9341 import_param() {
9342         local tgt=$1
9343         local param=$2
9344
9345         $LCTL get_param osc.$tgt.import | awk "/$param/ { print \$2 }"
9346 }
9347
9348 # this does exactly what osc_request.c:osc_announce_cached() does in
9349 # order to calculate max amount of grants to ask from server
9350 want_grant() {
9351         local tgt=$1
9352
9353         local nrpages=$($LCTL get_param -n osc.$tgt.max_pages_per_rpc)
9354         local rpc_in_flight=$($LCTL get_param -n osc.$tgt.max_rpcs_in_flight)
9355
9356         ((rpc_in_flight++));
9357         nrpages=$((nrpages * rpc_in_flight))
9358
9359         local dirty_max_pages=$($LCTL get_param -n osc.$tgt.max_dirty_mb)
9360
9361         dirty_max_pages=$((dirty_max_pages * 1024 * 1024 / PAGE_SIZE))
9362
9363         [[ $dirty_max_pages -gt $nrpages ]] && nrpages=$dirty_max_pages
9364         local undirty=$((nrpages * PAGE_SIZE))
9365
9366         local max_extent_pages
9367         max_extent_pages=$(import_param $tgt grant_max_extent_size)
9368         max_extent_pages=$((max_extent_pages / PAGE_SIZE))
9369         local nrextents=$(((nrpages + max_extent_pages - 1) / max_extent_pages))
9370         local grant_extent_tax
9371         grant_extent_tax=$(import_param $tgt grant_extent_tax)
9372
9373         undirty=$((undirty + nrextents * grant_extent_tax))
9374
9375         echo $undirty
9376 }
9377
9378 # this is size of unit for grant allocation. It should be equal to
9379 # what tgt_grant.c:tgt_grant_chunk() calculates
9380 grant_chunk() {
9381         local tgt=$1
9382         local max_brw_size
9383         local grant_extent_tax
9384
9385         max_brw_size=$(import_param $tgt max_brw_size)
9386
9387         grant_extent_tax=$(import_param $tgt grant_extent_tax)
9388
9389         echo $(((max_brw_size + grant_extent_tax) * 2))
9390 }
9391
9392 test_64d() {
9393         [ $OST1_VERSION -ge $(version_code 2.10.56) ] ||
9394                 skip "OST < 2.10.55 doesn't limit grants enough"
9395
9396         local tgt=$($LCTL dl | awk '/OST0000-osc-[^mM]/ { print $4 }')
9397
9398         [[ "$($LCTL get_param osc.${tgt}.import)" =~ "grant_param" ]] ||
9399                 skip "no grant_param connect flag"
9400
9401         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
9402
9403         $LCTL set_param -n -n debug="$OLDDEBUG" || true
9404         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
9405
9406
9407         local max_cur_granted=$(($(want_grant $tgt) + $(grant_chunk $tgt)))
9408         stack_trap "rm -f $DIR/$tfile && wait_delete_completed" EXIT
9409
9410         $LFS setstripe $DIR/$tfile -i 0 -c 1
9411         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1000 &
9412         ddpid=$!
9413
9414         while kill -0 $ddpid; do
9415                 local cur_grant=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
9416
9417                 if [[ $cur_grant -gt $max_cur_granted ]]; then
9418                         kill $ddpid
9419                         error "cur_grant $cur_grant > $max_cur_granted"
9420                 fi
9421
9422                 sleep 1
9423         done
9424 }
9425 run_test 64d "check grant limit exceed"
9426
9427 check_grants() {
9428         local tgt=$1
9429         local expected=$2
9430         local msg=$3
9431         local cur_grants=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
9432
9433         ((cur_grants == expected)) ||
9434                 error "$msg: grants mismatch: $cur_grants, expected $expected"
9435 }
9436
9437 round_up_p2() {
9438         echo $((($1 + $2 - 1) & ~($2 - 1)))
9439 }
9440
9441 test_64e() {
9442         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9443         [ $OST1_VERSION -ge $(version_code 2.11.56) ] ||
9444                 skip "Need OSS version at least 2.11.56"
9445
9446         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
9447         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
9448         $LCTL set_param debug=+cache
9449
9450         # Remount client to reset grant
9451         remount_client $MOUNT || error "failed to remount client"
9452         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9453
9454         local init_grants=$(import_param $osc_tgt initial_grant)
9455
9456         check_grants $osc_tgt $init_grants "init grants"
9457
9458         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
9459         local max_brw_size=$(import_param $osc_tgt max_brw_size)
9460         local gbs=$(import_param $osc_tgt grant_block_size)
9461
9462         # write random number of bytes from max_brw_size / 4 to max_brw_size
9463         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
9464         # align for direct io
9465         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
9466         # round to grant consumption unit
9467         local wb_round_up=$(round_up_p2 $write_bytes gbs)
9468
9469         local grants=$((wb_round_up + extent_tax))
9470
9471         $LFS setstripe -c 1 -i 0 $DIR/$tfile  || error "lfs setstripe failed"
9472         stack_trap "rm -f $DIR/$tfile"
9473
9474         # define OBD_FAIL_TGT_NO_GRANT 0x725
9475         # make the server not grant more back
9476         do_facet ost1 $LCTL set_param fail_loc=0x725
9477         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct
9478
9479         do_facet ost1 $LCTL set_param fail_loc=0
9480
9481         check_grants $osc_tgt $((init_grants - grants)) "dio w/o grant alloc"
9482
9483         rm -f $DIR/$tfile || error "rm failed"
9484
9485         # Remount client to reset grant
9486         remount_client $MOUNT || error "failed to remount client"
9487         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9488
9489         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
9490
9491         # define OBD_FAIL_TGT_NO_GRANT 0x725
9492         # make the server not grant more back
9493         do_facet ost1 $LCTL set_param fail_loc=0x725
9494         $MULTIOP $DIR/$tfile "oO_WRONLY:w${write_bytes}yc"
9495         do_facet ost1 $LCTL set_param fail_loc=0
9496
9497         check_grants $osc_tgt $((init_grants - grants)) "buf io w/o grant alloc"
9498 }
9499 run_test 64e "check grant consumption (no grant allocation)"
9500
9501 test_64f() {
9502         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9503
9504         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
9505         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
9506         $LCTL set_param debug=+cache
9507
9508         # Remount client to reset grant
9509         remount_client $MOUNT || error "failed to remount client"
9510         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9511
9512         local init_grants=$(import_param $osc_tgt initial_grant)
9513         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
9514         local max_brw_size=$(import_param $osc_tgt max_brw_size)
9515         local gbs=$(import_param $osc_tgt grant_block_size)
9516         local chunk=$(grant_chunk $osc_tgt)
9517
9518         # write random number of bytes from max_brw_size / 4 to max_brw_size
9519         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
9520         # align for direct io
9521         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
9522         # round to grant consumption unit
9523         local wb_round_up=$(round_up_p2 $write_bytes gbs)
9524
9525         local grants=$((wb_round_up + extent_tax))
9526
9527         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
9528         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct ||
9529                 error "error writing to $DIR/$tfile"
9530
9531         check_grants $osc_tgt $((init_grants - grants + chunk)) \
9532                 "direct io with grant allocation"
9533
9534         rm -f $DIR/$tfile || error "rm failed"
9535
9536         # Remount client to reset grant
9537         remount_client $MOUNT || error "failed to remount client"
9538         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9539
9540         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
9541
9542         local cmd="oO_WRONLY:w${write_bytes}_yc"
9543
9544         $MULTIOP $DIR/$tfile $cmd &
9545         MULTIPID=$!
9546         sleep 1
9547
9548         check_grants $osc_tgt $((init_grants - grants)) \
9549                 "buffered io, not write rpc"
9550
9551         kill -USR1 $MULTIPID
9552         wait
9553
9554         check_grants $osc_tgt $((init_grants - grants + chunk)) \
9555                 "buffered io, one RPC"
9556 }
9557 run_test 64f "check grant consumption (with grant allocation)"
9558
9559 test_64g() {
9560         (( $MDS1_VERSION >= $(version_code 2.14.56) )) ||
9561                 skip "Need MDS version at least 2.14.56"
9562
9563         local mdts=$(comma_list $(mdts_nodes))
9564
9565         local old=$($LCTL get_param mdc.$FSNAME-*.grant_shrink_interval |
9566                         tr '\n' ' ')
9567         stack_trap "$LCTL set_param $old"
9568
9569         # generate dirty pages and increase dirty granted on MDT
9570         stack_trap "rm -f $DIR/$tfile-*"
9571         for (( i = 0; i < 10; i++)); do
9572                 $LFS setstripe -E 1M -L mdt $DIR/$tfile-$i ||
9573                         error "can't set stripe"
9574                 dd if=/dev/zero of=$DIR/$tfile-$i bs=128k count=1 ||
9575                         error "can't dd"
9576                 $LFS getstripe $DIR/$tfile-$i | grep -q pattern.*mdt || {
9577                         $LFS getstripe $DIR/$tfile-$i
9578                         error "not DoM file"
9579                 }
9580         done
9581
9582         # flush dirty pages
9583         sync
9584
9585         # wait until grant shrink reset grant dirty on MDTs
9586         for ((i = 0; i < 120; i++)); do
9587                 grant_dirty=$(do_nodes $mdts $LCTL get_param -n  mdt.*.tot_dirty |
9588                         awk '{sum=sum+$1} END {print sum}')
9589                 vm_dirty=$(awk '/Dirty:/{print $2}' /proc/meminfo)
9590                 echo "$grant_dirty grants, $vm_dirty pages"
9591                 (( grant_dirty + vm_dirty == 0 )) && break
9592                 (( i == 3 )) && sync &&
9593                         $LCTL set_param mdc.$FSNAME-*.grant_shrink_interval=5
9594                 sleep 1
9595         done
9596
9597         grant_dirty=$(do_nodes $mdts $LCTL get_param -n  mdt.*.tot_dirty |
9598                 awk '{sum=sum+$1} END {print sum}')
9599         (( grant_dirty == 0 )) || error "$grant_dirty on MDT"
9600 }
9601 run_test 64g "grant shrink on MDT"
9602
9603 test_64h() {
9604         (( $OST1_VERSION >= $(version_code 2.14.56) )) ||
9605                 skip "need OST at least 2.14.56 to avoid grant shrink on read"
9606
9607         local instance=$($LFS getname -i $DIR)
9608         local osc_tgt="$FSNAME-OST0000-osc-$instance"
9609         local num_exps=$(do_facet ost1 \
9610             $LCTL get_param -n obdfilter.*OST0000*.num_exports)
9611         local max_brw_size=$(import_param $osc_tgt max_brw_size)
9612         local avail=$($LCTL get_param -n osc.*OST0000-osc-$instance.kbytesavail)
9613         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
9614
9615         # 10MiB is for file to be written, max_brw_size * 16 *
9616         # num_exps is space reserve so that tgt_grant_shrink() decided
9617         # to not shrink
9618         local expect=$((max_brw_size * 16 * num_exps + 10 * 1048576))
9619         (( avail * 1024 < expect )) &&
9620                 skip "need $expect bytes on ost1, have $(( avail * 1024 )) only"
9621
9622         save_lustre_params client "osc.*OST0000*.grant_shrink" > $p
9623         save_lustre_params client "osc.*OST0000*.grant_shrink_interval" >> $p
9624         stack_trap "restore_lustre_params < $p; rm -f $save" EXIT
9625         $LCTL set_param osc.*OST0000*.grant_shrink=1
9626         $LCTL set_param osc.*OST0000*.grant_shrink_interval=10
9627
9628         $LFS setstripe -c 1 -i 0 $DIR/$tfile
9629         stack_trap "rm -f $DIR/$tfile"
9630         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 oflag=sync
9631
9632         # drop cache so that coming read would do rpc
9633         cancel_lru_locks osc
9634
9635         # shrink interval is set to 10, pause for 7 seconds so that
9636         # grant thread did not wake up yet but coming read entered
9637         # shrink mode for rpc (osc_should_shrink_grant())
9638         sleep 7
9639
9640         declare -a cur_grant_bytes
9641         declare -a tot_granted
9642         cur_grant_bytes[0]=$($LCTL get_param -n osc.*OST0000*.cur_grant_bytes)
9643         tot_granted[0]=$(do_facet ost1 \
9644             $LCTL get_param -n obdfilter.*OST0000*.tot_granted)
9645
9646         dd if=$DIR/$tfile bs=4K count=1 of=/dev/null
9647
9648         cur_grant_bytes[1]=$($LCTL get_param -n osc.*OST0000*.cur_grant_bytes)
9649         tot_granted[1]=$(do_facet ost1 \
9650             $LCTL get_param -n obdfilter.*OST0000*.tot_granted)
9651
9652         # grant change should be equal on both sides
9653         (( cur_grant_bytes[0] - cur_grant_bytes[1] ==
9654                 tot_granted[0] - tot_granted[1])) ||
9655                 error "grant change mismatch, "                                \
9656                         "server: ${tot_granted[0]} to ${tot_granted[1]}, "     \
9657                         "client: ${cur_grant_bytes[0]} to ${cur_grant_bytes[1]}"
9658 }
9659 run_test 64h "grant shrink on read"
9660
9661 test_64i() {
9662         (( $OST1_VERSION >= $(version_code 2.14.56) )) ||
9663                 skip "need OST at least 2.14.56 to avoid grant shrink on replay"
9664
9665         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9666         remote_ost_nodsh && skip "remote OSTs with nodsh"
9667
9668         $LFS setstripe -c 1 -i 0 $DIR/$tfile
9669         stack_trap "rm -f $DIR/$tfile"
9670
9671         dd if=/dev/zero of=$DIR/$tfile bs=1M count=64
9672
9673         # lustre-ffff9fc75e850800 /mnt/lustre -> ffff9fc75e850800
9674         local instance=$($LFS getname -i $DIR)
9675
9676         local osc_tgt="$FSNAME-OST0000-osc-$instance"
9677         local cgb=$($LCTL get_param -n osc.$osc_tgt.cur_grant_bytes)
9678
9679         # shrink grants and simulate rpc loss
9680         #define OBD_FAIL_PTLRPC_DROP_REQ_OPC     0x513
9681         do_facet ost1 "$LCTL set_param fail_loc=0x80000513 fail_val=17"
9682         $LCTL set_param osc.$osc_tgt.cur_grant_bytes=$((cgb/2))B
9683
9684         fail ost1
9685
9686         dd if=/dev/zero of=$DIR/$tfile oflag=append bs=1M count=8 conv=notrunc
9687
9688         local testid=$(echo $TESTNAME | tr '_' ' ')
9689
9690         do_facet ost1 dmesg | tac | sed "/$testid/,$ d" |
9691                 grep "GRANT, real grant" &&
9692                 error "client has more grants then it owns" || true
9693 }
9694 run_test 64i "shrink on reconnect"
9695
9696 # bug 1414 - set/get directories' stripe info
9697 test_65a() {
9698         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9699
9700         test_mkdir $DIR/$tdir
9701         touch $DIR/$tdir/f1
9702         $LVERIFY $DIR/$tdir $DIR/$tdir/f1 || error "lverify failed"
9703 }
9704 run_test 65a "directory with no stripe info"
9705
9706 test_65b() {
9707         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9708
9709         test_mkdir $DIR/$tdir
9710         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9711
9712         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
9713                                                 error "setstripe"
9714         touch $DIR/$tdir/f2
9715         $LVERIFY $DIR/$tdir $DIR/$tdir/f2 || error "lverify failed"
9716 }
9717 run_test 65b "directory setstripe -S stripe_size*2 -i 0 -c 1"
9718
9719 test_65c() {
9720         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9721         [ $OSTCOUNT -lt 2 ] && skip_env "need at least 2 OSTs"
9722
9723         test_mkdir $DIR/$tdir
9724         local stripesize=$($LFS getstripe -S $DIR/$tdir)
9725
9726         $LFS setstripe -S $((stripesize * 4)) -i 1 \
9727                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
9728         touch $DIR/$tdir/f3
9729         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
9730 }
9731 run_test 65c "directory setstripe -S stripe_size*4 -i 1 -c $((OSTCOUNT-1))"
9732
9733 test_65d() {
9734         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9735
9736         test_mkdir $DIR/$tdir
9737         local STRIPECOUNT=$($LFS getstripe -c $DIR/$tdir)
9738         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9739
9740         if [[ $STRIPECOUNT -le 0 ]]; then
9741                 sc=1
9742         elif [[ $STRIPECOUNT -gt $LOV_MAX_STRIPE_COUNT ]]; then
9743                 [[ $OSTCOUNT -gt $LOV_MAX_STRIPE_COUNT ]] &&
9744                         sc=$LOV_MAX_STRIPE_COUNT || sc=$(($OSTCOUNT - 1))
9745         else
9746                 sc=$(($STRIPECOUNT - 1))
9747         fi
9748         $LFS setstripe -S $STRIPESIZE -c $sc $DIR/$tdir || error "setstripe"
9749         touch $DIR/$tdir/f4 $DIR/$tdir/f5
9750         $LVERIFY $DIR/$tdir $DIR/$tdir/f4 $DIR/$tdir/f5 ||
9751                 error "lverify failed"
9752 }
9753 run_test 65d "directory setstripe -S stripe_size -c stripe_count"
9754
9755 test_65e() {
9756         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9757
9758         test_mkdir $DIR/$tdir
9759
9760         $LFS setstripe $DIR/$tdir || error "setstripe"
9761         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
9762                                         error "no stripe info failed"
9763         touch $DIR/$tdir/f6
9764         $LVERIFY $DIR/$tdir $DIR/$tdir/f6 || error "lverify failed"
9765 }
9766 run_test 65e "directory setstripe defaults"
9767
9768 test_65f() {
9769         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9770
9771         test_mkdir $DIR/${tdir}f
9772         $RUNAS $LFS setstripe $DIR/${tdir}f &&
9773                 error "setstripe succeeded" || true
9774 }
9775 run_test 65f "dir setstripe permission (should return error) ==="
9776
9777 test_65g() {
9778         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9779
9780         test_mkdir $DIR/$tdir
9781         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9782
9783         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
9784                 error "setstripe -S failed"
9785         $LFS setstripe -d $DIR/$tdir || error "setstripe -d failed"
9786         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
9787                 error "delete default stripe failed"
9788 }
9789 run_test 65g "directory setstripe -d"
9790
9791 test_65h() {
9792         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9793
9794         test_mkdir $DIR/$tdir
9795         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9796
9797         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
9798                 error "setstripe -S failed"
9799         test_mkdir $DIR/$tdir/dd1
9800         [ $($LFS getstripe -c $DIR/$tdir) = $($LFS getstripe -c $DIR/$tdir/dd1) ] ||
9801                 error "stripe info inherit failed"
9802 }
9803 run_test 65h "directory stripe info inherit ===================="
9804
9805 test_65i() {
9806         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9807
9808         save_layout_restore_at_exit $MOUNT
9809
9810         # bug6367: set non-default striping on root directory
9811         $LFS setstripe -S 65536 -c -1 $MOUNT || error "error setting stripe"
9812
9813         # bug12836: getstripe on -1 default directory striping
9814         $LFS getstripe $MOUNT || error "getstripe $MOUNT failed"
9815
9816         # bug12836: getstripe -v on -1 default directory striping
9817         $LFS getstripe -v $MOUNT || error "getstripe -v $MOUNT failed"
9818
9819         # bug12836: new find on -1 default directory striping
9820         $LFS find -mtime -1 $MOUNT > /dev/null || error "find $MOUNT failed"
9821 }
9822 run_test 65i "various tests to set root directory striping"
9823
9824 test_65j() { # bug6367
9825         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9826
9827         sync; sleep 1
9828
9829         # if we aren't already remounting for each test, do so for this test
9830         if [ "$I_MOUNTED" = "yes" ]; then
9831                 cleanup || error "failed to unmount"
9832                 setup
9833         fi
9834
9835         save_layout_restore_at_exit $MOUNT
9836
9837         $LFS setstripe -d $MOUNT || error "setstripe failed"
9838 }
9839 run_test 65j "set default striping on root directory (bug 6367)="
9840
9841 cleanup_65k() {
9842         rm -rf $DIR/$tdir
9843         wait_delete_completed
9844         do_facet $SINGLEMDS "lctl set_param -n \
9845                 osp.$ost*MDT0000.max_create_count=$max_count"
9846         do_facet $SINGLEMDS "lctl set_param -n \
9847                 osp.$ost*MDT0000.create_count=$count"
9848         do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
9849         echo $INACTIVE_OSC "is Activate"
9850
9851         wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
9852 }
9853
9854 test_65k() { # bug11679
9855         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9856         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9857         remote_mds_nodsh && skip "remote MDS with nodsh"
9858
9859         local disable_precreate=true
9860         [ $MDS1_VERSION -le $(version_code 2.8.54) ] &&
9861                 disable_precreate=false
9862
9863         echo "Check OST status: "
9864         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
9865                 awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
9866
9867         for OSC in $MDS_OSCS; do
9868                 echo $OSC "is active"
9869                 do_facet $SINGLEMDS lctl --device %$OSC activate
9870         done
9871
9872         for INACTIVE_OSC in $MDS_OSCS; do
9873                 local ost=$(osc_to_ost $INACTIVE_OSC)
9874                 local ostnum=$(do_facet $SINGLEMDS lctl get_param -n \
9875                                lov.*md*.target_obd |
9876                                awk -F: /$ost/'{ print $1 }' | head -n 1)
9877
9878                 mkdir -p $DIR/$tdir
9879                 $LFS setstripe -i $ostnum -c 1 $DIR/$tdir
9880                 createmany -o $DIR/$tdir/$tfile.$ostnum. 1000
9881
9882                 echo "Deactivate: " $INACTIVE_OSC
9883                 do_facet $SINGLEMDS lctl --device %$INACTIVE_OSC deactivate
9884
9885                 local count=$(do_facet $SINGLEMDS "lctl get_param -n \
9886                               osp.$ost*MDT0000.create_count")
9887                 local max_count=$(do_facet $SINGLEMDS "lctl get_param -n \
9888                                   osp.$ost*MDT0000.max_create_count")
9889                 $disable_precreate &&
9890                         do_facet $SINGLEMDS "lctl set_param -n \
9891                                 osp.$ost*MDT0000.max_create_count=0"
9892
9893                 for idx in $(seq 0 $((OSTCOUNT - 1))); do
9894                         [ -f $DIR/$tdir/$idx ] && continue
9895                         echo "$LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx"
9896                         $LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx ||
9897                                 { cleanup_65k;
9898                                   error "setstripe $idx should succeed"; }
9899                         rm -f $DIR/$tdir/$idx || error "rm $idx failed"
9900                 done
9901                 unlinkmany $DIR/$tdir/$tfile.$ostnum. 1000
9902                 rmdir $DIR/$tdir
9903
9904                 do_facet $SINGLEMDS "lctl set_param -n \
9905                         osp.$ost*MDT0000.max_create_count=$max_count"
9906                 do_facet $SINGLEMDS "lctl set_param -n \
9907                         osp.$ost*MDT0000.create_count=$count"
9908                 do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
9909                 echo $INACTIVE_OSC "is Activate"
9910
9911                 wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
9912         done
9913 }
9914 run_test 65k "validate manual striping works properly with deactivated OSCs"
9915
9916 test_65l() { # bug 12836
9917         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9918
9919         test_mkdir -p $DIR/$tdir/test_dir
9920         $LFS setstripe -c -1 $DIR/$tdir/test_dir
9921         $LFS find -mtime -1 $DIR/$tdir >/dev/null
9922 }
9923 run_test 65l "lfs find on -1 stripe dir ========================"
9924
9925 test_65m() {
9926         local layout=$(save_layout $MOUNT)
9927         $RUNAS $LFS setstripe -c 2 $MOUNT && {
9928                 restore_layout $MOUNT $layout
9929                 error "setstripe should fail by non-root users"
9930         }
9931         true
9932 }
9933 run_test 65m "normal user can't set filesystem default stripe"
9934
9935 test_65n() {
9936         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
9937         [[ $MDS1_VERSION -ge $(version_code 2.12.50) ]] ||
9938                 skip "Need MDS version at least 2.12.50"
9939         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
9940
9941         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
9942         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
9943         which setfattr > /dev/null 2>&1 || skip_env "no setfattr command"
9944
9945         save_layout_restore_at_exit $MOUNT
9946
9947         # new subdirectory under root directory should not inherit
9948         # the default layout from root
9949         local dir1=$MOUNT/$tdir-1
9950         mkdir $dir1 || error "mkdir $dir1 failed"
9951         ! getfattr -n trusted.lov $dir1 &> /dev/null ||
9952                 error "$dir1 shouldn't have LOV EA"
9953
9954         # delete the default layout on root directory
9955         $LFS setstripe -d $MOUNT || error "delete root default layout failed"
9956
9957         local dir2=$MOUNT/$tdir-2
9958         mkdir $dir2 || error "mkdir $dir2 failed"
9959         ! getfattr -n trusted.lov $dir2 &> /dev/null ||
9960                 error "$dir2 shouldn't have LOV EA"
9961
9962         # set a new striping pattern on root directory
9963         local def_stripe_size=$($LFS getstripe -S $MOUNT)
9964         local new_def_stripe_size=$((def_stripe_size * 2))
9965         $LFS setstripe -S $new_def_stripe_size $MOUNT ||
9966                 error "set stripe size on $MOUNT failed"
9967
9968         # new file created in $dir2 should inherit the new stripe size from
9969         # the filesystem default
9970         local file2=$dir2/$tfile-2
9971         touch $file2 || error "touch $file2 failed"
9972
9973         local file2_stripe_size=$($LFS getstripe -S $file2)
9974         [[ $file2_stripe_size -eq $new_def_stripe_size ]] ||
9975         {
9976                 echo "file2_stripe_size: '$file2_stripe_size'"
9977                 echo "new_def_stripe_size: '$new_def_stripe_size'"
9978                 error "$file2 didn't inherit stripe size $new_def_stripe_size"
9979         }
9980
9981         local dir3=$MOUNT/$tdir-3
9982         mkdir $dir3 || error "mkdir $dir3 failed"
9983         # $dir3 shouldn't have LOV EA, but "lfs getstripe -d $dir3" should show
9984         # the root layout, which is the actual default layout that will be used
9985         # when new files are created in $dir3.
9986         local dir3_layout=$(get_layout_param $dir3)
9987         local root_dir_layout=$(get_layout_param $MOUNT)
9988         [[ "$dir3_layout" = "$root_dir_layout" ]] ||
9989         {
9990                 echo "dir3_layout: '$dir3_layout'"
9991                 echo "root_dir_layout: '$root_dir_layout'"
9992                 error "$dir3 should show the default layout from $MOUNT"
9993         }
9994
9995         # set OST pool on root directory
9996         local pool=$TESTNAME
9997         pool_add $pool || error "add $pool failed"
9998         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
9999                 error "add targets to $pool failed"
10000
10001         $LFS setstripe -p $pool $MOUNT ||
10002                 error "set OST pool on $MOUNT failed"
10003
10004         # new file created in $dir3 should inherit the pool from
10005         # the filesystem default
10006         local file3=$dir3/$tfile-3
10007         touch $file3 || error "touch $file3 failed"
10008
10009         local file3_pool=$($LFS getstripe -p $file3)
10010         [[ "$file3_pool" = "$pool" ]] ||
10011                 error "$file3 ('$file3_pool') didn't inherit OST pool '$pool'"
10012
10013         local dir4=$MOUNT/$tdir-4
10014         mkdir $dir4 || error "mkdir $dir4 failed"
10015         local dir4_layout=$(get_layout_param $dir4)
10016         root_dir_layout=$(get_layout_param $MOUNT)
10017         echo "$LFS getstripe -d $dir4"
10018         $LFS getstripe -d $dir4
10019         echo "$LFS getstripe -d $MOUNT"
10020         $LFS getstripe -d $MOUNT
10021         [[ "$dir4_layout" = "$root_dir_layout" ]] ||
10022         {
10023                 echo "dir4_layout: '$dir4_layout'"
10024                 echo "root_dir_layout: '$root_dir_layout'"
10025                 error "$dir4 should show the default layout from $MOUNT"
10026         }
10027
10028         # new file created in $dir4 should inherit the pool from
10029         # the filesystem default
10030         local file4=$dir4/$tfile-4
10031         touch $file4 || error "touch $file4 failed"
10032
10033         local file4_pool=$($LFS getstripe -p $file4)
10034         [[ "$file4_pool" = "$pool" ]] ||
10035                 error "$file4 ('$file4_pool') didn't inherit OST pool $pool"
10036
10037         # new subdirectory under non-root directory should inherit
10038         # the default layout from its parent directory
10039         $LFS setstripe -S $new_def_stripe_size -p $pool $dir4 ||
10040                 error "set directory layout on $dir4 failed"
10041
10042         local dir5=$dir4/$tdir-5
10043         mkdir $dir5 || error "mkdir $dir5 failed"
10044
10045         dir4_layout=$(get_layout_param $dir4)
10046         local dir5_layout=$(get_layout_param $dir5)
10047         [[ "$dir4_layout" = "$dir5_layout" ]] ||
10048         {
10049                 echo "dir4_layout: '$dir4_layout'"
10050                 echo "dir5_layout: '$dir5_layout'"
10051                 error "$dir5 should inherit the default layout from $dir4"
10052         }
10053
10054         # though subdir under ROOT doesn't inherit default layout, but
10055         # its sub dir/file should be created with default layout.
10056         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
10057         [[ $MDS1_VERSION -ge $(version_code 2.12.59) ]] ||
10058                 skip "Need MDS version at least 2.12.59"
10059
10060         local default_lmv_count=$($LFS getdirstripe -D -c $MOUNT)
10061         local default_lmv_index=$($LFS getdirstripe -D -i $MOUNT)
10062         local default_lmv_hash=$($LFS getdirstripe -D -H $MOUNT)
10063
10064         if [ $default_lmv_hash == "none" ]; then
10065                 stack_trap "$LFS setdirstripe -D -d $MOUNT" EXIT
10066         else
10067                 stack_trap "$LFS setdirstripe -D -i $default_lmv_index \
10068                         -c $default_lmv_count -H $default_lmv_hash $MOUNT" EXIT
10069         fi
10070
10071         $LFS setdirstripe -D -c 2 $MOUNT ||
10072                 error "setdirstripe -D -c 2 failed"
10073         mkdir $MOUNT/$tdir-6 || error "mkdir $tdir-6 failed"
10074         local lmv_count=$($LFS getdirstripe -c $MOUNT/$tdir-6)
10075         [ $lmv_count -eq 2 ] || error "$tdir-6 stripe count $lmv_count"
10076
10077         # $dir4 layout includes pool
10078         $LFS setstripe -S $((new_def_stripe_size * 2)) $dir4
10079         [[ "$pool" = $($LFS getstripe -p -d $dir4) ]] ||
10080                 error "pool lost on setstripe"
10081         $LFS setstripe -E -1 -S $new_def_stripe_size $dir4
10082         [[ "$pool" = $($LFS getstripe -p -d $dir4) ]] ||
10083                 error "pool lost on compound layout setstripe"
10084 }
10085 run_test 65n "don't inherit default layout from root for new subdirectories"
10086
10087 test_65o() {
10088         (( $MDS1_VERSION >= $(version_code 2.14.57) )) ||
10089                 skip "need MDS version at least 2.14.57"
10090
10091         # set OST pool on root directory
10092         local pool=$TESTNAME
10093
10094         pool_add $pool || error "add $pool failed"
10095         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
10096                 error "add targets to $pool failed"
10097
10098         local dir1=$MOUNT/$tdir
10099
10100         mkdir $dir1 || error "mkdir $dir1 failed"
10101
10102         # set a new striping pattern on root directory
10103         local def_stripe_size=$($LFS getstripe -S $MOUNT)
10104
10105         $LFS setstripe -p $pool $dir1 ||
10106                 error "set directory layout on $dir1 failed"
10107
10108         # $dir1 layout includes pool
10109         $LFS setstripe -S $((def_stripe_size * 2)) $dir1
10110         [[ "$pool" = $($LFS getstripe -p -d $dir1) ]] ||
10111                 error "pool lost on setstripe"
10112         $LFS setstripe -E 1M -L mdt -E -1 -c 1 $dir1
10113         $LFS getstripe $dir1
10114         [[ "$pool" = $($LFS getstripe -p -d $dir1) ]] ||
10115                 error "pool lost on compound layout setstripe"
10116
10117         $LFS setdirstripe -i 0 -c 2 $dir1/dir2 ||
10118                 error "setdirstripe failed on sub-dir with inherited pool"
10119         $LFS getstripe $dir1/dir2
10120         [[ "$pool" = $($LFS getstripe -p -d $dir1/dir2) ]] ||
10121                 error "pool lost on compound layout setdirstripe"
10122
10123         $LFS setstripe -E -1 -c 1 $dir1
10124         $LFS getstripe -d $dir1
10125         [[ "$pool" = $($LFS getstripe -p -d $dir1) ]] ||
10126                 error "pool lost on setstripe"
10127 }
10128 run_test 65o "pool inheritance for mdt component"
10129
10130 test_65p () { # LU-16152
10131         local src_dir=$DIR/$tdir/src_dir
10132         local dst_dir=$DIR/$tdir/dst_dir
10133         local yaml_file=$DIR/$tdir/layout.yaml
10134         local border
10135
10136         (( $CLIENT_VERSION >= $(version_code 2.15.51) )) ||
10137                 skip "Need at least version 2.15.51"
10138
10139         test_mkdir -p $src_dir
10140         $LFS setstripe -E 2048M -c 4 -E EOF -c 8 $src_dir ||
10141                 error "failed to setstripe"
10142         $LFS getstripe --yaml -d $src_dir > $yaml_file ||
10143                 error "failed to getstripe"
10144
10145         test_mkdir -p $dst_dir
10146         $LFS setstripe --yaml $yaml_file $dst_dir ||
10147                 error "failed to setstripe with yaml file"
10148         border=$($LFS getstripe -d $dst_dir |
10149                 awk '/lcme_extent.e_end:/ { print $2; exit; }') ||
10150                 error "failed to getstripe"
10151
10152         # 2048M is 0x80000000, or 2147483648
10153         (( $border == 2147483648 )) ||
10154                 error "failed to handle huge number in yaml layout"
10155 }
10156 run_test 65p "setstripe with yaml file and huge number"
10157
10158 # bug 2543 - update blocks count on client
10159 test_66() {
10160         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10161
10162         local COUNT=${COUNT:-8}
10163         dd if=/dev/zero of=$DIR/f66 bs=1k count=$COUNT
10164         sync; sync_all_data; sync; sync_all_data
10165         cancel_lru_locks osc
10166         local BLOCKS=$(ls -s --block-size=1k $DIR/f66 | awk '{ print $1 }')
10167         (( BLOCKS >= COUNT )) || error "$DIR/f66 blocks $BLOCKS < $COUNT"
10168 }
10169 run_test 66 "update inode blocks count on client ==============="
10170
10171 meminfo() {
10172         awk '($1 == "'$1':") { print $2 }' /proc/meminfo
10173 }
10174
10175 swap_used() {
10176         swapon -s | awk '($1 == "'$1'") { print $4 }'
10177 }
10178
10179 # bug5265, obdfilter oa2dentry return -ENOENT
10180 # #define OBD_FAIL_SRV_ENOENT 0x217
10181 test_69() {
10182         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10183         remote_ost_nodsh && skip "remote OST with nodsh"
10184
10185         f="$DIR/$tfile"
10186         $LFS setstripe -c 1 -i 0 $f
10187         stack_trap "rm -f $f ${f}.2"
10188
10189         $DIRECTIO write ${f}.2 0 1 || error "directio write error"
10190
10191         do_facet ost1 lctl set_param fail_loc=0x217
10192         $TRUNCATE $f 1 # vmtruncate() will ignore truncate() error.
10193         $DIRECTIO write $f 0 2 && error "write succeeded, expect -ENOENT"
10194
10195         do_facet ost1 lctl set_param fail_loc=0
10196         $DIRECTIO write $f 0 2 || error "write error"
10197
10198         cancel_lru_locks osc
10199         $DIRECTIO read $f 0 1 || error "read error"
10200
10201         do_facet ost1 lctl set_param fail_loc=0x217
10202         $DIRECTIO read $f 1 1 && error "read succeeded, expect -ENOENT"
10203
10204         do_facet ost1 lctl set_param fail_loc=0
10205 }
10206 run_test 69 "verify oa2dentry return -ENOENT doesn't LBUG ======"
10207
10208 test_71() {
10209         test_mkdir $DIR/$tdir
10210         $LFS setdirstripe -D -c$MDSCOUNT $DIR/$tdir
10211         bash rundbench -C -D $DIR/$tdir 2 || error "dbench failed!"
10212 }
10213 run_test 71 "Running dbench on lustre (don't segment fault) ===="
10214
10215 test_72a() { # bug 5695 - Test that on 2.6 remove_suid works properly
10216         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10217         [ "$RUNAS_ID" = "$UID" ] &&
10218                 skip_env "RUNAS_ID = UID = $UID -- skipping"
10219         # Check that testing environment is properly set up. Skip if not
10220         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_GID $RUNAS ||
10221                 skip_env "User $RUNAS_ID does not exist - skipping"
10222
10223         touch $DIR/$tfile
10224         chmod 777 $DIR/$tfile
10225         chmod ug+s $DIR/$tfile
10226         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=512 count=1 ||
10227                 error "$RUNAS dd $DIR/$tfile failed"
10228         # See if we are still setuid/sgid
10229         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
10230                 error "S/gid is not dropped on write"
10231         # Now test that MDS is updated too
10232         cancel_lru_locks mdc
10233         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
10234                 error "S/gid is not dropped on MDS"
10235         rm -f $DIR/$tfile
10236 }
10237 run_test 72a "Test that remove suid works properly (bug5695) ===="
10238
10239 test_72b() { # bug 24226 -- keep mode setting when size is not changing
10240         local perm
10241
10242         [ "$RUNAS_ID" = "$UID" ] &&
10243                 skip_env "RUNAS_ID = UID = $UID -- skipping"
10244         [ "$RUNAS_ID" -eq 0 ] &&
10245                 skip_env "RUNAS_ID = 0 -- skipping"
10246         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10247         # Check that testing environment is properly set up. Skip if not
10248         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_ID $RUNAS ||
10249                 skip_env "User $RUNAS_ID does not exist - skipping"
10250
10251         touch $DIR/${tfile}-f{g,u}
10252         test_mkdir $DIR/${tfile}-dg
10253         test_mkdir $DIR/${tfile}-du
10254         chmod 770 $DIR/${tfile}-{f,d}{g,u}
10255         chmod g+s $DIR/${tfile}-{f,d}g
10256         chmod u+s $DIR/${tfile}-{f,d}u
10257         for perm in 777 2777 4777; do
10258                 $RUNAS chmod $perm $DIR/${tfile}-fg && error "S/gid file allowed improper chmod to $perm"
10259                 $RUNAS chmod $perm $DIR/${tfile}-fu && error "S/uid file allowed improper chmod to $perm"
10260                 $RUNAS chmod $perm $DIR/${tfile}-dg && error "S/gid dir allowed improper chmod to $perm"
10261                 $RUNAS chmod $perm $DIR/${tfile}-du && error "S/uid dir allowed improper chmod to $perm"
10262         done
10263         true
10264 }
10265 run_test 72b "Test that we keep mode setting if without file data changed (bug 24226)"
10266
10267 # bug 3462 - multiple simultaneous MDC requests
10268 test_73() {
10269         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10270
10271         test_mkdir $DIR/d73-1
10272         test_mkdir $DIR/d73-2
10273         multiop_bg_pause $DIR/d73-1/f73-1 O_c || return 1
10274         pid1=$!
10275
10276         lctl set_param fail_loc=0x80000129
10277         $MULTIOP $DIR/d73-1/f73-2 Oc &
10278         sleep 1
10279         lctl set_param fail_loc=0
10280
10281         $MULTIOP $DIR/d73-2/f73-3 Oc &
10282         pid3=$!
10283
10284         kill -USR1 $pid1
10285         wait $pid1 || return 1
10286
10287         sleep 25
10288
10289         $CHECKSTAT -t file $DIR/d73-1/f73-1 || return 4
10290         $CHECKSTAT -t file $DIR/d73-1/f73-2 || return 5
10291         $CHECKSTAT -t file $DIR/d73-2/f73-3 || return 6
10292
10293         rm -rf $DIR/d73-*
10294 }
10295 run_test 73 "multiple MDC requests (should not deadlock)"
10296
10297 test_74a() { # bug 6149, 6184
10298         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10299
10300         touch $DIR/f74a
10301         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
10302         #
10303         # very important to OR with CFS_FAIL_ONCE (0x80000000) -- otherwise it
10304         # will spin in a tight reconnection loop
10305         $LCTL set_param fail_loc=0x8000030e
10306         # get any lock that won't be difficult - lookup works.
10307         ls $DIR/f74a
10308         $LCTL set_param fail_loc=0
10309         rm -f $DIR/f74a
10310         true
10311 }
10312 run_test 74a "ldlm_enqueue freed-export error path, ls (shouldn't LBUG)"
10313
10314 test_74b() { # bug 13310
10315         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10316
10317         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
10318         #
10319         # very important to OR with CFS_FAIL_ONCE (0x80000000) -- otherwise it
10320         # will spin in a tight reconnection loop
10321         $LCTL set_param fail_loc=0x8000030e
10322         # get a "difficult" lock
10323         touch $DIR/f74b
10324         $LCTL set_param fail_loc=0
10325         rm -f $DIR/f74b
10326         true
10327 }
10328 run_test 74b "ldlm_enqueue freed-export error path, touch (shouldn't LBUG)"
10329
10330 test_74c() {
10331         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10332
10333         #define OBD_FAIL_LDLM_NEW_LOCK
10334         $LCTL set_param fail_loc=0x319
10335         touch $DIR/$tfile && error "touch successful"
10336         $LCTL set_param fail_loc=0
10337         true
10338 }
10339 run_test 74c "ldlm_lock_create error path, (shouldn't LBUG)"
10340
10341 slab_lic=/sys/kernel/slab/lustre_inode_cache
10342 num_objects() {
10343         [ -f $slab_lic/shrink ] && echo 1 > $slab_lic/shrink
10344         [ -f $slab_lic/objects ] && awk '{ print $1 }' $slab_lic/objects ||
10345                 awk '/lustre_inode_cache/ { print $2; exit }' /proc/slabinfo
10346 }
10347
10348 test_76a() { # Now for b=20433, added originally in b=1443
10349         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10350
10351         cancel_lru_locks osc
10352         # there may be some slab objects cached per core
10353         local cpus=$(getconf _NPROCESSORS_ONLN 2>/dev/null)
10354         local before=$(num_objects)
10355         local count=$((512 * cpus))
10356         [ "$SLOW" = "no" ] && count=$((128 * cpus))
10357         local margin=$((count / 10))
10358         if [[ -f $slab_lic/aliases ]]; then
10359                 local aliases=$(cat $slab_lic/aliases)
10360                 (( aliases > 0 )) && margin=$((margin * aliases))
10361         fi
10362
10363         echo "before slab objects: $before"
10364         for i in $(seq $count); do
10365                 touch $DIR/$tfile
10366                 rm -f $DIR/$tfile
10367         done
10368         cancel_lru_locks osc
10369         local after=$(num_objects)
10370         echo "created: $count, after slab objects: $after"
10371         # shared slab counts are not very accurate, allow significant margin
10372         # the main goal is that the cache growth is not permanently > $count
10373         while (( after > before + margin )); do
10374                 sleep 1
10375                 after=$(num_objects)
10376                 wait=$((wait + 1))
10377                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
10378                 if (( wait > 60 )); then
10379                         error "inode slab grew from $before+$margin to $after"
10380                 fi
10381         done
10382 }
10383 run_test 76a "confirm clients recycle inodes properly ===="
10384
10385 test_76b() {
10386         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10387         [ $CLIENT_VERSION -ge $(version_code 2.13.55) ] || skip "not supported"
10388
10389         local count=512
10390         local before=$(num_objects)
10391
10392         for i in $(seq $count); do
10393                 mkdir $DIR/$tdir
10394                 rmdir $DIR/$tdir
10395         done
10396
10397         local after=$(num_objects)
10398         local wait=0
10399
10400         while (( after > before )); do
10401                 sleep 1
10402                 after=$(num_objects)
10403                 wait=$((wait + 1))
10404                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
10405                 if (( wait > 60 )); then
10406                         error "inode slab grew from $before to $after"
10407                 fi
10408         done
10409
10410         echo "slab objects before: $before, after: $after"
10411 }
10412 run_test 76b "confirm clients recycle directory inodes properly ===="
10413
10414 export ORIG_CSUM=""
10415 set_checksums()
10416 {
10417         # Note: in sptlrpc modes which enable its own bulk checksum, the
10418         # original crc32_le bulk checksum will be automatically disabled,
10419         # and the OBD_FAIL_OSC_CHECKSUM_SEND/OBD_FAIL_OSC_CHECKSUM_RECEIVE
10420         # will be checked by sptlrpc code against sptlrpc bulk checksum.
10421         # In this case set_checksums() will not be no-op, because sptlrpc
10422         # bulk checksum will be enabled all through the test.
10423
10424         [ "$ORIG_CSUM" ] || ORIG_CSUM=`lctl get_param -n osc.*.checksums | head -n1`
10425         lctl set_param -n osc.*.checksums $1
10426         return 0
10427 }
10428
10429 export ORIG_CSUM_TYPE="`lctl get_param -n osc.*osc-[^mM]*.checksum_type |
10430                         sed 's/.*\[\(.*\)\].*/\1/g' | head -n1`"
10431 CKSUM_TYPES=${CKSUM_TYPES:-$(lctl get_param -n osc.*osc-[^mM]*.checksum_type |
10432                              tr -d [] | head -n1)}
10433 set_checksum_type()
10434 {
10435         lctl set_param -n osc.*osc-[^mM]*.checksum_type $1
10436         rc=$?
10437         log "set checksum type to $1, rc = $rc"
10438         return $rc
10439 }
10440
10441 get_osc_checksum_type()
10442 {
10443         # arugment 1: OST name, like OST0000
10444         ost=$1
10445         checksum_type=$(lctl get_param -n osc.*${ost}-osc-[^mM]*.checksum_type |
10446                         sed 's/.*\[\(.*\)\].*/\1/g')
10447         rc=$?
10448         [ $rc -ne 0 ] && error "failed to get checksum type of $ost, rc = $rc, output = $checksum_type"
10449         echo $checksum_type
10450 }
10451
10452 F77_TMP=$TMP/f77-temp
10453 F77SZ=8
10454 setup_f77() {
10455         dd if=/dev/urandom of=$F77_TMP bs=1M count=$F77SZ || \
10456                 error "error writing to $F77_TMP"
10457 }
10458
10459 test_77a() { # bug 10889
10460         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10461         $GSS && skip_env "could not run with gss"
10462
10463         [ ! -f $F77_TMP ] && setup_f77
10464         set_checksums 1
10465         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ || error "dd error"
10466         set_checksums 0
10467         rm -f $DIR/$tfile
10468 }
10469 run_test 77a "normal checksum read/write operation"
10470
10471 test_77b() { # bug 10889
10472         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10473         $GSS && skip_env "could not run with gss"
10474
10475         [ ! -f $F77_TMP ] && setup_f77
10476         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
10477         $LCTL set_param fail_loc=0x80000409
10478         set_checksums 1
10479
10480         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
10481                 error "dd error: $?"
10482         $LCTL set_param fail_loc=0
10483
10484         for algo in $CKSUM_TYPES; do
10485                 cancel_lru_locks osc
10486                 set_checksum_type $algo
10487                 #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
10488                 $LCTL set_param fail_loc=0x80000408
10489                 cmp $F77_TMP $DIR/$tfile || error "file compare failed"
10490                 $LCTL set_param fail_loc=0
10491         done
10492         set_checksums 0
10493         set_checksum_type $ORIG_CSUM_TYPE
10494         rm -f $DIR/$tfile
10495 }
10496 run_test 77b "checksum error on client write, read"
10497
10498 cleanup_77c() {
10499         trap 0
10500         set_checksums 0
10501         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=0
10502         $check_ost &&
10503                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=0
10504         [ -n "$osc_file_prefix" ] && rm -f ${osc_file_prefix}*
10505         $check_ost && [ -n "$ost_file_prefix" ] &&
10506                 do_facet ost1 rm -f ${ost_file_prefix}\*
10507 }
10508
10509 test_77c() {
10510         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10511         $GSS && skip_env "could not run with gss"
10512         remote_ost_nodsh && skip "remote OST with nodsh"
10513
10514         local bad1
10515         local osc_file_prefix
10516         local osc_file
10517         local check_ost=false
10518         local ost_file_prefix
10519         local ost_file
10520         local orig_cksum
10521         local dump_cksum
10522         local fid
10523
10524         # ensure corruption will occur on first OSS/OST
10525         $LFS setstripe -i 0 $DIR/$tfile
10526
10527         [ ! -f $F77_TMP ] && setup_f77
10528         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
10529                 error "dd write error: $?"
10530         fid=$($LFS path2fid $DIR/$tfile)
10531
10532         if [ $OST1_VERSION -ge $(version_code 2.9.57) ]
10533         then
10534                 check_ost=true
10535                 ost_file_prefix=$(do_facet ost1 $LCTL get_param -n debug_path)
10536                 ost_file_prefix=${ost_file_prefix}-checksum_dump-ost-\\${fid}
10537         else
10538                 echo "OSS do not support bulk pages dump upon error"
10539         fi
10540
10541         osc_file_prefix=$($LCTL get_param -n debug_path)
10542         osc_file_prefix=${osc_file_prefix}-checksum_dump-osc-\\${fid}
10543
10544         trap cleanup_77c EXIT
10545
10546         set_checksums 1
10547         # enable bulk pages dump upon error on Client
10548         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=1
10549         # enable bulk pages dump upon error on OSS
10550         $check_ost &&
10551                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=1
10552
10553         # flush Client cache to allow next read to reach OSS
10554         cancel_lru_locks osc
10555
10556         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE       0x408
10557         $LCTL set_param fail_loc=0x80000408
10558         dd if=$DIR/$tfile of=/dev/null bs=1M || error "dd read error: $?"
10559         $LCTL set_param fail_loc=0
10560
10561         rm -f $DIR/$tfile
10562
10563         # check cksum dump on Client
10564         osc_file=$(ls ${osc_file_prefix}*)
10565         [ -n "$osc_file" ] || error "no checksum dump file on Client"
10566         # OBD_FAIL_OSC_CHECKSUM_RECEIVE corrupts with "bad1" at start of file
10567         bad1=$(dd if=$osc_file bs=1 count=4 2>/dev/null) || error "dd error: $?"
10568         [ $bad1 == "bad1" ] || error "unexpected corrupt pattern"
10569         orig_cksum=$(dd if=$F77_TMP bs=1 skip=4 count=1048572 2>/dev/null |
10570                      cksum)
10571         dump_cksum=$(dd if=$osc_file bs=1 skip=4 2>/dev/null | cksum)
10572         [[ "$orig_cksum" == "$dump_cksum" ]] ||
10573                 error "dump content does not match on Client"
10574
10575         $check_ost || skip "No need to check cksum dump on OSS"
10576
10577         # check cksum dump on OSS
10578         ost_file=$(do_facet ost1 ls ${ost_file_prefix}\*)
10579         [ -n "$ost_file" ] || error "no checksum dump file on OSS"
10580         orig_cksum=$(dd if=$F77_TMP bs=1048576 count=1 2>/dev/null | cksum)
10581         dump_cksum=$(do_facet ost1 dd if=$ost_file 2>/dev/null \| cksum)
10582         [[ "$orig_cksum" == "$dump_cksum" ]] ||
10583                 error "dump content does not match on OSS"
10584
10585         cleanup_77c
10586 }
10587 run_test 77c "checksum error on client read with debug"
10588
10589 test_77d() { # bug 10889
10590         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10591         $GSS && skip_env "could not run with gss"
10592
10593         stack_trap "rm -f $DIR/$tfile"
10594         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
10595         $LCTL set_param fail_loc=0x80000409
10596         set_checksums 1
10597         $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
10598                 error "direct write: rc=$?"
10599         $LCTL set_param fail_loc=0
10600         set_checksums 0
10601
10602         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
10603         $LCTL set_param fail_loc=0x80000408
10604         set_checksums 1
10605         cancel_lru_locks osc
10606         $DIRECTIO read $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
10607                 error "direct read: rc=$?"
10608         $LCTL set_param fail_loc=0
10609         set_checksums 0
10610 }
10611 run_test 77d "checksum error on OST direct write, read"
10612
10613 test_77f() { # bug 10889
10614         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10615         $GSS && skip_env "could not run with gss"
10616
10617         set_checksums 1
10618         stack_trap "rm -f $DIR/$tfile"
10619         for algo in $CKSUM_TYPES; do
10620                 cancel_lru_locks osc
10621                 set_checksum_type $algo
10622                 #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
10623                 $LCTL set_param fail_loc=0x409
10624                 $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) &&
10625                         error "direct write succeeded"
10626                 $LCTL set_param fail_loc=0
10627         done
10628         set_checksum_type $ORIG_CSUM_TYPE
10629         set_checksums 0
10630 }
10631 run_test 77f "repeat checksum error on write (expect error)"
10632
10633 test_77g() { # bug 10889
10634         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10635         $GSS && skip_env "could not run with gss"
10636         remote_ost_nodsh && skip "remote OST with nodsh"
10637
10638         [ ! -f $F77_TMP ] && setup_f77
10639
10640         local file=$DIR/$tfile
10641         stack_trap "rm -f $file" EXIT
10642
10643         $LFS setstripe -c 1 -i 0 $file
10644         #define OBD_FAIL_OST_CHECKSUM_RECEIVE       0x21a
10645         do_facet ost1 lctl set_param fail_loc=0x8000021a
10646         set_checksums 1
10647         dd if=$F77_TMP of=$file bs=1M count=$F77SZ ||
10648                 error "write error: rc=$?"
10649         do_facet ost1 lctl set_param fail_loc=0
10650         set_checksums 0
10651
10652         cancel_lru_locks osc
10653         #define OBD_FAIL_OST_CHECKSUM_SEND          0x21b
10654         do_facet ost1 lctl set_param fail_loc=0x8000021b
10655         set_checksums 1
10656         cmp $F77_TMP $file || error "file compare failed"
10657         do_facet ost1 lctl set_param fail_loc=0
10658         set_checksums 0
10659 }
10660 run_test 77g "checksum error on OST write, read"
10661
10662 test_77k() { # LU-10906
10663         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10664         $GSS && skip_env "could not run with gss"
10665
10666         local cksum_param="osc.$FSNAME*.checksums"
10667         local get_checksum="$LCTL get_param -n $cksum_param | head -n1"
10668         local checksum
10669         local i
10670
10671         [ "$ORIG_CSUM" ] || ORIG_CSUM=$(eval $get_checksum)
10672         stack_trap "wait_update $HOSTNAME '$get_checksum' $ORIG_CSUM || true"
10673         stack_trap "do_facet mgs $LCTL set_param -P $cksum_param=$ORIG_CSUM"
10674
10675         for i in 0 1; do
10676                 do_facet mgs $LCTL set_param -P $cksum_param=$i ||
10677                         error "failed to set checksum=$i on MGS"
10678                 wait_update $HOSTNAME "$get_checksum" $i
10679                 #remount
10680                 echo "remount client, checksum should be $i"
10681                 remount_client $MOUNT || error "failed to remount client"
10682                 checksum=$(eval $get_checksum)
10683                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
10684         done
10685         # remove persistent param to avoid races with checksum mountopt below
10686         do_facet mgs $LCTL set_param -P -d $cksum_param ||
10687                 error "failed to delete checksum on MGS"
10688
10689         for opt in "checksum" "nochecksum"; do
10690                 #remount with mount option
10691                 echo "remount client with option $opt, checksum should be $i"
10692                 umount_client $MOUNT || error "failed to umount client"
10693                 mount_client $MOUNT "$MOUNT_OPTS,$opt" ||
10694                         error "failed to mount client with option '$opt'"
10695                 checksum=$(eval $get_checksum)
10696                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
10697                 i=$((i - 1))
10698         done
10699
10700         remount_client $MOUNT || error "failed to remount client"
10701 }
10702 run_test 77k "enable/disable checksum correctly"
10703
10704 test_77l() {
10705         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10706         $GSS && skip_env "could not run with gss"
10707
10708         set_checksums 1
10709         stack_trap "set_checksums $ORIG_CSUM" EXIT
10710         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
10711
10712         set_checksum_type invalid && error "unexpected success of invalid checksum type"
10713
10714         $LFS setstripe -c 1 -i 0 $DIR/$tfile
10715         for algo in $CKSUM_TYPES; do
10716                 set_checksum_type $algo || error "fail to set checksum type $algo"
10717                 osc_algo=$(get_osc_checksum_type OST0000)
10718                 [ "$osc_algo" != "$algo" ] && error "checksum type is $osc_algo after setting it to $algo"
10719
10720                 # no locks, no reqs to let the connection idle
10721                 cancel_lru_locks osc
10722                 lru_resize_disable osc
10723                 wait_osc_import_state client ost1 IDLE
10724
10725                 # ensure ost1 is connected
10726                 stat $DIR/$tfile >/dev/null || error "can't stat"
10727                 wait_osc_import_state client ost1 FULL
10728
10729                 osc_algo=$(get_osc_checksum_type OST0000)
10730                 [ "$osc_algo" != "$algo" ] && error "checksum type changed from $algo to $osc_algo after reconnection"
10731         done
10732         return 0
10733 }
10734 run_test 77l "preferred checksum type is remembered after reconnected"
10735
10736 [ "$ORIG_CSUM" ] && set_checksums $ORIG_CSUM || true
10737 rm -f $F77_TMP
10738 unset F77_TMP
10739
10740 test_77m() {
10741         (( $CLIENT_VERSION >= $(version_code 2.14.52) )) ||
10742                 skip "Need at least version 2.14.52"
10743         local param=checksum_speed
10744
10745         $LCTL get_param $param || error "reading $param failed"
10746
10747         csum_speeds=$($LCTL get_param -n $param)
10748
10749         [[ "$csum_speeds" =~ "adler32" && "$csum_speeds" =~ "crc32" ]] ||
10750                 error "known checksum types are missing"
10751 }
10752 run_test 77m "Verify checksum_speed is correctly read"
10753
10754 check_filefrag_77n() {
10755         local nr_ext=0
10756         local starts=()
10757         local ends=()
10758
10759         while read extidx a b start end rest; do
10760                 if [[ "${extidx}" =~ ^[0-9]+: ]]; then
10761                         nr_ext=$(( $nr_ext + 1 ))
10762                         starts+=( ${start%..} )
10763                         ends+=( ${end%:} )
10764                 fi
10765         done < <( filefrag -sv $1 )
10766
10767         [[ $nr_ext -eq 2 ]] && [[ "${starts[-1]}" == $(( ${ends[0]} + 1 )) ]] && return 0
10768         return 1
10769 }
10770
10771 test_77n() {
10772         [[ "$CKSUM_TYPES" =~ t10 ]] || skip "no T10 checksum support on osc"
10773
10774         touch $DIR/$tfile
10775         $TRUNCATE $DIR/$tfile 0
10776         dd if=/dev/urandom of=$DIR/$tfile bs=4k conv=notrunc count=1 seek=0
10777         dd if=/dev/urandom of=$DIR/$tfile bs=4k conv=notrunc count=1 seek=2
10778         check_filefrag_77n $DIR/$tfile ||
10779                 skip "$tfile blocks not contiguous around hole"
10780
10781         set_checksums 1
10782         stack_trap "set_checksums $ORIG_CSUM" EXIT
10783         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
10784         stack_trap "rm -f $DIR/$tfile"
10785
10786         for algo in $CKSUM_TYPES; do
10787                 if [[ "$algo" =~ ^t10 ]]; then
10788                         set_checksum_type $algo ||
10789                                 error "fail to set checksum type $algo"
10790                         dd if=$DIR/$tfile of=/dev/null bs=12k count=1 iflag=direct ||
10791                                 error "fail to read $tfile with $algo"
10792                 fi
10793         done
10794         rm -f $DIR/$tfile
10795         return 0
10796 }
10797 run_test 77n "Verify read from a hole inside contiguous blocks with T10PI"
10798
10799 test_77o() {
10800         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
10801                 skip "Need MDS version at least 2.14.55"
10802         (( $OST1_VERSION >= $(version_code 2.14.55) )) ||
10803                 skip "Need OST version at least 2.14.55"
10804         local ofd=obdfilter
10805         local mdt=mdt
10806
10807         # print OST checksum_type
10808         echo "$ofd.$FSNAME-*.checksum_type:"
10809         do_nodes $(comma_list $(osts_nodes)) \
10810                 $LCTL get_param -n $ofd.$FSNAME-*.checksum_type
10811
10812         # print MDT checksum_type
10813         echo "$mdt.$FSNAME-*.checksum_type:"
10814         do_nodes $(comma_list $(mdts_nodes)) \
10815                 $LCTL get_param -n $mdt.$FSNAME-*.checksum_type
10816
10817         local o_count=$(do_nodes $(comma_list $(osts_nodes)) \
10818                    $LCTL get_param -n $ofd.$FSNAME-*.checksum_type | wc -l)
10819
10820         (( $o_count == $OSTCOUNT )) ||
10821                 error "found $o_count checksums, not \$MDSCOUNT=$OSTCOUNT"
10822
10823         local m_count=$(do_nodes $(comma_list $(mdts_nodes)) \
10824                    $LCTL get_param -n $mdt.$FSNAME-*.checksum_type | wc -l)
10825
10826         (( $m_count == $MDSCOUNT )) ||
10827                 error "found $m_count checksums, not \$MDSCOUNT=$MDSCOUNT"
10828 }
10829 run_test 77o "Verify checksum_type for server (mdt and ofd(obdfilter))"
10830
10831 cleanup_test_78() {
10832         trap 0
10833         rm -f $DIR/$tfile
10834 }
10835
10836 test_78() { # bug 10901
10837         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10838         remote_ost || skip_env "local OST"
10839
10840         NSEQ=5
10841         F78SIZE=$(($(awk '/MemFree:/ { print $2 }' /proc/meminfo) / 1024))
10842         echo "MemFree: $F78SIZE, Max file size: $MAXFREE"
10843         MEMTOTAL=$(($(awk '/MemTotal:/ { print $2 }' /proc/meminfo) / 1024))
10844         echo "MemTotal: $MEMTOTAL"
10845
10846         # reserve 256MB of memory for the kernel and other running processes,
10847         # and then take 1/2 of the remaining memory for the read/write buffers.
10848         if [ $MEMTOTAL -gt 512 ] ;then
10849                 MEMTOTAL=$(((MEMTOTAL - 256 ) / 2))
10850         else
10851                 # for those poor memory-starved high-end clusters...
10852                 MEMTOTAL=$((MEMTOTAL / 2))
10853         fi
10854         echo "Mem to use for directio: $MEMTOTAL"
10855
10856         [[ $F78SIZE -gt $MEMTOTAL ]] && F78SIZE=$MEMTOTAL
10857         [[ $F78SIZE -gt 512 ]] && F78SIZE=512
10858         [[ $F78SIZE -gt $((MAXFREE / 1024)) ]] && F78SIZE=$((MAXFREE / 1024))
10859         SMALLESTOST=$($LFS df $DIR | grep OST | awk '{ print $4 }' | sort -n |
10860                 head -n1)
10861         echo "Smallest OST: $SMALLESTOST"
10862         [[ $SMALLESTOST -lt 10240 ]] &&
10863                 skip "too small OSTSIZE, useless to run large O_DIRECT test"
10864
10865         trap cleanup_test_78 EXIT
10866
10867         [[ $F78SIZE -gt $((SMALLESTOST * $OSTCOUNT / 1024 - 80)) ]] &&
10868                 F78SIZE=$((SMALLESTOST * $OSTCOUNT / 1024 - 80))
10869
10870         [ "$SLOW" = "no" ] && NSEQ=1 && [ $F78SIZE -gt 32 ] && F78SIZE=32
10871         echo "File size: $F78SIZE"
10872         $LFS setstripe -c $OSTCOUNT $DIR/$tfile || error "setstripe failed"
10873         for i in $(seq 1 $NSEQ); do
10874                 FSIZE=$(($F78SIZE / ($NSEQ - $i + 1)))
10875                 echo directIO rdwr round $i of $NSEQ
10876                 $DIRECTIO rdwr $DIR/$tfile 0 $FSIZE 1048576||error "rdwr failed"
10877         done
10878
10879         cleanup_test_78
10880 }
10881 run_test 78 "handle large O_DIRECT writes correctly ============"
10882
10883 test_79() { # bug 12743
10884         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10885
10886         wait_delete_completed
10887
10888         BKTOTAL=$(calc_osc_kbytes kbytestotal)
10889         BKFREE=$(calc_osc_kbytes kbytesfree)
10890         BKAVAIL=$(calc_osc_kbytes kbytesavail)
10891
10892         STRING=`df -P $MOUNT | tail -n 1 | awk '{print $2","$3","$4}'`
10893         DFTOTAL=`echo $STRING | cut -d, -f1`
10894         DFUSED=`echo $STRING  | cut -d, -f2`
10895         DFAVAIL=`echo $STRING | cut -d, -f3`
10896         DFFREE=$(($DFTOTAL - $DFUSED))
10897
10898         ALLOWANCE=$((64 * $OSTCOUNT))
10899
10900         if [ $DFTOTAL -lt $(($BKTOTAL - $ALLOWANCE)) ] ||
10901            [ $DFTOTAL -gt $(($BKTOTAL + $ALLOWANCE)) ] ; then
10902                 error "df total($DFTOTAL) mismatch OST total($BKTOTAL)"
10903         fi
10904         if [ $DFFREE -lt $(($BKFREE - $ALLOWANCE)) ] ||
10905            [ $DFFREE -gt $(($BKFREE + $ALLOWANCE)) ] ; then
10906                 error "df free($DFFREE) mismatch OST free($BKFREE)"
10907         fi
10908         if [ $DFAVAIL -lt $(($BKAVAIL - $ALLOWANCE)) ] ||
10909            [ $DFAVAIL -gt $(($BKAVAIL + $ALLOWANCE)) ] ; then
10910                 error "df avail($DFAVAIL) mismatch OST avail($BKAVAIL)"
10911         fi
10912 }
10913 run_test 79 "df report consistency check ======================="
10914
10915 test_80() { # bug 10718
10916         remote_ost_nodsh && skip "remote OST with nodsh"
10917         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10918
10919         # relax strong synchronous semantics for slow backends like ZFS
10920         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
10921                 local soc="obdfilter.*.sync_lock_cancel"
10922                 local save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
10923
10924                 # "sync_on_lock_cancel" was broken by v2_11_55_0-26-g7059644e9a
10925                 if [ -z "$save" ]; then
10926                         soc="obdfilter.*.sync_on_lock_cancel"
10927                         save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
10928                 fi
10929
10930                 if [ "$save" != "never" ]; then
10931                         local hosts=$(comma_list $(osts_nodes))
10932
10933                         do_nodes $hosts $LCTL set_param $soc=never
10934                         stack_trap "do_nodes $hosts $LCTL set_param $soc=$save"
10935                 fi
10936         fi
10937
10938         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1M
10939         sync; sleep 1; sync
10940         local before=$(date +%s)
10941         cancel_lru_locks osc
10942         local after=$(date +%s)
10943         local diff=$((after - before))
10944         [ $diff -le 1 ] || error "elapsed for 1M@1T = $diff"
10945
10946         rm -f $DIR/$tfile
10947 }
10948 run_test 80 "Page eviction is equally fast at high offsets too"
10949
10950 test_81a() { # LU-456
10951         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10952         remote_ost_nodsh && skip "remote OST with nodsh"
10953
10954         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
10955         # MUST OR with the CFS_FAIL_ONCE (0x80000000)
10956         do_facet ost1 lctl set_param fail_loc=0x80000228
10957
10958         # write should trigger a retry and success
10959         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10960         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10961         RC=$?
10962         if [ $RC -ne 0 ] ; then
10963                 error "write should success, but failed for $RC"
10964         fi
10965 }
10966 run_test 81a "OST should retry write when get -ENOSPC ==============="
10967
10968 test_81b() { # LU-456
10969         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10970         remote_ost_nodsh && skip "remote OST with nodsh"
10971
10972         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
10973         # Don't OR with the CFS_FAIL_ONCE (0x80000000)
10974         do_facet ost1 lctl set_param fail_loc=0x228
10975
10976         # write should retry several times and return -ENOSPC finally
10977         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10978         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10979         RC=$?
10980         ENOSPC=28
10981         if [ $RC -ne $ENOSPC ] ; then
10982                 error "dd should fail for -ENOSPC, but succeed."
10983         fi
10984 }
10985 run_test 81b "OST should return -ENOSPC when retry still fails ======="
10986
10987 test_99() {
10988         [ -z "$(which cvs 2>/dev/null)" ] && skip_env "could not find cvs"
10989
10990         test_mkdir $DIR/$tdir.cvsroot
10991         chown $RUNAS_ID $DIR/$tdir.cvsroot
10992
10993         cd $TMP
10994         $RUNAS cvs -d $DIR/$tdir.cvsroot init || error "cvs init failed"
10995
10996         cd /etc/init.d
10997         # some versions of cvs import exit(1) when asked to import links or
10998         # files they can't read.  ignore those files.
10999         local toignore=$(find . -type l -printf '-I %f\n' -o \
11000                          ! -perm /4 -printf '-I %f\n')
11001         $RUNAS cvs -d $DIR/$tdir.cvsroot import -m "nomesg" $toignore \
11002                 $tdir.reposname vtag rtag
11003
11004         cd $DIR
11005         test_mkdir $DIR/$tdir.reposname
11006         chown $RUNAS_ID $DIR/$tdir.reposname
11007         $RUNAS cvs -d $DIR/$tdir.cvsroot co $tdir.reposname
11008
11009         cd $DIR/$tdir.reposname
11010         $RUNAS touch foo99
11011         $RUNAS cvs add -m 'addmsg' foo99
11012         $RUNAS cvs update
11013         $RUNAS cvs commit -m 'nomsg' foo99
11014         rm -fr $DIR/$tdir.cvsroot
11015 }
11016 run_test 99 "cvs strange file/directory operations"
11017
11018 test_100() {
11019         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11020         [[ "$NETTYPE" =~ tcp ]] ||
11021                 skip_env "TCP secure port test, not useful for NETTYPE=$NETTYPE"
11022         [[ -n "$(type -p ss)" ]] || skip_env "ss not available"
11023         remote_ost_nodsh && skip "remote OST with nodsh"
11024         remote_mds_nodsh && skip "remote MDS with nodsh"
11025         remote_servers || skip "useless for local single node setup"
11026
11027         ss -tna | ( rc=1; while read STATE SND RCV LOCAL REMOTE STAT; do
11028                 [[ "${REMOTE/*:/}" == "$ACCEPTOR_PORT" ]] || continue
11029
11030                 rc=0
11031                 if (( ${LOCAL/*:/} >= 1024 )); then
11032                         echo "bad: $PROT $SND $RCV $LOCAL $REMOTE $STAT"
11033                         ss -tna
11034                         error "local: ${LOCAL/*:/} > 1024 remote: ${REMOTE/*:/}"
11035                 fi
11036         done
11037         (( $rc == 0 )) || error "privileged port not found" )
11038 }
11039 run_test 100 "check local port using privileged port"
11040
11041 function get_named_value()
11042 {
11043     local tag=$1
11044
11045     grep -w "$tag" | sed "s/^$tag  *\([0-9]*\)  *.*/\1/"
11046 }
11047
11048 export CACHE_MAX=$($LCTL get_param -n llite.*.max_cached_mb |
11049                    awk '/^max_cached_mb/ { print $2 }')
11050
11051 cleanup_101a() {
11052         $LCTL set_param -n llite.*.max_cached_mb $CACHE_MAX
11053         trap 0
11054 }
11055
11056 test_101a() {
11057         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11058
11059         local s
11060         local discard
11061         local nreads=10000
11062         local cache_limit=32
11063
11064         $LCTL set_param -n osc.*-osc*.rpc_stats=0
11065         trap cleanup_101a EXIT
11066         $LCTL set_param -n llite.*.read_ahead_stats=0
11067         $LCTL set_param -n llite.*.max_cached_mb=$cache_limit
11068
11069         #
11070         # randomly read 10000 of 64K chunks from file 3x 32MB in size
11071         #
11072         echo "nreads: $nreads file size: $((cache_limit * 3))MB"
11073         $READS -f $DIR/$tfile -s$((cache_limit * 3192 * 1024)) -b65536 -C -n$nreads -t 180
11074
11075         discard=0
11076         for s in $($LCTL get_param -n llite.*.read_ahead_stats |
11077                    get_named_value 'read.but.discarded'); do
11078                         discard=$(($discard + $s))
11079         done
11080         cleanup_101a
11081
11082         $LCTL get_param osc.*-osc*.rpc_stats
11083         $LCTL get_param llite.*.read_ahead_stats
11084
11085         # Discard is generally zero, but sometimes a few random reads line up
11086         # and trigger larger readahead, which is wasted & leads to discards.
11087         if [[ $(($discard)) -gt $nreads ]]; then
11088                 error "too many ($discard) discarded pages"
11089         fi
11090         rm -f $DIR/$tfile || true
11091 }
11092 run_test 101a "check read-ahead for random reads"
11093
11094 setup_test101bc() {
11095         test_mkdir $DIR/$tdir
11096         local ssize=$1
11097         local FILE_LENGTH=$2
11098         STRIPE_OFFSET=0
11099
11100         local FILE_SIZE_MB=$((FILE_LENGTH / ssize))
11101
11102         local list=$(comma_list $(osts_nodes))
11103         set_osd_param $list '' read_cache_enable 0
11104         set_osd_param $list '' writethrough_cache_enable 0
11105
11106         trap cleanup_test101bc EXIT
11107         # prepare the read-ahead file
11108         $LFS setstripe -S $ssize -i $STRIPE_OFFSET -c $OSTCOUNT $DIR/$tfile
11109
11110         dd if=/dev/zero of=$DIR/$tfile bs=$ssize \
11111                                 count=$FILE_SIZE_MB 2> /dev/null
11112
11113 }
11114
11115 cleanup_test101bc() {
11116         trap 0
11117         rm -rf $DIR/$tdir
11118         rm -f $DIR/$tfile
11119
11120         local list=$(comma_list $(osts_nodes))
11121         set_osd_param $list '' read_cache_enable 1
11122         set_osd_param $list '' writethrough_cache_enable 1
11123 }
11124
11125 calc_total() {
11126         awk 'BEGIN{total=0}; {total+=$1}; END{print total}'
11127 }
11128
11129 ra_check_101() {
11130         local read_size=$1
11131         local stripe_size=$2
11132         local stride_length=$((stripe_size / read_size))
11133         local stride_width=$((stride_length * OSTCOUNT))
11134         local discard_limit=$(( ((stride_length - 1) * 3 / stride_width) *
11135                                 (stride_width - stride_length) ))
11136         local discard=$($LCTL get_param -n llite.*.read_ahead_stats |
11137                   get_named_value 'read.but.discarded' | calc_total)
11138
11139         if [[ $discard -gt $discard_limit ]]; then
11140                 $LCTL get_param llite.*.read_ahead_stats
11141                 error "($discard limit ${discard_limit}) discarded pages with size (${read_size})"
11142         else
11143                 echo "Read-ahead success for size ${read_size}"
11144         fi
11145 }
11146
11147 test_101b() {
11148         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11149         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11150
11151         local STRIPE_SIZE=1048576
11152         local STRIDE_SIZE=$((STRIPE_SIZE*OSTCOUNT))
11153
11154         if [ $SLOW == "yes" ]; then
11155                 local FILE_LENGTH=$((STRIDE_SIZE * 64))
11156         else
11157                 local FILE_LENGTH=$((STRIDE_SIZE * 8))
11158         fi
11159
11160         local ITERATION=$((FILE_LENGTH / STRIDE_SIZE))
11161
11162         # prepare the read-ahead file
11163         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
11164         cancel_lru_locks osc
11165         for BIDX in 2 4 8 16 32 64 128 256
11166         do
11167                 local BSIZE=$((BIDX*4096))
11168                 local READ_COUNT=$((STRIPE_SIZE/BSIZE))
11169                 local STRIDE_LENGTH=$((STRIDE_SIZE/BSIZE))
11170                 local OFFSET=$((STRIPE_SIZE/BSIZE*(OSTCOUNT - 1)))
11171                 $LCTL set_param -n llite.*.read_ahead_stats=0
11172                 $READS -f $DIR/$tfile  -l $STRIDE_LENGTH -o $OFFSET \
11173                               -s $FILE_LENGTH -b $STRIPE_SIZE -a $READ_COUNT -n $ITERATION
11174                 cancel_lru_locks osc
11175                 ra_check_101 $BSIZE $STRIPE_SIZE $FILE_LENGTH
11176         done
11177         cleanup_test101bc
11178         true
11179 }
11180 run_test 101b "check stride-io mode read-ahead ================="
11181
11182 test_101c() {
11183         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11184
11185         local STRIPE_SIZE=1048576
11186         local FILE_LENGTH=$((STRIPE_SIZE*100))
11187         local nreads=10000
11188         local rsize=65536
11189         local osc_rpc_stats
11190
11191         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
11192
11193         cancel_lru_locks osc
11194         $LCTL set_param osc.*.rpc_stats=0
11195         $READS -f $DIR/$tfile -s$FILE_LENGTH -b$rsize -n$nreads -t 180
11196         $LCTL get_param osc.*.rpc_stats
11197         for osc_rpc_stats in $($LCTL get_param -N osc.*.rpc_stats); do
11198                 local stats=$($LCTL get_param -n $osc_rpc_stats)
11199                 local lines=$(echo "$stats" | awk 'END {print NR;}')
11200                 local size
11201
11202                 if [ $lines -le 20 ]; then
11203                         echo "continue debug"
11204                         continue
11205                 fi
11206                 for size in 1 2 4 8; do
11207                         local rpc=$(echo "$stats" |
11208                                     awk '($1 == "'$size':") {print $2; exit; }')
11209                         [ $rpc != 0 ] && ((size * PAGE_SIZE < rsize)) &&
11210                                 error "Small $((size*PAGE_SIZE)) read IO $rpc!"
11211                 done
11212                 echo "$osc_rpc_stats check passed!"
11213         done
11214         cleanup_test101bc
11215         true
11216 }
11217 run_test 101c "check stripe_size aligned read-ahead"
11218
11219 test_101d() {
11220         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11221
11222         local file=$DIR/$tfile
11223         local sz_MB=${FILESIZE_101d:-80}
11224         local ra_MB=${READAHEAD_MB:-40}
11225
11226         local free_MB=$(($(df -P $DIR | tail -n 1 | awk '{ print $4 }') / 1024))
11227         [ $free_MB -lt $sz_MB ] &&
11228                 skip "Need free space ${sz_MB}M, have ${free_MB}M"
11229
11230         echo "Create test file $file size ${sz_MB}M, ${free_MB}M free"
11231         $LFS setstripe -c -1 $file || error "setstripe failed"
11232
11233         dd if=/dev/zero of=$file bs=1M count=$sz_MB || error "dd failed"
11234         echo Cancel LRU locks on lustre client to flush the client cache
11235         cancel_lru_locks osc
11236
11237         echo Disable read-ahead
11238         local old_RA=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
11239         $LCTL set_param -n llite.*.max_read_ahead_mb=0
11240         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb=$old_RA" EXIT
11241         $LCTL get_param -n llite.*.max_read_ahead_mb
11242
11243         echo "Reading the test file $file with read-ahead disabled"
11244         local sz_KB=$((sz_MB * 1024 / 4))
11245         # 10485760 bytes transferred in 0.000938 secs (11179579337 bytes/sec)
11246         # 104857600 bytes (105 MB) copied, 0.00876352 s, 12.0 GB/s
11247         local raOFF=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
11248                       sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
11249
11250         echo "Cancel LRU locks on lustre client to flush the client cache"
11251         cancel_lru_locks osc
11252         echo Enable read-ahead with ${ra_MB}MB
11253         $LCTL set_param -n llite.*.max_read_ahead_mb=$ra_MB
11254
11255         echo "Reading the test file $file with read-ahead enabled"
11256         local raON=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
11257                      sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
11258
11259         echo "read-ahead disabled time read $raOFF"
11260         echo "read-ahead enabled time read $raON"
11261
11262         rm -f $file
11263         wait_delete_completed
11264
11265         # use awk for this check instead of bash because it handles decimals
11266         awk "{ exit !($raOFF < 1.0 || $raOFF > $raON) }" <<<"ignore_me" ||
11267                 error "readahead ${raON}s > no-readahead ${raOFF}s ${sz_MB}M"
11268 }
11269 run_test 101d "file read with and without read-ahead enabled"
11270
11271 test_101e() {
11272         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11273
11274         local file=$DIR/$tfile
11275         local size_KB=500  #KB
11276         local count=100
11277         local bsize=1024
11278
11279         local free_KB=$(df -P $DIR | tail -n 1 | awk '{ print $4 }')
11280         local need_KB=$((count * size_KB))
11281         [[ $free_KB -le $need_KB ]] &&
11282                 skip_env "Need free space $need_KB, have $free_KB"
11283
11284         echo "Creating $count ${size_KB}K test files"
11285         for ((i = 0; i < $count; i++)); do
11286                 dd if=/dev/zero of=$file.$i bs=$bsize count=$size_KB 2>/dev/null
11287         done
11288
11289         echo "Cancel LRU locks on lustre client to flush the client cache"
11290         cancel_lru_locks $OSC
11291
11292         echo "Reset readahead stats"
11293         $LCTL set_param -n llite.*.read_ahead_stats=0
11294
11295         for ((i = 0; i < $count; i++)); do
11296                 dd if=$file.$i of=/dev/null bs=$bsize count=$size_KB 2>/dev/null
11297         done
11298
11299         $LCTL get_param llite.*.max_cached_mb
11300         $LCTL get_param llite.*.read_ahead_stats
11301         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11302                      get_named_value 'misses' | calc_total)
11303
11304         for ((i = 0; i < $count; i++)); do
11305                 rm -rf $file.$i 2>/dev/null
11306         done
11307
11308         #10000 means 20% reads are missing in readahead
11309         [[ $miss -lt 10000 ]] ||  error "misses too much for small reads"
11310 }
11311 run_test 101e "check read-ahead for small read(1k) for small files(500k)"
11312
11313 test_101f() {
11314         which iozone || skip_env "no iozone installed"
11315
11316         local old_debug=$($LCTL get_param debug)
11317         old_debug=${old_debug#*=}
11318         $LCTL set_param debug="reada mmap"
11319
11320         # create a test file
11321         iozone -i 0 -+n -r 1m -s 128m -w -f $DIR/$tfile > /dev/null 2>&1
11322
11323         echo Cancel LRU locks on lustre client to flush the client cache
11324         cancel_lru_locks osc
11325
11326         echo Reset readahead stats
11327         $LCTL set_param -n llite.*.read_ahead_stats=0
11328
11329         echo mmap read the file with small block size
11330         iozone -i 1 -u 1 -l 1 -+n -r 32k -s 128m -B -f $DIR/$tfile \
11331                 > /dev/null 2>&1
11332
11333         echo checking missing pages
11334         $LCTL get_param llite.*.read_ahead_stats
11335         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11336                         get_named_value 'misses' | calc_total)
11337
11338         $LCTL set_param debug="$old_debug"
11339         [ $miss -lt 3 ] || error "misses too much pages ('$miss')!"
11340         rm -f $DIR/$tfile
11341 }
11342 run_test 101f "check mmap read performance"
11343
11344 test_101g_brw_size_test() {
11345         local mb=$1
11346         local pages=$((mb * 1048576 / PAGE_SIZE))
11347         local file=$DIR/$tfile
11348
11349         $LCTL set_param osc.*.max_pages_per_rpc=${mb}M ||
11350                 { error "unable to set max_pages_per_rpc=${mb}M"; return 1; }
11351         for mp in $($LCTL get_param -n osc.*.max_pages_per_rpc); do
11352                 [ $mp -ne $pages ] && error "max_pages_per_rpc $mp != $pages" &&
11353                         return 2
11354         done
11355
11356         stack_trap "rm -f $file" EXIT
11357         $LCTL set_param -n osc.*.rpc_stats=0
11358
11359         # 10 RPCs should be enough for the test
11360         local count=10
11361         dd if=/dev/zero of=$file bs=${mb}M count=$count ||
11362                 { error "dd write ${mb} MB blocks failed"; return 3; }
11363         cancel_lru_locks osc
11364         dd of=/dev/null if=$file bs=${mb}M count=$count ||
11365                 { error "dd write ${mb} MB blocks failed"; return 4; }
11366
11367         # calculate number of full-sized read and write RPCs
11368         rpcs=($($LCTL get_param -n 'osc.*.rpc_stats' |
11369                 sed -n '/pages per rpc/,/^$/p' |
11370                 awk '/'$pages':/ { reads += $2; writes += $6 }; \
11371                 END { print reads,writes }'))
11372         # allow one extra full-sized read RPC for async readahead
11373         [[ ${rpcs[0]} == $count || ${rpcs[0]} == $((count + 1)) ]] ||
11374                 { error "${rpcs[0]} != $count read RPCs"; return 5; }
11375         [[ ${rpcs[1]} == $count ]] ||
11376                 { error "${rpcs[1]} != $count write RPCs"; return 6; }
11377 }
11378
11379 test_101g() {
11380         remote_ost_nodsh && skip "remote OST with nodsh"
11381
11382         local rpcs
11383         local osts=$(get_facets OST)
11384         local list=$(comma_list $(osts_nodes))
11385         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
11386         local brw_size="obdfilter.*.brw_size"
11387
11388         $LFS setstripe -i 0 -c 1 $DIR/$tfile
11389
11390         local orig_mb=$(do_facet ost1 $LCTL get_param -n $brw_size | head -n 1)
11391
11392         if { [ $OST1_VERSION -ge $(version_code 2.8.52) ] ||
11393                 { [ $OST1_VERSION -ge $(version_code 2.7.17) ] &&
11394                   [ $OST1_VERSION -lt $(version_code 2.7.50) ]; }; } &&
11395            { [ $CLIENT_VERSION -ge $(version_code 2.8.52) ] ||
11396                 { [ $CLIENT_VERSION -ge $(version_code 2.7.17) ] &&
11397                   [ $CLIENT_VERSION -lt $(version_code 2.7.50) ]; }; }; then
11398
11399                 [ $OST1_VERSION -ge $(version_code 2.9.52) ] &&
11400                         suffix="M"
11401
11402                 if [[ $orig_mb -lt 16 ]]; then
11403                         save_lustre_params $osts "$brw_size" > $p
11404                         do_nodes $list $LCTL set_param -n $brw_size=16$suffix ||
11405                                 error "set 16MB RPC size failed"
11406
11407                         echo "remount client to enable new RPC size"
11408                         remount_client $MOUNT || error "remount_client failed"
11409                 fi
11410
11411                 test_101g_brw_size_test 16 || error "16MB RPC test failed"
11412                 # should be able to set brw_size=12, but no rpc_stats for that
11413                 test_101g_brw_size_test 8 || error "8MB RPC test failed"
11414         fi
11415
11416         test_101g_brw_size_test 4 || error "4MB RPC test failed"
11417
11418         if [[ $orig_mb -lt 16 ]]; then
11419                 restore_lustre_params < $p
11420                 remount_client $MOUNT || error "remount_client restore failed"
11421         fi
11422
11423         rm -f $p $DIR/$tfile
11424 }
11425 run_test 101g "Big bulk(4/16 MiB) readahead"
11426
11427 test_101h() {
11428         $LFS setstripe -i 0 -c 1 $DIR/$tfile
11429
11430         dd if=/dev/zero of=$DIR/$tfile bs=1M count=70 ||
11431                 error "dd 70M file failed"
11432         echo Cancel LRU locks on lustre client to flush the client cache
11433         cancel_lru_locks osc
11434
11435         echo "Reset readahead stats"
11436         $LCTL set_param -n llite.*.read_ahead_stats 0
11437
11438         echo "Read 10M of data but cross 64M bundary"
11439         dd if=$DIR/$tfile of=/dev/null bs=10M skip=6 count=1
11440         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11441                      get_named_value 'misses' | calc_total)
11442         [ $miss -eq 1 ] || error "expected miss 1 but got $miss"
11443         rm -f $p $DIR/$tfile
11444 }
11445 run_test 101h "Readahead should cover current read window"
11446
11447 test_101i() {
11448         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 ||
11449                 error "dd 10M file failed"
11450
11451         local max_per_file_mb=$($LCTL get_param -n \
11452                 llite.*.max_read_ahead_per_file_mb 2>/dev/null)
11453         cancel_lru_locks osc
11454         stack_trap "$LCTL set_param llite.*.max_read_ahead_per_file_mb=$max_per_file_mb"
11455         $LCTL set_param llite.*.max_read_ahead_per_file_mb=1 ||
11456                 error "set max_read_ahead_per_file_mb to 1 failed"
11457
11458         echo "Reset readahead stats"
11459         $LCTL set_param llite.*.read_ahead_stats=0
11460
11461         dd if=$DIR/$tfile of=/dev/null bs=2M
11462
11463         $LCTL get_param llite.*.read_ahead_stats
11464         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11465                      awk '/misses/ { print $2 }')
11466         [ $miss -eq 5 ] || error "expected misses 5 but got $miss"
11467         rm -f $DIR/$tfile
11468 }
11469 run_test 101i "allow current readahead to exceed reservation"
11470
11471 test_101j() {
11472         $LFS setstripe -i 0 -c 1 $DIR/$tfile ||
11473                 error "setstripe $DIR/$tfile failed"
11474         local file_size=$((1048576 * 16))
11475         local old_ra=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
11476         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb $old_ra" EXIT
11477
11478         echo Disable read-ahead
11479         $LCTL set_param -n llite.*.max_read_ahead_mb=0
11480
11481         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$(($file_size / 1048576))
11482         for blk in $PAGE_SIZE 1048576 $file_size; do
11483                 cancel_lru_locks osc
11484                 echo "Reset readahead stats"
11485                 $LCTL set_param -n llite.*.read_ahead_stats=0
11486                 local count=$(($file_size / $blk))
11487                 dd if=$DIR/$tfile bs=$blk count=$count of=/dev/null
11488                 local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11489                              get_named_value 'failed.to.fast.read' | calc_total)
11490                 $LCTL get_param -n llite.*.read_ahead_stats
11491                 [ $miss -eq $count ] || error "expected $count got $miss"
11492         done
11493
11494         rm -f $p $DIR/$tfile
11495 }
11496 run_test 101j "A complete read block should be submitted when no RA"
11497
11498 test_readahead_base() {
11499         local file=$DIR/$tfile
11500         local size=$1
11501         local iosz
11502         local ramax
11503         local ranum
11504
11505         $LCTL set_param -n llite.*.read_ahead_stats=0
11506         # The first page is not accounted into readahead
11507         ramax=$(((size + PAGE_SIZE - 1) / PAGE_SIZE - 1))
11508         iosz=$(((size + 1048575) / 1048576 * 1048576))
11509         echo "Test readahead: size=$size ramax=$ramx iosz=$iosz"
11510
11511         $LCTL mark  "Test readahead: size=$size ramax=$ramx iosz=$iosz"
11512         fallocate -l $size $file || error "failed to fallocate $file"
11513         cancel_lru_locks osc
11514         $MULTIOP $file or${iosz}c || error "failed to read $file"
11515         $LCTL get_param -n llite.*.read_ahead_stats
11516         ranum=$($LCTL get_param -n llite.*.read_ahead_stats |
11517                 awk '/readahead.pages/ { print $7 }' | calc_total)
11518         (( $ranum <= $ramax )) ||
11519                 error "read-ahead pages is $ranum more than $ramax"
11520         rm -rf $file || error "failed to remove $file"
11521 }
11522
11523 test_101m()
11524 {
11525         local file=$DIR/$tfile
11526         local ramax
11527         local ranum
11528         local size
11529         local iosz
11530
11531         check_set_fallocate_or_skip
11532         stack_trap "rm -f $file" EXIT
11533
11534         test_readahead_base 4096
11535
11536         # file size: 16K = 16384
11537         test_readahead_base 16384
11538         test_readahead_base 16385
11539         test_readahead_base 16383
11540
11541         # file size: 1M + 1 = 1048576 + 1
11542         test_readahead_base 1048577
11543         # file size: 1M + 16K
11544         test_readahead_base $((1048576 + 16384))
11545
11546         # file size: stripe_size * (stripe_count - 1) + 16K
11547         $LFS setstripe -c -1 $file || error "failed to setstripe $file"
11548         test_readahead_base $((1048576 * (OSTCOUNT - 1) + 16384))
11549         # file size: stripe_size * stripe_count + 16K
11550         $LFS setstripe -c -1 $file || error "failed to setstripe $file"
11551         test_readahead_base $((1048576 * OSTCOUNT + 16384))
11552         # file size: 2 * stripe_size * stripe_count + 16K
11553         $LFS setstripe -c -1 $file || error "failed to setstripe $file"
11554         test_readahead_base $((2 * 1048576 * OSTCOUNT + 16384))
11555 }
11556 run_test 101m "read ahead for small file and last stripe of the file"
11557
11558 setup_test102() {
11559         test_mkdir $DIR/$tdir
11560         chown $RUNAS_ID $DIR/$tdir
11561         STRIPE_SIZE=65536
11562         STRIPE_OFFSET=1
11563         STRIPE_COUNT=$OSTCOUNT
11564         [[ $OSTCOUNT -gt 4 ]] && STRIPE_COUNT=4
11565
11566         trap cleanup_test102 EXIT
11567         cd $DIR
11568         $1 $LFS setstripe -S $STRIPE_SIZE -i $STRIPE_OFFSET -c $STRIPE_COUNT $tdir
11569         cd $DIR/$tdir
11570         for num in 1 2 3 4; do
11571                 for count in $(seq 1 $STRIPE_COUNT); do
11572                         for idx in $(seq 0 $[$STRIPE_COUNT - 1]); do
11573                                 local size=`expr $STRIPE_SIZE \* $num`
11574                                 local file=file"$num-$idx-$count"
11575                                 $1 $LFS setstripe -S $size -i $idx -c $count $file
11576                         done
11577                 done
11578         done
11579
11580         cd $DIR
11581         $1 tar cf $TMP/f102.tar $tdir --xattrs
11582 }
11583
11584 cleanup_test102() {
11585         trap 0
11586         rm -f $TMP/f102.tar
11587         rm -rf $DIR/d0.sanity/d102
11588 }
11589
11590 test_102a() {
11591         [ "$UID" != 0 ] && skip "must run as root"
11592         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep xattr)" ] &&
11593                 skip_env "must have user_xattr"
11594
11595         [ -z "$(which setfattr 2>/dev/null)" ] &&
11596                 skip_env "could not find setfattr"
11597
11598         local testfile=$DIR/$tfile
11599
11600         touch $testfile
11601         echo "set/get xattr..."
11602         setfattr -n trusted.name1 -v value1 $testfile ||
11603                 error "setfattr -n trusted.name1=value1 $testfile failed"
11604         getfattr -n trusted.name1 $testfile 2> /dev/null |
11605           grep "trusted.name1=.value1" ||
11606                 error "$testfile missing trusted.name1=value1"
11607
11608         setfattr -n user.author1 -v author1 $testfile ||
11609                 error "setfattr -n user.author1=author1 $testfile failed"
11610         getfattr -n user.author1 $testfile 2> /dev/null |
11611           grep "user.author1=.author1" ||
11612                 error "$testfile missing trusted.author1=author1"
11613
11614         echo "listxattr..."
11615         setfattr -n trusted.name2 -v value2 $testfile ||
11616                 error "$testfile unable to set trusted.name2"
11617         setfattr -n trusted.name3 -v value3 $testfile ||
11618                 error "$testfile unable to set trusted.name3"
11619         [ $(getfattr -d -m "^trusted" $testfile 2> /dev/null |
11620             grep "trusted.name" | wc -l) -eq 3 ] ||
11621                 error "$testfile missing 3 trusted.name xattrs"
11622
11623         setfattr -n user.author2 -v author2 $testfile ||
11624                 error "$testfile unable to set user.author2"
11625         setfattr -n user.author3 -v author3 $testfile ||
11626                 error "$testfile unable to set user.author3"
11627         [ $(getfattr -d -m "^user" $testfile 2> /dev/null |
11628             grep "user.author" | wc -l) -eq 3 ] ||
11629                 error "$testfile missing 3 user.author xattrs"
11630
11631         echo "remove xattr..."
11632         setfattr -x trusted.name1 $testfile ||
11633                 error "$testfile error deleting trusted.name1"
11634         getfattr -d -m trusted $testfile 2> /dev/null | grep "trusted.name1" &&
11635                 error "$testfile did not delete trusted.name1 xattr"
11636
11637         setfattr -x user.author1 $testfile ||
11638                 error "$testfile error deleting user.author1"
11639         echo "set lustre special xattr ..."
11640         $LFS setstripe -c1 $testfile
11641         local lovea=$(getfattr -n "trusted.lov" -e hex $testfile |
11642                 awk -F "=" '/trusted.lov/ { print $2 }' )
11643         setfattr -n "trusted.lov" -v $lovea $testfile ||
11644                 error "$testfile doesn't ignore setting trusted.lov again"
11645         setfattr -n "trusted.lov" -v "invalid_value" $testfile &&
11646                 error "$testfile allow setting invalid trusted.lov"
11647         rm -f $testfile
11648 }
11649 run_test 102a "user xattr test =================================="
11650
11651 check_102b_layout() {
11652         local layout="$*"
11653         local testfile=$DIR/$tfile
11654
11655         echo "test layout '$layout'"
11656         $LFS setstripe $layout $testfile || error "setstripe failed"
11657         $LFS getstripe -y $testfile
11658
11659         echo "get/set/list trusted.lov xattr ..." # b=10930
11660         local value=$(getfattr -n trusted.lov -e hex $testfile | grep trusted)
11661         [[ "$value" =~ "trusted.lov" ]] ||
11662                 error "can't get trusted.lov from $testfile"
11663         local stripe_count_orig=$($LFS getstripe -c $testfile) ||
11664                 error "getstripe failed"
11665
11666         $MCREATE $testfile.2 || error "mcreate $testfile.2 failed"
11667
11668         value=$(cut -d= -f2 <<<$value)
11669         # LU-13168: truncated xattr should fail if short lov_user_md header
11670         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
11671                 lens="${#value}" || lens="$(seq 4 2 ${#value})"
11672         for len in $lens; do
11673                 echo "setfattr $len $testfile.2"
11674                 setfattr -n trusted.lov -v ${value:0:$len} $testfile.2 &&
11675                         [ $len -lt 66 ] && error "short xattr len=$len worked"
11676         done
11677         local stripe_size=$($LFS getstripe -S $testfile.2)
11678         local stripe_count=$($LFS getstripe -c $testfile.2)
11679         [[ $stripe_size -eq 65536 ]] ||
11680                 error "stripe size $stripe_size != 65536"
11681         [[ $stripe_count -eq $stripe_count_orig ]] ||
11682                 error "stripe count $stripe_count != $stripe_count_orig"
11683         rm $testfile $testfile.2
11684 }
11685
11686 test_102b() {
11687         [ -z "$(which setfattr 2>/dev/null)" ] &&
11688                 skip_env "could not find setfattr"
11689         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11690
11691         # check plain layout
11692         check_102b_layout -S 65536 -i 1 -c $OSTCOUNT
11693
11694         # and also check composite layout
11695         check_102b_layout -E 1M -S 65536 -i 1 -c $OSTCOUNT -Eeof -S4M
11696
11697 }
11698 run_test 102b "getfattr/setfattr for trusted.lov EAs"
11699
11700 test_102c() {
11701         [ -z "$(which setfattr 2>/dev/null)" ] &&
11702                 skip_env "could not find setfattr"
11703         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11704
11705         # b10930: get/set/list lustre.lov xattr
11706         echo "get/set/list lustre.lov xattr ..."
11707         test_mkdir $DIR/$tdir
11708         chown $RUNAS_ID $DIR/$tdir
11709         local testfile=$DIR/$tdir/$tfile
11710         $RUNAS $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
11711                 error "setstripe failed"
11712         local STRIPECOUNT=$($RUNAS $LFS getstripe -c $testfile) ||
11713                 error "getstripe failed"
11714         $RUNAS getfattr -d -m "^lustre" $testfile 2> /dev/null | \
11715         grep "lustre.lov" || error "can't get lustre.lov from $testfile"
11716
11717         local testfile2=${testfile}2
11718         local value=`getfattr -n lustre.lov $testfile 2> /dev/null | \
11719                      grep "lustre.lov" |sed -e 's/[^=]\+=//'  `
11720
11721         $RUNAS $MCREATE $testfile2
11722         $RUNAS setfattr -n lustre.lov -v $value $testfile2
11723         local stripe_size=$($RUNAS $LFS getstripe -S $testfile2)
11724         local stripe_count=$($RUNAS $LFS getstripe -c $testfile2)
11725         [ $stripe_size -eq 65536 ] || error "stripe size $stripe_size != 65536"
11726         [ $stripe_count -eq $STRIPECOUNT ] ||
11727                 error "stripe count $stripe_count != $STRIPECOUNT"
11728 }
11729 run_test 102c "non-root getfattr/setfattr for lustre.lov EAs ==========="
11730
11731 compare_stripe_info1() {
11732         local stripe_index_all_zero=true
11733
11734         for num in 1 2 3 4; do
11735                 for count in $(seq 1 $STRIPE_COUNT); do
11736                         for offset in $(seq 0 $[$STRIPE_COUNT - 1]); do
11737                                 local size=$((STRIPE_SIZE * num))
11738                                 local file=file"$num-$offset-$count"
11739                                 stripe_size=$($LFS getstripe -S $PWD/$file)
11740                                 [[ $stripe_size -ne $size ]] &&
11741                                     error "$file: size $stripe_size != $size"
11742                                 stripe_count=$($LFS getstripe -c $PWD/$file)
11743                                 # allow fewer stripes to be created, ORI-601
11744                                 [[ $stripe_count -lt $(((3 * count + 3) / 4)) ]] &&
11745                                     error "$file: count $stripe_count != $count"
11746                                 stripe_index=$($LFS getstripe -i $PWD/$file)
11747                                 [[ $stripe_index -ne 0 ]] &&
11748                                         stripe_index_all_zero=false
11749                         done
11750                 done
11751         done
11752         $stripe_index_all_zero &&
11753                 error "all files are being extracted starting from OST index 0"
11754         return 0
11755 }
11756
11757 have_xattrs_include() {
11758         tar --help | grep -q xattrs-include &&
11759                 echo --xattrs-include="lustre.*"
11760 }
11761
11762 test_102d() {
11763         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11764         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11765
11766         XINC=$(have_xattrs_include)
11767         setup_test102
11768         tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
11769         cd $DIR/$tdir/$tdir
11770         compare_stripe_info1
11771 }
11772 run_test 102d "tar restore stripe info from tarfile,not keep osts"
11773
11774 test_102f() {
11775         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11776         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11777
11778         XINC=$(have_xattrs_include)
11779         setup_test102
11780         test_mkdir $DIR/$tdir.restore
11781         cd $DIR
11782         tar cf - --xattrs $tdir | tar xf - \
11783                 -C $DIR/$tdir.restore --xattrs $XINC
11784         cd $DIR/$tdir.restore/$tdir
11785         compare_stripe_info1
11786 }
11787 run_test 102f "tar copy files, not keep osts"
11788
11789 grow_xattr() {
11790         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep xattr)" ] &&
11791                 skip "must have user_xattr"
11792         [ -z "$(which setfattr 2>/dev/null)" ] &&
11793                 skip_env "could not find setfattr"
11794         [ -z "$(which getfattr 2>/dev/null)" ] &&
11795                 skip_env "could not find getfattr"
11796
11797         local xsize=${1:-1024}  # in bytes
11798         local file=$DIR/$tfile
11799         local value="$(generate_string $xsize)"
11800         local xbig=trusted.big
11801         local toobig=$2
11802
11803         touch $file
11804         log "save $xbig on $file"
11805         if [ -z "$toobig" ]
11806         then
11807                 setfattr -n $xbig -v $value $file ||
11808                         error "saving $xbig on $file failed"
11809         else
11810                 setfattr -n $xbig -v $value $file &&
11811                         error "saving $xbig on $file succeeded"
11812                 return 0
11813         fi
11814
11815         local orig=$(get_xattr_value $xbig $file)
11816         [[ "$orig" != "$value" ]] && error "$xbig different after saving $xbig"
11817
11818         local xsml=trusted.sml
11819         log "save $xsml on $file"
11820         setfattr -n $xsml -v val $file || error "saving $xsml on $file failed"
11821
11822         local new=$(get_xattr_value $xbig $file)
11823         [[ "$new" != "$orig" ]] && error "$xbig different after saving $xsml"
11824
11825         log "grow $xsml on $file"
11826         setfattr -n $xsml -v "$value" $file ||
11827                 error "growing $xsml on $file failed"
11828
11829         new=$(get_xattr_value $xbig $file)
11830         [[ "$new" != "$orig" ]] && error "$xbig different after growing $xsml"
11831         log "$xbig still valid after growing $xsml"
11832
11833         rm -f $file
11834 }
11835
11836 test_102h() { # bug 15777
11837         grow_xattr 1024
11838 }
11839 run_test 102h "grow xattr from inside inode to external block"
11840
11841 test_102ha() {
11842         large_xattr_enabled || skip_env "ea_inode feature disabled"
11843
11844         echo "setting xattr of max xattr size: $(max_xattr_size)"
11845         grow_xattr $(max_xattr_size)
11846
11847         echo "setting xattr of > max xattr size: $(max_xattr_size) + 10"
11848         echo "This should fail:"
11849         grow_xattr $(($(max_xattr_size) + 10)) 1
11850 }
11851 run_test 102ha "grow xattr from inside inode to external inode"
11852
11853 test_102i() { # bug 17038
11854         [ -z "$(which getfattr 2>/dev/null)" ] &&
11855                 skip "could not find getfattr"
11856
11857         touch $DIR/$tfile
11858         ln -s $DIR/$tfile $DIR/${tfile}link
11859         getfattr -n trusted.lov $DIR/$tfile ||
11860                 error "lgetxattr on $DIR/$tfile failed"
11861         getfattr -h -n trusted.lov $DIR/${tfile}link 2>&1 |
11862                 grep -i "no such attr" ||
11863                 error "error for lgetxattr on $DIR/${tfile}link is not ENODATA"
11864         rm -f $DIR/$tfile $DIR/${tfile}link
11865 }
11866 run_test 102i "lgetxattr test on symbolic link ============"
11867
11868 test_102j() {
11869         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11870         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11871
11872         XINC=$(have_xattrs_include)
11873         setup_test102 "$RUNAS"
11874         chown $RUNAS_ID $DIR/$tdir
11875         $RUNAS tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
11876         cd $DIR/$tdir/$tdir
11877         compare_stripe_info1 "$RUNAS"
11878 }
11879 run_test 102j "non-root tar restore stripe info from tarfile, not keep osts ==="
11880
11881 test_102k() {
11882         [ -z "$(which setfattr 2>/dev/null)" ] &&
11883                 skip "could not find setfattr"
11884
11885         touch $DIR/$tfile
11886         # b22187 just check that does not crash for regular file.
11887         setfattr -n trusted.lov $DIR/$tfile
11888         # b22187 'setfattr -n trusted.lov' should remove LOV EA for directories
11889         local test_kdir=$DIR/$tdir
11890         test_mkdir $test_kdir
11891         local default_size=$($LFS getstripe -S $test_kdir)
11892         local default_count=$($LFS getstripe -c $test_kdir)
11893         local default_offset=$($LFS getstripe -i $test_kdir)
11894         $LFS setstripe -S 65536 -i 0 -c $OSTCOUNT $test_kdir ||
11895                 error 'dir setstripe failed'
11896         setfattr -n trusted.lov $test_kdir
11897         local stripe_size=$($LFS getstripe -S $test_kdir)
11898         local stripe_count=$($LFS getstripe -c $test_kdir)
11899         local stripe_offset=$($LFS getstripe -i $test_kdir)
11900         [ $stripe_size -eq $default_size ] ||
11901                 error "stripe size $stripe_size != $default_size"
11902         [ $stripe_count -eq $default_count ] ||
11903                 error "stripe count $stripe_count != $default_count"
11904         [ $stripe_offset -eq $default_offset ] ||
11905                 error "stripe offset $stripe_offset != $default_offset"
11906         rm -rf $DIR/$tfile $test_kdir
11907 }
11908 run_test 102k "setfattr without parameter of value shouldn't cause a crash"
11909
11910 test_102l() {
11911         [ -z "$(which getfattr 2>/dev/null)" ] &&
11912                 skip "could not find getfattr"
11913
11914         # LU-532 trusted. xattr is invisible to non-root
11915         local testfile=$DIR/$tfile
11916
11917         touch $testfile
11918
11919         echo "listxattr as user..."
11920         chown $RUNAS_ID $testfile
11921         $RUNAS getfattr -d -m '.*' $testfile 2>&1 |
11922             grep -q "trusted" &&
11923                 error "$testfile trusted xattrs are user visible"
11924
11925         return 0;
11926 }
11927 run_test 102l "listxattr size test =================================="
11928
11929 test_102m() { # LU-3403 llite: error of listxattr when buffer is small
11930         local path=$DIR/$tfile
11931         touch $path
11932
11933         listxattr_size_check $path || error "listattr_size_check $path failed"
11934 }
11935 run_test 102m "Ensure listxattr fails on small bufffer ========"
11936
11937 cleanup_test102
11938
11939 getxattr() { # getxattr path name
11940         # Return the base64 encoding of the value of xattr name on path.
11941         local path=$1
11942         local name=$2
11943
11944         # # getfattr --absolute-names --encoding=base64 --name=trusted.lov $path
11945         # file: $path
11946         # trusted.lov=0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
11947         #
11948         # We print just 0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
11949
11950         getfattr --absolute-names --encoding=base64 --name=$name $path |
11951                 awk -F= -v name=$name '$1 == name {
11952                         print substr($0, index($0, "=") + 1);
11953         }'
11954 }
11955
11956 test_102n() { # LU-4101 mdt: protect internal xattrs
11957         [ -z "$(which setfattr 2>/dev/null)" ] &&
11958                 skip "could not find setfattr"
11959         if [ $MDS1_VERSION -lt $(version_code 2.5.50) ]
11960         then
11961                 skip "MDT < 2.5.50 allows setxattr on internal trusted xattrs"
11962         fi
11963
11964         local file0=$DIR/$tfile.0
11965         local file1=$DIR/$tfile.1
11966         local xattr0=$TMP/$tfile.0
11967         local xattr1=$TMP/$tfile.1
11968         local namelist="lov lma lmv link fid version som hsm"
11969         local name
11970         local value
11971
11972         rm -rf $file0 $file1 $xattr0 $xattr1
11973         touch $file0 $file1
11974
11975         # Get 'before' xattrs of $file1.
11976         getfattr --absolute-names --dump --match=- $file1 > $xattr0
11977
11978         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
11979                 namelist+=" lfsck_namespace"
11980         for name in $namelist; do
11981                 # Try to copy xattr from $file0 to $file1.
11982                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
11983
11984                 setfattr --name=trusted.$name --value="$value" $file1 ||
11985                         error "setxattr 'trusted.$name' failed"
11986
11987                 # Try to set a garbage xattr.
11988                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
11989
11990                 if [[ x$name == "xlov" ]]; then
11991                         setfattr --name=trusted.lov --value="$value" $file1 &&
11992                         error "setxattr invalid 'trusted.lov' success"
11993                 else
11994                         setfattr --name=trusted.$name --value="$value" $file1 ||
11995                                 error "setxattr invalid 'trusted.$name' failed"
11996                 fi
11997
11998                 # Try to remove the xattr from $file1. We don't care if this
11999                 # appears to succeed or fail, we just don't want there to be
12000                 # any changes or crashes.
12001                 setfattr --remove=$trusted.$name $file1 2> /dev/null
12002         done
12003
12004         if [ $MDS1_VERSION -gt $(version_code 2.6.50) ]
12005         then
12006                 name="lfsck_ns"
12007                 # Try to copy xattr from $file0 to $file1.
12008                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
12009
12010                 setfattr --name=trusted.$name --value="$value" $file1 ||
12011                         error "setxattr 'trusted.$name' failed"
12012
12013                 # Try to set a garbage xattr.
12014                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
12015
12016                 setfattr --name=trusted.$name --value="$value" $file1 ||
12017                         error "setxattr 'trusted.$name' failed"
12018
12019                 # Try to remove the xattr from $file1. We don't care if this
12020                 # appears to succeed or fail, we just don't want there to be
12021                 # any changes or crashes.
12022                 setfattr --remove=$trusted.$name $file1 2> /dev/null
12023         fi
12024
12025         # Get 'after' xattrs of file1.
12026         getfattr --absolute-names --dump --match=- $file1 > $xattr1
12027
12028         if ! diff $xattr0 $xattr1; then
12029                 error "before and after xattrs of '$file1' differ"
12030         fi
12031
12032         rm -rf $file0 $file1 $xattr0 $xattr1
12033
12034         return 0
12035 }
12036 run_test 102n "silently ignore setxattr on internal trusted xattrs"
12037
12038 test_102p() { # LU-4703 setxattr did not check ownership
12039         [ $MDS1_VERSION -lt $(version_code 2.5.56) ] &&
12040                 skip "MDS needs to be at least 2.5.56"
12041
12042         local testfile=$DIR/$tfile
12043
12044         touch $testfile
12045
12046         echo "setfacl as user..."
12047         $RUNAS setfacl -m "u:$RUNAS_ID:rwx" $testfile
12048         [ $? -ne 0 ] || error "setfacl by $RUNAS_ID was allowed on $testfile"
12049
12050         echo "setfattr as user..."
12051         setfacl -m "u:$RUNAS_ID:---" $testfile
12052         $RUNAS setfattr -x system.posix_acl_access $testfile
12053         [ $? -ne 0 ] || error "setfattr by $RUNAS_ID was allowed on $testfile"
12054 }
12055 run_test 102p "check setxattr(2) correctly fails without permission"
12056
12057 test_102q() {
12058         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] &&
12059                 skip "MDS needs to be at least 2.6.92"
12060
12061         orphan_linkea_check $DIR/$tfile || error "orphan_linkea_check"
12062 }
12063 run_test 102q "flistxattr should not return trusted.link EAs for orphans"
12064
12065 test_102r() {
12066         [ $MDS1_VERSION -lt $(version_code 2.6.93) ] &&
12067                 skip "MDS needs to be at least 2.6.93"
12068
12069         touch $DIR/$tfile || error "touch"
12070         setfattr -n user.$(basename $tfile) $DIR/$tfile || error "setfattr"
12071         getfattr -n user.$(basename $tfile) $DIR/$tfile || error "getfattr"
12072         rm $DIR/$tfile || error "rm"
12073
12074         #normal directory
12075         mkdir -p $DIR/$tdir || error "mkdir"
12076         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
12077         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
12078         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
12079                 error "$testfile error deleting user.author1"
12080         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
12081                 grep "user.$(basename $tdir)" &&
12082                 error "$tdir did not delete user.$(basename $tdir)"
12083         rmdir $DIR/$tdir || error "rmdir"
12084
12085         #striped directory
12086         test_mkdir $DIR/$tdir
12087         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
12088         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
12089         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
12090                 error "$testfile error deleting user.author1"
12091         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
12092                 grep "user.$(basename $tdir)" &&
12093                 error "$tdir did not delete user.$(basename $tdir)"
12094         rmdir $DIR/$tdir || error "rm striped dir"
12095 }
12096 run_test 102r "set EAs with empty values"
12097
12098 test_102s() {
12099         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
12100                 skip "MDS needs to be at least 2.11.52"
12101
12102         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
12103
12104         save_lustre_params client "llite.*.xattr_cache" > $save
12105
12106         for cache in 0 1; do
12107                 lctl set_param llite.*.xattr_cache=$cache
12108
12109                 rm -f $DIR/$tfile
12110                 touch $DIR/$tfile || error "touch"
12111                 for prefix in lustre security system trusted user; do
12112                         # Note getxattr() may fail with 'Operation not
12113                         # supported' or 'No such attribute' depending
12114                         # on prefix and cache.
12115                         getfattr -n $prefix.n102s $DIR/$tfile &&
12116                                 error "getxattr '$prefix.n102s' should fail (cache = $cache)"
12117                 done
12118         done
12119
12120         restore_lustre_params < $save
12121 }
12122 run_test 102s "getting nonexistent xattrs should fail"
12123
12124 test_102t() {
12125         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
12126                 skip "MDS needs to be at least 2.11.52"
12127
12128         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
12129
12130         save_lustre_params client "llite.*.xattr_cache" > $save
12131
12132         for cache in 0 1; do
12133                 lctl set_param llite.*.xattr_cache=$cache
12134
12135                 for buf_size in 0 256; do
12136                         rm -f $DIR/$tfile
12137                         touch $DIR/$tfile || error "touch"
12138                         setfattr -n user.multiop $DIR/$tfile
12139                         $MULTIOP $DIR/$tfile oa$buf_size ||
12140                                 error "cannot get zero length xattr value (buf_size = $buf_size)"
12141                 done
12142         done
12143
12144         restore_lustre_params < $save
12145 }
12146 run_test 102t "zero length xattr values handled correctly"
12147
12148 run_acl_subtest()
12149 {
12150         local test=$LUSTRE/tests/acl/$1.test
12151         local tmp=$(mktemp -t $1-XXXXXX).test
12152         local bin=$2
12153         local dmn=$3
12154         local grp=$4
12155         local nbd=$5
12156         export LANG=C
12157
12158
12159         local sedusers="-e s/bin/$bin/g -e s/daemon/$dmn/g"
12160         local sedgroups="-e s/:users/:$grp/g"
12161         [[ -z "$nbd" ]] || sedusers+=" -e s/nobody/$nbd/g"
12162
12163         sed $sedusers $sedgroups < $test > $tmp
12164         stack_trap "rm -f $tmp"
12165         [[ -s $tmp ]] || error "sed failed to create test script"
12166
12167         echo "performing $1 with bin='$bin' daemon='$dmn' users='$grp'..."
12168         $LUSTRE/tests/acl/run $tmp || error "run_acl_subtest '$1' failed"
12169 }
12170
12171 test_103a() {
12172         [ "$UID" != 0 ] && skip "must run as root"
12173         $GSS && skip_env "could not run under gss"
12174         [[ "$(lctl get_param -n mdc.*-mdc-*.connect_flags)" =~ "acl" ]] ||
12175                 skip_env "must have acl enabled"
12176         which setfacl || skip_env "could not find setfacl"
12177         remote_mds_nodsh && skip "remote MDS with nodsh"
12178
12179         ACLBIN=${ACLBIN:-"bin"}
12180         ACLDMN=${ACLDMN:-"daemon"}
12181         ACLGRP=${ACLGRP:-"users"}
12182         ACLNBD=${ACLNBD:-"nobody"}
12183
12184         if ! id $ACLBIN ||
12185            [[ "$(id -u $ACLBIN)" != "$(do_facet mds1 id -u $ACLBIN)" ]]; then
12186                 echo "bad 'bin' user '$ACLBIN', using '$USER0'"
12187                 ACLBIN=$USER0
12188                 if ! id $ACLBIN ; then
12189                         cat /etc/passwd
12190                         skip_env "can't find suitable ACL 'bin' $ACLBIN"
12191                 fi
12192         fi
12193         if ! id $ACLDMN || (( $(id -u $ACLDMN) < $(id -u $ACLBIN) )) ||
12194            [[ "$(id -u $ACLDMN)" != "$(do_facet mds1 id -u $ACLDMN)" ]]; then
12195                 echo "bad 'daemon' user '$ACLDMN', using '$USER1'"
12196                 ACLDMN=$USER1
12197                 if ! id $ACLDMN ; then
12198                         cat /etc/passwd
12199                         skip_env "can't find suitable ACL 'daemon' $ACLDMN"
12200                 fi
12201         fi
12202         if ! getent group $ACLGRP; then
12203                 echo "missing 'users' group '$ACLGRP', using '$TSTUSR'"
12204                 ACLGRP="$TSTUSR"
12205                 if ! getent group $ACLGRP; then
12206                         echo "cannot find group '$ACLGRP', adding it"
12207                         cat /etc/group
12208                         add_group 60000 $ACLGRP
12209                 fi
12210         fi
12211
12212         local bingid=$(getent group $ACLBIN | cut -d: -f 3)
12213         local dmngid=$(getent group $ACLDMN | cut -d: -f 3)
12214         local grpgid=$(getent group $ACLGRP | cut -d: -f 3)
12215
12216         if (( $bingid > $grpgid || $dmngid > $grpgid )); then
12217                 echo "group '$ACLGRP' has low gid=$grpgid, use '$TSTUSR'"
12218                 ACLGRP="$TSTUSR"
12219                 if ! getent group $ACLGRP; then
12220                         echo "cannot find group '$ACLGRP', adding it"
12221                         cat /etc/group
12222                         add_group 60000 $ACLGRP
12223                 fi
12224                 grpgid=$(getent group $ACLGRP | cut -d: -f 3)
12225                 if (( $bingid > $grpgid || $dmngid > $grpgid )); then
12226                         cat /etc/group
12227                         skip_env "$ACLGRP gid=$grpgid less than $bingid|$dmngid"
12228                 fi
12229         fi
12230
12231         gpasswd -a $ACLDMN $ACLBIN ||
12232                 error "setting client group failed"             # LU-5641
12233         do_facet mds1 gpasswd -a $ACLDMN $ACLBIN ||
12234                 error "setting MDS group failed"                # LU-5641
12235
12236         declare -a identity_old
12237
12238         for num in $(seq $MDSCOUNT); do
12239                 switch_identity $num true || identity_old[$num]=$?
12240         done
12241
12242         SAVE_UMASK=$(umask)
12243         umask 0022
12244         mkdir -p $DIR/$tdir
12245         cd $DIR/$tdir
12246
12247         run_acl_subtest cp $ACLBIN $ACLDMN $ACLGRP
12248         run_acl_subtest getfacl-noacl $ACLBIN $ACLDMN $ACLGRP
12249         run_acl_subtest misc $ACLBIN $ACLDMN $ACLGRP
12250         run_acl_subtest permissions $ACLBIN $ACLDMN $ACLGRP
12251         # LU-1482 mdd: Setting xattr are properly checked with and without ACLs
12252         # CentOS7- uses nobody=99, while newer distros use nobody=65534
12253         if ! id -u $ACLNBD ||
12254            (( $(id -u nobody) != $(do_facet mds1 id -u nobody) )); then
12255                 ACLNBD="nfsnobody"
12256                 if ! id -u $ACLNBD; then
12257                         ACLNBD=""
12258                 fi
12259         fi
12260         if [[ -n "$ACLNBD" ]] && ! getent group $ACLNBD; then
12261                 add_group $(id -u $ACLNBD) $ACLNBD
12262                 if ! getent group $ACLNBD; then
12263                         ACLNBD=""
12264                 fi
12265         fi
12266         if (( $MDS1_VERSION > $(version_code 2.8.55) )) &&
12267            [[ -n "$ACLNBD" ]] && which setfattr; then
12268                 run_acl_subtest permissions_xattr \
12269                         $ACLBIN $ACLDMN $ACLGRP $ACLNBD
12270         elif [[ -z "$ACLNBD" ]]; then
12271                 echo "skip 'permission_xattr' test - missing 'nobody' user/grp"
12272         else
12273                 echo "skip 'permission_xattr' test - missing setfattr command"
12274         fi
12275         run_acl_subtest setfacl $ACLBIN $ACLDMN $ACLGRP
12276
12277         # inheritance test got from HP
12278         cp $LUSTRE/tests/acl/make-tree . || error "cannot copy make-tree"
12279         chmod +x make-tree || error "chmod +x failed"
12280         run_acl_subtest inheritance $ACLBIN $ACLDMN $ACLGRP
12281         rm -f make-tree
12282
12283         echo "LU-974 ignore umask when acl is enabled..."
12284         run_acl_subtest 974 $ACLBIN $ACLDMN $ACLGRP
12285         if [ $MDSCOUNT -ge 2 ]; then
12286                 run_acl_subtest 974_remote $ACLBIN $ACLDMN $ACLGRP
12287         fi
12288
12289         echo "LU-2561 newly created file is same size as directory..."
12290         if [ "$mds1_FSTYPE" != "zfs" ]; then
12291                 run_acl_subtest 2561 $ACLBIN $ACLDMN $ACLGRP
12292         else
12293                 run_acl_subtest 2561_zfs $ACLBIN $ACLDMN $ACLGRP
12294         fi
12295
12296         run_acl_subtest 4924 $ACLBIN $ACLDMN $ACLGRP
12297
12298         cd $SAVE_PWD
12299         umask $SAVE_UMASK
12300
12301         for num in $(seq $MDSCOUNT); do
12302                 if [ "${identity_old[$num]}" = 1 ]; then
12303                         switch_identity $num false || identity_old[$num]=$?
12304                 fi
12305         done
12306 }
12307 run_test 103a "acl test"
12308
12309 test_103b() {
12310         declare -a pids
12311         local U
12312
12313         stack_trap "rm -f $DIR/$tfile.*"
12314         for U in {0..511}; do
12315                 {
12316                 local O=$(printf "%04o" $U)
12317
12318                 umask $(printf "%04o" $((511 ^ $O)))
12319                 $LFS setstripe -c 1 $DIR/$tfile.s$O
12320                 local S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.s$O))
12321
12322                 (( $S == ($O & 0666) )) ||
12323                         error "lfs setstripe $DIR/$tfile.s$O '$S' != '$O'"
12324
12325                 $LFS setstripe -E16M -c 1 -E1G -S4M $DIR/$tfile.p$O
12326                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.p$O))
12327                 (( $S == ($O & 0666) )) ||
12328                         error "lfs setstripe -E $DIR/$tfile.p$O '$S' != '$O'"
12329
12330                 $LFS setstripe -N2 -c 1 $DIR/$tfile.m$O
12331                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.m$O))
12332                 (( $S == ($O & 0666) )) ||
12333                         error "lfs setstripe -N2 $DIR/$tfile.m$O '$S' != '$O'"
12334                 rm -f $DIR/$tfile.[smp]$0
12335                 } &
12336                 local pid=$!
12337
12338                 # limit the concurrently running threads to 64. LU-11878
12339                 local idx=$((U % 64))
12340                 [ -z "${pids[idx]}" ] || wait ${pids[idx]}
12341                 pids[idx]=$pid
12342         done
12343         wait
12344 }
12345 run_test 103b "umask lfs setstripe"
12346
12347 test_103c() {
12348         mkdir -p $DIR/$tdir
12349         cp -rp $DIR/$tdir $DIR/$tdir.bak
12350
12351         [ -n "$(getfattr -d -m. $DIR/$tdir | grep posix_acl_default)" ] &&
12352                 error "$DIR/$tdir shouldn't contain default ACL"
12353         [ -n "$(getfattr -d -m. $DIR/$tdir.bak | grep posix_acl_default)" ] &&
12354                 error "$DIR/$tdir.bak shouldn't contain default ACL"
12355         true
12356 }
12357 run_test 103c "'cp -rp' won't set empty acl"
12358
12359 test_103e() {
12360         local numacl
12361         local fileacl
12362         local saved_debug=$($LCTL get_param -n debug)
12363
12364         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
12365                 skip "MDS needs to be at least 2.14.52"
12366
12367         large_xattr_enabled || skip_env "ea_inode feature disabled"
12368
12369         mkdir -p $DIR/$tdir
12370         # add big LOV EA to cause reply buffer overflow earlier
12371         $LFS setstripe -C 1000 $DIR/$tdir
12372         lctl set_param mdc.*-mdc*.stats=clear
12373
12374         $LCTL set_param debug=0
12375         stack_trap "$LCTL set_param debug=\"$saved_debug\"" EXIT
12376         stack_trap "$LCTL get_param mdc.*-mdc*.stats" EXIT
12377
12378         # add a large number of default ACLs (expect 8000+ for 2.13+)
12379         for U in {2..7000}; do
12380                 setfacl -d -m user:$U:rwx $DIR/$tdir ||
12381                         error "Able to add just $U default ACLs"
12382         done
12383         numacl=$(getfacl $DIR/$tdir |& grep -c "default:user")
12384         echo "$numacl default ACLs created"
12385
12386         stat $DIR/$tdir || error "Cannot stat directory"
12387         # check file creation
12388         touch $DIR/$tdir/$tfile ||
12389                 error "failed to create $tfile with $numacl default ACLs"
12390         stat $DIR/$tdir/$tfile  || error "Cannot stat file"
12391         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
12392         echo "$fileacl ACLs were inherited"
12393         (( $fileacl == $numacl )) ||
12394                 error "Not all default ACLs were inherited: $numacl != $fileacl"
12395         # check that new ACLs creation adds new ACLs to inherited ACLs
12396         setfacl -m user:19000:rwx $DIR/$tdir/$tfile ||
12397                 error "Cannot set new ACL"
12398         numacl=$((numacl + 1))
12399         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
12400         (( $fileacl == $numacl )) ||
12401                 error "failed to add new ACL: $fileacl != $numacl as expected"
12402         # adds more ACLs to a file to reach their maximum at 8000+
12403         numacl=0
12404         for U in {20000..25000}; do
12405                 setfacl -m user:$U:rwx $DIR/$tdir/$tfile || break
12406                 numacl=$((numacl + 1))
12407         done
12408         echo "Added $numacl more ACLs to the file"
12409         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
12410         echo "Total $fileacl ACLs in file"
12411         stat $DIR/$tdir/$tfile > /dev/null || error "Cannot stat file"
12412         rm -f $DIR/$tdir/$tfile || error "Cannot remove file"
12413         rmdir $DIR/$tdir || error "Cannot remove directory"
12414 }
12415 run_test 103e "inheritance of big amount of default ACLs"
12416
12417 test_103f() {
12418         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
12419                 skip "MDS needs to be at least 2.14.51"
12420
12421         large_xattr_enabled || skip_env "ea_inode feature disabled"
12422
12423         # enable changelog to consume more internal MDD buffers
12424         changelog_register
12425
12426         mkdir -p $DIR/$tdir
12427         # add big LOV EA
12428         $LFS setstripe -C 1000 $DIR/$tdir
12429         setfacl -d -m user:$U:rwx $DIR/$tdir || error "Cannot add default ACLs"
12430         mkdir $DIR/$tdir/inherited || error "failed to create subdirectory"
12431         rmdir $DIR/$tdir/inherited || error "Cannot remove subdirectory"
12432         rmdir $DIR/$tdir || error "Cannot remove directory"
12433 }
12434 run_test 103f "changelog doesn't interfere with default ACLs buffers"
12435
12436 test_104a() {
12437         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12438
12439         touch $DIR/$tfile
12440         lfs df || error "lfs df failed"
12441         lfs df -ih || error "lfs df -ih failed"
12442         lfs df -h $DIR || error "lfs df -h $DIR failed"
12443         lfs df -i $DIR || error "lfs df -i $DIR failed"
12444         lfs df $DIR/$tfile || error "lfs df $DIR/$tfile failed"
12445         lfs df -ih $DIR/$tfile || error "lfs df -ih $DIR/$tfile failed"
12446
12447         local OSC=$(lctl dl | grep OST0000-osc-[^M] | awk '{ print $4 }')
12448         lctl --device %$OSC deactivate
12449         lfs df || error "lfs df with deactivated OSC failed"
12450         lctl --device %$OSC activate
12451         # wait the osc back to normal
12452         wait_osc_import_ready client ost
12453
12454         lfs df || error "lfs df with reactivated OSC failed"
12455         rm -f $DIR/$tfile
12456 }
12457 run_test 104a "lfs df [-ih] [path] test ========================="
12458
12459 test_104b() {
12460         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12461         [ $RUNAS_ID -eq $UID ] &&
12462                 skip_env "RUNAS_ID = UID = $UID -- skipping"
12463
12464         denied_cnt=$(($($RUNAS $LFS check servers 2>&1 |
12465                         grep "Permission denied" | wc -l)))
12466         if [ $denied_cnt -ne 0 ]; then
12467                 error "lfs check servers test failed"
12468         fi
12469 }
12470 run_test 104b "$RUNAS lfs check servers test ===================="
12471
12472 #
12473 # Verify $1 is within range of $2.
12474 # Success when $1 is within range. That is, when $1 is >= 2% of $2 and
12475 # $1 is <= 2% of $2. Else Fail.
12476 #
12477 value_in_range() {
12478         # Strip all units (M, G, T)
12479         actual=$(echo $1 | tr -d A-Z)
12480         expect=$(echo $2 | tr -d A-Z)
12481
12482         expect_lo=$(($expect * 98 / 100)) # 2% below
12483         expect_hi=$(($expect * 102 / 100)) # 2% above
12484
12485         # permit 2% drift above and below
12486         (( $actual >= $expect_lo && $actual <= $expect_hi ))
12487 }
12488
12489 test_104c() {
12490         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12491         [ "$ost1_FSTYPE" == "zfs" ] || skip "zfs only test"
12492
12493         local ost_param="osd-zfs.$FSNAME-OST0000."
12494         local mdt_param="osd-zfs.$FSNAME-MDT0000."
12495         local ofacets=$(get_facets OST)
12496         local mfacets=$(get_facets MDS)
12497         local saved_ost_blocks=
12498         local saved_mdt_blocks=
12499
12500         echo "Before recordsize change"
12501         lfs_df=($($LFS df -h | grep "filesystem_summary:"))
12502         df=($(df -h | grep "$MOUNT"$))
12503
12504         # For checking.
12505         echo "lfs output : ${lfs_df[*]}"
12506         echo "df  output : ${df[*]}"
12507
12508         for facet in ${ofacets//,/ }; do
12509                 if [ -z $saved_ost_blocks ]; then
12510                         saved_ost_blocks=$(do_facet $facet \
12511                                 lctl get_param -n $ost_param.blocksize)
12512                         echo "OST Blocksize: $saved_ost_blocks"
12513                 fi
12514                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
12515                 do_facet $facet zfs set recordsize=32768 $ost
12516         done
12517
12518         # BS too small. Sufficient for functional testing.
12519         for facet in ${mfacets//,/ }; do
12520                 if [ -z $saved_mdt_blocks ]; then
12521                         saved_mdt_blocks=$(do_facet $facet \
12522                                 lctl get_param -n $mdt_param.blocksize)
12523                         echo "MDT Blocksize: $saved_mdt_blocks"
12524                 fi
12525                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
12526                 do_facet $facet zfs set recordsize=32768 $mdt
12527         done
12528
12529         # Give new values chance to reflect change
12530         sleep 2
12531
12532         echo "After recordsize change"
12533         lfs_df_after=($($LFS df -h | grep "filesystem_summary:"))
12534         df_after=($(df -h | grep "$MOUNT"$))
12535
12536         # For checking.
12537         echo "lfs output : ${lfs_df_after[*]}"
12538         echo "df  output : ${df_after[*]}"
12539
12540         # Verify lfs df
12541         value_in_range ${lfs_df_after[1]%.*} ${lfs_df[1]%.*} ||
12542                 error "lfs_df bytes: ${lfs_df_after[1]%.*} != ${lfs_df[1]%.*}"
12543         value_in_range ${lfs_df_after[2]%.*} ${lfs_df[2]%.*} ||
12544                 error "lfs_df used: ${lfs_df_after[2]%.*} != ${lfs_df[2]%.*}"
12545         value_in_range ${lfs_df_after[3]%.*} ${lfs_df[3]%.*} ||
12546                 error "lfs_df avail: ${lfs_df_after[3]%.*} != ${lfs_df[3]%.*}"
12547
12548         # Verify df
12549         value_in_range ${df_after[1]%.*} ${df[1]%.*} ||
12550                 error "df bytes: ${df_after[1]%.*} != ${df[1]%.*}"
12551         value_in_range ${df_after[2]%.*} ${df[2]%.*} ||
12552                 error "df used: ${df_after[2]%.*} != ${df[2]%.*}"
12553         value_in_range ${df_after[3]%.*} ${df[3]%.*} ||
12554                 error "df avail: ${df_after[3]%.*} != ${df[3]%.*}"
12555
12556         # Restore MDT recordize back to original
12557         for facet in ${mfacets//,/ }; do
12558                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
12559                 do_facet $facet zfs set recordsize=$saved_mdt_blocks $mdt
12560         done
12561
12562         # Restore OST recordize back to original
12563         for facet in ${ofacets//,/ }; do
12564                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
12565                 do_facet $facet zfs set recordsize=$saved_ost_blocks $ost
12566         done
12567
12568         return 0
12569 }
12570 run_test 104c "Verify df vs lfs_df stays same after recordsize change"
12571
12572 test_104d() {
12573         (( $RUNAS_ID != $UID )) ||
12574                 skip_env "RUNAS_ID = UID = $UID -- skipping"
12575
12576         (( $CLIENT_VERSION >= $(version_code 2.15.51) )) ||
12577                 skip "lustre version doesn't support lctl dl with non-root"
12578
12579         # debugfs only allows root users to access files, so the
12580         # previous move of the "devices" file to debugfs broke
12581         # "lctl dl" for non-root users. The LU-9680 Netlink
12582         # interface again allows non-root users to list devices.
12583         [ "$($RUNAS $LCTL dl | wc -l)" -ge 3 ] ||
12584                 error "lctl dl doesn't work for non root"
12585
12586         ost_count="$($RUNAS $LCTL dl | grep $FSNAME-OST* | wc -l)"
12587         [ "$ost_count" -eq $OSTCOUNT ]  ||
12588                 error "lctl dl reports wrong number of OST devices"
12589
12590         mdt_count="$($RUNAS $LCTL dl | grep $FSNAME-MDT* | wc -l)"
12591         [ "$mdt_count" -eq $MDSCOUNT ]  ||
12592                 error "lctl dl reports wrong number of MDT devices"
12593 }
12594 run_test 104d "$RUNAS lctl dl test"
12595
12596 test_105a() {
12597         # doesn't work on 2.4 kernels
12598         touch $DIR/$tfile
12599         if $(flock_is_enabled); then
12600                 flocks_test 1 on -f $DIR/$tfile || error "fail flock on"
12601         else
12602                 flocks_test 1 off -f $DIR/$tfile || error "fail flock off"
12603         fi
12604         rm -f $DIR/$tfile
12605 }
12606 run_test 105a "flock when mounted without -o flock test ========"
12607
12608 test_105b() {
12609         touch $DIR/$tfile
12610         if $(flock_is_enabled); then
12611                 flocks_test 1 on -c $DIR/$tfile || error "fail flock on"
12612         else
12613                 flocks_test 1 off -c $DIR/$tfile || error "fail flock off"
12614         fi
12615         rm -f $DIR/$tfile
12616 }
12617 run_test 105b "fcntl when mounted without -o flock test ========"
12618
12619 test_105c() {
12620         touch $DIR/$tfile
12621         if $(flock_is_enabled); then
12622                 flocks_test 1 on -l $DIR/$tfile || error "fail flock on"
12623         else
12624                 flocks_test 1 off -l $DIR/$tfile || error "fail flock off"
12625         fi
12626         rm -f $DIR/$tfile
12627 }
12628 run_test 105c "lockf when mounted without -o flock test"
12629
12630 test_105d() { # bug 15924
12631         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12632
12633         test_mkdir $DIR/$tdir
12634         flock_is_enabled || skip_env "mount w/o flock enabled"
12635         #define OBD_FAIL_LDLM_CP_CB_WAIT  0x315
12636         $LCTL set_param fail_loc=0x80000315
12637         flocks_test 2 $DIR/$tdir
12638 }
12639 run_test 105d "flock race (should not freeze) ========"
12640
12641 test_105e() { # bug 22660 && 22040
12642         flock_is_enabled || skip_env "mount w/o flock enabled"
12643
12644         touch $DIR/$tfile
12645         flocks_test 3 $DIR/$tfile
12646 }
12647 run_test 105e "Two conflicting flocks from same process"
12648
12649 test_106() { #bug 10921
12650         test_mkdir $DIR/$tdir
12651         $DIR/$tdir && error "exec $DIR/$tdir succeeded"
12652         chmod 777 $DIR/$tdir || error "chmod $DIR/$tdir failed"
12653 }
12654 run_test 106 "attempt exec of dir followed by chown of that dir"
12655
12656 test_107() {
12657         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12658
12659         CDIR=`pwd`
12660         local file=core
12661
12662         cd $DIR
12663         rm -f $file
12664
12665         local save_pattern=$(sysctl -n kernel.core_pattern)
12666         local save_uses_pid=$(sysctl -n kernel.core_uses_pid)
12667         sysctl -w kernel.core_pattern=$file
12668         sysctl -w kernel.core_uses_pid=0
12669
12670         ulimit -c unlimited
12671         sleep 60 &
12672         SLEEPPID=$!
12673
12674         sleep 1
12675
12676         kill -s 11 $SLEEPPID
12677         wait $SLEEPPID
12678         if [ -e $file ]; then
12679                 size=`stat -c%s $file`
12680                 [ $size -eq 0 ] && error "Fail to create core file $file"
12681         else
12682                 error "Fail to create core file $file"
12683         fi
12684         rm -f $file
12685         sysctl -w kernel.core_pattern=$save_pattern
12686         sysctl -w kernel.core_uses_pid=$save_uses_pid
12687         cd $CDIR
12688 }
12689 run_test 107 "Coredump on SIG"
12690
12691 test_110() {
12692         test_mkdir $DIR/$tdir
12693         test_mkdir $DIR/$tdir/$(str_repeat 'a' 255)
12694         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/$(str_repeat 'b' 256) &&
12695                 error "mkdir with 256 char should fail, but did not"
12696         touch $DIR/$tdir/$(str_repeat 'x' 255) ||
12697                 error "create with 255 char failed"
12698         touch $DIR/$tdir/$(str_repeat 'y' 256) &&
12699                 error "create with 256 char should fail, but did not"
12700
12701         ls -l $DIR/$tdir
12702         rm -rf $DIR/$tdir
12703 }
12704 run_test 110 "filename length checking"
12705
12706 test_116a() { # was previously test_116()
12707         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12708         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12709         remote_mds_nodsh && skip "remote MDS with nodsh"
12710
12711         echo -n "Free space priority "
12712         do_facet $SINGLEMDS lctl get_param -n lo[vd].*-mdtlov.qos_prio_free |
12713                 head -n1
12714         declare -a AVAIL
12715         free_min_max
12716
12717         [ $MINV -eq 0 ] && skip "no free space in OST$MINI, skip"
12718         [ $MINV -gt 10000000 ] && skip "too much free space in OST$MINI, skip"
12719         stack_trap simple_cleanup_common
12720
12721         # Check if we need to generate uneven OSTs
12722         test_mkdir -p $DIR/$tdir/OST${MINI}
12723         local FILL=$((MINV / 4))
12724         local DIFF=$((MAXV - MINV))
12725         local DIFF2=$((DIFF * 100 / MINV))
12726
12727         local threshold=$(do_facet $SINGLEMDS \
12728                 lctl get_param -n *.*MDT0000-mdtlov.qos_threshold_rr | head -n1)
12729         threshold=${threshold%%%}
12730         echo -n "Check for uneven OSTs: "
12731         echo -n "diff=${DIFF}KB (${DIFF2}%) must be > ${threshold}% ..."
12732
12733         if [[ $DIFF2 -gt $threshold ]]; then
12734                 echo "ok"
12735                 echo "Don't need to fill OST$MINI"
12736         else
12737                 # generate uneven OSTs. Write 2% over the QOS threshold value
12738                 echo "no"
12739                 DIFF=$((threshold - DIFF2 + 2))
12740                 DIFF2=$((MINV * DIFF / 100))
12741                 echo "Fill $DIFF% remaining space in OST$MINI with ${DIFF2}KB"
12742                 $LFS setstripe -i $MINI -c 1 $DIR/$tdir/OST${MINI} ||
12743                         error "setstripe failed"
12744                 DIFF=$((DIFF2 / 2048))
12745                 i=0
12746                 while [ $i -lt $DIFF ]; do
12747                         i=$((i + 1))
12748                         dd if=/dev/zero of=$DIR/$tdir/OST${MINI}/$tfile-$i \
12749                                 bs=2M count=1 2>/dev/null
12750                         echo -n .
12751                 done
12752                 echo .
12753                 sync
12754                 sleep_maxage
12755                 free_min_max
12756         fi
12757
12758         DIFF=$((MAXV - MINV))
12759         DIFF2=$((DIFF * 100 / MINV))
12760         echo -n "diff=$DIFF=$DIFF2% must be > $threshold% for QOS mode..."
12761         if [ $DIFF2 -gt $threshold ]; then
12762                 echo "ok"
12763         else
12764                 skip "QOS imbalance criteria not met"
12765         fi
12766
12767         MINI1=$MINI
12768         MINV1=$MINV
12769         MAXI1=$MAXI
12770         MAXV1=$MAXV
12771
12772         # now fill using QOS
12773         $LFS setstripe -c 1 $DIR/$tdir
12774         FILL=$((FILL / 200))
12775         if [ $FILL -gt 600 ]; then
12776                 FILL=600
12777         fi
12778         echo "writing $FILL files to QOS-assigned OSTs"
12779         i=0
12780         while [ $i -lt $FILL ]; do
12781                 i=$((i + 1))
12782                 dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=200k \
12783                         count=1 2>/dev/null
12784                 echo -n .
12785         done
12786         echo "wrote $i 200k files"
12787         sync
12788         sleep_maxage
12789
12790         echo "Note: free space may not be updated, so measurements might be off"
12791         free_min_max
12792         DIFF2=$((MAXV - MINV))
12793         echo "free space delta: orig $DIFF final $DIFF2"
12794         [ $DIFF2 -gt $DIFF ] && echo "delta got worse!"
12795         DIFF=$((MINV1 - ${AVAIL[$MINI1]}))
12796         echo "Wrote ${DIFF}KB to smaller OST $MINI1"
12797         DIFF2=$((MAXV1 - ${AVAIL[$MAXI1]}))
12798         echo "Wrote ${DIFF2}KB to larger OST $MAXI1"
12799         if [[ $DIFF -gt 0 ]]; then
12800                 FILL=$((DIFF2 * 100 / DIFF - 100))
12801                 echo "Wrote ${FILL}% more data to larger OST $MAXI1"
12802         fi
12803
12804         # Figure out which files were written where
12805         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
12806                awk '/'$MINI1': / {print $2; exit}')
12807         echo $UUID
12808         MINC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
12809         echo "$MINC files created on smaller OST $MINI1"
12810         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
12811                awk '/'$MAXI1': / {print $2; exit}')
12812         echo $UUID
12813         MAXC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
12814         echo "$MAXC files created on larger OST $MAXI1"
12815         if [[ $MINC -gt 0 ]]; then
12816                 FILL=$((MAXC * 100 / MINC - 100))
12817                 echo "Wrote ${FILL}% more files to larger OST $MAXI1"
12818         fi
12819         [[ $MAXC -gt $MINC ]] ||
12820                 error_ignore LU-9 "stripe QOS didn't balance free space"
12821 }
12822 run_test 116a "stripe QOS: free space balance ==================="
12823
12824 test_116b() { # LU-2093
12825         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12826         remote_mds_nodsh && skip "remote MDS with nodsh"
12827
12828 #define OBD_FAIL_MDS_OSC_CREATE_FAIL     0x147
12829         local old_rr=$(do_facet $SINGLEMDS lctl get_param -n \
12830                        lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr | head -1)
12831         [ -z "$old_rr" ] && skip "no QOS"
12832         do_facet $SINGLEMDS lctl set_param \
12833                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=0
12834         mkdir -p $DIR/$tdir
12835         do_facet $SINGLEMDS lctl set_param fail_loc=0x147
12836         createmany -o $DIR/$tdir/f- 20 || error "can't create"
12837         do_facet $SINGLEMDS lctl set_param fail_loc=0
12838         rm -rf $DIR/$tdir
12839         do_facet $SINGLEMDS lctl set_param \
12840                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=$old_rr
12841 }
12842 run_test 116b "QoS shouldn't LBUG if not enough OSTs found on the 2nd pass"
12843
12844 test_117() # bug 10891
12845 {
12846         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12847
12848         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
12849         #define OBD_FAIL_OST_SETATTR_CREDITS 0x21e
12850         lctl set_param fail_loc=0x21e
12851         > $DIR/$tfile || error "truncate failed"
12852         lctl set_param fail_loc=0
12853         echo "Truncate succeeded."
12854         rm -f $DIR/$tfile
12855 }
12856 run_test 117 "verify osd extend =========="
12857
12858 NO_SLOW_RESENDCOUNT=4
12859 export OLD_RESENDCOUNT=""
12860 set_resend_count () {
12861         local PROC_RESENDCOUNT="osc.${FSNAME}-OST*-osc-*.resend_count"
12862         OLD_RESENDCOUNT=$(lctl get_param -n $PROC_RESENDCOUNT | head -n1)
12863         lctl set_param -n $PROC_RESENDCOUNT $1
12864         echo resend_count is set to $(lctl get_param -n $PROC_RESENDCOUNT)
12865 }
12866
12867 # for reduce test_118* time (b=14842)
12868 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
12869
12870 # Reset async IO behavior after error case
12871 reset_async() {
12872         FILE=$DIR/reset_async
12873
12874         # Ensure all OSCs are cleared
12875         $LFS setstripe -c -1 $FILE
12876         dd if=/dev/zero of=$FILE bs=64k count=$OSTCOUNT
12877         sync
12878         rm $FILE
12879 }
12880
12881 test_118a() #bug 11710
12882 {
12883         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12884
12885         reset_async
12886
12887         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12888         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12889         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
12890
12891         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12892                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12893                 return 1;
12894         fi
12895         rm -f $DIR/$tfile
12896 }
12897 run_test 118a "verify O_SYNC works =========="
12898
12899 test_118b()
12900 {
12901         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12902         remote_ost_nodsh && skip "remote OST with nodsh"
12903
12904         reset_async
12905
12906         #define OBD_FAIL_SRV_ENOENT 0x217
12907         set_nodes_failloc "$(osts_nodes)" 0x217
12908         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12909         RC=$?
12910         set_nodes_failloc "$(osts_nodes)" 0
12911         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12912         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12913                     grep -c writeback)
12914
12915         if [[ $RC -eq 0 ]]; then
12916                 error "Must return error due to dropped pages, rc=$RC"
12917                 return 1;
12918         fi
12919
12920         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12921                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12922                 return 1;
12923         fi
12924
12925         echo "Dirty pages not leaked on ENOENT"
12926
12927         # Due to the above error the OSC will issue all RPCs syncronously
12928         # until a subsequent RPC completes successfully without error.
12929         $MULTIOP $DIR/$tfile Ow4096yc
12930         rm -f $DIR/$tfile
12931
12932         return 0
12933 }
12934 run_test 118b "Reclaim dirty pages on fatal error =========="
12935
12936 test_118c()
12937 {
12938         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12939
12940         # for 118c, restore the original resend count, LU-1940
12941         [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] &&
12942                                 set_resend_count $OLD_RESENDCOUNT
12943         remote_ost_nodsh && skip "remote OST with nodsh"
12944
12945         reset_async
12946
12947         #define OBD_FAIL_OST_EROFS               0x216
12948         set_nodes_failloc "$(osts_nodes)" 0x216
12949
12950         # multiop should block due to fsync until pages are written
12951         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
12952         MULTIPID=$!
12953         sleep 1
12954
12955         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
12956                 error "Multiop failed to block on fsync, pid=$MULTIPID"
12957         fi
12958
12959         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12960                     grep -c writeback)
12961         if [[ $WRITEBACK -eq 0 ]]; then
12962                 error "No page in writeback, writeback=$WRITEBACK"
12963         fi
12964
12965         set_nodes_failloc "$(osts_nodes)" 0
12966         wait $MULTIPID
12967         RC=$?
12968         if [[ $RC -ne 0 ]]; then
12969                 error "Multiop fsync failed, rc=$RC"
12970         fi
12971
12972         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12973         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12974                     grep -c writeback)
12975         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12976                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12977         fi
12978
12979         rm -f $DIR/$tfile
12980         echo "Dirty pages flushed via fsync on EROFS"
12981         return 0
12982 }
12983 run_test 118c "Fsync blocks on EROFS until dirty pages are flushed =========="
12984
12985 # continue to use small resend count to reduce test_118* time (b=14842)
12986 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
12987
12988 test_118d()
12989 {
12990         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12991         remote_ost_nodsh && skip "remote OST with nodsh"
12992
12993         reset_async
12994
12995         #define OBD_FAIL_OST_BRW_PAUSE_BULK
12996         set_nodes_failloc "$(osts_nodes)" 0x214
12997         # multiop should block due to fsync until pages are written
12998         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
12999         MULTIPID=$!
13000         sleep 1
13001
13002         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
13003                 error "Multiop failed to block on fsync, pid=$MULTIPID"
13004         fi
13005
13006         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13007                     grep -c writeback)
13008         if [[ $WRITEBACK -eq 0 ]]; then
13009                 error "No page in writeback, writeback=$WRITEBACK"
13010         fi
13011
13012         wait $MULTIPID || error "Multiop fsync failed, rc=$?"
13013         set_nodes_failloc "$(osts_nodes)" 0
13014
13015         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13016         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13017                     grep -c writeback)
13018         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13019                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13020         fi
13021
13022         rm -f $DIR/$tfile
13023         echo "Dirty pages gaurenteed flushed via fsync"
13024         return 0
13025 }
13026 run_test 118d "Fsync validation inject a delay of the bulk =========="
13027
13028 test_118f() {
13029         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13030
13031         reset_async
13032
13033         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
13034         lctl set_param fail_loc=0x8000040a
13035
13036         # Should simulate EINVAL error which is fatal
13037         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13038         RC=$?
13039         if [[ $RC -eq 0 ]]; then
13040                 error "Must return error due to dropped pages, rc=$RC"
13041         fi
13042
13043         lctl set_param fail_loc=0x0
13044
13045         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
13046         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13047         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13048                     grep -c writeback)
13049         if [[ $LOCKED -ne 0 ]]; then
13050                 error "Locked pages remain in cache, locked=$LOCKED"
13051         fi
13052
13053         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13054                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13055         fi
13056
13057         rm -f $DIR/$tfile
13058         echo "No pages locked after fsync"
13059
13060         reset_async
13061         return 0
13062 }
13063 run_test 118f "Simulate unrecoverable OSC side error =========="
13064
13065 test_118g() {
13066         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13067
13068         reset_async
13069
13070         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
13071         lctl set_param fail_loc=0x406
13072
13073         # simulate local -ENOMEM
13074         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13075         RC=$?
13076
13077         lctl set_param fail_loc=0
13078         if [[ $RC -eq 0 ]]; then
13079                 error "Must return error due to dropped pages, rc=$RC"
13080         fi
13081
13082         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
13083         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13084         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13085                         grep -c writeback)
13086         if [[ $LOCKED -ne 0 ]]; then
13087                 error "Locked pages remain in cache, locked=$LOCKED"
13088         fi
13089
13090         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13091                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13092         fi
13093
13094         rm -f $DIR/$tfile
13095         echo "No pages locked after fsync"
13096
13097         reset_async
13098         return 0
13099 }
13100 run_test 118g "Don't stay in wait if we got local -ENOMEM  =========="
13101
13102 test_118h() {
13103         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13104         remote_ost_nodsh && skip "remote OST with nodsh"
13105
13106         reset_async
13107
13108         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
13109         set_nodes_failloc "$(osts_nodes)" 0x20e
13110         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
13111         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13112         RC=$?
13113
13114         set_nodes_failloc "$(osts_nodes)" 0
13115         if [[ $RC -eq 0 ]]; then
13116                 error "Must return error due to dropped pages, rc=$RC"
13117         fi
13118
13119         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
13120         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13121         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13122                     grep -c writeback)
13123         if [[ $LOCKED -ne 0 ]]; then
13124                 error "Locked pages remain in cache, locked=$LOCKED"
13125         fi
13126
13127         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13128                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13129         fi
13130
13131         rm -f $DIR/$tfile
13132         echo "No pages locked after fsync"
13133
13134         return 0
13135 }
13136 run_test 118h "Verify timeout in handling recoverables errors  =========="
13137
13138 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
13139
13140 test_118i() {
13141         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13142         remote_ost_nodsh && skip "remote OST with nodsh"
13143
13144         reset_async
13145
13146         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
13147         set_nodes_failloc "$(osts_nodes)" 0x20e
13148
13149         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
13150         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
13151         PID=$!
13152         sleep 5
13153         set_nodes_failloc "$(osts_nodes)" 0
13154
13155         wait $PID
13156         RC=$?
13157         if [[ $RC -ne 0 ]]; then
13158                 error "got error, but should be not, rc=$RC"
13159         fi
13160
13161         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
13162         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13163         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
13164         if [[ $LOCKED -ne 0 ]]; then
13165                 error "Locked pages remain in cache, locked=$LOCKED"
13166         fi
13167
13168         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13169                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13170         fi
13171
13172         rm -f $DIR/$tfile
13173         echo "No pages locked after fsync"
13174
13175         return 0
13176 }
13177 run_test 118i "Fix error before timeout in recoverable error  =========="
13178
13179 [ "$SLOW" = "no" ] && set_resend_count 4
13180
13181 test_118j() {
13182         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13183         remote_ost_nodsh && skip "remote OST with nodsh"
13184
13185         reset_async
13186
13187         #define OBD_FAIL_OST_BRW_WRITE_BULK2     0x220
13188         set_nodes_failloc "$(osts_nodes)" 0x220
13189
13190         # return -EIO from OST
13191         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13192         RC=$?
13193         set_nodes_failloc "$(osts_nodes)" 0x0
13194         if [[ $RC -eq 0 ]]; then
13195                 error "Must return error due to dropped pages, rc=$RC"
13196         fi
13197
13198         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
13199         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13200         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
13201         if [[ $LOCKED -ne 0 ]]; then
13202                 error "Locked pages remain in cache, locked=$LOCKED"
13203         fi
13204
13205         # in recoverable error on OST we want resend and stay until it finished
13206         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13207                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13208         fi
13209
13210         rm -f $DIR/$tfile
13211         echo "No pages locked after fsync"
13212
13213         return 0
13214 }
13215 run_test 118j "Simulate unrecoverable OST side error =========="
13216
13217 test_118k()
13218 {
13219         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13220         remote_ost_nodsh && skip "remote OSTs with nodsh"
13221
13222         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
13223         set_nodes_failloc "$(osts_nodes)" 0x20e
13224         test_mkdir $DIR/$tdir
13225
13226         for ((i=0;i<10;i++)); do
13227                 (dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=1M count=10 || \
13228                         error "dd to $DIR/$tdir/$tfile-$i failed" )&
13229                 SLEEPPID=$!
13230                 sleep 0.500s
13231                 kill $SLEEPPID
13232                 wait $SLEEPPID
13233         done
13234
13235         set_nodes_failloc "$(osts_nodes)" 0
13236         rm -rf $DIR/$tdir
13237 }
13238 run_test 118k "bio alloc -ENOMEM and IO TERM handling ========="
13239
13240 test_118l() # LU-646
13241 {
13242         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13243
13244         test_mkdir $DIR/$tdir
13245         $MULTIOP $DIR/$tdir Dy || error "fsync dir failed"
13246         rm -rf $DIR/$tdir
13247 }
13248 run_test 118l "fsync dir"
13249
13250 test_118m() # LU-3066
13251 {
13252         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13253
13254         test_mkdir $DIR/$tdir
13255         $MULTIOP $DIR/$tdir DY || error "fdatasync dir failed"
13256         rm -rf $DIR/$tdir
13257 }
13258 run_test 118m "fdatasync dir ========="
13259
13260 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
13261
13262 test_118n()
13263 {
13264         local begin
13265         local end
13266
13267         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13268         remote_ost_nodsh && skip "remote OSTs with nodsh"
13269
13270         # Sleep to avoid a cached response.
13271         #define OBD_STATFS_CACHE_SECONDS 1
13272         sleep 2
13273
13274         # Inject a 10 second delay in the OST_STATFS handler.
13275         #define OBD_FAIL_OST_STATFS_DELAY 0x242
13276         set_nodes_failloc "$(osts_nodes)" 0x242
13277
13278         begin=$SECONDS
13279         stat --file-system $MOUNT > /dev/null
13280         end=$SECONDS
13281
13282         set_nodes_failloc "$(osts_nodes)" 0
13283
13284         if ((end - begin > 20)); then
13285             error "statfs took $((end - begin)) seconds, expected 10"
13286         fi
13287 }
13288 run_test 118n "statfs() sends OST_STATFS requests in parallel"
13289
13290 test_119a() # bug 11737
13291 {
13292         BSIZE=$((512 * 1024))
13293         directio write $DIR/$tfile 0 1 $BSIZE
13294         # We ask to read two blocks, which is more than a file size.
13295         # directio will indicate an error when requested and actual
13296         # sizes aren't equeal (a normal situation in this case) and
13297         # print actual read amount.
13298         NOB=`directio read $DIR/$tfile 0 2 $BSIZE | awk '/error/ {print $6}'`
13299         if [ "$NOB" != "$BSIZE" ]; then
13300                 error "read $NOB bytes instead of $BSIZE"
13301         fi
13302         rm -f $DIR/$tfile
13303 }
13304 run_test 119a "Short directIO read must return actual read amount"
13305
13306 test_119b() # bug 11737
13307 {
13308         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
13309
13310         $LFS setstripe -c 2 $DIR/$tfile || error "setstripe failed"
13311         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1 || error "dd failed"
13312         sync
13313         $MULTIOP $DIR/$tfile oO_RDONLY:O_DIRECT:r$((2048 * 1024)) ||
13314                 error "direct read failed"
13315         rm -f $DIR/$tfile
13316 }
13317 run_test 119b "Sparse directIO read must return actual read amount"
13318
13319 test_119c() # bug 13099
13320 {
13321         BSIZE=1048576
13322         directio write $DIR/$tfile 3 1 $BSIZE || error "direct write failed"
13323         directio readhole $DIR/$tfile 0 2 $BSIZE || error "reading hole failed"
13324         rm -f $DIR/$tfile
13325 }
13326 run_test 119c "Testing for direct read hitting hole"
13327
13328 test_120a() {
13329         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13330         remote_mds_nodsh && skip "remote MDS with nodsh"
13331         test_mkdir -i0 -c1 $DIR/$tdir
13332         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13333                 skip_env "no early lock cancel on server"
13334
13335         lru_resize_disable mdc
13336         lru_resize_disable osc
13337         cancel_lru_locks mdc
13338         # asynchronous object destroy at MDT could cause bl ast to client
13339         cancel_lru_locks osc
13340
13341         stat $DIR/$tdir > /dev/null
13342         can1=$(do_facet mds1 \
13343                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13344                awk '/ldlm_cancel/ {print $2}')
13345         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13346                awk '/ldlm_bl_callback/ {print $2}')
13347         test_mkdir -i0 -c1 $DIR/$tdir/d1
13348         can2=$(do_facet mds1 \
13349                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13350                awk '/ldlm_cancel/ {print $2}')
13351         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13352                awk '/ldlm_bl_callback/ {print $2}')
13353         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
13354         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
13355         lru_resize_enable mdc
13356         lru_resize_enable osc
13357 }
13358 run_test 120a "Early Lock Cancel: mkdir test"
13359
13360 test_120b() {
13361         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13362         remote_mds_nodsh && skip "remote MDS with nodsh"
13363         test_mkdir $DIR/$tdir
13364         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13365                 skip_env "no early lock cancel on server"
13366
13367         lru_resize_disable mdc
13368         lru_resize_disable osc
13369         cancel_lru_locks mdc
13370         stat $DIR/$tdir > /dev/null
13371         can1=$(do_facet $SINGLEMDS \
13372                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13373                awk '/ldlm_cancel/ {print $2}')
13374         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13375                awk '/ldlm_bl_callback/ {print $2}')
13376         touch $DIR/$tdir/f1
13377         can2=$(do_facet $SINGLEMDS \
13378                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13379                awk '/ldlm_cancel/ {print $2}')
13380         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13381                awk '/ldlm_bl_callback/ {print $2}')
13382         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
13383         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
13384         lru_resize_enable mdc
13385         lru_resize_enable osc
13386 }
13387 run_test 120b "Early Lock Cancel: create test"
13388
13389 test_120c() {
13390         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13391         remote_mds_nodsh && skip "remote MDS with nodsh"
13392         test_mkdir -i0 -c1 $DIR/$tdir
13393         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13394                 skip "no early lock cancel on server"
13395
13396         lru_resize_disable mdc
13397         lru_resize_disable osc
13398         test_mkdir -i0 -c1 $DIR/$tdir/d1
13399         test_mkdir -i0 -c1 $DIR/$tdir/d2
13400         touch $DIR/$tdir/d1/f1
13401         cancel_lru_locks mdc
13402         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 > /dev/null
13403         can1=$(do_facet mds1 \
13404                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13405                awk '/ldlm_cancel/ {print $2}')
13406         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13407                awk '/ldlm_bl_callback/ {print $2}')
13408         ln $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
13409         can2=$(do_facet mds1 \
13410                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13411                awk '/ldlm_cancel/ {print $2}')
13412         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13413                awk '/ldlm_bl_callback/ {print $2}')
13414         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
13415         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
13416         lru_resize_enable mdc
13417         lru_resize_enable osc
13418 }
13419 run_test 120c "Early Lock Cancel: link test"
13420
13421 test_120d() {
13422         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13423         remote_mds_nodsh && skip "remote MDS with nodsh"
13424         test_mkdir -i0 -c1 $DIR/$tdir
13425         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13426                 skip_env "no early lock cancel on server"
13427
13428         lru_resize_disable mdc
13429         lru_resize_disable osc
13430         touch $DIR/$tdir
13431         cancel_lru_locks mdc
13432         stat $DIR/$tdir > /dev/null
13433         can1=$(do_facet mds1 \
13434                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13435                awk '/ldlm_cancel/ {print $2}')
13436         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13437                awk '/ldlm_bl_callback/ {print $2}')
13438         chmod a+x $DIR/$tdir
13439         can2=$(do_facet mds1 \
13440                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13441                awk '/ldlm_cancel/ {print $2}')
13442         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13443                awk '/ldlm_bl_callback/ {print $2}')
13444         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
13445         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
13446         lru_resize_enable mdc
13447         lru_resize_enable osc
13448 }
13449 run_test 120d "Early Lock Cancel: setattr test"
13450
13451 test_120e() {
13452         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13453         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13454                 skip_env "no early lock cancel on server"
13455         remote_mds_nodsh && skip "remote MDS with nodsh"
13456
13457         local dlmtrace_set=false
13458
13459         test_mkdir -i0 -c1 $DIR/$tdir
13460         lru_resize_disable mdc
13461         lru_resize_disable osc
13462         ! $LCTL get_param debug | grep -q dlmtrace &&
13463                 $LCTL set_param debug=+dlmtrace && dlmtrace_set=true
13464         dd if=/dev/zero of=$DIR/$tdir/f1 count=1
13465         cancel_lru_locks mdc
13466         cancel_lru_locks osc
13467         dd if=$DIR/$tdir/f1 of=/dev/null
13468         stat $DIR/$tdir $DIR/$tdir/f1 > /dev/null
13469         # XXX client can not do early lock cancel of OST lock
13470         # during unlink (LU-4206), so cancel osc lock now.
13471         sleep 2
13472         cancel_lru_locks osc
13473         can1=$(do_facet mds1 \
13474                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13475                awk '/ldlm_cancel/ {print $2}')
13476         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13477                awk '/ldlm_bl_callback/ {print $2}')
13478         unlink $DIR/$tdir/f1
13479         sleep 5
13480         can2=$(do_facet mds1 \
13481                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13482                awk '/ldlm_cancel/ {print $2}')
13483         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13484                awk '/ldlm_bl_callback/ {print $2}')
13485         [ $can1 -ne $can2 ] && error "$((can2 - can1)) cancel RPC occured" &&
13486                 $LCTL dk $TMP/cancel.debug.txt
13487         [ $blk1 -ne $blk2 ] && error "$((blk2 - blk1)) blocking RPC occured" &&
13488                 $LCTL dk $TMP/blocking.debug.txt
13489         $dlmtrace_set && $LCTL set_param debug=-dlmtrace
13490         lru_resize_enable mdc
13491         lru_resize_enable osc
13492 }
13493 run_test 120e "Early Lock Cancel: unlink test"
13494
13495 test_120f() {
13496         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13497         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13498                 skip_env "no early lock cancel on server"
13499         remote_mds_nodsh && skip "remote MDS with nodsh"
13500
13501         test_mkdir -i0 -c1 $DIR/$tdir
13502         lru_resize_disable mdc
13503         lru_resize_disable osc
13504         test_mkdir -i0 -c1 $DIR/$tdir/d1
13505         test_mkdir -i0 -c1 $DIR/$tdir/d2
13506         dd if=/dev/zero of=$DIR/$tdir/d1/f1 count=1
13507         dd if=/dev/zero of=$DIR/$tdir/d2/f2 count=1
13508         cancel_lru_locks mdc
13509         cancel_lru_locks osc
13510         dd if=$DIR/$tdir/d1/f1 of=/dev/null
13511         dd if=$DIR/$tdir/d2/f2 of=/dev/null
13512         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2 > /dev/null
13513         # XXX client can not do early lock cancel of OST lock
13514         # during rename (LU-4206), so cancel osc lock now.
13515         sleep 2
13516         cancel_lru_locks osc
13517         can1=$(do_facet mds1 \
13518                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13519                awk '/ldlm_cancel/ {print $2}')
13520         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13521                awk '/ldlm_bl_callback/ {print $2}')
13522         mrename $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
13523         sleep 5
13524         can2=$(do_facet mds1 \
13525                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13526                awk '/ldlm_cancel/ {print $2}')
13527         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13528                awk '/ldlm_bl_callback/ {print $2}')
13529         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
13530         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
13531         lru_resize_enable mdc
13532         lru_resize_enable osc
13533 }
13534 run_test 120f "Early Lock Cancel: rename test"
13535
13536 test_120g() {
13537         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13538         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13539                 skip_env "no early lock cancel on server"
13540         remote_mds_nodsh && skip "remote MDS with nodsh"
13541
13542         lru_resize_disable mdc
13543         lru_resize_disable osc
13544         count=10000
13545         echo create $count files
13546         test_mkdir $DIR/$tdir
13547         cancel_lru_locks mdc
13548         cancel_lru_locks osc
13549         t0=$(date +%s)
13550
13551         can0=$(do_facet $SINGLEMDS \
13552                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13553                awk '/ldlm_cancel/ {print $2}')
13554         blk0=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13555                awk '/ldlm_bl_callback/ {print $2}')
13556         createmany -o $DIR/$tdir/f $count
13557         sync
13558         can1=$(do_facet $SINGLEMDS \
13559                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13560                awk '/ldlm_cancel/ {print $2}')
13561         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13562                awk '/ldlm_bl_callback/ {print $2}')
13563         t1=$(date +%s)
13564         echo total: $((can1-can0)) cancels, $((blk1-blk0)) blockings
13565         echo rm $count files
13566         rm -r $DIR/$tdir
13567         sync
13568         can2=$(do_facet $SINGLEMDS \
13569                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13570                awk '/ldlm_cancel/ {print $2}')
13571         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13572                awk '/ldlm_bl_callback/ {print $2}')
13573         t2=$(date +%s)
13574         echo total: $count removes in $((t2-t1))
13575         echo total: $((can2-can1)) cancels, $((blk2-blk1)) blockings
13576         sleep 2
13577         # wait for commitment of removal
13578         lru_resize_enable mdc
13579         lru_resize_enable osc
13580 }
13581 run_test 120g "Early Lock Cancel: performance test"
13582
13583 test_121() { #bug #10589
13584         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13585
13586         rm -rf $DIR/$tfile
13587         writes=$(LANG=C dd if=/dev/zero of=$DIR/$tfile count=1 2>&1 | awk -F '+' '/out$/ {print $1}')
13588 #define OBD_FAIL_LDLM_CANCEL_RACE        0x310
13589         lctl set_param fail_loc=0x310
13590         cancel_lru_locks osc > /dev/null
13591         reads=$(LANG=C dd if=$DIR/$tfile of=/dev/null 2>&1 | awk -F '+' '/in$/ {print $1}')
13592         lctl set_param fail_loc=0
13593         [[ $reads -eq $writes ]] ||
13594                 error "read $reads blocks, must be $writes blocks"
13595 }
13596 run_test 121 "read cancel race ========="
13597
13598 test_123a_base() { # was test 123, statahead(bug 11401)
13599         local lsx="$1"
13600
13601         ost_set_temp_seq_width_all $DATA_SEQ_MAX_WIDTH
13602
13603         SLOWOK=0
13604         if ! grep -q "processor.*: 1" /proc/cpuinfo; then
13605                 log "testing UP system. Performance may be lower than expected."
13606                 SLOWOK=1
13607         fi
13608         running_in_vm && SLOWOK=1
13609
13610         $LCTL set_param mdc.*.batch_stats=0
13611
13612         rm -rf $DIR/$tdir
13613         test_mkdir $DIR/$tdir
13614         NUMFREE=$(df -i -P $DIR | tail -n 1 | awk '{ print $4 }')
13615         [[ $NUMFREE -gt 100000 ]] && NUMFREE=100000 || NUMFREE=$((NUMFREE-1000))
13616         MULT=10
13617         for ((i=100, j=0; i<=$NUMFREE; j=$i, i=$((i * MULT)) )); do
13618                 createmany -o $DIR/$tdir/$tfile $j $((i - j))
13619
13620                 max=$(lctl get_param -n llite.*.statahead_max | head -n 1)
13621                 lctl set_param -n llite.*.statahead_max 0
13622                 lctl get_param llite.*.statahead_max
13623                 cancel_lru_locks mdc
13624                 cancel_lru_locks osc
13625                 stime=$(date +%s)
13626                 time $lsx $DIR/$tdir | wc -l
13627                 etime=$(date +%s)
13628                 delta=$((etime - stime))
13629                 log "$lsx $i files without statahead: $delta sec"
13630                 lctl set_param llite.*.statahead_max=$max
13631
13632                 swrong=$(lctl get_param -n llite.*.statahead_stats |
13633                          awk '/statahead.wrong:/ { print $NF }')
13634                 lctl get_param -n llite.*.statahead_max | grep '[0-9]'
13635                 cancel_lru_locks mdc
13636                 cancel_lru_locks osc
13637                 stime=$(date +%s)
13638                 time $lsx $DIR/$tdir | wc -l
13639                 etime=$(date +%s)
13640                 delta_sa=$((etime - stime))
13641                 log "$lsx $i files with statahead: $delta_sa sec"
13642                 lctl get_param -n llite.*.statahead_stats
13643                 ewrong=$(lctl get_param -n llite.*.statahead_stats |
13644                          awk '/statahead.wrong:/ { print $NF }')
13645
13646                 [[ $swrong -lt $ewrong ]] &&
13647                         log "statahead was stopped, maybe too many locks held!"
13648                 [[ $delta -eq 0 || $delta_sa -eq 0 ]] && continue
13649
13650                 if (( $delta_sa*100 > $delta*105 && $delta_sa > $delta+2)); then
13651                         max=$(lctl get_param -n llite.*.statahead_max |
13652                                 head -n 1)
13653                         lctl set_param -n llite.*.statahead_max 0
13654                         lctl get_param llite.*.statahead_max
13655                         cancel_lru_locks mdc
13656                         cancel_lru_locks osc
13657                         stime=$(date +%s)
13658                         time $lsx $DIR/$tdir | wc -l
13659                         etime=$(date +%s)
13660                         delta=$((etime - stime))
13661                         log "$lsx $i files again without statahead: $delta sec"
13662                         lctl set_param llite.*.statahead_max=$max
13663                         if (( $delta_sa*100 > delta*105 && delta_sa > delta+2 )); then
13664                                 if [ $SLOWOK -eq 0 ]; then
13665                                         error "$lsx $i files is slower with statahead!"
13666                                 else
13667                                         log "$lsx $i files is slower with statahead!"
13668                                 fi
13669                                 break
13670                         fi
13671                 fi
13672
13673                 [ $delta -gt 20 ] && break
13674                 [ $delta -gt 8 ] && MULT=$((50 / delta))
13675                 [ "$SLOW" = "no" -a $delta -gt 5 ] && break
13676         done
13677         log "$lsx done"
13678
13679         stime=$(date +%s)
13680         rm -r $DIR/$tdir
13681         sync
13682         etime=$(date +%s)
13683         delta=$((etime - stime))
13684         log "rm -r $DIR/$tdir/: $delta seconds"
13685         log "rm done"
13686         lctl get_param -n llite.*.statahead_stats
13687         $LCTL get_param mdc.*.batch_stats
13688 }
13689
13690 test_123aa() {
13691         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13692
13693         test_123a_base "ls -l"
13694 }
13695 run_test 123aa "verify statahead work"
13696
13697 test_123ab() {
13698         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13699
13700         statx_supported || skip_env "Test must be statx() syscall supported"
13701
13702         test_123a_base "$STATX -l"
13703 }
13704 run_test 123ab "verify statahead work by using statx"
13705
13706 test_123ac() {
13707         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13708
13709         statx_supported || skip_env "Test must be statx() syscall supported"
13710
13711         local rpcs_before
13712         local rpcs_after
13713         local agl_before
13714         local agl_after
13715
13716         cancel_lru_locks $OSC
13717         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
13718         agl_before=$($LCTL get_param -n llite.*.statahead_stats |
13719                      awk '/agl.total:/ { print $NF }')
13720         test_123a_base "$STATX -c \"%n %i %A %h %u %g %W %X %Z\" -D"
13721         test_123a_base "$STATX --cached=always -D"
13722         agl_after=$($LCTL get_param -n llite.*.statahead_stats |
13723                     awk '/agl.total:/ { print $NF }')
13724         [ $agl_before -eq $agl_after ] ||
13725                 error "Should not trigger AGL thread - $agl_before:$agl_after"
13726         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
13727         [ $rpcs_after -eq $rpcs_before ] ||
13728                 error "$STATX should not send glimpse RPCs to $OSC"
13729 }
13730 run_test 123ac "verify statahead work by using statx without glimpse RPCs"
13731
13732 test_batch_statahead() {
13733         local max=$1
13734         local batch_max=$2
13735         local num=10000
13736         local batch_rpcs
13737         local unbatch_rpcs
13738         local hit_total
13739
13740         echo -e "\nbatching: statahead_max=$max statahead_batch_max=$batch_max"
13741         $LCTL set_param mdc.*.batch_stats=0
13742         $LCTL set_param llite.*.statahead_max=$max
13743         $LCTL set_param llite.*.statahead_batch_max=$batch_max
13744         # Verify that batched statahead is faster than one without statahead
13745         test_123a_base "ls -l"
13746
13747         stack_trap "rm -rf $DIR/$tdir" EXIT
13748         mkdir $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
13749         createmany -o $DIR/$tdir/$tfile $num || error "failed to create files"
13750
13751         # unbatched statahead
13752         $LCTL set_param llite.*.statahead_batch_max=0
13753         $LCTL set_param llite.*.statahead_stats=clear
13754         $LCTL set_param mdc.*.stats=clear
13755         cancel_lru_locks mdc
13756         cancel_lru_locks osc
13757         time ls -l $DIR/$tdir | wc -l
13758         unbatch_rpcs=$(calc_stats mdc.*.stats ldlm_ibits_enqueue)
13759         sleep 2
13760         hit_total=$($LCTL get_param -n llite.*.statahead_stats |
13761                     awk '/hit.total:/ { print $NF }')
13762         # hit ratio should be larger than 75% (7500).
13763         (( $hit_total > 7500 )) ||
13764                 error "unbatched statahead hit count ($hit_total) is too low"
13765
13766         # batched statahead
13767         $LCTL set_param llite.*.statahead_batch_max=$batch_max
13768         $LCTL set_param llite.*.statahead_stats=clear
13769         $LCTL set_param mdc.*.batch_stats=clear
13770         $LCTL set_param mdc.*.stats=clear
13771         cancel_lru_locks mdc
13772         cancel_lru_locks osc
13773         time ls -l $DIR/$tdir | wc -l
13774         batch_rpcs=$(calc_stats mdc.*.stats mds_batch)
13775         # wait for statahead thread to quit and update statahead stats
13776         sleep 2
13777         hit_total=$($LCTL get_param -n llite.*.statahead_stats |
13778                     awk '/hit.total:/ { print $NF }')
13779         # hit ratio should be larger than 75% (7500).
13780         (( $hit_total > 7500 )) ||
13781                 error "batched statahead hit count ($hit_total) is too low"
13782
13783         echo "unbatched RPCs: $unbatch_rpcs, batched RPCs: $batch_rpcs"
13784         (( $unbatch_rpcs > $batch_rpcs )) ||
13785                 error "batched statahead does not reduce RPC count"
13786         $LCTL get_param mdc.*.batch_stats
13787 }
13788
13789 test_123ad() {
13790         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13791
13792         (( $MDS1_VERSION >= $(version_code 2.15.53) )) ||
13793                 skip "Need server version at least 2.15.53"
13794
13795         local max
13796         local batch_max
13797
13798         max=$($LCTL get_param -n llite.*.statahead_max | head -n 1)
13799         batch_max=$($LCTL get_param -n llite.*.statahead_batch_max | head -n 1)
13800
13801         stack_trap "$LCTL set_param llite.*.statahead_max=$max" EXIT
13802         stack_trap "$LCTL set_param llite.*.statahead_batch_max=$batch_max" EXIT
13803
13804         test_batch_statahead 32 32
13805         test_batch_statahead 2048 256
13806 }
13807 run_test 123ad "Verify batching statahead works correctly"
13808
13809 test_123b () { # statahead(bug 15027)
13810         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13811
13812         test_mkdir $DIR/$tdir
13813         createmany -o $DIR/$tdir/$tfile-%d 1000
13814
13815         cancel_lru_locks mdc
13816         cancel_lru_locks osc
13817
13818 #define OBD_FAIL_MDC_GETATTR_ENQUEUE     0x803
13819         lctl set_param fail_loc=0x80000803
13820         ls -lR $DIR/$tdir > /dev/null
13821         log "ls done"
13822         lctl set_param fail_loc=0x0
13823         lctl get_param -n llite.*.statahead_stats
13824         rm -r $DIR/$tdir
13825         sync
13826
13827 }
13828 run_test 123b "not panic with network error in statahead enqueue (bug 15027)"
13829
13830 test_123c() {
13831         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
13832
13833         test_mkdir -i 0 -c 1 $DIR/$tdir.0
13834         test_mkdir -i 1 -c 1 $DIR/$tdir.1
13835         touch $DIR/$tdir.1/{1..3}
13836         mv $DIR/$tdir.1/{1..3} $DIR/$tdir.0
13837
13838         remount_client $MOUNT
13839
13840         $MULTIOP $DIR/$tdir.0 Q
13841
13842         # let statahead to complete
13843         ls -l $DIR/$tdir.0 > /dev/null
13844
13845         testid=$(echo $TESTNAME | tr '_' ' ')
13846         dmesg | tac | sed "/$testid/,$ d" | grep "Can not initialize inode" &&
13847                 error "statahead warning" || true
13848 }
13849 run_test 123c "Can not initialize inode warning on DNE statahead"
13850
13851 test_123d() {
13852         local num=100
13853         local swrong
13854         local ewrong
13855
13856         test_mkdir -c -1 $DIR/$tdir || error "test_mkdir $DIR/$tdir failed"
13857         $LFS setdirstripe -D -c $MDSCOUNT $DIR/$tdir ||
13858                 error "setdirstripe $DIR/$tdir failed"
13859         createmany -d $DIR/$tdir/$tfile $num || error "createmany $num failed"
13860         remount_client $MOUNT
13861         $LCTL get_param llite.*.statahead_max
13862         $LCTL set_param llite.*.statahead_stats=0 ||
13863                 error "clear statahead_stats failed"
13864         swrong=$(lctl get_param -n llite.*.statahead_stats |
13865                  awk '/statahead.wrong:/ { print $NF }')
13866         ls -l $DIR/$tdir || error "ls -l $DIR/$tdir failed"
13867         # wait for statahead thread finished to update hit/miss stats.
13868         sleep 1
13869         $LCTL get_param -n llite.*.statahead_stats
13870         ewrong=$(lctl get_param -n llite.*.statahead_stats |
13871                  awk '/statahead.wrong:/ { print $NF }')
13872         (( $swrong == $ewrong )) ||
13873                 log "statahead was stopped, maybe too many locks held!"
13874 }
13875 run_test 123d "Statahead on striped directories works correctly"
13876
13877 test_123e() {
13878         local max
13879         local batch_max
13880         local dir=$DIR/$tdir
13881
13882         mkdir $dir || error "mkdir $dir failed"
13883         $LFS setstripe -C 32 $dir || error "setstripe $dir failed"
13884         stack_trap "rm -rf $dir"
13885
13886         touch $dir/$tfile.{0..1000} || error "touch 1000 files failed"
13887
13888         max=$($LCTL get_param -n llite.*.statahead_max | head -n 1)
13889         batch_max=$($LCTL get_param -n llite.*.statahead_batch_max | head -n 1)
13890         stack_trap "$LCTL set_param llite.*.statahead_max=$max" EXIT
13891         stack_trap "$LCTL set_param llite.*.statahead_batch_max=$batch_max" EXIT
13892
13893         $LCTL set_param llite.*.statahead_max=2048
13894         $LCTL set_param llite.*.statahead_batch_max=1024
13895
13896         ls -l $dir
13897         $LCTL get_param mdc.*.batch_stats
13898         $LCTL get_param llite.*.statahead_*
13899 }
13900 run_test 123e "statahead with large wide striping"
13901
13902 test_123f() {
13903         local max
13904         local batch_max
13905         local dir=$DIR/$tdir
13906
13907         mkdir $dir || error "mkdir $dir failed"
13908         $LFS setstripe -C 1000 $dir || error "setstripe $dir failed"
13909         stack_trap "rm -rf $dir"
13910
13911         touch $dir/$tfile.{0..200} || error "touch 200 files failed"
13912
13913         max=$($LCTL get_param -n llite.*.statahead_max | head -n 1)
13914         batch_max=$($LCTL get_param -n llite.*.statahead_batch_max | head -n 1)
13915
13916         $LCTL set_param llite.*.statahead_max=64
13917         $LCTL set_param llite.*.statahead_batch_max=64
13918
13919         ls -l $dir
13920         lctl get_param mdc.*.batch_stats
13921         lctl get_param llite.*.statahead_*
13922
13923         $LCTL set_param llite.*.statahead_max=$max
13924         $LCTL set_param llite.*.statahead_batch_max=$batch_max
13925 }
13926 run_test 123f "Retry mechanism with large wide striping files"
13927
13928 test_124a() {
13929         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13930         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13931                 skip_env "no lru resize on server"
13932
13933         local NR=2000
13934
13935         test_mkdir $DIR/$tdir
13936
13937         log "create $NR files at $DIR/$tdir"
13938         createmany -o $DIR/$tdir/f $NR ||
13939                 error "failed to create $NR files in $DIR/$tdir"
13940
13941         cancel_lru_locks mdc
13942         ls -l $DIR/$tdir > /dev/null
13943
13944         local NSDIR=""
13945         local LRU_SIZE=0
13946         for VALUE in $($LCTL get_param ldlm.namespaces.*mdc-*.lru_size); do
13947                 local PARAM=$(echo ${VALUE[0]} | cut -d "=" -f1)
13948                 LRU_SIZE=$($LCTL get_param -n $PARAM)
13949                 if [[ $LRU_SIZE -gt $(default_lru_size) ]]; then
13950                         NSDIR=$(echo $PARAM | cut -d "." -f1-3)
13951                         log "NSDIR=$NSDIR"
13952                         log "NS=$(basename $NSDIR)"
13953                         break
13954                 fi
13955         done
13956
13957         if [[ -z "$NSDIR" || $LRU_SIZE -lt $(default_lru_size) ]]; then
13958                 skip "Not enough cached locks created!"
13959         fi
13960         log "LRU=$LRU_SIZE"
13961
13962         local SLEEP=30
13963
13964         # We know that lru resize allows one client to hold $LIMIT locks
13965         # for 10h. After that locks begin to be killed by client.
13966         local MAX_HRS=10
13967         local LIMIT=$($LCTL get_param -n $NSDIR.pool.limit)
13968         log "LIMIT=$LIMIT"
13969         if [ $LIMIT -lt $LRU_SIZE ]; then
13970                 skip "Limit is too small $LIMIT"
13971         fi
13972
13973         # Make LVF so higher that sleeping for $SLEEP is enough to _start_
13974         # killing locks. Some time was spent for creating locks. This means
13975         # that up to the moment of sleep finish we must have killed some of
13976         # them (10-100 locks). This depends on how fast ther were created.
13977         # Many of them were touched in almost the same moment and thus will
13978         # be killed in groups.
13979         local LVF=$(($MAX_HRS * 60 * 60 / $SLEEP * $LIMIT / $LRU_SIZE * 100))
13980
13981         # Use $LRU_SIZE_B here to take into account real number of locks
13982         # created in the case of CMD, LRU_SIZE_B != $NR in most of cases
13983         local LRU_SIZE_B=$LRU_SIZE
13984         log "LVF=$LVF"
13985         local OLD_LVF=$($LCTL get_param -n $NSDIR.pool.lock_volume_factor)
13986         log "OLD_LVF=$OLD_LVF"
13987         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $LVF
13988
13989         # Let's make sure that we really have some margin. Client checks
13990         # cached locks every 10 sec.
13991         SLEEP=$((SLEEP+20))
13992         log "Sleep ${SLEEP} sec"
13993         local SEC=0
13994         while ((SEC<$SLEEP)); do
13995                 echo -n "..."
13996                 sleep 5
13997                 SEC=$((SEC+5))
13998                 LRU_SIZE=$($LCTL get_param -n $NSDIR/lru_size)
13999                 echo -n "$LRU_SIZE"
14000         done
14001         echo ""
14002         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $OLD_LVF
14003         local LRU_SIZE_A=$($LCTL get_param -n $NSDIR.lru_size)
14004
14005         [[ $LRU_SIZE_B -gt $LRU_SIZE_A ]] || {
14006                 error "No locks dropped in ${SLEEP}s. LRU size: $LRU_SIZE_A"
14007                 unlinkmany $DIR/$tdir/f $NR
14008                 return
14009         }
14010
14011         log "Dropped "$((LRU_SIZE_B-LRU_SIZE_A))" locks in ${SLEEP}s"
14012         log "unlink $NR files at $DIR/$tdir"
14013         unlinkmany $DIR/$tdir/f $NR
14014 }
14015 run_test 124a "lru resize ======================================="
14016
14017 get_max_pool_limit()
14018 {
14019         local limit=$($LCTL get_param \
14020                       -n ldlm.namespaces.*-MDT0000-mdc-*.pool.limit)
14021         local max=0
14022         for l in $limit; do
14023                 if [[ $l -gt $max ]]; then
14024                         max=$l
14025                 fi
14026         done
14027         echo $max
14028 }
14029
14030 test_124b() {
14031         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14032         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
14033                 skip_env "no lru resize on server"
14034
14035         LIMIT=$(get_max_pool_limit)
14036
14037         NR=$(($(default_lru_size)*20))
14038         if [[ $NR -gt $LIMIT ]]; then
14039                 log "Limit lock number by $LIMIT locks"
14040                 NR=$LIMIT
14041         fi
14042
14043         IFree=$(mdsrate_inodes_available)
14044         if [ $IFree -lt $NR ]; then
14045                 log "Limit lock number by $IFree inodes"
14046                 NR=$IFree
14047         fi
14048
14049         lru_resize_disable mdc
14050         test_mkdir -p $DIR/$tdir/disable_lru_resize
14051
14052         createmany -o $DIR/$tdir/disable_lru_resize/f $NR
14053         log "doing ls -la $DIR/$tdir/disable_lru_resize 3 times"
14054         cancel_lru_locks mdc
14055         stime=`date +%s`
14056         PID=""
14057         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
14058         PID="$PID $!"
14059         sleep 2
14060         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
14061         PID="$PID $!"
14062         sleep 2
14063         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
14064         PID="$PID $!"
14065         wait $PID
14066         etime=`date +%s`
14067         nolruresize_delta=$((etime-stime))
14068         log "ls -la time: $nolruresize_delta seconds"
14069         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
14070         unlinkmany $DIR/$tdir/disable_lru_resize/f $NR
14071
14072         lru_resize_enable mdc
14073         test_mkdir -p $DIR/$tdir/enable_lru_resize
14074
14075         createmany -o $DIR/$tdir/enable_lru_resize/f $NR
14076         log "doing ls -la $DIR/$tdir/enable_lru_resize 3 times"
14077         cancel_lru_locks mdc
14078         stime=`date +%s`
14079         PID=""
14080         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
14081         PID="$PID $!"
14082         sleep 2
14083         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
14084         PID="$PID $!"
14085         sleep 2
14086         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
14087         PID="$PID $!"
14088         wait $PID
14089         etime=`date +%s`
14090         lruresize_delta=$((etime-stime))
14091         log "ls -la time: $lruresize_delta seconds"
14092         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
14093
14094         if [ $lruresize_delta -gt $nolruresize_delta ]; then
14095                 log "ls -la is $(((lruresize_delta - $nolruresize_delta) * 100 / $nolruresize_delta))% slower with lru resize enabled"
14096         elif [ $nolruresize_delta -gt $lruresize_delta ]; then
14097                 log "ls -la is $(((nolruresize_delta - $lruresize_delta) * 100 / $nolruresize_delta))% faster with lru resize enabled"
14098         else
14099                 log "lru resize performs the same with no lru resize"
14100         fi
14101         unlinkmany $DIR/$tdir/enable_lru_resize/f $NR
14102 }
14103 run_test 124b "lru resize (performance test) ======================="
14104
14105 test_124c() {
14106         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14107         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
14108                 skip_env "no lru resize on server"
14109
14110         # cache ununsed locks on client
14111         local nr=100
14112         cancel_lru_locks mdc
14113         test_mkdir $DIR/$tdir
14114         createmany -o $DIR/$tdir/f $nr ||
14115                 error "failed to create $nr files in $DIR/$tdir"
14116         ls -l $DIR/$tdir > /dev/null
14117
14118         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
14119         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
14120         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
14121         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
14122         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
14123
14124         # set lru_max_age to 1 sec
14125         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
14126         echo "sleep $((recalc_p * 2)) seconds..."
14127         sleep $((recalc_p * 2))
14128
14129         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
14130         # restore lru_max_age
14131         $LCTL set_param -n $nsdir.lru_max_age $max_age
14132         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
14133         unlinkmany $DIR/$tdir/f $nr
14134 }
14135 run_test 124c "LRUR cancel very aged locks"
14136
14137 test_124d() {
14138         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14139         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
14140                 skip_env "no lru resize on server"
14141
14142         # cache ununsed locks on client
14143         local nr=100
14144
14145         lru_resize_disable mdc
14146         stack_trap "lru_resize_enable mdc" EXIT
14147
14148         cancel_lru_locks mdc
14149
14150         # asynchronous object destroy at MDT could cause bl ast to client
14151         test_mkdir $DIR/$tdir
14152         createmany -o $DIR/$tdir/f $nr ||
14153                 error "failed to create $nr files in $DIR/$tdir"
14154         stack_trap "unlinkmany $DIR/$tdir/f $nr" EXIT
14155
14156         ls -l $DIR/$tdir > /dev/null
14157
14158         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
14159         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
14160         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
14161         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
14162
14163         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
14164
14165         # set lru_max_age to 1 sec
14166         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
14167         stack_trap "$LCTL set_param -n $nsdir.lru_max_age $max_age" EXIT
14168
14169         echo "sleep $((recalc_p * 2)) seconds..."
14170         sleep $((recalc_p * 2))
14171
14172         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
14173
14174         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
14175 }
14176 run_test 124d "cancel very aged locks if lru-resize diasbaled"
14177
14178 test_125() { # 13358
14179         $LCTL get_param -n llite.*.client_type | grep -q local ||
14180                 skip "must run as local client"
14181         $LCTL get_param -n mdc.*-mdc-*.connect_flags | grep -q acl ||
14182                 skip_env "must have acl enabled"
14183         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
14184
14185         test_mkdir $DIR/$tdir
14186         $LFS setstripe -S 65536 -c -1 $DIR/$tdir || error "setstripe failed"
14187         setfacl -R -m u:$USER0:rwx $DIR/$tdir ||
14188                 error "setfacl $DIR/$tdir failed"
14189         ls -ld $DIR/$tdir || error "cannot access $DIR/$tdir"
14190 }
14191 run_test 125 "don't return EPROTO when a dir has a non-default striping and ACLs"
14192
14193 test_126() { # bug 12829/13455
14194         $GSS && skip_env "must run as gss disabled"
14195         $LCTL get_param -n llite.*.client_type | grep -q local ||
14196                 skip "must run as local client"
14197         [ "$UID" != 0 ] && skip "must run as root, not UID $UID"
14198
14199         $RUNAS -u 0 -g 1 touch $DIR/$tfile || error "touch failed"
14200         gid=`ls -n $DIR/$tfile | awk '{print $4}'`
14201         rm -f $DIR/$tfile
14202         [ $gid -eq "1" ] || error "gid is set to" $gid "instead of 1"
14203 }
14204 run_test 126 "check that the fsgid provided by the client is taken into account"
14205
14206 test_127a() { # bug 15521
14207         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14208         local name count samp unit min max sum sumsq
14209         local tmpfile=$TMP/$tfile.tmp
14210
14211         $LFS setstripe -i 0 -c 1 $DIR/$tfile || error "setstripe failed"
14212         echo "stats before reset"
14213         stack_trap "rm -f $tmpfile"
14214         local now=$(date +%s)
14215
14216         $LCTL get_param osc.*.stats | tee $tmpfile
14217
14218         local snapshot_time=$(awk '/snapshot_time/ { print $2; exit }' $tmpfile)
14219         local start_time=$(awk '/start_time/ { print $2; exit }' $tmpfile)
14220         local elapsed=$(awk '/elapsed_time/ { print $2; exit }' $tmpfile)
14221         local uptime=$(awk '{ print $1 }' /proc/uptime)
14222
14223         # snapshot_time should match POSIX epoch time, allow some delta for VMs
14224         (( ${snapshot_time%\.*} >= $now - 5 &&
14225            ${snapshot_time%\.*} <= $now + 5 )) ||
14226                 error "snapshot_time=$snapshot_time != now=$now"
14227         # elapsed _should_ be from mount, but at least less than uptime
14228         (( ${elapsed%\.*} < ${uptime%\.*} )) ||
14229                 error "elapsed=$elapsed > uptime=$uptime"
14230         (( ${snapshot_time%\.*} - ${start_time%\.*} >= ${elapsed%\.*} - 2 &&
14231            ${snapshot_time%\.*} - ${start_time%\.*} <= ${elapsed%\.*} + 2 )) ||
14232                 error "elapsed=$elapsed != $snapshot_time - $start_time"
14233
14234         $LCTL set_param osc.*.stats=0
14235         local reset=$(date +%s)
14236         local fsize=$((2048 * 1024))
14237
14238         dd if=/dev/zero of=$DIR/$tfile bs=$fsize count=1
14239         cancel_lru_locks osc
14240         dd if=$DIR/$tfile of=/dev/null bs=$fsize
14241
14242         now=$(date +%s)
14243         $LCTL get_param osc.*0000-osc-*.stats > $tmpfile
14244         while read name count samp unit min max sum sumsq; do
14245                 [[ "$samp" == "samples" ]] || continue
14246
14247                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
14248                 [ ! $min ] && error "Missing min value for $name proc entry"
14249                 eval $name=$count || error "Wrong proc format"
14250
14251                 case $name in
14252                 read_bytes|write_bytes)
14253                         [[ "$unit" =~ "bytes" ]] ||
14254                                 error "unit is not 'bytes': $unit"
14255                         (( $min >= 4096 )) || error "min is too small: $min"
14256                         (( $min <= $fsize )) || error "min is too big: $min"
14257                         (( $max >= 4096 )) || error "max is too small: $max"
14258                         (( $max <= $fsize )) || error "max is too big: $max"
14259                         (( $sum == $fsize )) || error "sum is wrong: $sum"
14260                         (( $sumsq >= ($fsize / 4096) * (4096 * 4096) )) ||
14261                                 error "sumsquare is too small: $sumsq"
14262                         (( $sumsq <= $fsize * $fsize )) ||
14263                                 error "sumsquare is too big: $sumsq"
14264                         ;;
14265                 ost_read|ost_write)
14266                         [[ "$unit" =~ "usec" ]] ||
14267                                 error "unit is not 'usec': $unit"
14268                         ;;
14269                 *)      ;;
14270                 esac
14271         done < $tmpfile
14272
14273         #check that we actually got some stats
14274         [ "$read_bytes" ] || error "Missing read_bytes stats"
14275         [ "$write_bytes" ] || error "Missing write_bytes stats"
14276         [ "$read_bytes" != 0 ] || error "no read done"
14277         [ "$write_bytes" != 0 ] || error "no write done"
14278
14279         snapshot_time=$(awk '/snapshot_time/ { print $2; exit }' $tmpfile)
14280         start_time=$(awk '/start_time/ { print $2; exit }' $tmpfile)
14281         elapsed=$(awk '/elapsed_time/ { print $2; exit }' $tmpfile)
14282
14283         # snapshot_time should match POSIX epoch time, allow some delta for VMs
14284         (( ${snapshot_time%\.*} >= $now - 5 &&
14285            ${snapshot_time%\.*} <= $now + 5 )) ||
14286                 error "reset snapshot_time=$snapshot_time != now=$now"
14287         # elapsed should be from time of stats reset
14288         (( ${elapsed%\.*} >= $now - $reset - 2 &&
14289            ${elapsed%\.*} <= $now - $reset + 2 )) ||
14290                 error "reset elapsed=$elapsed > $now - $reset"
14291         (( ${snapshot_time%\.*} - ${start_time%\.*} >= ${elapsed%\.*} - 2 &&
14292            ${snapshot_time%\.*} - ${start_time%\.*} <= ${elapsed%\.*} + 2 )) ||
14293                 error "reset elapsed=$elapsed != $snapshot_time - $start_time"
14294 }
14295 run_test 127a "verify the client stats are sane"
14296
14297 test_127b() { # bug LU-333
14298         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14299         local name count samp unit min max sum sumsq
14300
14301         echo "stats before reset"
14302         $LCTL get_param llite.*.stats
14303         $LCTL set_param llite.*.stats=0
14304
14305         # perform 2 reads and writes so MAX is different from SUM.
14306         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
14307         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
14308         cancel_lru_locks osc
14309         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
14310         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
14311
14312         $LCTL get_param llite.*.stats | grep samples > $TMP/$tfile.tmp
14313         stack_trap "rm -f $TMP/$tfile.tmp"
14314         while read name count samp unit min max sum sumsq; do
14315                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
14316                 eval $name=$count || error "Wrong proc format"
14317
14318                 case $name in
14319                 read_bytes|write_bytes)
14320                         [[ "$unit" =~ "bytes" ]] ||
14321                                 error "unit is not 'bytes': $unit"
14322                         (( $count == 2 )) || error "count is not 2: $count"
14323                         (( $min == $PAGE_SIZE )) ||
14324                                 error "min is not $PAGE_SIZE: $min"
14325                         (( $max == $PAGE_SIZE )) ||
14326                                 error "max is not $PAGE_SIZE: $max"
14327                         (( $sum == $PAGE_SIZE * 2 )) ||
14328                                 error "sum is not $((PAGE_SIZE * 2)): $sum"
14329                         ;;
14330                 read|write)
14331                         [[ "$unit" =~ "usec" ]] ||
14332                                 error "unit is not 'usec': $unit"
14333                         ;;
14334                 *)      ;;
14335                 esac
14336         done < $TMP/$tfile.tmp
14337
14338         #check that we actually got some stats
14339         [ "$read_bytes" ] || error "Missing read_bytes stats"
14340         [ "$write_bytes" ] || error "Missing write_bytes stats"
14341         [ "$read_bytes" != 0 ] || error "no read done"
14342         [ "$write_bytes" != 0 ] || error "no write done"
14343 }
14344 run_test 127b "verify the llite client stats are sane"
14345
14346 test_127c() { # LU-12394
14347         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
14348         local size
14349         local bsize
14350         local reads
14351         local writes
14352         local count
14353
14354         $LCTL set_param llite.*.extents_stats=1
14355         stack_trap "$LCTL set_param llite.*.extents_stats=0" EXIT
14356
14357         # Use two stripes so there is enough space in default config
14358         $LFS setstripe -c 2 $DIR/$tfile
14359
14360         # Extent stats start at 0-4K and go in power of two buckets
14361         # LL_HIST_START = 12 --> 2^12 = 4K
14362         # We do 3K*2^i, so 3K, 6K, 12K, 24K... hitting each bucket.
14363         # We do not do buckets larger than 64 MiB to avoid ENOSPC issues on
14364         # small configs
14365         for size in 3K 6K 12K 24K 48K 96K 192K 384K 768K 1536K 3M 6M 12M 24M 48M;
14366                 do
14367                 # Write and read, 2x each, second time at a non-zero offset
14368                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1
14369                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1 seek=10
14370                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1
14371                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1 seek=10
14372                 rm -f $DIR/$tfile
14373         done
14374
14375         $LCTL get_param llite.*.extents_stats
14376
14377         count=2
14378         for bsize in 4K 8K 16K 32K 64K 128K 256K 512K 1M 2M 4M 8M 16M 32M 64M;
14379                 do
14380                 local bucket=$($LCTL get_param -n llite.*.extents_stats |
14381                                 grep -m 1 $bsize)
14382                 reads=$(echo $bucket | awk '{print $5}')
14383                 writes=$(echo $bucket | awk '{print $9}')
14384                 [ "$reads" -eq $count ] ||
14385                         error "$reads reads in < $bsize bucket, expect $count"
14386                 [ "$writes" -eq $count ] ||
14387                         error "$writes writes in < $bsize bucket, expect $count"
14388         done
14389
14390         # Test mmap write and read
14391         $LCTL set_param llite.*.extents_stats=c
14392         size=512
14393         dd if=/dev/zero of=$DIR/$tfile bs=${size}K count=1
14394         $MULTIOP $DIR/$tfile OSMRUc || error "$MULTIOP $DIR/$tfile failed"
14395         $MULTIOP $DIR/$tfile OSMWUc || error "$MULTIOP $DIR/$tfile failed"
14396
14397         $LCTL get_param llite.*.extents_stats
14398
14399         count=$(((size*1024) / PAGE_SIZE))
14400
14401         bsize=$((2 * PAGE_SIZE / 1024))K
14402
14403         bucket=$($LCTL get_param -n llite.*.extents_stats |
14404                         grep -m 1 $bsize)
14405         reads=$(echo $bucket | awk '{print $5}')
14406         writes=$(echo $bucket | awk '{print $9}')
14407         # mmap writes fault in the page first, creating an additonal read
14408         [ "$reads" -eq $((2 * count)) ] ||
14409                 error "$reads reads in < $bsize bucket, expect $count"
14410         [ "$writes" -eq $count ] ||
14411                 error "$writes writes in < $bsize bucket, expect $count"
14412 }
14413 run_test 127c "test llite extent stats with regular & mmap i/o"
14414
14415 test_128() { # bug 15212
14416         touch $DIR/$tfile
14417         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
14418                 find $DIR/$tfile
14419                 find $DIR/$tfile
14420         EOF
14421
14422         result=$(grep error $TMP/$tfile.log)
14423         rm -f $DIR/$tfile $TMP/$tfile.log
14424         [ -z "$result" ] ||
14425                 error "consecutive find's under interactive lfs failed"
14426 }
14427 run_test 128 "interactive lfs for 2 consecutive find's"
14428
14429 set_dir_limits () {
14430         local mntdev
14431         local canondev
14432         local node
14433
14434         local ldproc=/proc/fs/ldiskfs
14435         local facets=$(get_facets MDS)
14436
14437         for facet in ${facets//,/ }; do
14438                 canondev=$(ldiskfs_canon \
14439                            *.$(convert_facet2label $facet).mntdev $facet)
14440                 do_facet $facet "test -e $ldproc/$canondev/max_dir_size" ||
14441                         ldproc=/sys/fs/ldiskfs
14442                 do_facet $facet "echo $1 >$ldproc/$canondev/max_dir_size"
14443                 do_facet $facet "echo $2 >$ldproc/$canondev/warning_dir_size"
14444         done
14445 }
14446
14447 check_mds_dmesg() {
14448         local facets=$(get_facets MDS)
14449         for facet in ${facets//,/ }; do
14450                 do_facet $facet "dmesg | tail -3 | grep $1" && return 0
14451         done
14452         return 1
14453 }
14454
14455 test_129() {
14456         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14457         [[ $MDS1_VERSION -ge $(version_code 2.5.56) ]] ||
14458                 skip "Need MDS version with at least 2.5.56"
14459         if [ "$mds1_FSTYPE" != ldiskfs ]; then
14460                 skip_env "ldiskfs only test"
14461         fi
14462         remote_mds_nodsh && skip "remote MDS with nodsh"
14463
14464         local ENOSPC=28
14465         local has_warning=false
14466
14467         rm -rf $DIR/$tdir
14468         mkdir -p $DIR/$tdir
14469
14470         # block size of mds1
14471         local maxsize=$(($($LCTL get_param -n mdc.*MDT0000*.blocksize) * 8))
14472         set_dir_limits $maxsize $((maxsize * 6 / 8))
14473         stack_trap "set_dir_limits 0 0"
14474         stack_trap "unlinkmany $DIR/$tdir/file_base_ 2000 || true"
14475         local dirsize=$(stat -c%s "$DIR/$tdir")
14476         local nfiles=0
14477         while (( $dirsize <= $maxsize )); do
14478                 $MCREATE $DIR/$tdir/file_base_$nfiles
14479                 rc=$?
14480                 # check two errors:
14481                 # ENOSPC for ext4 max_dir_size, which has been used since
14482                 # kernel v3.6-rc1-8-gdf981d03ee, lustre v2_4_50_0-79-gaed82035c0
14483                 if (( rc == ENOSPC )); then
14484                         set_dir_limits 0 0
14485                         echo "rc=$rc returned as expected after $nfiles files"
14486
14487                         createmany -o $DIR/$tdir/file_extra_$nfiles. 5 ||
14488                                 error "create failed w/o dir size limit"
14489
14490                         # messages may be rate limited if test is run repeatedly
14491                         check_mds_dmesg '"is approaching max"' ||
14492                                 echo "warning message should be output"
14493                         check_mds_dmesg '"has reached max"' ||
14494                                 echo "reached message should be output"
14495
14496                         dirsize=$(stat -c%s "$DIR/$tdir")
14497
14498                         [[ $dirsize -ge $maxsize ]] && return 0
14499                         error "dirsize $dirsize < $maxsize after $nfiles files"
14500                 elif (( rc != 0 )); then
14501                         break
14502                 fi
14503                 nfiles=$((nfiles + 1))
14504                 dirsize=$(stat -c%s "$DIR/$tdir")
14505         done
14506
14507         error "rc=$rc, size=$dirsize/$maxsize, mdt=$MDSCOUNT, nfiles=$nfiles"
14508 }
14509 run_test 129 "test directory size limit ========================"
14510
14511 OLDIFS="$IFS"
14512 cleanup_130() {
14513         trap 0
14514         IFS="$OLDIFS"
14515         rm -f $DIR/$tfile
14516 }
14517
14518 test_130a() {
14519         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
14520         [[ -z "$filefrag_op" ]] || skip_env "filefrag does not support FIEMAP"
14521
14522         trap cleanup_130 EXIT RETURN
14523
14524         local fm_file=$DIR/$tfile
14525         $LFS setstripe -S 65536 -c 1 $fm_file || error "setstripe on $fm_file"
14526         dd if=/dev/zero of=$fm_file bs=65536 count=1 ||
14527                 error "dd failed for $fm_file"
14528
14529         # LU-1795: test filefrag/FIEMAP once, even if unsupported on ZFS
14530         filefrag -ves $fm_file
14531         local rc=$?
14532         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14533                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14534         (( $rc == 0 )) || error "filefrag $fm_file failed"
14535
14536         filefrag_op=$(filefrag -ve -k $fm_file |
14537                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
14538         local lun=$($LFS getstripe -i $fm_file)
14539
14540         local start_blk=$(echo $filefrag_op | cut -d: -f2 | cut -d. -f1)
14541         IFS=$'\n'
14542         local tot_len=0
14543         for line in $filefrag_op; do
14544                 local frag_lun=$(echo $line | cut -d: -f5)
14545                 local ext_len=$(echo $line | cut -d: -f4)
14546
14547                 if (( $frag_lun != $lun )); then
14548                         error "FIEMAP on 1-stripe file($fm_file) failed"
14549                         return
14550                 fi
14551                 (( tot_len += ext_len ))
14552         done
14553
14554         if (( lun != frag_lun || start_blk != 0 || tot_len != 64 )); then
14555                 error "FIEMAP on 1-stripe file($fm_file) failed"
14556                 return
14557         fi
14558
14559         echo "FIEMAP on single striped file succeeded"
14560 }
14561 run_test 130a "FIEMAP (1-stripe file)"
14562
14563 test_130b() {
14564         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
14565
14566         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
14567         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
14568         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14569                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14570
14571         trap cleanup_130 EXIT RETURN
14572
14573         local fm_file=$DIR/$tfile
14574         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
14575                 error "setstripe on $fm_file"
14576
14577         dd if=/dev/zero of=$fm_file bs=1M count=$OSTCOUNT ||
14578                 error "dd failed on $fm_file"
14579
14580         filefrag -ves $fm_file || error "filefrag $fm_file failed"
14581         filefrag_op=$(filefrag -ve -k $fm_file |
14582                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
14583
14584         local last_lun=$(echo $filefrag_op | cut -d: -f5 |
14585                          sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14586
14587         IFS=$'\n'
14588         local tot_len=0
14589         local num_luns=1
14590
14591         for line in $filefrag_op; do
14592                 local frag_lun=$(echo $line | cut -d: -f5 |
14593                                  sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14594                 local ext_len=$(echo $line | cut -d: -f4)
14595                 if (( $frag_lun != $last_lun )); then
14596                         if (( tot_len != 1024 )); then
14597                                 error "FIEMAP on $fm_file failed; returned len $tot_len for OST $last_lun instead of 1024"
14598                                 return
14599                         else
14600                                 (( num_luns += 1 ))
14601                                 tot_len=0
14602                         fi
14603                 fi
14604                 (( tot_len += ext_len ))
14605                 last_lun=$frag_lun
14606         done
14607         if (( num_luns != $OSTCOUNT || tot_len != 1024 )); then
14608                 error "FIEMAP on $fm_file failed; returned wrong number of luns or wrong len for OST $last_lun"
14609                 return
14610         fi
14611
14612         echo "FIEMAP on $OSTCOUNT-stripe file succeeded"
14613 }
14614 run_test 130b "FIEMAP ($OSTCOUNT-stripe file)"
14615
14616 test_130c() {
14617         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
14618
14619         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
14620         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
14621         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14622                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14623
14624         trap cleanup_130 EXIT RETURN
14625
14626         local fm_file=$DIR/$tfile
14627         $LFS setstripe -S 65536 -c 2 $fm_file || error "setstripe on $fm_file"
14628
14629         dd if=/dev/zero of=$fm_file seek=1 bs=1M count=1 ||
14630                 error "dd failed on $fm_file"
14631
14632         filefrag -ves $fm_file || error "filefrag $fm_file failed"
14633         filefrag_op=$(filefrag -ve -k $fm_file |
14634                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
14635
14636         local last_lun=$(echo $filefrag_op | cut -d: -f5 |
14637                          sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14638
14639         IFS=$'\n'
14640         local tot_len=0
14641         local num_luns=1
14642         for line in $filefrag_op; do
14643                 local frag_lun=$(echo $line | cut -d: -f5 |
14644                                  sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14645                 local ext_len=$(echo $line | cut -d: -f4)
14646                 if (( $frag_lun != $last_lun )); then
14647                         local logical=$(echo $line | cut -d: -f2 | cut -d. -f1)
14648                         if (( logical != 512 )); then
14649                                 error "FIEMAP on $fm_file failed; returned logical start for lun $logical instead of 512"
14650                                 return
14651                         fi
14652                         if (( tot_len != 512 )); then
14653                                 error "FIEMAP on $fm_file failed; returned len $tot_len for OST $last_lun instead of 1024"
14654                                 return
14655                         else
14656                                 (( num_luns += 1 ))
14657                                 tot_len=0
14658                         fi
14659                 fi
14660                 (( tot_len += ext_len ))
14661                 last_lun=$frag_lun
14662         done
14663         if (( num_luns != 2 || tot_len != 512 )); then
14664                 error "FIEMAP on $fm_file failed; returned wrong number of luns or wrong len for OST $last_lun"
14665                 return
14666         fi
14667
14668         echo "FIEMAP on 2-stripe file with hole succeeded"
14669 }
14670 run_test 130c "FIEMAP (2-stripe file with hole)"
14671
14672 test_130d() {
14673         (( $OSTCOUNT >= 3 )) || skip "needs >= 3 OSTs"
14674
14675         filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
14676         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
14677         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14678                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14679
14680         trap cleanup_130 EXIT RETURN
14681
14682         local fm_file=$DIR/$tfile
14683         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
14684                         error "setstripe on $fm_file"
14685
14686         local actual_stripe_count=$($LFS getstripe -c $fm_file)
14687         dd if=/dev/zero of=$fm_file bs=1M count=$actual_stripe_count ||
14688                 error "dd failed on $fm_file"
14689
14690         filefrag -ves $fm_file || error "filefrag $fm_file failed"
14691         filefrag_op=$(filefrag -ve -k $fm_file |
14692                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
14693
14694         local last_lun=$(echo $filefrag_op | cut -d: -f5 |
14695                          sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14696
14697         IFS=$'\n'
14698         local tot_len=0
14699         local num_luns=1
14700         for line in $filefrag_op; do
14701                 local frag_lun=$(echo $line | cut -d: -f5 |
14702                                  sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14703                 local ext_len=$(echo $line | cut -d: -f4)
14704                 if (( $frag_lun != $last_lun )); then
14705                         if (( tot_len != 1024 )); then
14706                                 error "FIEMAP on $fm_file failed; returned len $tot_len for OST $last_lun instead of 1024"
14707                                 return
14708                         else
14709                                 (( num_luns += 1 ))
14710                                 local tot_len=0
14711                         fi
14712                 fi
14713                 (( tot_len += ext_len ))
14714                 last_lun=$frag_lun
14715         done
14716         if (( num_luns != actual_stripe_count || tot_len != 1024 )); then
14717                 error "FIEMAP on $fm_file failed; returned wrong number of luns or wrong len for OST $last_lun"
14718                 return
14719         fi
14720
14721         echo "FIEMAP on N-stripe file succeeded"
14722 }
14723 run_test 130d "FIEMAP (N-stripe file)"
14724
14725 test_130e() {
14726         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
14727
14728         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
14729         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
14730         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14731                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14732
14733         trap cleanup_130 EXIT RETURN
14734
14735         local fm_file=$DIR/$tfile
14736         $LFS setstripe -S 131072 -c 2 $fm_file || error "setstripe on $fm_file"
14737         stack_trap "rm -f $fm_file"
14738
14739         local num_blks=512
14740         local expected_len=$(( (num_blks / 2) * 64 ))
14741         for ((i = 0; i < $num_blks; i++)); do
14742                 dd if=/dev/zero of=$fm_file count=1 bs=64k seek=$((2*$i)) \
14743                         conv=notrunc > /dev/null 2>&1
14744         done
14745
14746         filefrag -ves $fm_file || error "filefrag $fm_file failed"
14747         filefrag_op=$(filefrag -ve -k $fm_file |
14748                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
14749
14750         local last_lun=$(echo $filefrag_op | cut -d: -f5)
14751
14752         IFS=$'\n'
14753         local tot_len=0
14754         local num_luns=1
14755         for line in $filefrag_op; do
14756                 local frag_lun=$(echo $line | cut -d: -f5)
14757                 local ext_len=$(echo $line | cut -d: -f4)
14758                 if (( $frag_lun != $last_lun )); then
14759                         if (( tot_len != $expected_len )); then
14760                                 error "OST$last_lun $tot_len != $expected_len"
14761                         else
14762                                 (( num_luns += 1 ))
14763                                 tot_len=0
14764                         fi
14765                 fi
14766                 (( tot_len += ext_len ))
14767                 last_lun=$frag_lun
14768         done
14769         if (( num_luns != 2 || tot_len != $expected_len )); then
14770                 error "OST$last_lun $num_luns != 2, $tot_len != $expected_len"
14771         fi
14772
14773         echo "FIEMAP with continuation calls succeeded"
14774 }
14775 run_test 130e "FIEMAP (test continuation FIEMAP calls)"
14776
14777 test_130f() {
14778         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
14779         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
14780         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14781                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14782
14783         local fm_file=$DIR/$tfile
14784         $MULTIOP $fm_file oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T33554432c ||
14785                 error "multiop create with lov_delay_create on $fm_file"
14786
14787         filefrag -ves $fm_file || error "filefrag $fm_file failed"
14788         filefrag_extents=$(filefrag -vek $fm_file |
14789                            awk '/extents? found/ { print $2 }')
14790         if (( $filefrag_extents != 0 )); then
14791                 error "$fm_file: filefrag_extents=$filefrag_extents != 0"
14792         fi
14793
14794         rm -f $fm_file
14795 }
14796 run_test 130f "FIEMAP (unstriped file)"
14797
14798 test_130g() {
14799         (( $MDS1_VERSION >= $(version_code 2.12.53) )) ||
14800                 skip "Need MDS version with at least 2.12.53 for overstriping"
14801         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
14802         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
14803         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14804                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14805
14806         local file=$DIR/$tfile
14807         local nr=$((OSTCOUNT * 100))
14808
14809         $LFS setstripe -C $nr $file || error "failed to setstripe -C $nr $file"
14810
14811         stack_trap "rm -f $file"
14812         dd if=/dev/zero of=$file count=$nr bs=1M
14813         sync
14814         nr=$($LFS getstripe -c $file)
14815
14816         local extents=$(filefrag -v $file |
14817                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}' | wc -l)
14818
14819         echo "filefrag list $extents extents in file with stripecount $nr"
14820         if (( extents < nr )); then
14821                 $LFS getstripe $file
14822                 filefrag -v $file
14823                 error "filefrag printed $extents < $nr extents"
14824         fi
14825 }
14826 run_test 130g "FIEMAP (overstripe file)"
14827
14828 # Test for writev/readv
14829 test_131a() {
14830         rwv -f $DIR/$tfile -w -n 3 524288 1048576 1572864 ||
14831                 error "writev test failed"
14832         rwv -f $DIR/$tfile -r -v -n 2 1572864 1048576 ||
14833                 error "readv failed"
14834         rm -f $DIR/$tfile
14835 }
14836 run_test 131a "test iov's crossing stripe boundary for writev/readv"
14837
14838 test_131b() {
14839         local fsize=$((524288 + 1048576 + 1572864))
14840         rwv -f $DIR/$tfile -w -a -n 3 524288 1048576 1572864 &&
14841                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
14842                         error "append writev test failed"
14843
14844         ((fsize += 1572864 + 1048576))
14845         rwv -f $DIR/$tfile -w -a -n 2 1572864 1048576 &&
14846                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
14847                         error "append writev test failed"
14848         rm -f $DIR/$tfile
14849 }
14850 run_test 131b "test append writev"
14851
14852 test_131c() {
14853         rwv -f $DIR/$tfile -w -d -n 1 1048576 || return 0
14854         error "NOT PASS"
14855 }
14856 run_test 131c "test read/write on file w/o objects"
14857
14858 test_131d() {
14859         rwv -f $DIR/$tfile -w -n 1 1572864
14860         NOB=`rwv -f $DIR/$tfile -r -n 3 524288 524288 1048576 | awk '/error/ {print $6}'`
14861         if [ "$NOB" != 1572864 ]; then
14862                 error "Short read filed: read $NOB bytes instead of 1572864"
14863         fi
14864         rm -f $DIR/$tfile
14865 }
14866 run_test 131d "test short read"
14867
14868 test_131e() {
14869         rwv -f $DIR/$tfile -w -s 1048576 -n 1 1048576
14870         rwv -f $DIR/$tfile -r -z -s 0 -n 1 524288 || \
14871         error "read hitting hole failed"
14872         rm -f $DIR/$tfile
14873 }
14874 run_test 131e "test read hitting hole"
14875
14876 check_stats() {
14877         local facet=$1
14878         local op=$2
14879         local want=${3:-0}
14880         local res
14881
14882         # open             11 samples [usecs] 468 4793 13658 35791898
14883         case $facet in
14884         mds*) res=($(do_facet $facet \
14885                    $LCTL get_param mdt.$FSNAME-MDT0000.md_stats | grep "$op"))
14886                  ;;
14887         ost*) res=($(do_facet $facet \
14888                   $LCTL get_param obdfilter.$FSNAME-OST0000.stats | grep "$op"))
14889                  ;;
14890         *) error "Wrong facet '$facet'" ;;
14891         esac
14892         [[ -n "$res" ]] || error "counter for $op on $facet not incremented"
14893         # if $want is zero, it means any stat increment is ok.
14894         if (( $want > 0 )); then
14895                 local count=${res[1]}
14896
14897                 if (( $count != $want )); then
14898                         if [[ $facet =~ "mds" ]]; then
14899                                 do_nodes $(comma_list $(mdts_nodes)) \
14900                                         $LCTL get_param mdt.*.md_stats
14901                         else
14902                                 do_nodes $(comma_list $(osts-nodes)) \
14903                                         $LCTL get_param obdfilter.*.stats
14904                         fi
14905                         error "The $op counter on $facet is $count, not $want"
14906                 fi
14907         fi
14908 }
14909
14910 test_133a() {
14911         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14912         remote_ost_nodsh && skip "remote OST with nodsh"
14913         remote_mds_nodsh && skip "remote MDS with nodsh"
14914         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
14915                 skip_env "MDS doesn't support rename stats"
14916
14917         local testdir=$DIR/${tdir}/stats_testdir
14918
14919         mkdir -p $DIR/${tdir}
14920
14921         # clear stats.
14922         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14923         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
14924
14925         # verify mdt stats first.
14926         mkdir_on_mdt0 ${testdir} || error "mkdir_on_mdt0 failed"
14927         check_stats $SINGLEMDS "mkdir" 1
14928
14929         # clear "open" from "lfs mkdir" above
14930         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14931         touch ${testdir}/${tfile} || error "touch failed"
14932         check_stats $SINGLEMDS "open" 1
14933         check_stats $SINGLEMDS "close" 1
14934         [ $MDS1_VERSION -ge $(version_code 2.8.54) ] && {
14935                 mknod ${testdir}/${tfile}-pipe p || error "mknod failed"
14936                 check_stats $SINGLEMDS "mknod" 2
14937         }
14938         rm -f ${testdir}/${tfile}-pipe || error "pipe remove failed"
14939         check_stats $SINGLEMDS "unlink" 1
14940         rm -f ${testdir}/${tfile} || error "file remove failed"
14941         check_stats $SINGLEMDS "unlink" 2
14942
14943         # remove working dir and check mdt stats again.
14944         rmdir ${testdir} || error "rmdir failed"
14945         check_stats $SINGLEMDS "rmdir" 1
14946
14947         local testdir1=$DIR/${tdir}/stats_testdir1
14948         mkdir_on_mdt0 -p ${testdir}
14949         mkdir_on_mdt0 -p ${testdir1}
14950         touch ${testdir1}/test1
14951         mv ${testdir1}/test1 ${testdir} || error "file crossdir rename"
14952         check_stats $SINGLEMDS "crossdir_rename" 1
14953
14954         mv ${testdir}/test1 ${testdir}/test0 || error "file samedir rename"
14955         check_stats $SINGLEMDS "samedir_rename" 1
14956
14957         rm -rf $DIR/${tdir}
14958 }
14959 run_test 133a "Verifying MDT stats ========================================"
14960
14961 test_133b() {
14962         local res
14963
14964         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14965         remote_ost_nodsh && skip "remote OST with nodsh"
14966         remote_mds_nodsh && skip "remote MDS with nodsh"
14967
14968         local testdir=$DIR/${tdir}/stats_testdir
14969
14970         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
14971         mkdir_on_mdt0 ${testdir} || error "mkdir_on_mdt0 failed"
14972         touch ${testdir}/${tfile} || error "touch failed"
14973         cancel_lru_locks mdc
14974
14975         # clear stats.
14976         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14977         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
14978
14979         # extra mdt stats verification.
14980         chmod 444 ${testdir}/${tfile} || error "chmod failed"
14981         check_stats $SINGLEMDS "setattr" 1
14982         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14983         if [ $MDS1_VERSION -ne $(version_code 2.2.0) ]
14984         then            # LU-1740
14985                 ls -l ${testdir}/${tfile} > /dev/null|| error "ls failed"
14986                 check_stats $SINGLEMDS "getattr" 1
14987         fi
14988         rm -rf $DIR/${tdir}
14989
14990         # when DNE is enabled, MDT uses STATFS RPC to ping other targets
14991         # so the check below is not reliable
14992         [ $MDSCOUNT -eq 1 ] || return 0
14993
14994         # Sleep to avoid a cached response.
14995         #define OBD_STATFS_CACHE_SECONDS 1
14996         sleep 2
14997         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14998         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
14999         $LFS df || error "lfs failed"
15000         check_stats $SINGLEMDS "statfs" 1
15001
15002         # check aggregated statfs (LU-10018)
15003         [ $MDS1_VERSION -lt $(version_code 2.11.54) ] &&
15004                 return 0
15005         [ $CLIENT_VERSION -lt $(version_code 2.11.54) ] &&
15006                 return 0
15007         sleep 2
15008         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15009         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
15010         df $DIR
15011         check_stats $SINGLEMDS "statfs" 1
15012
15013         # We want to check that the client didn't send OST_STATFS to
15014         # ost1 but the MDT also uses OST_STATFS for precreate. So some
15015         # extra care is needed here.
15016         if remote_mds; then
15017                 local nid=$($LCTL list_nids | head -1 | sed  "s/\./\\\./g")
15018                 local param="obdfilter.$FSNAME-OST0000.exports.'$nid'.stats"
15019
15020                 res=$(do_facet ost1 $LCTL get_param $param | grep statfs)
15021                 [ "$res" ] && error "OST got STATFS"
15022         fi
15023
15024         return 0
15025 }
15026 run_test 133b "Verifying extra MDT stats =================================="
15027
15028 test_133c() {
15029         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15030         remote_ost_nodsh && skip "remote OST with nodsh"
15031         remote_mds_nodsh && skip "remote MDS with nodsh"
15032
15033         local testdir=$DIR/$tdir/stats_testdir
15034
15035         test_mkdir -p $testdir
15036
15037         # verify obdfilter stats.
15038         $LFS setstripe -c 1 -i 0 $testdir/$tfile
15039         sync
15040         cancel_lru_locks osc
15041         wait_delete_completed
15042
15043         # clear stats.
15044         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15045         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
15046
15047         dd if=/dev/zero of=$testdir/$tfile conv=notrunc bs=512k count=1 ||
15048                 error "dd failed"
15049         sync
15050         cancel_lru_locks osc
15051         check_stats ost1 "write" 1
15052
15053         dd if=$testdir/$tfile of=/dev/null bs=1k count=1 || error "dd failed"
15054         check_stats ost1 "read" 1
15055
15056         > $testdir/$tfile || error "truncate failed"
15057         check_stats ost1 "punch" 1
15058
15059         rm -f $testdir/$tfile || error "file remove failed"
15060         wait_delete_completed
15061         check_stats ost1 "destroy" 1
15062
15063         rm -rf $DIR/$tdir
15064 }
15065 run_test 133c "Verifying OST stats ========================================"
15066
15067 order_2() {
15068         local value=$1
15069         local orig=$value
15070         local order=1
15071
15072         while [ $value -ge 2 ]; do
15073                 order=$((order*2))
15074                 value=$((value/2))
15075         done
15076
15077         if [ $orig -gt $order ]; then
15078                 order=$((order*2))
15079         fi
15080         echo $order
15081 }
15082
15083 size_in_KMGT() {
15084     local value=$1
15085     local size=('K' 'M' 'G' 'T');
15086     local i=0
15087     local size_string=$value
15088
15089     while [ $value -ge 1024 ]; do
15090         if [ $i -gt 3 ]; then
15091             #T is the biggest unit we get here, if that is bigger,
15092             #just return XXXT
15093             size_string=${value}T
15094             break
15095         fi
15096         value=$((value >> 10))
15097         if [ $value -lt 1024 ]; then
15098             size_string=${value}${size[$i]}
15099             break
15100         fi
15101         i=$((i + 1))
15102     done
15103
15104     echo $size_string
15105 }
15106
15107 get_rename_size() {
15108         local size=$1
15109         local context=${2:-.}
15110         local sample=$(do_facet $SINGLEMDS $LCTL \
15111                 get_param mdt.$FSNAME-MDT0000.rename_stats |
15112                 grep -A1 $context |
15113                 awk '/ '${size}'/ {print $4}' | sed -e "s/,//g")
15114         echo $sample
15115 }
15116
15117 test_133d() {
15118         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15119         remote_ost_nodsh && skip "remote OST with nodsh"
15120         remote_mds_nodsh && skip "remote MDS with nodsh"
15121         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
15122                 skip_env "MDS doesn't support rename stats"
15123
15124         local testdir1=$DIR/${tdir}/stats_testdir1
15125         local testdir2=$DIR/${tdir}/stats_testdir2
15126         mkdir -p $DIR/${tdir} || error "mkdir $tdir failed"
15127
15128         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
15129
15130         mkdir_on_mdt0 ${testdir1} || error "mkdir $testdir1 failed"
15131         mkdir_on_mdt0 ${testdir2} || error "mkdir $testdir2 failed"
15132
15133         createmany -o $testdir1/test 512 || error "createmany failed"
15134
15135         # check samedir rename size
15136         mv ${testdir1}/test0 ${testdir1}/test_0
15137
15138         local testdir1_size=$(ls -l $DIR/${tdir} |
15139                 awk '/stats_testdir1/ {print $5}')
15140         local testdir2_size=$(ls -l $DIR/${tdir} |
15141                 awk '/stats_testdir2/ {print $5}')
15142
15143         testdir1_size=$(order_2 $testdir1_size)
15144         testdir2_size=$(order_2 $testdir2_size)
15145
15146         testdir1_size=$(size_in_KMGT $testdir1_size)
15147         testdir2_size=$(size_in_KMGT $testdir2_size)
15148
15149         echo "source rename dir size: ${testdir1_size}"
15150         echo "target rename dir size: ${testdir2_size}"
15151
15152         local cmd="do_facet $SINGLEMDS $LCTL "
15153         cmd+="get_param mdt.$FSNAME-MDT0000.rename_stats"
15154
15155         eval $cmd || error "$cmd failed"
15156         local samedir=$($cmd | grep 'same_dir')
15157         local same_sample=$(get_rename_size $testdir1_size)
15158         [ -z "$samedir" ] && error "samedir_rename_size count error"
15159         [[ $same_sample -eq 1 ]] ||
15160                 error "samedir_rename_size error $same_sample"
15161         echo "Check same dir rename stats success"
15162
15163         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
15164
15165         # check crossdir rename size
15166         mv ${testdir1}/test_0 ${testdir2}/test_0
15167
15168         testdir1_size=$(ls -l $DIR/${tdir} |
15169                 awk '/stats_testdir1/ {print $5}')
15170         testdir2_size=$(ls -l $DIR/${tdir} |
15171                 awk '/stats_testdir2/ {print $5}')
15172
15173         testdir1_size=$(order_2 $testdir1_size)
15174         testdir2_size=$(order_2 $testdir2_size)
15175
15176         testdir1_size=$(size_in_KMGT $testdir1_size)
15177         testdir2_size=$(size_in_KMGT $testdir2_size)
15178
15179         echo "source rename dir size: ${testdir1_size}"
15180         echo "target rename dir size: ${testdir2_size}"
15181
15182         eval $cmd || error "$cmd failed"
15183         local crossdir=$($cmd | grep 'crossdir')
15184         local src_sample=$(get_rename_size $testdir1_size crossdir_src)
15185         local tgt_sample=$(get_rename_size $testdir2_size crossdir_tgt)
15186         [ -z "$crossdir" ] && error "crossdir_rename_size count error"
15187         [[ $src_sample -eq 1 ]] ||
15188                 error "crossdir_rename_size error $src_sample"
15189         [[ $tgt_sample -eq 1 ]] ||
15190                 error "crossdir_rename_size error $tgt_sample"
15191         echo "Check cross dir rename stats success"
15192         rm -rf $DIR/${tdir}
15193 }
15194 run_test 133d "Verifying rename_stats ========================================"
15195
15196 test_133e() {
15197         remote_mds_nodsh && skip "remote MDS with nodsh"
15198         remote_ost_nodsh && skip "remote OST with nodsh"
15199         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15200
15201         local testdir=$DIR/${tdir}/stats_testdir
15202         local ctr f0 f1 bs=32768 count=42 sum
15203
15204         mkdir -p ${testdir} || error "mkdir failed"
15205
15206         $LFS setstripe -c 1 -i 0 ${testdir}/${tfile}
15207
15208         for ctr in {write,read}_bytes; do
15209                 sync
15210                 cancel_lru_locks osc
15211
15212                 do_facet ost1 $LCTL set_param -n \
15213                         "obdfilter.*.exports.clear=clear"
15214
15215                 if [ $ctr = write_bytes ]; then
15216                         f0=/dev/zero
15217                         f1=${testdir}/${tfile}
15218                 else
15219                         f0=${testdir}/${tfile}
15220                         f1=/dev/null
15221                 fi
15222
15223                 dd if=$f0 of=$f1 conv=notrunc bs=$bs count=$count || \
15224                         error "dd failed"
15225                 sync
15226                 cancel_lru_locks osc
15227
15228                 sum=$(do_facet ost1 $LCTL get_param \
15229                         "obdfilter.*.exports.*.stats" |
15230                         awk -v ctr=$ctr 'BEGIN { sum = 0 }
15231                                 $1 == ctr { sum += $7 }
15232                                 END { printf("%0.0f", sum) }')
15233
15234                 if ((sum != bs * count)); then
15235                         error "Bad $ctr sum, expected $((bs * count)), got $sum"
15236                 fi
15237         done
15238
15239         rm -rf $DIR/${tdir}
15240 }
15241 run_test 133e "Verifying OST {read,write}_bytes nid stats ================="
15242
15243 test_133f() {
15244         [[ $(lustre_version_code $facet) -ge $(version_code 2.7.65) ]] ||
15245                 skip "too old lustre for get_param -R ($facet_ver)"
15246
15247         # verifying readability.
15248         $LCTL get_param -R '*' &> /dev/null
15249
15250         # Verifing writability with badarea_io.
15251         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
15252         local skipped_params='force_lbug|changelog_mask|daemon_file'
15253         $LCTL list_param -FR '*' | grep '=' | tr -d = |
15254                 egrep -v "$skipped_params" |
15255                 xargs -n 1 find $proc_dirs -name |
15256                 xargs -n 1 badarea_io ||
15257                 error "client badarea_io failed"
15258
15259         # remount the FS in case writes/reads /proc break the FS
15260         cleanup || error "failed to unmount"
15261         setup || error "failed to setup"
15262 }
15263 run_test 133f "Check reads/writes of client lustre proc files with bad area io"
15264
15265 test_133g() {
15266         remote_mds_nodsh && skip "remote MDS with nodsh"
15267         remote_ost_nodsh && skip "remote OST with nodsh"
15268
15269         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
15270         local proc_dirs_str=$(eval echo $proc_dirs)
15271         local skipped_params="'force_lbug|changelog_mask|daemon_file'"
15272         local facet
15273         for facet in mds1 ost1; do
15274                 local facet_ver=$(lustre_version_code $facet)
15275                 if [ $facet_ver -ge $(version_code 2.7.65) ]; then
15276                         do_facet $facet "$LCTL get_param -R '*'" &> /dev/null
15277                 else
15278                         log "$facet: too old lustre for get_param -R"
15279                 fi
15280                 if [ $facet_ver -ge $(version_code 2.5.54) ]; then
15281                         do_facet $facet "$LCTL list_param -FR '*' | grep '=' |
15282                                 tr -d = | egrep -v $skipped_params |
15283                                 xargs -n 1 find $proc_dirs_str -name |
15284                                 xargs -n 1 badarea_io" ||
15285                                         error "$facet badarea_io failed"
15286                 else
15287                         skip_noexit "$facet: too old lustre for get_param -R"
15288                 fi
15289         done
15290
15291         # remount the FS in case writes/reads /proc break the FS
15292         cleanup || error "failed to unmount"
15293         setup || error "failed to setup"
15294 }
15295 run_test 133g "Check reads/writes of server lustre proc files with bad area io"
15296
15297 test_133h() {
15298         remote_mds_nodsh && skip "remote MDS with nodsh"
15299         remote_ost_nodsh && skip "remote OST with nodsh"
15300         [[ $MDS1_VERSION -lt $(version_code 2.9.54) ]] &&
15301                 skip "Need MDS version at least 2.9.54"
15302
15303         local facet
15304         for facet in client mds1 ost1; do
15305                 # Get the list of files that are missing the terminating newline
15306                 local plist=$(do_facet $facet
15307                         $LCTL list_param -FR '*' | grep '=' | tr -d =)
15308                 local ent
15309                 for ent in $plist; do
15310                         local missing=$(do_facet $facet $LCTL get_param $ent \|\
15311                                 awk -v FS='\v' -v RS='\v\v' \
15312                                 "'END { if(NR>0 && \\\$NF !~ /.*\\\n\$/) \
15313                                         print FILENAME}'" 2>/dev/null)
15314                         [ -z $missing ] || {
15315                                 do_facet $facet $LCTL get_param $ent | od -An -tx1
15316                                 error "file does not end with newline: $facet-$ent"
15317                         }
15318                 done
15319         done
15320 }
15321 run_test 133h "Proc files should end with newlines"
15322
15323 test_134a() {
15324         remote_mds_nodsh && skip "remote MDS with nodsh"
15325         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
15326                 skip "Need MDS version at least 2.7.54"
15327
15328         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
15329         cancel_lru_locks mdc
15330
15331         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
15332         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
15333         [ $unused -eq 0 ] || error "$unused locks are not cleared"
15334
15335         local nr=1000
15336         createmany -o $DIR/$tdir/f $nr ||
15337                 error "failed to create $nr files in $DIR/$tdir"
15338         unused=$($LCTL get_param -n $nsdir.lock_unused_count)
15339
15340         #define OBD_FAIL_LDLM_WATERMARK_LOW     0x327
15341         do_facet mds1 $LCTL set_param fail_loc=0x327
15342         do_facet mds1 $LCTL set_param fail_val=500
15343         touch $DIR/$tdir/m
15344
15345         echo "sleep 10 seconds ..."
15346         sleep 10
15347         local lck_cnt=$($LCTL get_param -n $nsdir.lock_unused_count)
15348
15349         do_facet mds1 $LCTL set_param fail_loc=0
15350         do_facet mds1 $LCTL set_param fail_val=0
15351         [ $lck_cnt -lt $unused ] ||
15352                 error "No locks reclaimed, before:$unused, after:$lck_cnt"
15353
15354         rm $DIR/$tdir/m
15355         unlinkmany $DIR/$tdir/f $nr
15356 }
15357 run_test 134a "Server reclaims locks when reaching lock_reclaim_threshold"
15358
15359 test_134b() {
15360         remote_mds_nodsh && skip "remote MDS with nodsh"
15361         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
15362                 skip "Need MDS version at least 2.7.54"
15363
15364         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
15365         cancel_lru_locks mdc
15366
15367         local low_wm=$(do_facet mds1 $LCTL get_param -n \
15368                         ldlm.lock_reclaim_threshold_mb)
15369         # disable reclaim temporarily
15370         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=0
15371
15372         #define OBD_FAIL_LDLM_WATERMARK_HIGH     0x328
15373         do_facet mds1 $LCTL set_param fail_loc=0x328
15374         do_facet mds1 $LCTL set_param fail_val=500
15375
15376         $LCTL set_param debug=+trace
15377
15378         local nr=600
15379         createmany -o $DIR/$tdir/f $nr &
15380         local create_pid=$!
15381
15382         echo "Sleep $TIMEOUT seconds ..."
15383         sleep $TIMEOUT
15384         if ! ps -p $create_pid  > /dev/null 2>&1; then
15385                 do_facet mds1 $LCTL set_param fail_loc=0
15386                 do_facet mds1 $LCTL set_param fail_val=0
15387                 do_facet mds1 $LCTL set_param \
15388                         ldlm.lock_reclaim_threshold_mb=${low_wm}m
15389                 error "createmany finished incorrectly!"
15390         fi
15391         do_facet mds1 $LCTL set_param fail_loc=0
15392         do_facet mds1 $LCTL set_param fail_val=0
15393         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=${low_wm}m
15394         wait $create_pid || return 1
15395
15396         unlinkmany $DIR/$tdir/f $nr
15397 }
15398 run_test 134b "Server rejects lock request when reaching lock_limit_mb"
15399
15400 test_135() {
15401         remote_mds_nodsh && skip "remote MDS with nodsh"
15402         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
15403                 skip "Need MDS version at least 2.13.50"
15404         local fname
15405
15406         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
15407
15408 #define OBD_FAIL_PLAIN_RECORDS 0x1319
15409         #set only one record at plain llog
15410         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1319 fail_val=1
15411
15412         ost_set_temp_seq_width_all $DATA_SEQ_MAX_WIDTH
15413
15414         #fill already existed plain llog each 64767
15415         #wrapping whole catalog
15416         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
15417
15418         createmany -o $DIR/$tdir/$tfile_ 64700
15419         for (( i = 0; i < 64700; i = i + 2 ))
15420         do
15421                 rm $DIR/$tdir/$tfile_$i &
15422                 rm $DIR/$tdir/$tfile_$((i + 1)) &
15423                 local pid=$!
15424                 wait $pid
15425         done
15426
15427         #waiting osp synchronization
15428         wait_delete_completed
15429 }
15430 run_test 135 "Race catalog processing"
15431
15432 test_136() {
15433         remote_mds_nodsh && skip "remote MDS with nodsh"
15434         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
15435                 skip "Need MDS version at least 2.13.50"
15436         local fname
15437
15438         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
15439         $LFS setstripe -c 1 -i 0 $DIR/$tdir || error "failed to set striping"
15440         #set only one record at plain llog
15441 #define OBD_FAIL_CATALOG_FULL_CHECK                0x131a
15442         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x131a fail_val=1
15443
15444         ost_set_temp_seq_width_all $DATA_SEQ_MAX_WIDTH
15445
15446         #fill already existed 2 plain llogs each 64767
15447         #wrapping whole catalog
15448         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
15449         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 3 / 2))
15450         wait_delete_completed
15451
15452         createmany -o $DIR/$tdir/$tfile_ 10
15453         sleep 25
15454
15455         do_facet $SINGLEMDS $LCTL set_param fail_val=3
15456         for (( i = 0; i < 10; i = i + 3 ))
15457         do
15458                 rm $DIR/$tdir/$tfile_$i &
15459                 rm $DIR/$tdir/$tfile_$((i + 1)) &
15460                 local pid=$!
15461                 wait $pid
15462                 sleep 7
15463                 rm $DIR/$tdir/$tfile_$((i + 2)) &
15464         done
15465
15466         #waiting osp synchronization
15467         wait_delete_completed
15468 }
15469 run_test 136 "Race catalog processing 2"
15470
15471 test_140() { #bug-17379
15472         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15473
15474         test_mkdir $DIR/$tdir
15475         cd $DIR/$tdir || error "Changing to $DIR/$tdir"
15476         cp $(which stat) . || error "Copying stat to $DIR/$tdir"
15477
15478         # VFS limits max symlink depth to 5(4KSTACK) or 7(8KSTACK) or 8
15479         # For kernel > 3.5, bellow only tests consecutive symlink (MAX 40)
15480         local i=0
15481         while i=$((i + 1)); do
15482                 test_mkdir $i
15483                 cd $i || error "Changing to $i"
15484                 ln -s ../stat stat || error "Creating stat symlink"
15485                 # Read the symlink until ELOOP present,
15486                 # not LBUGing the system is considered success,
15487                 # we didn't overrun the stack.
15488                 $OPENFILE -f O_RDONLY stat >/dev/null 2>&1; ret=$?
15489                 if [ $ret -ne 0 ]; then
15490                         if [ $ret -eq 40 ]; then
15491                                 break  # -ELOOP
15492                         else
15493                                 error "Open stat symlink"
15494                                         return
15495                         fi
15496                 fi
15497         done
15498         i=$((i - 1))
15499         echo "The symlink depth = $i"
15500         [ $i -eq 5 ] || [ $i -eq 7 ] || [ $i -eq 8 ] || [ $i -eq 40 ] ||
15501                 error "Invalid symlink depth"
15502
15503         # Test recursive symlink
15504         ln -s symlink_self symlink_self
15505         $OPENFILE -f O_RDONLY symlink_self >/dev/null 2>&1; ret=$?
15506         echo "open symlink_self returns $ret"
15507         [ $ret -eq 40 ] || error "recursive symlink doesn't return -ELOOP"
15508 }
15509 run_test 140 "Check reasonable stack depth (shouldn't LBUG) ===="
15510
15511 test_150a() {
15512         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15513
15514         local TF="$TMP/$tfile"
15515
15516         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15517         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
15518         cp $TF $DIR/$tfile
15519         cancel_lru_locks $OSC
15520         cmp $TF $DIR/$tfile || error "$TMP/$tfile $DIR/$tfile differ"
15521         remount_client $MOUNT
15522         df -P $MOUNT
15523         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (remount)"
15524
15525         $TRUNCATE $TF 6000
15526         $TRUNCATE $DIR/$tfile 6000
15527         cancel_lru_locks $OSC
15528         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (truncate1)"
15529
15530         echo "12345" >>$TF
15531         echo "12345" >>$DIR/$tfile
15532         cancel_lru_locks $OSC
15533         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append1)"
15534
15535         echo "12345" >>$TF
15536         echo "12345" >>$DIR/$tfile
15537         cancel_lru_locks $OSC
15538         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append2)"
15539 }
15540 run_test 150a "truncate/append tests"
15541
15542 test_150b() {
15543         check_set_fallocate_or_skip
15544         local out
15545
15546         touch $DIR/$tfile
15547         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15548         out=$(check_fallocate $DIR/$tfile 2>&1) ||
15549                 skip_eopnotsupp "$out|check_fallocate failed"
15550 }
15551 run_test 150b "Verify fallocate (prealloc) functionality"
15552
15553 test_150bb() {
15554         check_set_fallocate_or_skip
15555
15556         touch $DIR/$tfile
15557         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15558         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=20 || error "dd failed"
15559         > $DIR/$tfile
15560         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
15561         # precomputed md5sum for 20MB of zeroes
15562         local expect="8f4e33f3dc3e414ff94e5fb6905cba8c"
15563         local sum=($(md5sum $DIR/$tfile))
15564
15565         [[ "${sum[0]}" == "$expect" ]] || error "fallocate unwritten is not zero"
15566
15567         check_set_fallocate 1
15568
15569         > $DIR/$tfile
15570         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
15571         sum=($(md5sum $DIR/$tfile))
15572
15573         [[ "${sum[0]}" == "$expect" ]] || error "fallocate zero is not zero"
15574 }
15575 run_test 150bb "Verify fallocate modes both zero space"
15576
15577 test_150c() {
15578         check_set_fallocate_or_skip
15579         local striping="-c2"
15580
15581         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15582         $LFS setstripe -c $OSTCOUNT -S1M $DIR/$tfile || error "setstripe failed"
15583         fallocate -l ${OSTCOUNT}m $DIR/$tfile || error "fallocate failed"
15584         local bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
15585         local want=$((OSTCOUNT * 1048576))
15586
15587         # Must allocate all requested space, not more than 5% extra
15588         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
15589                 error "bytes $bytes is not $want"
15590
15591         rm -f $DIR/$tfile
15592
15593         echo "verify fallocate on PFL file"
15594
15595         [[ "x$DOM" == "xyes" ]] && striping="-L mdt"
15596
15597         $LFS setstripe -E1M $striping -E16M -c3 -Eeof -c 4 $DIR/$tfile ||
15598                 error "Create $DIR/$tfile failed"
15599         fallocate -l $((1048576 * 512)) $DIR/$tfile || error "fallocate failed"
15600         bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
15601         want=$((512 * 1048576))
15602
15603         # Must allocate all requested space, not more than 5% extra
15604         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
15605                 error "bytes $bytes is not $want"
15606 }
15607 run_test 150c "Verify fallocate Size and Blocks"
15608
15609 test_150d() {
15610         check_set_fallocate_or_skip
15611         local striping="-c2"
15612
15613         [[ "x$DOM" == "xyes" ]] && striping="-L mdt"
15614
15615         stack_trap "rm -f $DIR/$tdir; wait_delete_completed"
15616         $LFS setstripe -E1M $striping -E eof -c $OSTCOUNT -S1M $DIR/$tdir ||
15617                 error "setstripe failed"
15618         fallocate -o 1G -l ${OSTCOUNT}m $DIR/$tdir || error "fallocate failed"
15619         local bytes=$(($(stat -c '%b * %B' $DIR/$tdir)))
15620         local want=$((OSTCOUNT * 1048576))
15621
15622         # Must allocate all requested space, not more than 5% extra
15623         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
15624                 error "bytes $bytes is not $want"
15625 }
15626 run_test 150d "Verify fallocate Size and Blocks - Non zero start"
15627
15628 test_150e() {
15629         check_set_fallocate_or_skip
15630
15631         echo "df before:"
15632         $LFS df
15633         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15634         $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
15635                 error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
15636
15637         # Find OST with Minimum Size
15638         min_size_ost=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
15639                        sort -un | head -1)
15640
15641         # Get 100MB per OST of the available space to reduce run time
15642         # else 60% of the available space if we are running SLOW tests
15643         if [ $SLOW == "no" ]; then
15644                 local space=$((1024 * 100 * OSTCOUNT))
15645         else
15646                 local space=$(((min_size_ost * 60)/100 * OSTCOUNT))
15647         fi
15648
15649         fallocate -l${space}k $DIR/$tfile ||
15650                 error "fallocate ${space}k $DIR/$tfile failed"
15651         echo "'fallocate -l ${space}k $DIR/$tfile' succeeded"
15652
15653         # get size immediately after fallocate. This should be correctly
15654         # updated
15655         local size=$(stat -c '%s' $DIR/$tfile)
15656         local used=$(( $(stat -c '%b * %B' $DIR/$tfile) / 1024))
15657
15658         # Sleep for a while for statfs to get updated. And not pull from cache.
15659         sleep 2
15660
15661         echo "df after fallocate:"
15662         $LFS df
15663
15664         (( size / 1024 == space )) || error "size $size != requested $space"
15665         [ "$ost1_FSTYPE" != ldiskfs ] || (( used >= space )) ||
15666                 error "used $used < space $space"
15667
15668         rm $DIR/$tfile || error "rm failed"
15669         sync
15670         wait_delete_completed
15671
15672         echo "df after unlink:"
15673         $LFS df
15674 }
15675 run_test 150e "Verify 60% of available OST space consumed by fallocate"
15676
15677 test_150f() {
15678         local size
15679         local blocks
15680         local want_size_before=20480 # in bytes
15681         local want_blocks_before=40 # 512 sized blocks
15682         local want_blocks_after=24  # 512 sized blocks
15683         local length=$(((want_blocks_before - want_blocks_after) * 512))
15684
15685         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
15686                 skip "need at least 2.14.0 for fallocate punch"
15687
15688         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
15689                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
15690         fi
15691
15692         check_set_fallocate_or_skip
15693         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15694
15695         [[ "x$DOM" == "xyes" ]] &&
15696                 $LFS setstripe -E1M -L mdt -E eof $DIR/$tfile
15697
15698         echo "Verify fallocate punch: Range within the file range"
15699         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
15700                 error "dd failed for bs 4096 and count 5"
15701
15702         # Call fallocate with punch range which is within the file range
15703         out=$(fallocate -p --offset 4096 -l $length $DIR/$tfile 2>&1) ||
15704                 skip_eopnotsupp "$out|fallocate: offset 4096 and length $length"
15705         # client must see changes immediately after fallocate
15706         size=$(stat -c '%s' $DIR/$tfile)
15707         blocks=$(stat -c '%b' $DIR/$tfile)
15708
15709         # Verify punch worked.
15710         (( blocks == want_blocks_after )) ||
15711                 error "punch failed: blocks $blocks != $want_blocks_after"
15712
15713         (( size == want_size_before )) ||
15714                 error "punch failed: size $size != $want_size_before"
15715
15716         # Verify there is hole in file
15717         local data_off=$(lseek_test -d 4096 $DIR/$tfile)
15718         # precomputed md5sum
15719         local expect="4a9a834a2db02452929c0a348273b4aa"
15720
15721         cksum=($(md5sum $DIR/$tfile))
15722         [[ "${cksum[0]}" == "$expect" ]] ||
15723                 error "unexpected MD5SUM after punch: ${cksum[0]}"
15724
15725         # Start second sub-case for fallocate punch.
15726         echo "Verify fallocate punch: Range overlapping and less than blocksize"
15727         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
15728                 error "dd failed for bs 4096 and count 5"
15729
15730         # Punch range less than block size will have no change in block count
15731         want_blocks_after=40  # 512 sized blocks
15732
15733         # Punch overlaps two blocks and less than blocksize
15734         out=$(fallocate -p --offset 4000 -l 3000 $DIR/$tfile 2>&1) ||
15735                 skip_eopnotsupp "$out|fallocate: offset 4000 length 3000"
15736         size=$(stat -c '%s' $DIR/$tfile)
15737         blocks=$(stat -c '%b' $DIR/$tfile)
15738
15739         # Verify punch worked.
15740         (( blocks == want_blocks_after )) ||
15741                 error "punch failed: blocks $blocks != $want_blocks_after"
15742
15743         (( size == want_size_before )) ||
15744                 error "punch failed: size $size != $want_size_before"
15745
15746         # Verify if range is really zero'ed out. We expect Zeros.
15747         # precomputed md5sum
15748         expect="c57ec5d769c3dbe3426edc3f7d7e11d3"
15749         cksum=($(md5sum $DIR/$tfile))
15750         [[ "${cksum[0]}" == "$expect" ]] ||
15751                 error "unexpected MD5SUM after punch: ${cksum[0]}"
15752 }
15753 run_test 150f "Verify fallocate punch functionality"
15754
15755 test_150g() {
15756         local space
15757         local size
15758         local blocks
15759         local blocks_after
15760         local size_after
15761         local BS=4096 # Block size in bytes
15762
15763         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
15764                 skip "need at least 2.14.0 for fallocate punch"
15765
15766         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
15767                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
15768         fi
15769
15770         check_set_fallocate_or_skip
15771         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15772
15773         if [[ "x$DOM" == "xyes" ]]; then
15774                 $LFS setstripe -E2M -L mdt -E eof -c${OSTCOUNT} $DIR/$tfile ||
15775                         error "$LFS setstripe DoM + ${OSTCOUNT} OST failed"
15776         else
15777                 $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
15778                         error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
15779         fi
15780
15781         # Get 100MB per OST of the available space to reduce run time
15782         # else 60% of the available space if we are running SLOW tests
15783         if [ $SLOW == "no" ]; then
15784                 space=$((1024 * 100 * OSTCOUNT))
15785         else
15786                 # Find OST with Minimum Size
15787                 space=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
15788                         sort -un | head -1)
15789                 echo "min size OST: $space"
15790                 space=$(((space * 60)/100 * OSTCOUNT))
15791         fi
15792         # space in 1k units, round to 4k blocks
15793         local blkcount=$((space * 1024 / $BS))
15794
15795         echo "Verify fallocate punch: Very large Range"
15796         fallocate -l${space}k $DIR/$tfile ||
15797                 error "fallocate ${space}k $DIR/$tfile failed"
15798         # write 1M at the end, start and in the middle
15799         yes 'A' | dd of=$DIR/$tfile bs=$BS count=256 ||
15800                 error "dd failed: bs $BS count 256"
15801         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount - 256)) count=256 ||
15802                 error "dd failed: bs $BS count 256 seek $((blkcount - 256))"
15803         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount / 2)) count=1024 ||
15804                 error "dd failed: bs $BS count 256 seek $((blkcount / 2))"
15805
15806         # Gather stats.
15807         size=$(stat -c '%s' $DIR/$tfile)
15808
15809         # gather punch length.
15810         local punch_size=$((size - (BS * 2)))
15811
15812         echo "punch_size = $punch_size"
15813         echo "size - punch_size: $((size - punch_size))"
15814         echo "size - punch_size in blocks: $(((size - punch_size)/BS))"
15815
15816         # Call fallocate to punch all except 2 blocks. We leave the
15817         # first and the last block
15818         echo "fallocate -p --offset $BS -l $punch_size $DIR/$tfile"
15819         out=$(fallocate -p --offset $BS -l $punch_size $DIR/$tfile 2>&1) ||
15820                 skip_eopnotsupp "$out|fallocate: offset $BS length $punch_size"
15821
15822         size_after=$(stat -c '%s' $DIR/$tfile)
15823         blocks_after=$(stat -c '%b' $DIR/$tfile)
15824
15825         # Verify punch worked.
15826         # Size should be kept
15827         (( size == size_after )) ||
15828                 error "punch failed: size $size != $size_after"
15829
15830         # two 4k data blocks to remain plus possible 1 extra extent block
15831         (( blocks_after <= ((BS / 512) * 3) )) ||
15832                 error "too many blocks remains: $blocks_after"
15833
15834         # Verify that file has hole between the first and the last blocks
15835         local hole_start=$(lseek_test -l 0 $DIR/$tfile)
15836         local hole_end=$(lseek_test -d $BS $DIR/$tfile)
15837
15838         echo "Hole at [$hole_start, $hole_end)"
15839         (( hole_start == BS )) ||
15840                 error "no hole at offset $BS after punch"
15841
15842         (( hole_end == BS + punch_size )) ||
15843                 error "data at offset $hole_end < $((BS + punch_size))"
15844 }
15845 run_test 150g "Verify fallocate punch on large range"
15846
15847 test_150h() {
15848         local file=$DIR/$tfile
15849         local size
15850
15851         check_set_fallocate_or_skip
15852         statx_supported || skip_env "Test must be statx() syscall supported"
15853
15854         # fallocate() does not update the size information on the MDT
15855         fallocate -l 16K $file || error "failed to fallocate $file"
15856         cancel_lru_locks $OSC
15857         # STATX with cached-always mode will not send glimpse RPCs to OST,
15858         # it uses the caching attrs on the client side as much as possible.
15859         size=$($STATX --cached=always -c %s $file)
15860         [ $size == 16384 ] ||
15861                 error "size after fallocate() is $size, expected 16384"
15862 }
15863 run_test 150h "Verify extend fallocate updates the file size"
15864
15865 #LU-2902 roc_hit was not able to read all values from lproc
15866 function roc_hit_init() {
15867         local list=$(comma_list $(osts_nodes))
15868         local dir=$DIR/$tdir-check
15869         local file=$dir/$tfile
15870         local BEFORE
15871         local AFTER
15872         local idx
15873
15874         test_mkdir $dir
15875         #use setstripe to do a write to every ost
15876         for i in $(seq 0 $((OSTCOUNT-1))); do
15877                 $LFS setstripe -c 1 -i $i $dir || error "$LFS setstripe $file failed"
15878                 dd if=/dev/urandom of=$file bs=4k count=4 2>&1 > /dev/null
15879                 idx=$(printf %04x $i)
15880                 BEFORE=$(get_osd_param $list *OST*$idx stats |
15881                         awk '$1 == "cache_access" {sum += $7}
15882                                 END { printf("%0.0f", sum) }')
15883
15884                 cancel_lru_locks osc
15885                 cat $file >/dev/null
15886
15887                 AFTER=$(get_osd_param $list *OST*$idx stats |
15888                         awk '$1 == "cache_access" {sum += $7}
15889                                 END { printf("%0.0f", sum) }')
15890
15891                 echo BEFORE:$BEFORE AFTER:$AFTER
15892                 if ! let "AFTER - BEFORE == 4"; then
15893                         rm -rf $dir
15894                         error "roc_hit is not safe to use"
15895                 fi
15896                 rm $file
15897         done
15898
15899         rm -rf $dir
15900 }
15901
15902 function roc_hit() {
15903         local list=$(comma_list $(osts_nodes))
15904         echo $(get_osd_param $list '' stats |
15905                 awk '$1 == "cache_hit" {sum += $7}
15906                         END { printf("%0.0f", sum) }')
15907 }
15908
15909 function set_cache() {
15910         local on=1
15911
15912         if [ "$2" == "off" ]; then
15913                 on=0;
15914         fi
15915         local list=$(comma_list $(osts_nodes))
15916         set_osd_param $list '' $1_cache_enable $on
15917
15918         cancel_lru_locks osc
15919 }
15920
15921 test_151() {
15922         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15923         remote_ost_nodsh && skip "remote OST with nodsh"
15924         (( CLIENT_VERSION == OST1_VERSION )) ||
15925                 skip "LU-13081: no interop testing for OSS cache"
15926
15927         local CPAGES=3
15928         local list=$(comma_list $(osts_nodes))
15929
15930         # check whether obdfilter is cache capable at all
15931         if ! get_osd_param $list '' read_cache_enable >/dev/null; then
15932                 skip "not cache-capable obdfilter"
15933         fi
15934
15935         # check cache is enabled on all obdfilters
15936         if get_osd_param $list '' read_cache_enable | grep 0; then
15937                 skip "oss cache is disabled"
15938         fi
15939
15940         set_osd_param $list '' writethrough_cache_enable 1
15941
15942         # check write cache is enabled on all obdfilters
15943         if get_osd_param $list '' writethrough_cache_enable | grep 0; then
15944                 skip "oss write cache is NOT enabled"
15945         fi
15946
15947         roc_hit_init
15948
15949         #define OBD_FAIL_OBD_NO_LRU  0x609
15950         do_nodes $list $LCTL set_param fail_loc=0x609
15951
15952         # pages should be in the case right after write
15953         dd if=/dev/urandom of=$DIR/$tfile bs=4k count=$CPAGES ||
15954                 error "dd failed"
15955
15956         local BEFORE=$(roc_hit)
15957         cancel_lru_locks osc
15958         cat $DIR/$tfile >/dev/null
15959         local AFTER=$(roc_hit)
15960
15961         do_nodes $list $LCTL set_param fail_loc=0
15962
15963         if ! let "AFTER - BEFORE == CPAGES"; then
15964                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
15965         fi
15966
15967         cancel_lru_locks osc
15968         # invalidates OST cache
15969         do_nodes $list "echo 1 > /proc/sys/vm/drop_caches"
15970         set_osd_param $list '' read_cache_enable 0
15971         cat $DIR/$tfile >/dev/null
15972
15973         # now data shouldn't be found in the cache
15974         BEFORE=$(roc_hit)
15975         cancel_lru_locks osc
15976         cat $DIR/$tfile >/dev/null
15977         AFTER=$(roc_hit)
15978         if let "AFTER - BEFORE != 0"; then
15979                 error "IN CACHE: before: $BEFORE, after: $AFTER"
15980         fi
15981
15982         set_osd_param $list '' read_cache_enable 1
15983         rm -f $DIR/$tfile
15984 }
15985 run_test 151 "test cache on oss and controls ==============================="
15986
15987 test_152() {
15988         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15989
15990         local TF="$TMP/$tfile"
15991
15992         # simulate ENOMEM during write
15993 #define OBD_FAIL_OST_NOMEM      0x226
15994         lctl set_param fail_loc=0x80000226
15995         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
15996         cp $TF $DIR/$tfile
15997         sync || error "sync failed"
15998         lctl set_param fail_loc=0
15999
16000         # discard client's cache
16001         cancel_lru_locks osc
16002
16003         # simulate ENOMEM during read
16004         lctl set_param fail_loc=0x80000226
16005         cmp $TF $DIR/$tfile || error "cmp failed"
16006         lctl set_param fail_loc=0
16007
16008         rm -f $TF
16009 }
16010 run_test 152 "test read/write with enomem ============================"
16011
16012 test_153() {
16013         $MULTIOP $DIR/$tfile Ow4096Ycu || error "multiop failed"
16014 }
16015 run_test 153 "test if fdatasync does not crash ======================="
16016
16017 dot_lustre_fid_permission_check() {
16018         local fid=$1
16019         local ffid=$MOUNT/.lustre/fid/$fid
16020         local test_dir=$2
16021
16022         echo "stat fid $fid"
16023         stat $ffid || error "stat $ffid failed."
16024         echo "touch fid $fid"
16025         touch $ffid || error "touch $ffid failed."
16026         echo "write to fid $fid"
16027         cat /etc/hosts > $ffid || error "write $ffid failed."
16028         echo "read fid $fid"
16029         diff /etc/hosts $ffid || error "read $ffid failed."
16030         echo "append write to fid $fid"
16031         cat /etc/hosts >> $ffid || error "append write $ffid failed."
16032         echo "rename fid $fid"
16033         mv $ffid $test_dir/$tfile.1 &&
16034                 error "rename $ffid to $tfile.1 should fail."
16035         touch $test_dir/$tfile.1
16036         mv $test_dir/$tfile.1 $ffid &&
16037                 error "rename $tfile.1 to $ffid should fail."
16038         rm -f $test_dir/$tfile.1
16039         echo "truncate fid $fid"
16040         $TRUNCATE $ffid 777 || error "truncate $ffid failed."
16041         echo "link fid $fid"
16042         ln -f $ffid $test_dir/tfile.lnk || error "link $ffid failed."
16043         if [[ $($LCTL get_param -n mdc.*-mdc-*.connect_flags) =~ acl ]]; then
16044                 echo "setfacl fid $fid"
16045                 setfacl -R -m u:$USER0:rwx $ffid ||
16046                         error "setfacl $ffid failed"
16047                 echo "getfacl fid $fid"
16048                 getfacl $ffid || error "getfacl $ffid failed."
16049         fi
16050         echo "unlink fid $fid"
16051         unlink $MOUNT/.lustre/fid/$fid && error "unlink $ffid should fail."
16052         echo "mknod fid $fid"
16053         mknod $ffid c 1 3 && error "mknod $ffid should fail."
16054
16055         fid=[0xf00000400:0x1:0x0]
16056         ffid=$MOUNT/.lustre/fid/$fid
16057
16058         echo "stat non-exist fid $fid"
16059         stat $ffid > /dev/null && error "stat non-exist $ffid should fail."
16060         echo "write to non-exist fid $fid"
16061         cat /etc/hosts > $ffid && error "write non-exist $ffid should fail."
16062         echo "link new fid $fid"
16063         ln $test_dir/$tfile $ffid && error "link $ffid should fail."
16064
16065         mkdir -p $test_dir/$tdir
16066         touch $test_dir/$tdir/$tfile
16067         fid=$($LFS path2fid $test_dir/$tdir)
16068         rc=$?
16069         [ $rc -ne 0 ] &&
16070                 error "error: could not get fid for $test_dir/$dir/$tfile."
16071
16072         ffid=$MOUNT/.lustre/fid/$fid
16073
16074         echo "ls $fid"
16075         ls $ffid || error "ls $ffid failed."
16076         echo "touch $fid/$tfile.1"
16077         touch $ffid/$tfile.1 || error "touch $ffid/$tfile.1 failed."
16078
16079         echo "touch $MOUNT/.lustre/fid/$tfile"
16080         touch $MOUNT/.lustre/fid/$tfile && \
16081                 error "touch $MOUNT/.lustre/fid/$tfile should fail."
16082
16083         echo "setxattr to $MOUNT/.lustre/fid"
16084         setfattr -n trusted.name1 -v value1 $MOUNT/.lustre/fid
16085
16086         echo "listxattr for $MOUNT/.lustre/fid"
16087         getfattr -d -m "^trusted" $MOUNT/.lustre/fid
16088
16089         echo "delxattr from $MOUNT/.lustre/fid"
16090         setfattr -x trusted.name1 $MOUNT/.lustre/fid
16091
16092         echo "touch invalid fid: $MOUNT/.lustre/fid/[0x200000400:0x2:0x3]"
16093         touch $MOUNT/.lustre/fid/[0x200000400:0x2:0x3] &&
16094                 error "touch invalid fid should fail."
16095
16096         echo "touch non-normal fid: $MOUNT/.lustre/fid/[0x1:0x2:0x0]"
16097         touch $MOUNT/.lustre/fid/[0x1:0x2:0x0] &&
16098                 error "touch non-normal fid should fail."
16099
16100         echo "rename $tdir to $MOUNT/.lustre/fid"
16101         mrename $test_dir/$tdir $MOUNT/.lustre/fid &&
16102                 error "rename to $MOUNT/.lustre/fid should fail."
16103
16104         if [ $MDS1_VERSION -ge $(version_code 2.3.51) ]
16105         then            # LU-3547
16106                 local old_obf_mode=$(stat --format="%a" $DIR/.lustre/fid)
16107                 local new_obf_mode=777
16108
16109                 echo "change mode of $DIR/.lustre/fid to $new_obf_mode"
16110                 chmod $new_obf_mode $DIR/.lustre/fid ||
16111                         error "chmod $new_obf_mode $DIR/.lustre/fid failed"
16112
16113                 local obf_mode=$(stat --format=%a $DIR/.lustre/fid)
16114                 [ $obf_mode -eq $new_obf_mode ] ||
16115                         error "stat $DIR/.lustre/fid returned wrong mode $obf_mode"
16116
16117                 echo "restore mode of $DIR/.lustre/fid to $old_obf_mode"
16118                 chmod $old_obf_mode $DIR/.lustre/fid ||
16119                         error "chmod $old_obf_mode $DIR/.lustre/fid failed"
16120         fi
16121
16122         $OPENFILE -f O_LOV_DELAY_CREATE:O_CREAT $test_dir/$tfile-2
16123         fid=$($LFS path2fid $test_dir/$tfile-2)
16124
16125         if [ $MDS1_VERSION -ge $(version_code 2.6.50) ]
16126         then # LU-5424
16127                 echo "cp /etc/passwd $MOUNT/.lustre/fid/$fid"
16128                 cp /etc/passwd $MOUNT/.lustre/fid/$fid ||
16129                         error "create lov data thru .lustre failed"
16130         fi
16131         echo "cp /etc/passwd $test_dir/$tfile-2"
16132         cp /etc/passwd $test_dir/$tfile-2 ||
16133                 error "copy to $test_dir/$tfile-2 failed."
16134         echo "diff /etc/passwd $MOUNT/.lustre/fid/$fid"
16135         diff /etc/passwd $MOUNT/.lustre/fid/$fid ||
16136                 error "diff /etc/passwd $MOUNT/.lustre/fid/$fid failed."
16137
16138         rm -rf $test_dir/tfile.lnk
16139         rm -rf $test_dir/$tfile-2
16140 }
16141
16142 test_154A() {
16143         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
16144                 skip "Need MDS version at least 2.4.1"
16145
16146         local tf=$DIR/$tfile
16147         touch $tf
16148
16149         local fid=$($LFS path2fid $tf)
16150         [ -z "$fid" ] && error "path2fid unable to get $tf FID"
16151
16152         # check that we get the same pathname back
16153         local rootpath
16154         local found
16155         for rootpath in "$MOUNT" "$MOUNT///" "$MOUNT/$tfile"; do
16156                 echo "$rootpath $fid"
16157                 found=$($LFS fid2path $rootpath "$fid")
16158                 [ -z "$found" ] && error "fid2path unable to get '$fid' path"
16159                 [ "$found" == "$tf" ] || error "fid2path $found != $tf"
16160         done
16161
16162         # check wrong root path format
16163         rootpath=$MOUNT"_wrong"
16164         found=$($LFS fid2path $rootpath "$fid")
16165         [ -z "$found" ] || error "should fail ($rootpath != $MOUNT)"
16166 }
16167 run_test 154A "lfs path2fid and fid2path basic checks"
16168
16169 test_154B() {
16170         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
16171                 skip "Need MDS version at least 2.4.1"
16172
16173         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
16174         touch $DIR/$tdir/$tfile || error "touch $DIR/$tdir/$tfile failed"
16175         local linkea=$($LL_DECODE_LINKEA $DIR/$tdir/$tfile | grep 'pfid')
16176         [ -z "$linkea" ] && error "decode linkea $DIR/$tdir/$tfile failed"
16177
16178         local name=$(echo $linkea | awk '/pfid/ {print $5}' | sed -e "s/'//g")
16179         local PFID=$(echo $linkea | awk '/pfid/ {print $3}' | sed -e "s/,//g")
16180
16181         # check that we get the same pathname
16182         echo "PFID: $PFID, name: $name"
16183         local FOUND=$($LFS fid2path $MOUNT "$PFID")
16184         [ -z "$FOUND" ] && error "fid2path unable to get $PFID path"
16185         [ "$FOUND/$name" != "$DIR/$tdir/$tfile" ] &&
16186                 error "ll_decode_linkea has $FOUND/$name != $DIR/$tdir/$tfile"
16187
16188         rm -rf $DIR/$tdir || error "Can not delete directory $DIR/$tdir"
16189 }
16190 run_test 154B "verify the ll_decode_linkea tool"
16191
16192 test_154a() {
16193         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16194         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
16195         (( $MDS1_VERSION >= $(version_code 2.2.51) )) ||
16196                 skip "Need MDS version at least 2.2.51"
16197         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
16198
16199         cp /etc/hosts $DIR/$tfile
16200
16201         fid=$($LFS path2fid $DIR/$tfile)
16202         rc=$?
16203         [ $rc -ne 0 ] && error "error: could not get fid for $DIR/$tfile."
16204
16205         dot_lustre_fid_permission_check "$fid" $DIR ||
16206                 error "dot lustre permission check $fid failed"
16207
16208         ls -a $MOUNT | grep "\.lustre" && error ".lustre should not be listed"
16209
16210         rm -rf $MOUNT/.lustre && error ".lustre is not allowed to be unlinked"
16211
16212         touch $MOUNT/.lustre/file &&
16213                 error "creation is not allowed under .lustre"
16214
16215         mkdir $MOUNT/.lustre/dir &&
16216                 error "mkdir is not allowed under .lustre"
16217
16218         rm -rf $DIR/$tfile
16219 }
16220 run_test 154a "Open-by-FID"
16221
16222 test_154b() {
16223         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16224         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
16225         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16226         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
16227                 skip "Need MDS version at least 2.2.51"
16228
16229         local remote_dir=$DIR/$tdir/remote_dir
16230         local MDTIDX=1
16231         local rc=0
16232
16233         mkdir -p $DIR/$tdir
16234         $LFS mkdir -i $MDTIDX $remote_dir ||
16235                 error "create remote directory failed"
16236
16237         cp /etc/hosts $remote_dir/$tfile
16238
16239         fid=$($LFS path2fid $remote_dir/$tfile)
16240         rc=$?
16241         [ $rc -ne 0 ] && error "error: could not get fid for $remote_dir/$tfile"
16242
16243         dot_lustre_fid_permission_check "$fid" $remote_dir ||
16244                 error "dot lustre permission check $fid failed"
16245         rm -rf $DIR/$tdir
16246 }
16247 run_test 154b "Open-by-FID for remote directory"
16248
16249 test_154c() {
16250         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
16251                 skip "Need MDS version at least 2.4.1"
16252
16253         touch $DIR/$tfile.1 $DIR/$tfile.2 $DIR/$tfile.3
16254         local FID1=$($LFS path2fid $DIR/$tfile.1)
16255         local FID2=$($LFS path2fid $DIR/$tfile.2)
16256         local FID3=$($LFS path2fid $DIR/$tfile.3)
16257
16258         local N=1
16259         $LFS path2fid $DIR/$tfile.[123] | while read PATHNAME FID; do
16260                 [ "$PATHNAME" = "$DIR/$tfile.$N:" ] ||
16261                         error "path2fid pathname $PATHNAME != $DIR/$tfile.$N:"
16262                 local want=FID$N
16263                 [ "$FID" = "${!want}" ] ||
16264                         error "path2fid $PATHNAME FID $FID != FID$N ${!want}"
16265                 N=$((N + 1))
16266         done
16267
16268         $LFS fid2path $MOUNT "$FID1" "$FID2" "$FID3" | while read PATHNAME;
16269         do
16270                 [ "$PATHNAME" = "$DIR/$tfile.$N" ] ||
16271                         error "fid2path pathname $PATHNAME != $DIR/$tfile.$N:"
16272                 N=$((N + 1))
16273         done
16274 }
16275 run_test 154c "lfs path2fid and fid2path multiple arguments"
16276
16277 test_154d() {
16278         remote_mds_nodsh && skip "remote MDS with nodsh"
16279         [[ $MDS1_VERSION -lt $(version_code 2.5.53) ]] &&
16280                 skip "Need MDS version at least 2.5.53"
16281
16282         if remote_mds; then
16283                 nid=$($LCTL list_nids | sed  "s/\./\\\./g")
16284         else
16285                 nid="0@lo"
16286         fi
16287         local proc_ofile="mdt.*.exports.'$nid'.open_files"
16288         local fd
16289         local cmd
16290
16291         rm -f $DIR/$tfile
16292         touch $DIR/$tfile
16293
16294         local fid=$($LFS path2fid $DIR/$tfile)
16295         # Open the file
16296         fd=$(free_fd)
16297         cmd="exec $fd<$DIR/$tfile"
16298         eval $cmd
16299         local fid_list=$(do_facet $SINGLEMDS $LCTL get_param $proc_ofile)
16300         echo "$fid_list" | grep "$fid"
16301         rc=$?
16302
16303         cmd="exec $fd>/dev/null"
16304         eval $cmd
16305         if [ $rc -ne 0 ]; then
16306                 error "FID $fid not found in open files list $fid_list"
16307         fi
16308 }
16309 run_test 154d "Verify open file fid"
16310
16311 test_154e()
16312 {
16313         [[ $MDS1_VERSION -lt $(version_code 2.6.50) ]] &&
16314                 skip "Need MDS version at least 2.6.50"
16315
16316         if ls -a $MOUNT | grep -q '^\.lustre$'; then
16317                 error ".lustre returned by readdir"
16318         fi
16319 }
16320 run_test 154e ".lustre is not returned by readdir"
16321
16322 test_154f() {
16323         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
16324
16325         # create parent directory on a single MDT to avoid cross-MDT hardlinks
16326         mkdir_on_mdt0 $DIR/$tdir
16327         # test dirs inherit from its stripe
16328         mkdir -p $DIR/$tdir/foo1 || error "mkdir error"
16329         mkdir -p $DIR/$tdir/foo2 || error "mkdir error"
16330         cp /etc/hosts $DIR/$tdir/foo1/$tfile
16331         ln $DIR/$tdir/foo1/$tfile $DIR/$tdir/foo2/link
16332         touch $DIR/f
16333
16334         # get fid of parents
16335         local FID0=$($LFS path2fid $DIR/$tdir)
16336         local FID1=$($LFS path2fid $DIR/$tdir/foo1)
16337         local FID2=$($LFS path2fid $DIR/$tdir/foo2)
16338         local FID3=$($LFS path2fid $DIR)
16339
16340         # check that path2fid --parents returns expected <parent_fid>/name
16341         # 1) test for a directory (single parent)
16342         local parent=$($LFS path2fid --parents $DIR/$tdir/foo1)
16343         [ "$parent" == "$FID0/foo1" ] ||
16344                 error "expected parent: $FID0/foo1, got: $parent"
16345
16346         # 2) test for a file with nlink > 1 (multiple parents)
16347         parent=$($LFS path2fid --parents $DIR/$tdir/foo1/$tfile)
16348         echo "$parent" | grep -F "$FID1/$tfile" ||
16349                 error "$FID1/$tfile not returned in parent list"
16350         echo "$parent" | grep -F "$FID2/link" ||
16351                 error "$FID2/link not returned in parent list"
16352
16353         # 3) get parent by fid
16354         local file_fid=$($LFS path2fid $DIR/$tdir/foo1/$tfile)
16355         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
16356         echo "$parent" | grep -F "$FID1/$tfile" ||
16357                 error "$FID1/$tfile not returned in parent list (by fid)"
16358         echo "$parent" | grep -F "$FID2/link" ||
16359                 error "$FID2/link not returned in parent list (by fid)"
16360
16361         # 4) test for entry in root directory
16362         parent=$($LFS path2fid --parents $DIR/f)
16363         echo "$parent" | grep -F "$FID3/f" ||
16364                 error "$FID3/f not returned in parent list"
16365
16366         # 5) test it on root directory
16367         [ -z "$($LFS path2fid --parents $MOUNT 2>/dev/null)" ] ||
16368                 error "$MOUNT should not have parents"
16369
16370         # enable xattr caching and check that linkea is correctly updated
16371         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
16372         save_lustre_params client "llite.*.xattr_cache" > $save
16373         lctl set_param llite.*.xattr_cache 1
16374
16375         # 6.1) linkea update on rename
16376         mv $DIR/$tdir/foo1/$tfile $DIR/$tdir/foo2/$tfile.moved
16377
16378         # get parents by fid
16379         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
16380         # foo1 should no longer be returned in parent list
16381         echo "$parent" | grep -F "$FID1" &&
16382                 error "$FID1 should no longer be in parent list"
16383         # the new path should appear
16384         echo "$parent" | grep -F "$FID2/$tfile.moved" ||
16385                 error "$FID2/$tfile.moved is not in parent list"
16386
16387         # 6.2) linkea update on unlink
16388         rm -f $DIR/$tdir/foo2/link
16389         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
16390         # foo2/link should no longer be returned in parent list
16391         echo "$parent" | grep -F "$FID2/link" &&
16392                 error "$FID2/link should no longer be in parent list"
16393         true
16394
16395         rm -f $DIR/f
16396         restore_lustre_params < $save
16397         rm -f $save
16398 }
16399 run_test 154f "get parent fids by reading link ea"
16400
16401 test_154g()
16402 {
16403         [[ $MDS1_VERSION -ge $(version_code 2.6.92) &&
16404            $CLIENT_VERSION -gt $(version_code 2.6.99) ]] ||
16405                 skip "Need MDS version at least 2.6.92"
16406
16407         mkdir_on_mdt0 $DIR/$tdir
16408         llapi_fid_test -d $DIR/$tdir
16409 }
16410 run_test 154g "various llapi FID tests"
16411
16412 test_154h()
16413 {
16414         (( $CLIENT_VERSION >= $(version_code 2.15.55.1) )) ||
16415                 skip "Need client at least version 2.15.55.1"
16416
16417         # Create an empty file
16418         touch $DIR/$tfile
16419
16420         # Get FID (interactive mode) and save under $TMP/$tfile.log
16421         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
16422                 path2fid $DIR/$tfile
16423         EOF
16424
16425         fid=$(cat $TMP/$tfile.log)
16426         # $fid should not be empty
16427         [[ ! -z $fid ]] || error "FID is empty"
16428         $LFS rmfid $DIR "$fid" || error "rmfid failed for $fid"
16429 }
16430 run_test 154h "Verify interactive path2fid"
16431
16432 test_155_small_load() {
16433     local temp=$TMP/$tfile
16434     local file=$DIR/$tfile
16435
16436     dd if=/dev/urandom of=$temp bs=6096 count=1 || \
16437         error "dd of=$temp bs=6096 count=1 failed"
16438     cp $temp $file
16439     cancel_lru_locks $OSC
16440     cmp $temp $file || error "$temp $file differ"
16441
16442     $TRUNCATE $temp 6000
16443     $TRUNCATE $file 6000
16444     cmp $temp $file || error "$temp $file differ (truncate1)"
16445
16446     echo "12345" >>$temp
16447     echo "12345" >>$file
16448     cmp $temp $file || error "$temp $file differ (append1)"
16449
16450     echo "12345" >>$temp
16451     echo "12345" >>$file
16452     cmp $temp $file || error "$temp $file differ (append2)"
16453
16454     rm -f $temp $file
16455     true
16456 }
16457
16458 test_155_big_load() {
16459         remote_ost_nodsh && skip "remote OST with nodsh"
16460
16461         local temp=$TMP/$tfile
16462         local file=$DIR/$tfile
16463
16464         free_min_max
16465         local cache_size=$(do_facet ost$((MAXI+1)) \
16466                 "awk '/cache/ {sum+=\\\$4} END {print sum}' /proc/cpuinfo")
16467
16468         # LU-16042: can not get the cache size on Arm64 VM here, fallback to a
16469         # pre-set value
16470         if [ -z "$cache_size" ]; then
16471                 cache_size=256
16472         fi
16473         local large_file_size=$((cache_size * 2))
16474
16475         echo "OSS cache size: $cache_size KB"
16476         echo "Large file size: $large_file_size KB"
16477
16478         [ $MAXV -le $large_file_size ] &&
16479                 skip_env "max available OST size needs > $large_file_size KB"
16480
16481         $LFS setstripe $file -c 1 -i $MAXI || error "$LFS setstripe $file failed"
16482
16483         dd if=/dev/urandom of=$temp bs=$large_file_size count=1k ||
16484                 error "dd of=$temp bs=$large_file_size count=1k failed"
16485         cp $temp $file
16486         ls -lh $temp $file
16487         cancel_lru_locks osc
16488         cmp $temp $file || error "$temp $file differ"
16489
16490         rm -f $temp $file
16491         true
16492 }
16493
16494 save_writethrough() {
16495         local facets=$(get_facets OST)
16496
16497         save_lustre_params $facets "osd-*.*.writethrough_cache_enable" > $1
16498 }
16499
16500 test_155a() {
16501         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16502
16503         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16504
16505         save_writethrough $p
16506
16507         set_cache read on
16508         set_cache writethrough on
16509         test_155_small_load
16510         restore_lustre_params < $p
16511         rm -f $p
16512 }
16513 run_test 155a "Verify small file correctness: read cache:on write_cache:on"
16514
16515 test_155b() {
16516         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16517
16518         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16519
16520         save_writethrough $p
16521
16522         set_cache read on
16523         set_cache writethrough off
16524         test_155_small_load
16525         restore_lustre_params < $p
16526         rm -f $p
16527 }
16528 run_test 155b "Verify small file correctness: read cache:on write_cache:off"
16529
16530 test_155c() {
16531         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16532
16533         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16534
16535         save_writethrough $p
16536
16537         set_cache read off
16538         set_cache writethrough on
16539         test_155_small_load
16540         restore_lustre_params < $p
16541         rm -f $p
16542 }
16543 run_test 155c "Verify small file correctness: read cache:off write_cache:on"
16544
16545 test_155d() {
16546         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16547
16548         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16549
16550         save_writethrough $p
16551
16552         set_cache read off
16553         set_cache writethrough off
16554         test_155_small_load
16555         restore_lustre_params < $p
16556         rm -f $p
16557 }
16558 run_test 155d "Verify small file correctness: read cache:off write_cache:off"
16559
16560 test_155e() {
16561         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16562
16563         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16564
16565         save_writethrough $p
16566
16567         set_cache read on
16568         set_cache writethrough on
16569         test_155_big_load
16570         restore_lustre_params < $p
16571         rm -f $p
16572 }
16573 run_test 155e "Verify big file correctness: read cache:on write_cache:on"
16574
16575 test_155f() {
16576         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16577
16578         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16579
16580         save_writethrough $p
16581
16582         set_cache read on
16583         set_cache writethrough off
16584         test_155_big_load
16585         restore_lustre_params < $p
16586         rm -f $p
16587 }
16588 run_test 155f "Verify big file correctness: read cache:on write_cache:off"
16589
16590 test_155g() {
16591         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16592
16593         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16594
16595         save_writethrough $p
16596
16597         set_cache read off
16598         set_cache writethrough on
16599         test_155_big_load
16600         restore_lustre_params < $p
16601         rm -f $p
16602 }
16603 run_test 155g "Verify big file correctness: read cache:off write_cache:on"
16604
16605 test_155h() {
16606         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16607
16608         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16609
16610         save_writethrough $p
16611
16612         set_cache read off
16613         set_cache writethrough off
16614         test_155_big_load
16615         restore_lustre_params < $p
16616         rm -f $p
16617 }
16618 run_test 155h "Verify big file correctness: read cache:off write_cache:off"
16619
16620 test_156() {
16621         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16622         remote_ost_nodsh && skip "remote OST with nodsh"
16623         [ $OST1_VERSION -lt $(version_code 2.6.93) ] &&
16624                 skip "stats not implemented on old servers"
16625         [ "$ost1_FSTYPE" = "zfs" ] &&
16626                 skip "LU-1956/LU-2261: stats not implemented on OSD ZFS"
16627         (( CLIENT_VERSION == OST1_VERSION )) ||
16628                 skip "LU-13081: no interop testing for OSS cache"
16629
16630         local CPAGES=3
16631         local BEFORE
16632         local AFTER
16633         local file="$DIR/$tfile"
16634         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16635
16636         save_writethrough $p
16637         roc_hit_init
16638
16639         log "Turn on read and write cache"
16640         set_cache read on
16641         set_cache writethrough on
16642
16643         log "Write data and read it back."
16644         log "Read should be satisfied from the cache."
16645         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
16646         BEFORE=$(roc_hit)
16647         cancel_lru_locks osc
16648         cat $file >/dev/null
16649         AFTER=$(roc_hit)
16650         if ! let "AFTER - BEFORE == CPAGES"; then
16651                 error "NOT IN CACHE (2): before: $BEFORE, after: $AFTER"
16652         else
16653                 log "cache hits: before: $BEFORE, after: $AFTER"
16654         fi
16655
16656         log "Read again; it should be satisfied from the cache."
16657         BEFORE=$AFTER
16658         cancel_lru_locks osc
16659         cat $file >/dev/null
16660         AFTER=$(roc_hit)
16661         if ! let "AFTER - BEFORE == CPAGES"; then
16662                 error "NOT IN CACHE (3): before: $BEFORE, after: $AFTER"
16663         else
16664                 log "cache hits:: before: $BEFORE, after: $AFTER"
16665         fi
16666
16667         log "Turn off the read cache and turn on the write cache"
16668         set_cache read off
16669         set_cache writethrough on
16670
16671         log "Read again; it should be satisfied from the cache."
16672         BEFORE=$(roc_hit)
16673         cancel_lru_locks osc
16674         cat $file >/dev/null
16675         AFTER=$(roc_hit)
16676         if ! let "AFTER - BEFORE == CPAGES"; then
16677                 error "NOT IN CACHE (4): before: $BEFORE, after: $AFTER"
16678         else
16679                 log "cache hits:: before: $BEFORE, after: $AFTER"
16680         fi
16681
16682         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
16683                 # > 2.12.56 uses pagecache if cached
16684                 log "Read again; it should not be satisfied from the cache."
16685                 BEFORE=$AFTER
16686                 cancel_lru_locks osc
16687                 cat $file >/dev/null
16688                 AFTER=$(roc_hit)
16689                 if ! let "AFTER - BEFORE == 0"; then
16690                         error "IN CACHE (5): before: $BEFORE, after: $AFTER"
16691                 else
16692                         log "cache hits:: before: $BEFORE, after: $AFTER"
16693                 fi
16694         fi
16695
16696         log "Write data and read it back."
16697         log "Read should be satisfied from the cache."
16698         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
16699         BEFORE=$(roc_hit)
16700         cancel_lru_locks osc
16701         cat $file >/dev/null
16702         AFTER=$(roc_hit)
16703         if ! let "AFTER - BEFORE == CPAGES"; then
16704                 error "NOT IN CACHE (6): before: $BEFORE, after: $AFTER"
16705         else
16706                 log "cache hits:: before: $BEFORE, after: $AFTER"
16707         fi
16708
16709         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
16710                 # > 2.12.56 uses pagecache if cached
16711                 log "Read again; it should not be satisfied from the cache."
16712                 BEFORE=$AFTER
16713                 cancel_lru_locks osc
16714                 cat $file >/dev/null
16715                 AFTER=$(roc_hit)
16716                 if ! let "AFTER - BEFORE == 0"; then
16717                         error "IN CACHE (7): before: $BEFORE, after: $AFTER"
16718                 else
16719                         log "cache hits:: before: $BEFORE, after: $AFTER"
16720                 fi
16721         fi
16722
16723         log "Turn off read and write cache"
16724         set_cache read off
16725         set_cache writethrough off
16726
16727         log "Write data and read it back"
16728         log "It should not be satisfied from the cache."
16729         rm -f $file
16730         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
16731         cancel_lru_locks osc
16732         BEFORE=$(roc_hit)
16733         cat $file >/dev/null
16734         AFTER=$(roc_hit)
16735         if ! let "AFTER - BEFORE == 0"; then
16736                 error_ignore bz20762 "IN CACHE (8):before:$BEFORE,after:$AFTER"
16737         else
16738                 log "cache hits:: before: $BEFORE, after: $AFTER"
16739         fi
16740
16741         log "Turn on the read cache and turn off the write cache"
16742         set_cache read on
16743         set_cache writethrough off
16744
16745         log "Write data and read it back"
16746         log "It should not be satisfied from the cache."
16747         rm -f $file
16748         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
16749         BEFORE=$(roc_hit)
16750         cancel_lru_locks osc
16751         cat $file >/dev/null
16752         AFTER=$(roc_hit)
16753         if ! let "AFTER - BEFORE == 0"; then
16754                 error_ignore bz20762 "IN CACHE (9):before:$BEFORE,after:$AFTER"
16755         else
16756                 log "cache hits:: before: $BEFORE, after: $AFTER"
16757         fi
16758
16759         log "Read again; it should be satisfied from the cache."
16760         BEFORE=$(roc_hit)
16761         cancel_lru_locks osc
16762         cat $file >/dev/null
16763         AFTER=$(roc_hit)
16764         if ! let "AFTER - BEFORE == CPAGES"; then
16765                 error "NOT IN CACHE (1): before: $BEFORE, after: $AFTER"
16766         else
16767                 log "cache hits:: before: $BEFORE, after: $AFTER"
16768         fi
16769
16770         restore_lustre_params < $p
16771         rm -f $p $file
16772 }
16773 run_test 156 "Verification of tunables"
16774
16775 test_160a() {
16776         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16777         remote_mds_nodsh && skip "remote MDS with nodsh"
16778         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
16779                 skip "Need MDS version at least 2.2.0"
16780
16781         changelog_register || error "changelog_register failed"
16782         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16783         changelog_users $SINGLEMDS | grep -q $cl_user ||
16784                 error "User $cl_user not found in changelog_users"
16785
16786         mkdir_on_mdt0 $DIR/$tdir
16787
16788         # change something
16789         test_mkdir -p $DIR/$tdir/pics/2008/zachy
16790         changelog_clear 0 || error "changelog_clear failed"
16791         touch $DIR/$tdir/pics/2008/zachy/$tfile                 # open 1
16792         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg       # open 2
16793         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
16794         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
16795         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
16796         rm $DIR/$tdir/pics/desktop.jpg
16797
16798         echo "verifying changelog mask"
16799         changelog_chmask "-MKDIR"
16800         changelog_chmask "-CLOSE"
16801
16802         test_mkdir -p $DIR/$tdir/pics/zach/sofia                # not logged
16803         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # not logged
16804
16805         changelog_chmask "+MKDIR"
16806         changelog_chmask "+CLOSE"
16807
16808         test_mkdir -p $DIR/$tdir/pics/2008/sofia                # mkdir 1
16809         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # open 3
16810
16811         MKDIRS=$(changelog_dump | grep -c "MKDIR")
16812         CLOSES=$(changelog_dump | grep -c "CLOSE")
16813         [ $MKDIRS -eq 1 ] || error "MKDIR changelog mask count $MKDIRS != 1"
16814         [ $CLOSES -eq 3 ] || error "CLOSE changelog mask count $CLOSES != 3"
16815
16816         # verify contents
16817         echo "verifying target fid"
16818         local fidc=$(changelog_extract_field "CREAT" "$tfile" "t=")
16819         local fidf=$($LFS path2fid $DIR/$tdir/pics/zach/$tfile)
16820         [ "$fidc" == "$fidf" ] ||
16821                 error "changelog '$tfile' fid $fidc != file fid $fidf"
16822         echo "verifying parent fid"
16823         # The FID returned from the Changelog may be the directory shard on
16824         # a different MDT, and not the FID returned by path2fid on the parent.
16825         # Instead of comparing FIDs, verify that fid2path(fidp) is correct,
16826         # since this is what will matter when recreating this file in the tree.
16827         local fidp=$(changelog_extract_field "CREAT" "$tfile" "p=")
16828         local pathp=$($LFS fid2path $MOUNT "$fidp")
16829         [ "${pathp%/}" == "$DIR/$tdir/pics/zach" ] ||
16830                 error "changelog fid2path($fidc) $pathp != $DIR/$tdir/pics/zach"
16831
16832         echo "getting records for $cl_user"
16833         changelog_users $SINGLEMDS
16834         local user_rec1=$(changelog_user_rec $SINGLEMDS $cl_user)
16835         local nclr=3
16836         __changelog_clear $SINGLEMDS $cl_user +$nclr ||
16837                 error "changelog_clear failed"
16838         local user_rec2=$(changelog_user_rec $SINGLEMDS $cl_user)
16839         echo "verifying user clear: $user_rec1 + $nclr == $user_rec2"
16840         [ $user_rec2 == $((user_rec1 + nclr)) ] ||
16841                 error "user index expect $user_rec1 + $nclr != $user_rec2"
16842
16843         local min0_rec=$(changelog_users $SINGLEMDS |
16844                 awk 'min == "" || $2 < min { min = $2 }; END { print min }')
16845         local first_rec=$($LFS changelog $(facet_svc $SINGLEMDS) |
16846                           awk '{ print $1; exit; }')
16847
16848         changelog_dump | tail -n 5
16849         echo "verifying user min purge: $min0_rec + 1 == $first_rec"
16850         [ $first_rec == $((min0_rec + 1)) ] ||
16851                 error "first index should be $min0_rec + 1 not $first_rec"
16852
16853         # LU-3446 changelog index reset on MDT restart
16854         local cur_rec1=$(changelog_users $SINGLEMDS |
16855                          awk '/^current.index:/ { print $NF }')
16856         changelog_clear 0 ||
16857                 error "clear all changelog records for $cl_user failed"
16858         stop $SINGLEMDS || error "Fail to stop $SINGLEMDS"
16859         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
16860                 error "Fail to start $SINGLEMDS"
16861         local cur_rec2=$(changelog_users $SINGLEMDS |
16862                          awk '/^current.index:/ { print $NF }')
16863         echo "verifying index survives MDT restart: $cur_rec1 == $cur_rec2"
16864         [ $cur_rec1 == $cur_rec2 ] ||
16865                 error "current index should be $cur_rec1 not $cur_rec2"
16866
16867         echo "verifying users from this test are deregistered"
16868         changelog_deregister || error "changelog_deregister failed"
16869         changelog_users $SINGLEMDS | grep -q $cl_user &&
16870                 error "User '$cl_user' still in changelog_users"
16871
16872         # lctl get_param -n mdd.*.changelog_users
16873         # current_index: 144
16874         # ID    index (idle seconds)
16875         # cl3   144   (2) mask=<list>
16876         if [ -z "$(changelog_users $SINGLEMDS | grep -v current.index)" ]; then
16877                 # this is the normal case where all users were deregistered
16878                 # make sure no new records are added when no users are present
16879                 local last_rec1=$(changelog_users $SINGLEMDS |
16880                                   awk '/^current.index:/ { print $NF }')
16881                 touch $DIR/$tdir/chloe
16882                 local last_rec2=$(changelog_users $SINGLEMDS |
16883                                   awk '/^current.index:/ { print $NF }')
16884                 echo "verify changelogs are off: $last_rec1 == $last_rec2"
16885                 [ $last_rec1 == $last_rec2 ] || error "changelogs not off"
16886         else
16887                 # any changelog users must be leftovers from a previous test
16888                 changelog_users $SINGLEMDS
16889                 echo "other changelog users; can't verify off"
16890         fi
16891 }
16892 run_test 160a "changelog sanity"
16893
16894 test_160b() { # LU-3587
16895         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16896         remote_mds_nodsh && skip "remote MDS with nodsh"
16897         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
16898                 skip "Need MDS version at least 2.2.0"
16899
16900         changelog_register || error "changelog_register failed"
16901         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16902         changelog_users $SINGLEMDS | grep -q $cl_user ||
16903                 error "User '$cl_user' not found in changelog_users"
16904
16905         local longname1=$(str_repeat a 255)
16906         local longname2=$(str_repeat b 255)
16907
16908         cd $DIR
16909         echo "creating very long named file"
16910         touch $longname1 || error "create of '$longname1' failed"
16911         echo "renaming very long named file"
16912         mv $longname1 $longname2
16913
16914         changelog_dump | grep RENME | tail -n 5
16915         rm -f $longname2
16916 }
16917 run_test 160b "Verify that very long rename doesn't crash in changelog"
16918
16919 test_160c() {
16920         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16921         remote_mds_nodsh && skip "remote MDS with nodsh"
16922
16923         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
16924                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
16925                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
16926                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
16927
16928         local rc=0
16929
16930         # Registration step
16931         changelog_register || error "changelog_register failed"
16932
16933         rm -rf $DIR/$tdir
16934         mkdir -p $DIR/$tdir
16935         $MCREATE $DIR/$tdir/foo_160c
16936         changelog_chmask "-TRUNC"
16937         $TRUNCATE $DIR/$tdir/foo_160c 200
16938         changelog_chmask "+TRUNC"
16939         $TRUNCATE $DIR/$tdir/foo_160c 199
16940         changelog_dump | tail -n 5
16941         local truncs=$(changelog_dump | tail -n 5 | grep -c TRUNC)
16942         [ $truncs -eq 1 ] || error "TRUNC changelog mask count $truncs != 1"
16943 }
16944 run_test 160c "verify that changelog log catch the truncate event"
16945
16946 test_160d() {
16947         remote_mds_nodsh && skip "remote MDS with nodsh"
16948         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16949         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16950         [[ $MDS1_VERSION -ge $(version_code 2.7.60) ]] ||
16951                 skip "Need MDS version at least 2.7.60"
16952
16953         # Registration step
16954         changelog_register || error "changelog_register failed"
16955
16956         mkdir -p $DIR/$tdir/migrate_dir
16957         changelog_clear 0 || error "changelog_clear failed"
16958
16959         $LFS migrate -m 1 $DIR/$tdir/migrate_dir || error "migrate fails"
16960         changelog_dump | tail -n 5
16961         local migrates=$(changelog_dump | grep -c "MIGRT")
16962         [ $migrates -eq 1 ] || error "MIGRATE changelog count $migrates != 1"
16963 }
16964 run_test 160d "verify that changelog log catch the migrate event"
16965
16966 test_160e() {
16967         remote_mds_nodsh && skip "remote MDS with nodsh"
16968
16969         # Create a user
16970         changelog_register || error "changelog_register failed"
16971
16972         local MDT0=$(facet_svc $SINGLEMDS)
16973         local rc
16974
16975         # No user (expect fail)
16976         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister
16977         rc=$?
16978         if [ $rc -eq 0 ]; then
16979                 error "Should fail without user"
16980         elif [ $rc -ne 4 ]; then
16981                 error "changelog_deregister failed with $rc, expect 4(CMD_HELP)"
16982         fi
16983
16984         # Delete a future user (expect fail)
16985         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister "cl77"
16986         rc=$?
16987         if [ $rc -eq 0 ]; then
16988                 error "Deleted non-existant user cl77"
16989         elif [ $rc -ne 2 ]; then
16990                 error "changelog_deregister failed with $rc, expect 2 (ENOENT)"
16991         fi
16992
16993         # Clear to a bad index (1 billion should be safe)
16994         $LFS changelog_clear $MDT0 "${CL_USERS[$SINGLEMDS]%% *}" 1000000000
16995         rc=$?
16996
16997         if [ $rc -eq 0 ]; then
16998                 error "Successfully cleared to invalid CL index"
16999         elif [ $rc -ne 22 ]; then
17000                 error "changelog_clear failed with $rc, expected 22 (EINVAL)"
17001         fi
17002 }
17003 run_test 160e "changelog negative testing (should return errors)"
17004
17005 test_160f() {
17006         remote_mds_nodsh && skip "remote MDS with nodsh" && return
17007         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
17008                 skip "Need MDS version at least 2.10.56"
17009
17010         local mdts=$(comma_list $(mdts_nodes))
17011
17012         # Create a user
17013         changelog_register || error "first changelog_register failed"
17014         changelog_register || error "second changelog_register failed"
17015         local cl_users
17016         declare -A cl_user1
17017         declare -A cl_user2
17018         local user_rec1
17019         local user_rec2
17020         local i
17021
17022         # generate some changelog records to accumulate on each MDT
17023         # use all_char because created files should be evenly distributed
17024         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
17025                 error "test_mkdir $tdir failed"
17026         log "$(date +%s): creating first files"
17027         for ((i = 0; i < MDSCOUNT * 2; i++)); do
17028                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT)) ||
17029                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT)) failed"
17030         done
17031
17032         # check changelogs have been generated
17033         local start=$SECONDS
17034         local idle_time=$((MDSCOUNT * 5 + 5))
17035         local nbcl=$(changelog_dump | wc -l)
17036         [[ $nbcl -eq 0 ]] && error "no changelogs found"
17037
17038         for param in "changelog_max_idle_time=$idle_time" \
17039                      "changelog_gc=1" \
17040                      "changelog_min_gc_interval=2" \
17041                      "changelog_min_free_cat_entries=3"; do
17042                 local MDT0=$(facet_svc $SINGLEMDS)
17043                 local var="${param%=*}"
17044                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
17045
17046                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
17047                 do_nodes $mdts $LCTL set_param mdd.*.$param
17048         done
17049
17050         # force cl_user2 to be idle (1st part), but also cancel the
17051         # cl_user1 records so that it is not evicted later in the test.
17052         local sleep1=$((idle_time / 2))
17053         echo "$(date +%s): sleep1 $sleep1/${idle_time}s"
17054         sleep $sleep1
17055
17056         # simulate changelog catalog almost full
17057         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
17058         do_nodes $mdts "$LCTL set_param fail_loc=0x1313 fail_val=3"
17059
17060         for i in $(seq $MDSCOUNT); do
17061                 cl_users=(${CL_USERS[mds$i]})
17062                 cl_user1[mds$i]="${cl_users[0]}"
17063                 cl_user2[mds$i]="${cl_users[1]}"
17064
17065                 [ -n "${cl_user1[mds$i]}" ] ||
17066                         error "mds$i: no user registered"
17067                 [ -n "${cl_user2[mds$i]}" ] ||
17068                         error "mds$i: only ${cl_user2[mds$i]} is registered"
17069
17070                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17071                 [ -n "$user_rec1" ] ||
17072                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17073                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
17074                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17075                 [ -n "$user_rec2" ] ||
17076                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17077                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
17078                      "$user_rec1 + 2 == $user_rec2"
17079                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
17080                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
17081                               "$user_rec1 + 2, but is $user_rec2"
17082                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
17083                 [ -n "$user_rec2" ] ||
17084                         error "mds$i: User ${cl_user2[mds$i]} not registered"
17085                 [ $user_rec1 == $user_rec2 ] ||
17086                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
17087                               "$user_rec1, but is $user_rec2"
17088         done
17089
17090         # force cl_user2 idle (2nd part) to just exceed changelog_max_idle_time
17091         local sleep2=$((idle_time - (SECONDS - start) + 1))
17092         echo "$(date +%s): sleep2 $sleep2/${idle_time}s"
17093         sleep $sleep2
17094
17095         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
17096         # cl_user1 should be OK because it recently processed records.
17097         echo "$(date +%s): creating $((MDSCOUNT * 2)) files"
17098         for ((i = 0; i < MDSCOUNT * 2; i++)); do
17099                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT+2))||
17100                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT+2)) failed"
17101         done
17102
17103         # ensure gc thread is done
17104         for i in $(mdts_nodes); do
17105                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
17106                         error "$i: GC-thread not done"
17107         done
17108
17109         local first_rec
17110         for (( i = 1; i <= MDSCOUNT; i++ )); do
17111                 # check cl_user1 still registered
17112                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
17113                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17114                 # check cl_user2 unregistered
17115                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
17116                         error "mds$i: User ${cl_user2[mds$i]} still registered"
17117
17118                 # check changelogs are present and starting at $user_rec1 + 1
17119                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17120                 [ -n "$user_rec1" ] ||
17121                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17122                 first_rec=$($LFS changelog $(facet_svc mds$i) |
17123                             awk '{ print $1; exit; }')
17124
17125                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
17126                 [ $((user_rec1 + 1)) == $first_rec ] ||
17127                         error "mds$i: rec $first_rec != $user_rec1 + 1"
17128         done
17129 }
17130 run_test 160f "changelog garbage collect (timestamped users)"
17131
17132 test_160g() {
17133         remote_mds_nodsh && skip "remote MDS with nodsh"
17134         [[ $MDS1_VERSION -ge $(version_code 2.14.55) ]] ||
17135                 skip "Need MDS version at least 2.14.55"
17136
17137         local mdts=$(comma_list $(mdts_nodes))
17138
17139         # Create a user
17140         changelog_register || error "first changelog_register failed"
17141         changelog_register || error "second changelog_register failed"
17142         local cl_users
17143         declare -A cl_user1
17144         declare -A cl_user2
17145         local user_rec1
17146         local user_rec2
17147         local i
17148
17149         # generate some changelog records to accumulate on each MDT
17150         # use all_char because created files should be evenly distributed
17151         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
17152                 error "test_mkdir $tdir failed"
17153         for ((i = 0; i < MDSCOUNT; i++)); do
17154                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
17155                         error "create $DIR/$tdir/d$i.1 failed"
17156         done
17157
17158         # check changelogs have been generated
17159         local nbcl=$(changelog_dump | wc -l)
17160         (( $nbcl > 0 )) || error "no changelogs found"
17161
17162         # reduce the max_idle_indexes value to make sure we exceed it
17163         for param in "changelog_max_idle_indexes=2" \
17164                      "changelog_gc=1" \
17165                      "changelog_min_gc_interval=2"; do
17166                 local MDT0=$(facet_svc $SINGLEMDS)
17167                 local var="${param%=*}"
17168                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
17169
17170                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
17171                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
17172                         error "unable to set mdd.*.$param"
17173         done
17174
17175         local start=$SECONDS
17176         for i in $(seq $MDSCOUNT); do
17177                 cl_users=(${CL_USERS[mds$i]})
17178                 cl_user1[mds$i]="${cl_users[0]}"
17179                 cl_user2[mds$i]="${cl_users[1]}"
17180
17181                 [ -n "${cl_user1[mds$i]}" ] ||
17182                         error "mds$i: user1 is not registered"
17183                 [ -n "${cl_user2[mds$i]}" ] ||
17184                         error "mds$i: only ${cl_user1[mds$i]} is registered"
17185
17186                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17187                 [ -n "$user_rec1" ] ||
17188                         error "mds$i: user1 ${cl_user1[mds$i]} not found"
17189                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
17190                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17191                 [ -n "$user_rec2" ] ||
17192                         error "mds$i: user1 ${cl_user1[mds$i]} not found (2)"
17193                 echo "mds$i: verifying user1 ${cl_user1[mds$i]} clear: " \
17194                      "$user_rec1 + 2 == $user_rec2"
17195                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
17196                         error "mds$i: user1 ${cl_user1[mds$i]} index " \
17197                               "expected $user_rec1 + 2, but is $user_rec2"
17198                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
17199                 [ -n "$user_rec2" ] ||
17200                         error "mds$i: user2 ${cl_user2[mds$i]} not found"
17201                 [ $user_rec1 == $user_rec2 ] ||
17202                         error "mds$i: user2 ${cl_user2[mds$i]} index " \
17203                               "expected $user_rec1, but is $user_rec2"
17204         done
17205
17206         # ensure we are past the previous changelog_min_gc_interval set above
17207         local sleep2=$((start + 2 - SECONDS))
17208         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
17209         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
17210         # cl_user1 should be OK because it recently processed records.
17211         for ((i = 0; i < MDSCOUNT; i++)); do
17212                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 ||
17213                         error "create $DIR/$tdir/d$i.3 failed"
17214         done
17215
17216         # ensure gc thread is done
17217         for i in $(mdts_nodes); do
17218                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
17219                         error "$i: GC-thread not done"
17220         done
17221
17222         local first_rec
17223         for (( i = 1; i <= MDSCOUNT; i++ )); do
17224                 # check cl_user1 still registered
17225                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
17226                         error "mds$i: user1 ${cl_user1[mds$i]} not found (3)"
17227                 # check cl_user2 unregistered
17228                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
17229                         error "mds$i: user2 ${cl_user2[mds$i]} is registered"
17230
17231                 # check changelogs are present and starting at $user_rec1 + 1
17232                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17233                 [ -n "$user_rec1" ] ||
17234                         error "mds$i: user1 ${cl_user1[mds$i]} not found (4)"
17235                 first_rec=$($LFS changelog $(facet_svc mds$i) |
17236                             awk '{ print $1; exit; }')
17237
17238                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
17239                 [ $((user_rec1 + 1)) == $first_rec ] ||
17240                         error "mds$i: rec $first_rec != $user_rec1 + 1"
17241         done
17242 }
17243 run_test 160g "changelog garbage collect on idle records"
17244
17245 test_160h() {
17246         remote_mds_nodsh && skip "remote MDS with nodsh" && return
17247         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
17248                 skip "Need MDS version at least 2.10.56"
17249
17250         local mdts=$(comma_list $(mdts_nodes))
17251
17252         # Create a user
17253         changelog_register || error "first changelog_register failed"
17254         changelog_register || error "second changelog_register failed"
17255         local cl_users
17256         declare -A cl_user1
17257         declare -A cl_user2
17258         local user_rec1
17259         local user_rec2
17260         local i
17261
17262         # generate some changelog records to accumulate on each MDT
17263         # use all_char because created files should be evenly distributed
17264         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
17265                 error "test_mkdir $tdir failed"
17266         for ((i = 0; i < MDSCOUNT; i++)); do
17267                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
17268                         error "create $DIR/$tdir/d$i.1 failed"
17269         done
17270
17271         # check changelogs have been generated
17272         local nbcl=$(changelog_dump | wc -l)
17273         [[ $nbcl -eq 0 ]] && error "no changelogs found"
17274
17275         for param in "changelog_max_idle_time=10" \
17276                      "changelog_gc=1" \
17277                      "changelog_min_gc_interval=2"; do
17278                 local MDT0=$(facet_svc $SINGLEMDS)
17279                 local var="${param%=*}"
17280                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
17281
17282                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
17283                 do_nodes $mdts $LCTL set_param mdd.*.$param
17284         done
17285
17286         # force cl_user2 to be idle (1st part)
17287         sleep 9
17288
17289         for i in $(seq $MDSCOUNT); do
17290                 cl_users=(${CL_USERS[mds$i]})
17291                 cl_user1[mds$i]="${cl_users[0]}"
17292                 cl_user2[mds$i]="${cl_users[1]}"
17293
17294                 [ -n "${cl_user1[mds$i]}" ] ||
17295                         error "mds$i: no user registered"
17296                 [ -n "${cl_user2[mds$i]}" ] ||
17297                         error "mds$i: only ${cl_user2[mds$i]} is registered"
17298
17299                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17300                 [ -n "$user_rec1" ] ||
17301                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17302                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
17303                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17304                 [ -n "$user_rec2" ] ||
17305                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17306                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
17307                      "$user_rec1 + 2 == $user_rec2"
17308                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
17309                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
17310                               "$user_rec1 + 2, but is $user_rec2"
17311                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
17312                 [ -n "$user_rec2" ] ||
17313                         error "mds$i: User ${cl_user2[mds$i]} not registered"
17314                 [ $user_rec1 == $user_rec2 ] ||
17315                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
17316                               "$user_rec1, but is $user_rec2"
17317         done
17318
17319         # force cl_user2 to be idle (2nd part) and to reach
17320         # changelog_max_idle_time
17321         sleep 2
17322
17323         # force each GC-thread start and block then
17324         # one per MDT/MDD, set fail_val accordingly
17325         #define OBD_FAIL_FORCE_GC_THREAD 0x1316
17326         do_nodes $mdts $LCTL set_param fail_loc=0x1316
17327
17328         # generate more changelogs to trigger fail_loc
17329         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
17330                 error "create $DIR/$tdir/${tfile}bis failed"
17331
17332         # stop MDT to stop GC-thread, should be done in back-ground as it will
17333         # block waiting for the thread to be released and exit
17334         declare -A stop_pids
17335         for i in $(seq $MDSCOUNT); do
17336                 stop mds$i &
17337                 stop_pids[mds$i]=$!
17338         done
17339
17340         for i in $(mdts_nodes); do
17341                 local facet
17342                 local nb=0
17343                 local facets=$(facets_up_on_host $i)
17344
17345                 for facet in ${facets//,/ }; do
17346                         if [[ $facet == mds* ]]; then
17347                                 nb=$((nb + 1))
17348                         fi
17349                 done
17350                 # ensure each MDS's gc threads are still present and all in "R"
17351                 # state (OBD_FAIL_FORCE_GC_THREAD effect!)
17352                 [[ $(do_node $i pgrep chlg_gc_thread | wc -l) -eq $nb ]] ||
17353                         error "$i: expected $nb GC-thread"
17354                 wait_update $i \
17355                         "ps -C chlg_gc_thread -o state --no-headers | uniq" \
17356                         "R" 20 ||
17357                         error "$i: GC-thread not found in R-state"
17358                 # check umounts of each MDT on MDS have reached kthread_stop()
17359                 [[ $(do_node $i pgrep umount | wc -l) -eq $nb ]] ||
17360                         error "$i: expected $nb umount"
17361                 wait_update $i \
17362                         "ps -C umount -o state --no-headers | uniq" "D" 20 ||
17363                         error "$i: umount not found in D-state"
17364         done
17365
17366         # release all GC-threads
17367         do_nodes $mdts $LCTL set_param fail_loc=0
17368
17369         # wait for MDT stop to complete
17370         for i in $(seq $MDSCOUNT); do
17371                 wait ${stop_pids[mds$i]} || error "mds$i: stop failed"
17372         done
17373
17374         # XXX
17375         # may try to check if any orphan changelog records are present
17376         # via ldiskfs/zfs and llog_reader...
17377
17378         # re-start/mount MDTs
17379         for i in $(seq $MDSCOUNT); do
17380                 start mds$i $(mdsdevname $i) $MDS_MOUNT_OPTS ||
17381                         error "Fail to start mds$i"
17382         done
17383
17384         local first_rec
17385         for i in $(seq $MDSCOUNT); do
17386                 # check cl_user1 still registered
17387                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
17388                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17389                 # check cl_user2 unregistered
17390                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
17391                         error "mds$i: User ${cl_user2[mds$i]} still registered"
17392
17393                 # check changelogs are present and starting at $user_rec1 + 1
17394                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17395                 [ -n "$user_rec1" ] ||
17396                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17397                 first_rec=$($LFS changelog $(facet_svc mds$i) |
17398                             awk '{ print $1; exit; }')
17399
17400                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
17401                 [ $((user_rec1 + 1)) == $first_rec ] ||
17402                         error "mds$i: first index should be $user_rec1 + 1, " \
17403                               "but is $first_rec"
17404         done
17405 }
17406 run_test 160h "changelog gc thread stop upon umount, orphan records delete " \
17407               "during mount"
17408
17409 test_160i() {
17410
17411         local mdts=$(comma_list $(mdts_nodes))
17412
17413         changelog_register || error "first changelog_register failed"
17414
17415         # generate some changelog records to accumulate on each MDT
17416         # use all_char because created files should be evenly distributed
17417         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
17418                 error "test_mkdir $tdir failed"
17419         for ((i = 0; i < MDSCOUNT; i++)); do
17420                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
17421                         error "create $DIR/$tdir/d$i.1 failed"
17422         done
17423
17424         # check changelogs have been generated
17425         local nbcl=$(changelog_dump | wc -l)
17426         [[ $nbcl -eq 0 ]] && error "no changelogs found"
17427
17428         # simulate race between register and unregister
17429         # XXX as fail_loc is set per-MDS, with DNE configs the race
17430         # simulation will only occur for one MDT per MDS and for the
17431         # others the normal race scenario will take place
17432         #define CFS_FAIL_CHLOG_USER_REG_UNREG_RACE          0x1315
17433         do_nodes $mdts $LCTL set_param fail_loc=0x10001315
17434         do_nodes $mdts $LCTL set_param fail_val=1
17435
17436         # unregister 1st user
17437         changelog_deregister &
17438         local pid1=$!
17439         # wait some time for deregister work to reach race rdv
17440         sleep 2
17441         # register 2nd user
17442         changelog_register || error "2nd user register failed"
17443
17444         wait $pid1 || error "1st user deregister failed"
17445
17446         local i
17447         local last_rec
17448         declare -A LAST_REC
17449         for i in $(seq $MDSCOUNT); do
17450                 if changelog_users mds$i | grep "^cl"; then
17451                         # make sure new records are added with one user present
17452                         LAST_REC[mds$i]=$(changelog_users $SINGLEMDS |
17453                                           awk '/^current.index:/ { print $NF }')
17454                 else
17455                         error "mds$i has no user registered"
17456                 fi
17457         done
17458
17459         # generate more changelog records to accumulate on each MDT
17460         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
17461                 error "create $DIR/$tdir/${tfile}bis failed"
17462
17463         for i in $(seq $MDSCOUNT); do
17464                 last_rec=$(changelog_users $SINGLEMDS |
17465                            awk '/^current.index:/ { print $NF }')
17466                 echo "verify changelogs are on: $last_rec != ${LAST_REC[mds$i]}"
17467                 [ $last_rec != ${LAST_REC[mds$i]} ] ||
17468                         error "changelogs are off on mds$i"
17469         done
17470 }
17471 run_test 160i "changelog user register/unregister race"
17472
17473 test_160j() {
17474         remote_mds_nodsh && skip "remote MDS with nodsh"
17475         [[ $MDS1_VERSION -lt $(version_code 2.12.56) ]] &&
17476                 skip "Need MDS version at least 2.12.56"
17477
17478         mount_client $MOUNT2 || error "mount_client on $MOUNT2 failed"
17479         stack_trap "umount $MOUNT2" EXIT
17480
17481         changelog_register || error "first changelog_register failed"
17482         stack_trap "changelog_deregister" EXIT
17483
17484         # generate some changelog
17485         # use all_char because created files should be evenly distributed
17486         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
17487                 error "mkdir $tdir failed"
17488         for ((i = 0; i < MDSCOUNT; i++)); do
17489                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
17490                         error "create $DIR/$tdir/d$i.1 failed"
17491         done
17492
17493         # open the changelog device
17494         exec 3>/dev/changelog-$FSNAME-MDT0000
17495         stack_trap "exec 3>&-" EXIT
17496         exec 4</dev/changelog-$FSNAME-MDT0000
17497         stack_trap "exec 4<&-" EXIT
17498
17499         # umount the first lustre mount
17500         umount $MOUNT
17501         stack_trap "mount_client $MOUNT" EXIT
17502
17503         # read changelog, which may or may not fail, but should not crash
17504         cat <&4 >/dev/null
17505
17506         # clear changelog
17507         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
17508         changelog_users $SINGLEMDS | grep -q $cl_user ||
17509                 error "User $cl_user not found in changelog_users"
17510
17511         printf 'clear:'$cl_user':0' >&3
17512 }
17513 run_test 160j "client can be umounted while its chanangelog is being used"
17514
17515 test_160k() {
17516         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17517         remote_mds_nodsh && skip "remote MDS with nodsh"
17518
17519         mkdir -p $DIR/$tdir/1/1
17520
17521         changelog_register || error "changelog_register failed"
17522         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
17523
17524         changelog_users $SINGLEMDS | grep -q $cl_user ||
17525                 error "User '$cl_user' not found in changelog_users"
17526 #define OBD_FAIL_MDS_CHANGELOG_REORDER 0x15d
17527         do_facet mds1 $LCTL set_param fail_loc=0x8000015d fail_val=3
17528         rmdir $DIR/$tdir/1/1 & sleep 1
17529         mkdir $DIR/$tdir/2
17530         touch $DIR/$tdir/2/2
17531         rm -rf $DIR/$tdir/2
17532
17533         wait
17534         sleep 4
17535
17536         changelog_dump | grep rmdir || error "rmdir not recorded"
17537 }
17538 run_test 160k "Verify that changelog records are not lost"
17539
17540 # Verifies that a file passed as a parameter has recently had an operation
17541 # performed on it that has generated an MTIME changelog which contains the
17542 # correct parent FID. As files might reside on a different MDT from the
17543 # parent directory in DNE configurations, the FIDs are translated to paths
17544 # before being compared, which should be identical
17545 compare_mtime_changelog() {
17546         local file="${1}"
17547         local mdtidx
17548         local mtime
17549         local cl_fid
17550         local pdir
17551         local dir
17552
17553         mdtidx=$($LFS getstripe --mdt-index $file)
17554         mdtidx=$(printf "%04x" $mdtidx)
17555
17556         # Obtain the parent FID from the MTIME changelog
17557         mtime=$($LFS changelog $FSNAME-MDT$mdtidx | tail -n 1 | grep MTIME)
17558         [ -z "$mtime" ] && error "MTIME changelog not recorded"
17559
17560         cl_fid=$(sed -e 's/.* p=//' -e 's/ .*//' <<<$mtime)
17561         [ -z "$cl_fid" ] && error "parent FID not present"
17562
17563         # Verify that the path for the parent FID is the same as the path for
17564         # the test directory
17565         pdir=$($LFS fid2path $MOUNT "$cl_fid")
17566
17567         dir=$(dirname $1)
17568
17569         [[ "${pdir%/}" == "$dir" ]] ||
17570                 error "MTIME changelog parent FID is wrong, expected $dir, got $pdir"
17571 }
17572
17573 test_160l() {
17574         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17575
17576         remote_mds_nodsh && skip "remote MDS with nodsh"
17577         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
17578                 skip "Need MDS version at least 2.13.55"
17579
17580         local cl_user
17581
17582         changelog_register || error "changelog_register failed"
17583         cl_user="${CL_USERS[$SINGLEMDS]%% *}"
17584
17585         changelog_users $SINGLEMDS | grep -q $cl_user ||
17586                 error "User '$cl_user' not found in changelog_users"
17587
17588         # Clear some types so that MTIME changelogs are generated
17589         changelog_chmask "-CREAT"
17590         changelog_chmask "-CLOSE"
17591
17592         test_mkdir $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
17593
17594         # Test CL_MTIME during setattr
17595         touch $DIR/$tdir/$tfile
17596         compare_mtime_changelog $DIR/$tdir/$tfile
17597
17598         # Test CL_MTIME during close
17599         $MULTIOP $DIR/$tdir/${tfile}_2 O_2w4096c || error "multiop failed"
17600         compare_mtime_changelog $DIR/$tdir/${tfile}_2
17601 }
17602 run_test 160l "Verify that MTIME changelog records contain the parent FID"
17603
17604 test_160m() {
17605         remote_mds_nodsh && skip "remote MDS with nodsh" && return
17606         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
17607                 skip "Need MDS version at least 2.14.51"
17608         local cl_users
17609         local cl_user1
17610         local cl_user2
17611         local pid1
17612
17613         # Create a user
17614         changelog_register || error "first changelog_register failed"
17615         changelog_register || error "second changelog_register failed"
17616
17617         cl_users=(${CL_USERS[mds1]})
17618         cl_user1="${cl_users[0]}"
17619         cl_user2="${cl_users[1]}"
17620         # generate some changelog records to accumulate on MDT0
17621         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
17622         createmany -m $DIR/$tdir/$tfile 50 ||
17623                 error "create $DIR/$tdir/$tfile failed"
17624         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
17625         rm -f $DIR/$tdir
17626
17627         # check changelogs have been generated
17628         local nbcl=$(changelog_dump | wc -l)
17629         [[ $nbcl -eq 0 ]] && error "no changelogs found"
17630
17631 #define OBD_FAIL_MDS_CHANGELOG_RACE      0x15f
17632         do_facet mds1 $LCTL set_param fail_loc=0x8000015f fail_val=0
17633
17634         __changelog_clear mds1 $cl_user1 +10
17635         __changelog_clear mds1 $cl_user2 0 &
17636         pid1=$!
17637         sleep 2
17638         __changelog_clear mds1 $cl_user1 0 ||
17639                 error "fail to cancel record for $cl_user1"
17640         wait $pid1
17641         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
17642 }
17643 run_test 160m "Changelog clear race"
17644
17645 test_160n() {
17646         remote_mds_nodsh && skip "remote MDS with nodsh" && return
17647         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
17648                 skip "Need MDS version at least 2.14.51"
17649         local cl_users
17650         local cl_user1
17651         local cl_user2
17652         local pid1
17653         local first_rec
17654         local last_rec=0
17655
17656         # Create a user
17657         changelog_register || error "first changelog_register failed"
17658
17659         cl_users=(${CL_USERS[mds1]})
17660         cl_user1="${cl_users[0]}"
17661
17662         # generate some changelog records to accumulate on MDT0
17663         test_mkdir -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
17664         first_rec=$(changelog_users $SINGLEMDS |
17665                         awk '/^current.index:/ { print $NF }')
17666         while (( last_rec < (( first_rec + 65000)) )); do
17667                 createmany -m $DIR/$tdir/$tfile 10000 ||
17668                         error "create $DIR/$tdir/$tfile failed"
17669
17670                 for i in $(seq 0 10000); do
17671                         mrename $DIR/$tdir/$tfile$i $DIR/$tdir/$tfile-new$i \
17672                                 > /dev/null
17673                 done
17674
17675                 unlinkmany $DIR/$tdir/$tfile-new 10000 ||
17676                         error "unlinkmany failed unlink"
17677                 last_rec=$(changelog_users $SINGLEMDS |
17678                         awk '/^current.index:/ { print $NF }')
17679                 echo last record $last_rec
17680                 (( last_rec == 0 )) && error "no changelog found"
17681         done
17682
17683 #define OBD_FAIL_MDS_CHANGELOG_DEL       0x16c
17684         do_facet mds1 $LCTL set_param fail_loc=0x8000016c fail_val=0
17685
17686         __changelog_clear mds1 $cl_user1 0 &
17687         pid1=$!
17688         sleep 2
17689         __changelog_clear mds1 $cl_user1 0 ||
17690                 error "fail to cancel record for $cl_user1"
17691         wait $pid1
17692         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
17693 }
17694 run_test 160n "Changelog destroy race"
17695
17696 test_160o() {
17697         local mdt="$(facet_svc $SINGLEMDS)"
17698
17699         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
17700         remote_mds_nodsh && skip "remote MDS with nodsh"
17701         [ $MDS1_VERSION -ge $(version_code 2.14.52) ] ||
17702                 skip "Need MDS version at least 2.14.52"
17703
17704         changelog_register --user test_160o -m unlnk+close+open ||
17705                 error "changelog_register failed"
17706
17707         do_facet $SINGLEMDS $LCTL --device $mdt \
17708                                 changelog_register -u "Tt3_-#" &&
17709                 error "bad symbols in name should fail"
17710
17711         do_facet $SINGLEMDS $LCTL --device $mdt \
17712                                 changelog_register -u test_160o &&
17713                 error "the same name registration should fail"
17714
17715         do_facet $SINGLEMDS $LCTL --device $mdt \
17716                         changelog_register -u test_160toolongname &&
17717                 error "too long name registration should fail"
17718
17719         changelog_chmask "MARK+HSM"
17720         lctl get_param mdd.*.changelog*mask
17721         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
17722         changelog_users $SINGLEMDS | grep -q $cl_user ||
17723                 error "User $cl_user not found in changelog_users"
17724         #verify username
17725         echo $cl_user | grep -q test_160o ||
17726                 error "User $cl_user has no specific name 'test160o'"
17727
17728         # change something
17729         changelog_clear 0 || error "changelog_clear failed"
17730         # generate some changelog records to accumulate on MDT0
17731         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
17732         touch $DIR/$tdir/$tfile                 # open 1
17733
17734         OPENS=$(changelog_dump | grep -c "OPEN")
17735         [[ $OPENS -eq 1 ]] || error "OPEN changelog mask count $OPENS != 1"
17736
17737         # must be no MKDIR it wasn't set as user mask
17738         MKDIR=$(changelog_dump | grep -c "MKDIR")
17739         [[ $MKDIR -eq 0 ]] || error "MKDIR changelog mask found $MKDIR > 0"
17740
17741         oldmask=$(do_facet $SINGLEMDS $LCTL get_param \
17742                                 mdd.$mdt.changelog_current_mask -n)
17743         # register maskless user
17744         changelog_register || error "changelog_register failed"
17745         # effective mask should be not changed because it is not minimal
17746         mask=$(do_facet $SINGLEMDS $LCTL get_param \
17747                                 mdd.$mdt.changelog_current_mask -n)
17748         [[ $mask == $oldmask ]] || error "mask was changed: $mask vs $oldmask"
17749         # set server mask to minimal value
17750         changelog_chmask "MARK"
17751         # check effective mask again, should be treated as DEFMASK now
17752         mask=$(do_facet $SINGLEMDS $LCTL get_param \
17753                                 mdd.$mdt.changelog_current_mask -n)
17754         [[ $mask == *"HLINK"* ]] || error "mask is not DEFMASK as expected"
17755
17756         if (( $MDS1_VERSION >= $(version_code 2.15.52) )) ; then
17757                 # set server mask back to some value
17758                 changelog_chmask "CLOSE,UNLNK"
17759                 # check effective mask again, should not remain as DEFMASK
17760                 mask=$(do_facet $SINGLEMDS $LCTL get_param \
17761                                 mdd.$mdt.changelog_current_mask -n)
17762                 [[ $mask != *"HLINK"* ]] || error "mask is still DEFMASK"
17763         fi
17764
17765         do_facet $SINGLEMDS $LCTL --device $mdt \
17766                                 changelog_deregister -u test_160o ||
17767                 error "cannot deregister by name"
17768 }
17769 run_test 160o "changelog user name and mask"
17770
17771 test_160p() {
17772         remote_mds_nodsh && skip "remote MDS with nodsh" && return
17773         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
17774                 skip "Need MDS version at least 2.14.51"
17775         [[ "$mds1_FSTYPE" == "ldiskfs" ]] || skip "ldiskfs only test"
17776         local cl_users
17777         local cl_user1
17778         local entry_count
17779
17780         # Create a user
17781         changelog_register || error "first changelog_register failed"
17782
17783         cl_users=(${CL_USERS[mds1]})
17784         cl_user1="${cl_users[0]}"
17785
17786         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
17787         createmany -m $DIR/$tdir/$tfile 50 ||
17788                 error "create $DIR/$tdir/$tfile failed"
17789         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
17790         rm -rf $DIR/$tdir
17791
17792         # check changelogs have been generated
17793         entry_count=$(changelog_dump | wc -l)
17794         ((entry_count != 0)) || error "no changelog entries found"
17795
17796         # remove changelog_users and check that orphan entries are removed
17797         stop mds1
17798         local dev=$(mdsdevname 1)
17799         do_facet mds1 "$DEBUGFS -w -R 'rm changelog_users' $dev"
17800         start mds1 $dev $MDS_MOUNT_OPTS || error "cannot start mds1"
17801         entry_count=$(changelog_dump | wc -l)
17802         ((entry_count == 0)) ||
17803                 error "found $entry_count changelog entries, expected none"
17804 }
17805 run_test 160p "Changelog orphan cleanup with no users"
17806
17807 test_160q() {
17808         local mdt="$(facet_svc $SINGLEMDS)"
17809         local clu
17810
17811         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
17812         remote_mds_nodsh && skip "remote MDS with nodsh"
17813         [ $MDS1_VERSION -ge $(version_code 2.14.54) ] ||
17814                 skip "Need MDS version at least 2.14.54"
17815
17816         # set server mask to minimal value like server init does
17817         changelog_chmask "MARK"
17818         clu=$(do_facet $SINGLEMDS $LCTL --device $mdt changelog_register -n) ||
17819                 error "changelog_register failed"
17820         # check effective mask again, should be treated as DEFMASK now
17821         mask=$(do_facet $SINGLEMDS $LCTL get_param \
17822                                 mdd.$mdt.changelog_current_mask -n)
17823         do_facet $SINGLEMDS $LCTL --device $mdt changelog_deregister $clu ||
17824                 error "changelog_deregister failed"
17825         [[ $mask == *"HLINK"* ]] || error "mask is not DEFMASK as expected"
17826 }
17827 run_test 160q "changelog effective mask is DEFMASK if not set"
17828
17829 test_160s() {
17830         remote_mds_nodsh && skip "remote MDS with nodsh"
17831         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
17832                 skip "Need MDS version at least 2.14.55"
17833
17834         local mdts=$(comma_list $(mdts_nodes))
17835
17836         #define OBD_FAIL_TIME_IN_CHLOG_USER     0x1314
17837         do_nodes $mdts $LCTL set_param fail_loc=0x1314 \
17838                                        fail_val=$((24 * 3600 * 10))
17839
17840         # Create a user which is 10 days old
17841         changelog_register || error "first changelog_register failed"
17842         local cl_users
17843         declare -A cl_user1
17844         local i
17845
17846         # generate some changelog records to accumulate on each MDT
17847         # use all_char because created files should be evenly distributed
17848         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
17849                 error "test_mkdir $tdir failed"
17850         for ((i = 0; i < MDSCOUNT; i++)); do
17851                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
17852                         error "create $DIR/$tdir/d$i.1 failed"
17853         done
17854
17855         # check changelogs have been generated
17856         local nbcl=$(changelog_dump | wc -l)
17857         (( nbcl > 0 )) || error "no changelogs found"
17858
17859         # reduce the max_idle_indexes value to make sure we exceed it
17860         for param in "changelog_max_idle_indexes=2097446912" \
17861                      "changelog_max_idle_time=2592000" \
17862                      "changelog_gc=1" \
17863                      "changelog_min_gc_interval=2"; do
17864                 local MDT0=$(facet_svc $SINGLEMDS)
17865                 local var="${param%=*}"
17866                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
17867
17868                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
17869                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
17870                         error "unable to set mdd.*.$param"
17871         done
17872
17873         local start=$SECONDS
17874         for i in $(seq $MDSCOUNT); do
17875                 cl_users=(${CL_USERS[mds$i]})
17876                 cl_user1[mds$i]="${cl_users[0]}"
17877
17878                 [[ -n "${cl_user1[mds$i]}" ]] ||
17879                         error "mds$i: no user registered"
17880         done
17881
17882         #define OBD_FAIL_MDS_CHANGELOG_IDX_PUMP   0x16d
17883         do_nodes $mdts $LCTL set_param fail_loc=0x16d fail_val=500000000
17884
17885         # ensure we are past the previous changelog_min_gc_interval set above
17886         local sleep2=$((start + 2 - SECONDS))
17887         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
17888
17889         # Generate one more changelog to trigger GC
17890         for ((i = 0; i < MDSCOUNT; i++)); do
17891                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 $DIR/$tdir/d$i.4 ||
17892                         error "create $DIR/$tdir/d$i.3 failed"
17893         done
17894
17895         # ensure gc thread is done
17896         for node in $(mdts_nodes); do
17897                 wait_update $node "pgrep chlg_gc_thread" "" 20 ||
17898                         error "$node: GC-thread not done"
17899         done
17900
17901         do_nodes $mdts $LCTL set_param fail_loc=0
17902
17903         for (( i = 1; i <= MDSCOUNT; i++ )); do
17904                 # check cl_user1 is purged
17905                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" &&
17906                         error "mds$i: User ${cl_user1[mds$i]} is registered"
17907         done
17908         return 0
17909 }
17910 run_test 160s "changelog garbage collect on idle records * time"
17911
17912 test_160t() {
17913         remote_mds_nodsh && skip "remote MDS with nodsh"
17914         (( $MDS1_VERSION >= $(version_code 2.15.50) )) ||
17915                 skip "Need MDS version at least 2.15.50"
17916
17917         local MDT0=$(facet_svc $SINGLEMDS)
17918         local cl_users
17919         local cl_user1
17920         local cl_user2
17921         local start
17922
17923         changelog_register --user user1 -m all ||
17924                 error "user1 failed to register"
17925
17926         mkdir_on_mdt0 $DIR/$tdir
17927         # create default overstripe to maximize changelog size
17928         $LFS setstripe  -C 8 $DIR/$tdir || error "setstripe failed"
17929         createmany -o $DIR/$tdir/u1_ 2000 || error "createmany for user1 failed"
17930         llog_size1=$(do_facet mds1 $LCTL get_param -n mdd.$MDT0.changelog_size)
17931
17932         # user2 consumes less records so less space
17933         changelog_register --user user2 || error "user2 failed to register"
17934         createmany -o $DIR/$tdir/u2_ 500 || error "createmany for user2 failed"
17935         llog_size2=$(do_facet mds1 $LCTL get_param -n mdd.$MDT0.changelog_size)
17936
17937         # check changelogs have been generated
17938         local nbcl=$(changelog_dump | wc -l)
17939         (( nbcl > 0 )) || error "no changelogs found"
17940
17941         # reduce the changelog_min_gc_interval to force check
17942         for param in "changelog_gc=1" "changelog_min_gc_interval=2"; do
17943                 local var="${param%=*}"
17944                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
17945
17946                 stack_trap "do_facet mds1 $LCTL set_param mdd.$MDT0.$var=$old"
17947                 do_facet mds1 $LCTL set_param mdd.$MDT0.$param ||
17948                         error "unable to set mdd.*.$param"
17949         done
17950
17951         start=$SECONDS
17952         cl_users=(${CL_USERS[mds1]})
17953         cl_user1="${cl_users[0]}"
17954         cl_user2="${cl_users[1]}"
17955
17956         [[ -n $cl_user1 ]] ||
17957                 error "mds1: user #1 isn't registered"
17958         [[ -n $cl_user2 ]] ||
17959                 error "mds1: user #2 isn't registered"
17960
17961         # ensure we are past the previous changelog_min_gc_interval set above
17962         local sleep2=$((start + 2 - SECONDS))
17963         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
17964
17965         #define OBD_FAIL_MDS_CHANGELOG_ENOSPC 0x018c
17966         do_facet mds1 $LCTL set_param fail_loc=0x018c \
17967                         fail_val=$(((llog_size1 + llog_size2) / 2))
17968
17969         # Generate more changelog to trigger GC
17970         createmany -o $DIR/$tdir/u3_ 4 ||
17971                 error "create failed for more files"
17972
17973         # ensure gc thread is done
17974         wait_update_facet mds1 "pgrep chlg_gc_thread" "" 20 ||
17975                 error "mds1: GC-thread not done"
17976
17977         do_facet mds1 $LCTL set_param fail_loc=0
17978
17979         # check cl_user1 is purged
17980         changelog_users mds1 | grep -q "$cl_user1" &&
17981                 error "User $cl_user1 is registered"
17982         # check cl_user2 is not purged
17983         changelog_users mds1 | grep -q "$cl_user2" ||
17984                 error "User $cl_user2 is not registered"
17985 }
17986 run_test 160t "changelog garbage collect on lack of space"
17987
17988 test_161a() {
17989         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17990
17991         test_mkdir -c1 $DIR/$tdir
17992         cp /etc/hosts $DIR/$tdir/$tfile
17993         test_mkdir -c1 $DIR/$tdir/foo1
17994         test_mkdir -c1 $DIR/$tdir/foo2
17995         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/sofia
17996         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/zachary
17997         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/luna
17998         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/thor
17999         local FID=$($LFS path2fid $DIR/$tdir/$tfile | tr -d '[]')
18000         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
18001                 $LFS fid2path $DIR $FID
18002                 error "bad link ea"
18003         fi
18004         # middle
18005         rm $DIR/$tdir/foo2/zachary
18006         # last
18007         rm $DIR/$tdir/foo2/thor
18008         # first
18009         rm $DIR/$tdir/$tfile
18010         # rename
18011         mv $DIR/$tdir/foo1/sofia $DIR/$tdir/foo2/maggie
18012         [ "$($LFS fid2path $FSNAME --link 1 $FID)" != "$tdir/foo2/maggie" ] &&
18013                 { $LFS fid2path $DIR $FID; error "bad link rename"; }
18014         rm $DIR/$tdir/foo2/maggie
18015
18016         # overflow the EA
18017         local longname=$tfile.avg_len_is_thirty_two_
18018         stack_trap "unlinkmany $DIR/$tdir/foo2/$longname 1000 || \
18019                 error_noexit 'failed to unlink many hardlinks'" EXIT
18020         createmany -l$DIR/$tdir/foo1/luna $DIR/$tdir/foo2/$longname 1000 ||
18021                 error "failed to hardlink many files"
18022         links=$($LFS fid2path $DIR $FID | wc -l)
18023         echo -n "${links}/1000 links in link EA"
18024         [[ $links -gt 60 ]] || error "expected at least 60 links in link EA"
18025 }
18026 run_test 161a "link ea sanity"
18027
18028 test_161b() {
18029         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18030         [ $MDSCOUNT -lt 2 ] && skip_env "skipping remote directory test"
18031
18032         local MDTIDX=1
18033         local remote_dir=$DIR/$tdir/remote_dir
18034
18035         mkdir -p $DIR/$tdir
18036         $LFS mkdir -i $MDTIDX $remote_dir ||
18037                 error "create remote directory failed"
18038
18039         cp /etc/hosts $remote_dir/$tfile
18040         mkdir -p $remote_dir/foo1
18041         mkdir -p $remote_dir/foo2
18042         ln $remote_dir/$tfile $remote_dir/foo1/sofia
18043         ln $remote_dir/$tfile $remote_dir/foo2/zachary
18044         ln $remote_dir/$tfile $remote_dir/foo1/luna
18045         ln $remote_dir/$tfile $remote_dir/foo2/thor
18046
18047         local FID=$($LFS path2fid $remote_dir/$tfile | tr -d '[' |
18048                      tr -d ']')
18049         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
18050                 $LFS fid2path $DIR $FID
18051                 error "bad link ea"
18052         fi
18053         # middle
18054         rm $remote_dir/foo2/zachary
18055         # last
18056         rm $remote_dir/foo2/thor
18057         # first
18058         rm $remote_dir/$tfile
18059         # rename
18060         mv $remote_dir/foo1/sofia $remote_dir/foo2/maggie
18061         local link_path=$($LFS fid2path $FSNAME --link 1 $FID)
18062         if [ "$DIR/$link_path" != "$remote_dir/foo2/maggie" ]; then
18063                 $LFS fid2path $DIR $FID
18064                 error "bad link rename"
18065         fi
18066         rm $remote_dir/foo2/maggie
18067
18068         # overflow the EA
18069         local longname=filename_avg_len_is_thirty_two_
18070         createmany -l$remote_dir/foo1/luna $remote_dir/foo2/$longname 1000 ||
18071                 error "failed to hardlink many files"
18072         links=$($LFS fid2path $DIR $FID | wc -l)
18073         echo -n "${links}/1000 links in link EA"
18074         [[ ${links} -gt 60 ]] ||
18075                 error "expected at least 60 links in link EA"
18076         unlinkmany $remote_dir/foo2/$longname 1000 ||
18077         error "failed to unlink many hardlinks"
18078 }
18079 run_test 161b "link ea sanity under remote directory"
18080
18081 test_161c() {
18082         remote_mds_nodsh && skip "remote MDS with nodsh"
18083         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18084         [[ $MDS1_VERSION -lt $(version_code 2.1.5) ]] &&
18085                 skip "Need MDS version at least 2.1.5"
18086
18087         # define CLF_RENAME_LAST 0x0001
18088         # rename overwrite a target having nlink = 1 (changelog flag 0x1)
18089         changelog_register || error "changelog_register failed"
18090
18091         rm -rf $DIR/$tdir
18092         test_mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir
18093         touch $DIR/$tdir/foo_161c
18094         touch $DIR/$tdir/bar_161c
18095         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
18096         changelog_dump | grep RENME | tail -n 5
18097         local flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
18098         changelog_clear 0 || error "changelog_clear failed"
18099         if [ x$flags != "x0x1" ]; then
18100                 error "flag $flags is not 0x1"
18101         fi
18102
18103         echo "rename overwrite target with nlink = 1, changelog flags=$flags"
18104         # rename overwrite a target having nlink > 1 (changelog flag 0x0)
18105         touch $DIR/$tdir/foo_161c
18106         touch $DIR/$tdir/bar_161c
18107         ln $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
18108         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
18109         changelog_dump | grep RENME | tail -n 5
18110         flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
18111         changelog_clear 0 || error "changelog_clear failed"
18112         if [ x$flags != "x0x0" ]; then
18113                 error "flag $flags is not 0x0"
18114         fi
18115         echo "rename overwrite a target having nlink > 1," \
18116                 "changelog record has flags of $flags"
18117
18118         # rename doesn't overwrite a target (changelog flag 0x0)
18119         touch $DIR/$tdir/foo_161c
18120         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/foo2_161c
18121         changelog_dump | grep RENME | tail -n 5
18122         flags=$(changelog_dump | grep RENME | tail -1 | cut -f5 -d' ')
18123         changelog_clear 0 || error "changelog_clear failed"
18124         if [ x$flags != "x0x0" ]; then
18125                 error "flag $flags is not 0x0"
18126         fi
18127         echo "rename doesn't overwrite a target," \
18128                 "changelog record has flags of $flags"
18129
18130         # define CLF_UNLINK_LAST 0x0001
18131         # unlink a file having nlink = 1 (changelog flag 0x1)
18132         rm -f $DIR/$tdir/foo2_161c
18133         changelog_dump | grep UNLNK | tail -n 5
18134         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
18135         changelog_clear 0 || error "changelog_clear failed"
18136         if [ x$flags != "x0x1" ]; then
18137                 error "flag $flags is not 0x1"
18138         fi
18139         echo "unlink a file having nlink = 1," \
18140                 "changelog record has flags of $flags"
18141
18142         # unlink a file having nlink > 1 (changelog flag 0x0)
18143         ln -f $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
18144         rm -f $DIR/$tdir/foobar_161c
18145         changelog_dump | grep UNLNK | tail -n 5
18146         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
18147         changelog_clear 0 || error "changelog_clear failed"
18148         if [ x$flags != "x0x0" ]; then
18149                 error "flag $flags is not 0x0"
18150         fi
18151         echo "unlink a file having nlink > 1, changelog record flags '$flags'"
18152 }
18153 run_test 161c "check CL_RENME[UNLINK] changelog record flags"
18154
18155 test_161d() {
18156         remote_mds_nodsh && skip "remote MDS with nodsh"
18157         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
18158
18159         local pid
18160         local fid
18161
18162         changelog_register || error "changelog_register failed"
18163
18164         # work in a standalone dir to avoid locking on $DIR/$MOUNT to
18165         # interfer with $MOUNT/.lustre/fid/ access
18166         mkdir $DIR/$tdir
18167         [[ $? -eq 0 ]] || error "mkdir failed"
18168
18169         #define OBD_FAIL_LLITE_CREATE_NODE_PAUSE 0x140c | CFS_FAIL_ONCE
18170         $LCTL set_param fail_loc=0x8000140c
18171         # 5s pause
18172         $LCTL set_param fail_val=5
18173
18174         # create file
18175         echo foofoo > $DIR/$tdir/$tfile &
18176         pid=$!
18177
18178         # wait for create to be delayed
18179         sleep 2
18180
18181         ps -p $pid
18182         [[ $? -eq 0 ]] || error "create should be blocked"
18183
18184         local tempfile="$(mktemp --tmpdir $tfile.XXXXXX)"
18185         stack_trap "rm -f $tempfile"
18186         fid=$(changelog_extract_field "CREAT" "$tfile" "t=")
18187         cat $MOUNT/.lustre/fid/$fid 2>/dev/null >$tempfile || error "cat failed"
18188         # some delay may occur during ChangeLog publishing and file read just
18189         # above, that could allow file write to happen finally
18190         [[ -s $tempfile ]] && echo "file should be empty"
18191
18192         $LCTL set_param fail_loc=0
18193
18194         wait $pid
18195         [[ $? -eq 0 ]] || error "create failed"
18196 }
18197 run_test 161d "create with concurrent .lustre/fid access"
18198
18199 check_path() {
18200         local expected="$1"
18201         shift
18202         local fid="$2"
18203
18204         local path
18205         path=$($LFS fid2path "$@")
18206         local rc=$?
18207
18208         if [ $rc -ne 0 ]; then
18209                 error "path looked up of '$expected' failed: rc=$rc"
18210         elif [ "$path" != "$expected" ]; then
18211                 error "path looked up '$path' instead of '$expected'"
18212         else
18213                 echo "FID '$fid' resolves to path '$path' as expected"
18214         fi
18215 }
18216
18217 test_162a() { # was test_162
18218         test_mkdir -p -c1 $DIR/$tdir/d2
18219         touch $DIR/$tdir/d2/$tfile
18220         touch $DIR/$tdir/d2/x1
18221         touch $DIR/$tdir/d2/x2
18222         test_mkdir -p -c1 $DIR/$tdir/d2/a/b/c
18223         test_mkdir -p -c1 $DIR/$tdir/d2/p/q/r
18224         # regular file
18225         local fid=$($LFS path2fid $DIR/$tdir/d2/$tfile | tr -d '[]')
18226         check_path "$tdir/d2/$tfile" $FSNAME "$fid" --link 0
18227
18228         # softlink
18229         ln -s $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/slink
18230         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink | tr -d '[]')
18231         check_path "$tdir/d2/p/q/r/slink" $FSNAME "$fid" --link 0
18232
18233         # softlink to wrong file
18234         ln -s /this/is/garbage $DIR/$tdir/d2/p/q/r/slink.wrong
18235         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink.wrong | tr -d '[]')
18236         check_path "$tdir/d2/p/q/r/slink.wrong" $FSNAME "$fid" --link 0
18237
18238         # hardlink
18239         ln $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/hlink
18240         mv $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/a/b/c/new_file
18241         fid=$($LFS path2fid $DIR/$tdir/d2/a/b/c/new_file | tr -d '[]')
18242         # fid2path dir/fsname should both work
18243         check_path "$tdir/d2/a/b/c/new_file" $FSNAME "$fid" --link 1
18244         check_path "$DIR/$tdir/d2/p/q/r/hlink" $DIR "$fid" --link 0
18245
18246         # hardlink count: check that there are 2 links
18247         local nlinks=$($LFS fid2path $DIR "$fid" | wc -l)
18248         [ $nlinks -eq 2 ] || error "expect 2 links, found $nlinks"
18249
18250         # hardlink indexing: remove the first link
18251         rm $DIR/$tdir/d2/p/q/r/hlink
18252         check_path "$tdir/d2/a/b/c/new_file" $FSNAME $fid --link 0
18253 }
18254 run_test 162a "path lookup sanity"
18255
18256 test_162b() {
18257         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18258         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18259
18260         mkdir $DIR/$tdir
18261         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
18262                                 error "create striped dir failed"
18263
18264         local FID=$($LFS getdirstripe $DIR/$tdir/striped_dir |
18265                                         tail -n 1 | awk '{print $2}')
18266         stat $MOUNT/.lustre/fid/$FID && error "sub_stripe can be accessed"
18267
18268         touch $DIR/$tdir/striped_dir/f{0..4} || error "touch f0..4 failed"
18269         mkdir $DIR/$tdir/striped_dir/d{0..4} || error "mkdir d0..4 failed"
18270
18271         # regular file
18272         for ((i=0;i<5;i++)); do
18273                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/f$i | tr -d '[]') ||
18274                         error "get fid for f$i failed"
18275                 check_path "$tdir/striped_dir/f$i" $FSNAME $FID --link 0
18276
18277                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/d$i | tr -d '[]') ||
18278                         error "get fid for d$i failed"
18279                 check_path "$tdir/striped_dir/d$i" $FSNAME $FID --link 0
18280         done
18281
18282         return 0
18283 }
18284 run_test 162b "striped directory path lookup sanity"
18285
18286 # LU-4239: Verify fid2path works with paths 100 or more directories deep
18287 test_162c() {
18288         [[ $MDS1_VERSION -lt $(version_code 2.7.51) ]] &&
18289                 skip "Need MDS version at least 2.7.51"
18290
18291         local lpath=$tdir.local
18292         local rpath=$tdir.remote
18293
18294         test_mkdir $DIR/$lpath
18295         test_mkdir $DIR/$rpath
18296
18297         for ((i = 0; i <= 101; i++)); do
18298                 lpath="$lpath/$i"
18299                 mkdir $DIR/$lpath
18300                 FID=$($LFS path2fid $DIR/$lpath | tr -d '[]') ||
18301                         error "get fid for local directory $DIR/$lpath failed"
18302                 check_path "$DIR/$lpath" $MOUNT $FID --link 0
18303
18304                 rpath="$rpath/$i"
18305                 test_mkdir $DIR/$rpath
18306                 FID=$($LFS path2fid $DIR/$rpath | tr -d '[]') ||
18307                         error "get fid for remote directory $DIR/$rpath failed"
18308                 check_path "$DIR/$rpath" $MOUNT $FID --link 0
18309         done
18310
18311         return 0
18312 }
18313 run_test 162c "fid2path works with paths 100 or more directories deep"
18314
18315 oalr_event_count() {
18316         local event="${1}"
18317         local trace="${2}"
18318
18319         awk -v name="${FSNAME}-OST0000" \
18320             -v event="${event}" \
18321             '$1 == "TRACE" && $2 == event && $3 == name' \
18322             "${trace}" |
18323         wc -l
18324 }
18325
18326 oalr_expect_event_count() {
18327         local event="${1}"
18328         local trace="${2}"
18329         local expect="${3}"
18330         local count
18331
18332         count=$(oalr_event_count "${event}" "${trace}")
18333         if ((count == expect)); then
18334                 return 0
18335         fi
18336
18337         error_noexit "${event} event count was '${count}', expected ${expect}"
18338         cat "${trace}" >&2
18339         exit 1
18340 }
18341
18342 cleanup_165() {
18343         do_facet ost1 killall --quiet -KILL ofd_access_log_reader || true
18344         stop ost1
18345         start ost1 "$(ostdevname 1)" $OST_MOUNT_OPTS
18346 }
18347
18348 setup_165() {
18349         sync # Flush previous IOs so we can count log entries.
18350         do_facet ost1 $LCTL set_param "obdfilter.${FSNAME}-OST0000.access_log_size=4096"
18351         stack_trap cleanup_165 EXIT
18352 }
18353
18354 test_165a() {
18355         local trace="/tmp/${tfile}.trace"
18356         local rc
18357         local count
18358
18359         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
18360                 skip "OFD access log unsupported"
18361
18362         setup_165
18363         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
18364         sleep 5
18365
18366         do_facet ost1 ofd_access_log_reader --list
18367         stop ost1
18368
18369         do_facet ost1 killall -TERM ofd_access_log_reader
18370         wait
18371         rc=$?
18372
18373         if ((rc != 0)); then
18374                 error "ofd_access_log_reader exited with rc = '${rc}'"
18375         fi
18376
18377         # Parse trace file for discovery events:
18378         oalr_expect_event_count alr_log_add "${trace}" 1
18379         oalr_expect_event_count alr_log_eof "${trace}" 1
18380         oalr_expect_event_count alr_log_free "${trace}" 1
18381 }
18382 run_test 165a "ofd access log discovery"
18383
18384 test_165b() {
18385         local trace="/tmp/${tfile}.trace"
18386         local file="${DIR}/${tfile}"
18387         local pfid1
18388         local pfid2
18389         local -a entry
18390         local rc
18391         local count
18392         local size
18393         local flags
18394
18395         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
18396                 skip "OFD access log unsupported"
18397
18398         setup_165
18399         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
18400         sleep 5
18401
18402         do_facet ost1 ofd_access_log_reader --list
18403
18404         lfs setstripe -c 1 -i 0 "${file}"
18405         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
18406                 error "cannot create '${file}'"
18407
18408         sleep 5
18409         do_facet ost1 killall -TERM ofd_access_log_reader
18410         wait
18411         rc=$?
18412
18413         if ((rc != 0)); then
18414                 error "ofd_access_log_reader exited with rc = '${rc}'"
18415         fi
18416
18417         oalr_expect_event_count alr_log_entry "${trace}" 1
18418
18419         pfid1=$($LFS path2fid "${file}")
18420
18421         # 1     2             3   4    5     6   7    8    9     10
18422         # TRACE alr_log_entry OST PFID BEGIN END TIME SIZE COUNT FLAGS
18423         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
18424
18425         echo "entry = '${entry[*]}'" >&2
18426
18427         pfid2=${entry[4]}
18428         if [[ "${pfid1}" != "${pfid2}" ]]; then
18429                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
18430         fi
18431
18432         size=${entry[8]}
18433         if ((size != 1048576)); then
18434                 error "entry '${entry[*]}' has invalid io size '${size}', expected 1048576"
18435         fi
18436
18437         flags=${entry[10]}
18438         if [[ "${flags}" != "w" ]]; then
18439                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'w'"
18440         fi
18441
18442         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
18443         sleep 5
18444
18445         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r524288c ||
18446                 error "cannot read '${file}'"
18447         sleep 5
18448
18449         do_facet ost1 killall -TERM ofd_access_log_reader
18450         wait
18451         rc=$?
18452
18453         if ((rc != 0)); then
18454                 error "ofd_access_log_reader exited with rc = '${rc}'"
18455         fi
18456
18457         oalr_expect_event_count alr_log_entry "${trace}" 1
18458
18459         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
18460         echo "entry = '${entry[*]}'" >&2
18461
18462         pfid2=${entry[4]}
18463         if [[ "${pfid1}" != "${pfid2}" ]]; then
18464                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
18465         fi
18466
18467         size=${entry[8]}
18468         if ((size != 524288)); then
18469                 error "entry '${entry[*]}' has invalid io size '${size}', 524288"
18470         fi
18471
18472         flags=${entry[10]}
18473         if [[ "${flags}" != "r" ]]; then
18474                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'r'"
18475         fi
18476 }
18477 run_test 165b "ofd access log entries are produced and consumed"
18478
18479 test_165c() {
18480         local trace="/tmp/${tfile}.trace"
18481         local file="${DIR}/${tdir}/${tfile}"
18482
18483         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
18484                 skip "OFD access log unsupported"
18485
18486         test_mkdir "${DIR}/${tdir}"
18487
18488         setup_165
18489         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
18490         sleep 5
18491
18492         lfs setstripe -c 1 -i 0 "${DIR}/${tdir}"
18493
18494         # 4096 / 64 = 64. Create twice as many entries.
18495         for ((i = 0; i < 128; i++)); do
18496                 $MULTIOP "${file}-${i}" oO_CREAT:O_WRONLY:w512c ||
18497                         error "cannot create file"
18498         done
18499
18500         sync
18501
18502         do_facet ost1 killall -TERM ofd_access_log_reader
18503         wait
18504         rc=$?
18505         if ((rc != 0)); then
18506                 error "ofd_access_log_reader exited with rc = '${rc}'"
18507         fi
18508
18509         unlinkmany  "${file}-%d" 128
18510 }
18511 run_test 165c "full ofd access logs do not block IOs"
18512
18513 oal_get_read_count() {
18514         local stats="$1"
18515
18516         # STATS lustre-OST0001 alr_read_count 1
18517
18518         do_facet ost1 cat "${stats}" |
18519         awk '$1 == "STATS" && $3 == "alr_read_count" { count = $4; }
18520              END { print count; }'
18521 }
18522
18523 oal_expect_read_count() {
18524         local stats="$1"
18525         local count
18526         local expect="$2"
18527
18528         # Ask ofd_access_log_reader to write stats.
18529         do_facet ost1 killall -USR1 ofd_access_log_reader
18530
18531         # Allow some time for things to happen.
18532         sleep 1
18533
18534         count=$(oal_get_read_count "${stats}")
18535         if ((count == expect)); then
18536                 return 0
18537         fi
18538
18539         error_noexit "bad read count, got ${count}, expected ${expect}"
18540         do_facet ost1 cat "${stats}" >&2
18541         exit 1
18542 }
18543
18544 test_165d() {
18545         local stats="/tmp/${tfile}.stats"
18546         local file="${DIR}/${tdir}/${tfile}"
18547         local param="obdfilter.${FSNAME}-OST0000.access_log_mask"
18548
18549         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
18550                 skip "OFD access log unsupported"
18551
18552         test_mkdir "${DIR}/${tdir}"
18553
18554         setup_165
18555         do_facet ost1 ofd_access_log_reader --stats="${stats}" &
18556         sleep 5
18557
18558         lfs setstripe -c 1 -i 0 "${file}"
18559
18560         do_facet ost1 lctl set_param "${param}=rw"
18561         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
18562                 error "cannot create '${file}'"
18563         oal_expect_read_count "${stats}" 1
18564
18565         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
18566                 error "cannot read '${file}'"
18567         oal_expect_read_count "${stats}" 2
18568
18569         do_facet ost1 lctl set_param "${param}=r"
18570         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
18571                 error "cannot create '${file}'"
18572         oal_expect_read_count "${stats}" 2
18573
18574         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
18575                 error "cannot read '${file}'"
18576         oal_expect_read_count "${stats}" 3
18577
18578         do_facet ost1 lctl set_param "${param}=w"
18579         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
18580                 error "cannot create '${file}'"
18581         oal_expect_read_count "${stats}" 4
18582
18583         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
18584                 error "cannot read '${file}'"
18585         oal_expect_read_count "${stats}" 4
18586
18587         do_facet ost1 lctl set_param "${param}=0"
18588         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
18589                 error "cannot create '${file}'"
18590         oal_expect_read_count "${stats}" 4
18591
18592         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
18593                 error "cannot read '${file}'"
18594         oal_expect_read_count "${stats}" 4
18595
18596         do_facet ost1 killall -TERM ofd_access_log_reader
18597         wait
18598         rc=$?
18599         if ((rc != 0)); then
18600                 error "ofd_access_log_reader exited with rc = '${rc}'"
18601         fi
18602 }
18603 run_test 165d "ofd_access_log mask works"
18604
18605 test_165e() {
18606         local stats="/tmp/${tfile}.stats"
18607         local file0="${DIR}/${tdir}-0/${tfile}"
18608         local file1="${DIR}/${tdir}-1/${tfile}"
18609
18610         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
18611                 skip "OFD access log unsupported"
18612
18613         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
18614
18615         test_mkdir -c 1 -i 0 "${DIR}/${tdir}-0"
18616         test_mkdir -c 1 -i 1 "${DIR}/${tdir}-1"
18617
18618         lfs setstripe -c 1 -i 0 "${file0}"
18619         lfs setstripe -c 1 -i 0 "${file1}"
18620
18621         setup_165
18622         do_facet ost1 ofd_access_log_reader -I 1 --stats="${stats}" &
18623         sleep 5
18624
18625         $MULTIOP "${file0}" oO_CREAT:O_WRONLY:w512c ||
18626                 error "cannot create '${file0}'"
18627         sync
18628         oal_expect_read_count "${stats}" 0
18629
18630         $MULTIOP "${file1}" oO_CREAT:O_WRONLY:w512c ||
18631                 error "cannot create '${file1}'"
18632         sync
18633         oal_expect_read_count "${stats}" 1
18634
18635         do_facet ost1 killall -TERM ofd_access_log_reader
18636         wait
18637         rc=$?
18638         if ((rc != 0)); then
18639                 error "ofd_access_log_reader exited with rc = '${rc}'"
18640         fi
18641 }
18642 run_test 165e "ofd_access_log MDT index filter works"
18643
18644 test_165f() {
18645         local trace="/tmp/${tfile}.trace"
18646         local rc
18647         local count
18648
18649         setup_165
18650         do_facet ost1 timeout 60 ofd_access_log_reader \
18651                 --exit-on-close --debug=- --trace=- > "${trace}" &
18652         sleep 5
18653         stop ost1
18654
18655         wait
18656         rc=$?
18657
18658         if ((rc != 0)); then
18659                 error_noexit "ofd_access_log_reader exited with rc = '${rc}'"
18660                 cat "${trace}"
18661                 exit 1
18662         fi
18663 }
18664 run_test 165f "ofd_access_log_reader --exit-on-close works"
18665
18666 test_169() {
18667         # do directio so as not to populate the page cache
18668         log "creating a 10 Mb file"
18669         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c ||
18670                 error "multiop failed while creating a file"
18671         log "starting reads"
18672         dd if=$DIR/$tfile of=/dev/null bs=4096 &
18673         log "truncating the file"
18674         $MULTIOP $DIR/$tfile oO_TRUNC:c ||
18675                 error "multiop failed while truncating the file"
18676         log "killing dd"
18677         kill %+ || true # reads might have finished
18678         echo "wait until dd is finished"
18679         wait
18680         log "removing the temporary file"
18681         rm -rf $DIR/$tfile || error "tmp file removal failed"
18682 }
18683 run_test 169 "parallel read and truncate should not deadlock"
18684
18685 test_170() {
18686         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18687
18688         $LCTL clear     # bug 18514
18689         $LCTL debug_daemon start $TMP/${tfile}_log_good
18690         touch $DIR/$tfile
18691         $LCTL debug_daemon stop
18692         sed -e "s/^...../a/g" $TMP/${tfile}_log_good > $TMP/${tfile}_log_bad ||
18693                 error "sed failed to read log_good"
18694
18695         $LCTL debug_daemon start $TMP/${tfile}_log_good
18696         rm -rf $DIR/$tfile
18697         $LCTL debug_daemon stop
18698
18699         $LCTL df $TMP/${tfile}_log_bad > $TMP/${tfile}_log_bad.out 2>&1 ||
18700                error "lctl df log_bad failed"
18701
18702         local bad_line=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
18703         local good_line1=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
18704
18705         $LCTL df $TMP/${tfile}_log_good > $TMP/${tfile}_log_good.out 2>&1
18706         local good_line2=$(tail -n 1 $TMP/${tfile}_log_good.out | awk '{print $5}')
18707
18708         [ "$bad_line" ] && [ "$good_line1" ] && [ "$good_line2" ] ||
18709                 error "bad_line good_line1 good_line2 are empty"
18710
18711         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
18712         cat $TMP/${tfile}_log_bad >> $TMP/${tfile}_logs_corrupt
18713         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
18714
18715         $LCTL df $TMP/${tfile}_logs_corrupt > $TMP/${tfile}_log_bad.out 2>&1
18716         local bad_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
18717         local good_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
18718
18719         [ "$bad_line_new" ] && [ "$good_line_new" ] ||
18720                 error "bad_line_new good_line_new are empty"
18721
18722         local expected_good=$((good_line1 + good_line2*2))
18723
18724         rm -f $TMP/${tfile}*
18725         # LU-231, short malformed line may not be counted into bad lines
18726         if [ $bad_line -ne $bad_line_new ] &&
18727                    [ $bad_line -ne $((bad_line_new - 1)) ]; then
18728                 error "expected $bad_line bad lines, but got $bad_line_new"
18729                 return 1
18730         fi
18731
18732         if [ $expected_good -ne $good_line_new ]; then
18733                 error "expected $expected_good good lines, but got $good_line_new"
18734                 return 2
18735         fi
18736         true
18737 }
18738 run_test 170 "test lctl df to handle corrupted log ====================="
18739
18740 test_171() { # bug20592
18741         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18742
18743         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
18744         $LCTL set_param fail_loc=0x50e
18745         $LCTL set_param fail_val=3000
18746         multiop_bg_pause $DIR/$tfile O_s || true
18747         local MULTIPID=$!
18748         kill -USR1 $MULTIPID
18749         # cause log dump
18750         sleep 3
18751         wait $MULTIPID
18752         if dmesg | grep "recursive fault"; then
18753                 error "caught a recursive fault"
18754         fi
18755         $LCTL set_param fail_loc=0
18756         true
18757 }
18758 run_test 171 "test libcfs_debug_dumplog_thread stuck in do_exit() ======"
18759
18760 test_172() {
18761
18762         #define OBD_FAIL_OBD_CLEANUP  0x60e
18763         $LCTL set_param fail_loc=0x60e
18764         umount $MOUNT || error "umount $MOUNT failed"
18765         stack_trap "mount_client $MOUNT"
18766
18767         (( $($LCTL dl | egrep -c " osc | lov | lmv | mdc ") > 0 )) ||
18768                 error "no client OBDs are remained"
18769
18770         $LCTL dl | while read devno state type name foo; do
18771                 case $type in
18772                 lov|osc|lmv|mdc)
18773                         $LCTL --device $name cleanup
18774                         $LCTL --device $name detach
18775                         ;;
18776                 *)
18777                         # skip server devices
18778                         ;;
18779                 esac
18780         done
18781
18782         if (( $($LCTL dl | egrep -c " osc | lov | lmv | mdc ") > 0 )); then
18783                 $LCTL dl | egrep " osc | lov | lmv | mdc "
18784                 error "some client OBDs are still remained"
18785         fi
18786
18787 }
18788 run_test 172 "manual device removal with lctl cleanup/detach ======"
18789
18790 # it would be good to share it with obdfilter-survey/iokit-libecho code
18791 setup_obdecho_osc () {
18792         local rc=0
18793         local ost_nid=$1
18794         local obdfilter_name=$2
18795         echo "Creating new osc for $obdfilter_name on $ost_nid"
18796         # make sure we can find loopback nid
18797         $LCTL add_uuid $ost_nid $ost_nid >/dev/null 2>&1
18798
18799         [ $rc -eq 0 ] && { $LCTL attach osc ${obdfilter_name}_osc     \
18800                            ${obdfilter_name}_osc_UUID || rc=2; }
18801         [ $rc -eq 0 ] && { $LCTL --device ${obdfilter_name}_osc setup \
18802                            ${obdfilter_name}_UUID  $ost_nid || rc=3; }
18803         return $rc
18804 }
18805
18806 cleanup_obdecho_osc () {
18807         local obdfilter_name=$1
18808         $LCTL --device ${obdfilter_name}_osc cleanup >/dev/null
18809         $LCTL --device ${obdfilter_name}_osc detach  >/dev/null
18810         return 0
18811 }
18812
18813 obdecho_test() {
18814         local OBD=$1
18815         local node=$2
18816         local pages=${3:-64}
18817         local rc=0
18818         local id
18819
18820         local count=10
18821         local obd_size=$(get_obd_size $node $OBD)
18822         local page_size=$(get_page_size $node)
18823         if [[ -n "$obd_size" ]]; then
18824                 local new_count=$((obd_size / (pages * page_size / 1024)))
18825                 [[ $new_count -ge $count ]] || count=$new_count
18826         fi
18827
18828         do_facet $node "$LCTL attach echo_client ec ec_uuid" || rc=1
18829         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec setup $OBD" ||
18830                            rc=2; }
18831         if [ $rc -eq 0 ]; then
18832             id=$(do_facet $node "$LCTL --device ec create 1"  | awk '/object id/ {print $6}')
18833             [ ${PIPESTATUS[0]} -eq 0 -a -n "$id" ] || rc=3
18834         fi
18835         echo "New object id is $id"
18836         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec getattr $id" ||
18837                            rc=4; }
18838         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec "                 \
18839                            "test_brw $count w v $pages $id" || rc=4; }
18840         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec destroy $id 1" ||
18841                            rc=4; }
18842         [ $rc -eq 0 ] || [ $rc -gt 2 ] &&
18843                 { do_facet $node "$LCTL --device ec cleanup" || rc=5; }
18844         [ $rc -eq 0 ] || [ $rc -gt 1 ] &&
18845                 { do_facet $node "$LCTL --device ec detach" || rc=6; }
18846         [ $rc -ne 0 ] && echo "obecho_create_test failed: $rc"
18847         return $rc
18848 }
18849
18850 test_180a() {
18851         skip "obdecho on osc is no longer supported"
18852 }
18853 run_test 180a "test obdecho on osc"
18854
18855 test_180b() {
18856         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18857         remote_ost_nodsh && skip "remote OST with nodsh"
18858
18859         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
18860                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
18861                 error "failed to load module obdecho"
18862
18863         local target=$(do_facet ost1 $LCTL dl |
18864                        awk '/obdfilter/ { print $4; exit; }')
18865
18866         if [ -n "$target" ]; then
18867                 obdecho_test $target ost1 || error "obdecho_test failed with $?"
18868         else
18869                 do_facet ost1 $LCTL dl
18870                 error "there is no obdfilter target on ost1"
18871         fi
18872 }
18873 run_test 180b "test obdecho directly on obdfilter"
18874
18875 test_180c() { # LU-2598
18876         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18877         remote_ost_nodsh && skip "remote OST with nodsh"
18878         [[ $MDS1_VERSION -lt $(version_code 2.4.0) ]] &&
18879                 skip "Need MDS version at least 2.4.0"
18880
18881         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
18882                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
18883                 error "failed to load module obdecho"
18884
18885         local target=$(do_facet ost1 $LCTL dl |
18886                        awk '/obdfilter/ { print $4; exit; }')
18887
18888         if [ -n "$target" ]; then
18889                 local pages=16384 # 64MB bulk I/O RPC size
18890
18891                 obdecho_test "$target" ost1 "$pages" ||
18892                         error "obdecho_test with pages=$pages failed with $?"
18893         else
18894                 do_facet ost1 $LCTL dl
18895                 error "there is no obdfilter target on ost1"
18896         fi
18897 }
18898 run_test 180c "test huge bulk I/O size on obdfilter, don't LASSERT"
18899
18900 test_181() { # bug 22177
18901         test_mkdir $DIR/$tdir
18902         # create enough files to index the directory
18903         createmany -o $DIR/$tdir/foobar 4000
18904         # print attributes for debug purpose
18905         lsattr -d .
18906         # open dir
18907         multiop_bg_pause $DIR/$tdir D_Sc || return 1
18908         MULTIPID=$!
18909         # remove the files & current working dir
18910         unlinkmany $DIR/$tdir/foobar 4000
18911         rmdir $DIR/$tdir
18912         kill -USR1 $MULTIPID
18913         wait $MULTIPID
18914         stat $DIR/$tdir && error "open-unlinked dir was not removed!"
18915         return 0
18916 }
18917 run_test 181 "Test open-unlinked dir ========================"
18918
18919 test_182a() {
18920         local fcount=1000
18921         local tcount=10
18922
18923         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
18924
18925         $LCTL set_param mdc.*.rpc_stats=clear
18926
18927         for (( i = 0; i < $tcount; i++ )) ; do
18928                 mkdir $DIR/$tdir/$i
18929         done
18930
18931         for (( i = 0; i < $tcount; i++ )) ; do
18932                 createmany -o $DIR/$tdir/$i/f- $fcount &
18933         done
18934         wait
18935
18936         for (( i = 0; i < $tcount; i++ )) ; do
18937                 unlinkmany $DIR/$tdir/$i/f- $fcount &
18938         done
18939         wait
18940
18941         $LCTL get_param mdc.*.rpc_stats
18942
18943         rm -rf $DIR/$tdir
18944 }
18945 run_test 182a "Test parallel modify metadata operations from mdc"
18946
18947 test_182b() {
18948         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
18949         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
18950         local dcount=1000
18951         local tcount=10
18952         local stime
18953         local etime
18954         local delta
18955
18956         do_facet mds1 $LCTL list_param \
18957                 osp.$FSNAME-MDT*-osp-MDT*.rpc_stats ||
18958                 skip "MDS lacks parallel RPC handling"
18959
18960         $LFS mkdir -i 0 $DIR/$tdir || error "creating dir $DIR/$tdir"
18961
18962         rpc_count=$(do_facet mds1 $LCTL get_param -n \
18963                     osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight)
18964
18965         stime=$(date +%s)
18966         createmany -i 0 -d $DIR/$tdir/t- $tcount
18967
18968         for (( i = 0; i < $tcount; i++ )) ; do
18969                 createmany -i 0 -d $DIR/$tdir/t-$i/d- 0 $dcount &
18970         done
18971         wait
18972         etime=$(date +%s)
18973         delta=$((etime - stime))
18974         echo "Time for file creation $delta sec for $rpc_count parallel RPCs"
18975
18976         stime=$(date +%s)
18977         for (( i = 0; i < $tcount; i++ )) ; do
18978                 unlinkmany -d $DIR/$tdir/$i/d- $dcount &
18979         done
18980         wait
18981         etime=$(date +%s)
18982         delta=$((etime - stime))
18983         echo "Time for file removal $delta sec for $rpc_count parallel RPCs"
18984
18985         rm -rf $DIR/$tdir
18986
18987         $LFS mkdir -i 0 $DIR/$tdir || error "creating dir $DIR/$tdir"
18988
18989         do_facet mds1 $LCTL set_param osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight=1
18990
18991         stime=$(date +%s)
18992         createmany -i 0 -d $DIR/$tdir/t- $tcount
18993
18994         for (( i = 0; i < $tcount; i++ )) ; do
18995                 createmany -i 0 -d $DIR/$tdir/t-$i/d- 0 $dcount &
18996         done
18997         wait
18998         etime=$(date +%s)
18999         delta=$((etime - stime))
19000         echo "Time for file creation $delta sec for 1 RPC sent at a time"
19001
19002         stime=$(date +%s)
19003         for (( i = 0; i < $tcount; i++ )) ; do
19004                 unlinkmany -d $DIR/$tdir/t-$i/d- $dcount &
19005         done
19006         wait
19007         etime=$(date +%s)
19008         delta=$((etime - stime))
19009         echo "Time for file removal $delta sec for 1 RPC sent at a time"
19010
19011         do_facet mds1 $LCTL set_param osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight=$rpc_count
19012 }
19013 run_test 182b "Test parallel modify metadata operations from osp"
19014
19015 test_183() { # LU-2275
19016         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19017         remote_mds_nodsh && skip "remote MDS with nodsh"
19018         [[ $MDS1_VERSION -lt $(version_code 2.3.56) ]] &&
19019                 skip "Need MDS version at least 2.3.56"
19020
19021         mkdir_on_mdt0 $DIR/$tdir || error "creating dir $DIR/$tdir"
19022         echo aaa > $DIR/$tdir/$tfile
19023
19024 #define OBD_FAIL_MDS_NEGATIVE_POSITIVE  0x148
19025         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x148
19026
19027         ls -l $DIR/$tdir && error "ls succeeded, should have failed"
19028         cat $DIR/$tdir/$tfile && error "cat succeeded, should have failed"
19029
19030         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
19031
19032         # Flush negative dentry cache
19033         touch $DIR/$tdir/$tfile
19034
19035         # We are not checking for any leaked references here, they'll
19036         # become evident next time we do cleanup with module unload.
19037         rm -rf $DIR/$tdir
19038 }
19039 run_test 183 "No crash or request leak in case of strange dispositions ========"
19040
19041 # test suite 184 is for LU-2016, LU-2017
19042 test_184a() {
19043         check_swap_layouts_support
19044
19045         dir0=$DIR/$tdir/$testnum
19046         test_mkdir -p -c1 $dir0
19047         ref1=/etc/passwd
19048         ref2=/etc/group
19049         file1=$dir0/f1
19050         file2=$dir0/f2
19051         $LFS setstripe -c1 $file1
19052         cp $ref1 $file1
19053         $LFS setstripe -c2 $file2
19054         cp $ref2 $file2
19055         gen1=$($LFS getstripe -g $file1)
19056         gen2=$($LFS getstripe -g $file2)
19057
19058         $LFS swap_layouts $file1 $file2 || error "swap of file layout failed"
19059         gen=$($LFS getstripe -g $file1)
19060         [[ $gen1 != $gen ]] ||
19061                 error "Layout generation on $file1 does not change"
19062         gen=$($LFS getstripe -g $file2)
19063         [[ $gen2 != $gen ]] ||
19064                 error "Layout generation on $file2 does not change"
19065
19066         cmp $ref1 $file2 || error "content compare failed ($ref1 != $file2)"
19067         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
19068
19069         lfsck_verify_pfid $file1 $file2 || error "PFID are not transferred"
19070 }
19071 run_test 184a "Basic layout swap"
19072
19073 test_184b() {
19074         check_swap_layouts_support
19075
19076         dir0=$DIR/$tdir/$testnum
19077         mkdir -p $dir0 || error "creating dir $dir0"
19078         file1=$dir0/f1
19079         file2=$dir0/f2
19080         file3=$dir0/f3
19081         dir1=$dir0/d1
19082         dir2=$dir0/d2
19083         mkdir $dir1 $dir2
19084         $LFS setstripe -c1 $file1
19085         $LFS setstripe -c2 $file2
19086         $LFS setstripe -c1 $file3
19087         chown $RUNAS_ID $file3
19088         gen1=$($LFS getstripe -g $file1)
19089         gen2=$($LFS getstripe -g $file2)
19090
19091         $LFS swap_layouts $dir1 $dir2 &&
19092                 error "swap of directories layouts should fail"
19093         $LFS swap_layouts $dir1 $file1 &&
19094                 error "swap of directory and file layouts should fail"
19095         $RUNAS $LFS swap_layouts $file1 $file2 &&
19096                 error "swap of file we cannot write should fail"
19097         $LFS swap_layouts $file1 $file3 &&
19098                 error "swap of file with different owner should fail"
19099         /bin/true # to clear error code
19100 }
19101 run_test 184b "Forbidden layout swap (will generate errors)"
19102
19103 test_184c() {
19104         local cmpn_arg=$(cmp -n 2>&1 | grep "invalid option")
19105         [ -n "$cmpn_arg" ] && skip_env "cmp does not support -n"
19106         check_swap_layouts_support
19107         check_swap_layout_no_dom $DIR
19108
19109         local dir0=$DIR/$tdir/$testnum
19110         mkdir -p $dir0 || error "creating dir $dir0"
19111
19112         local ref1=$dir0/ref1
19113         local ref2=$dir0/ref2
19114         local file1=$dir0/file1
19115         local file2=$dir0/file2
19116         # create a file large enough for the concurrent test
19117         dd if=/dev/urandom of=$ref1 bs=1M count=$((RANDOM % 50 + 20))
19118         dd if=/dev/urandom of=$ref2 bs=1M count=$((RANDOM % 50 + 20))
19119         echo "ref file size: ref1($(stat -c %s $ref1))," \
19120              "ref2($(stat -c %s $ref2))"
19121
19122         cp $ref2 $file2
19123         dd if=$ref1 of=$file1 bs=16k &
19124         local DD_PID=$!
19125
19126         # Make sure dd starts to copy file, but wait at most 5 seconds
19127         local loops=0
19128         while [ ! -s $file1 -a $((loops++)) -lt 50 ]; do sleep 0.1; done
19129
19130         $LFS swap_layouts $file1 $file2
19131         local rc=$?
19132         wait $DD_PID
19133         [[ $? == 0 ]] || error "concurrent write on $file1 failed"
19134         [[ $rc == 0 ]] || error "swap of $file1 and $file2 failed"
19135
19136         # how many bytes copied before swapping layout
19137         local copied=$(stat -c %s $file2)
19138         local remaining=$(stat -c %s $ref1)
19139         remaining=$((remaining - copied))
19140         echo "Copied $copied bytes before swapping layout..."
19141
19142         cmp -n $copied $file1 $ref2 | grep differ &&
19143                 error "Content mismatch [0, $copied) of ref2 and file1"
19144         cmp -n $copied $file2 $ref1 ||
19145                 error "Content mismatch [0, $copied) of ref1 and file2"
19146         cmp -i $copied:$copied -n $remaining $file1 $ref1 ||
19147                 error "Content mismatch [$copied, EOF) of ref1 and file1"
19148
19149         # clean up
19150         rm -f $ref1 $ref2 $file1 $file2
19151 }
19152 run_test 184c "Concurrent write and layout swap"
19153
19154 test_184d() {
19155         check_swap_layouts_support
19156         check_swap_layout_no_dom $DIR
19157         [ -z "$(which getfattr 2>/dev/null)" ] &&
19158                 skip_env "no getfattr command"
19159
19160         local file1=$DIR/$tdir/$tfile-1
19161         local file2=$DIR/$tdir/$tfile-2
19162         local file3=$DIR/$tdir/$tfile-3
19163         local lovea1
19164         local lovea2
19165
19166         mkdir -p $DIR/$tdir
19167         touch $file1 || error "create $file1 failed"
19168         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
19169                 error "create $file2 failed"
19170         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
19171                 error "create $file3 failed"
19172         lovea1=$(get_layout_param $file1)
19173
19174         $LFS swap_layouts $file2 $file3 ||
19175                 error "swap $file2 $file3 layouts failed"
19176         $LFS swap_layouts $file1 $file2 ||
19177                 error "swap $file1 $file2 layouts failed"
19178
19179         lovea2=$(get_layout_param $file2)
19180         echo "$lovea1"
19181         echo "$lovea2"
19182         [ "$lovea1" == "$lovea2" ] || error "lovea $lovea1 != $lovea2"
19183
19184         lovea1=$(getfattr -n trusted.lov $file1 | grep ^trusted)
19185         [[ -z "$lovea1" ]] || error "$file1 shouldn't have lovea"
19186 }
19187 run_test 184d "allow stripeless layouts swap"
19188
19189 test_184e() {
19190         [[ $MDS1_VERSION -ge $(version_code 2.6.94) ]] ||
19191                 skip "Need MDS version at least 2.6.94"
19192         check_swap_layouts_support
19193         check_swap_layout_no_dom $DIR
19194         [ -z "$(which getfattr 2>/dev/null)" ] &&
19195                 skip_env "no getfattr command"
19196
19197         local file1=$DIR/$tdir/$tfile-1
19198         local file2=$DIR/$tdir/$tfile-2
19199         local file3=$DIR/$tdir/$tfile-3
19200         local lovea
19201
19202         mkdir -p $DIR/$tdir
19203         touch $file1 || error "create $file1 failed"
19204         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
19205                 error "create $file2 failed"
19206         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
19207                 error "create $file3 failed"
19208
19209         $LFS swap_layouts $file1 $file2 ||
19210                 error "swap $file1 $file2 layouts failed"
19211
19212         lovea=$(getfattr -n trusted.lov $file1 | grep ^trusted)
19213         [[ -z "$lovea" ]] || error "$file1 shouldn't have lovea"
19214
19215         echo 123 > $file1 || error "Should be able to write into $file1"
19216
19217         $LFS swap_layouts $file1 $file3 ||
19218                 error "swap $file1 $file3 layouts failed"
19219
19220         echo 123 > $file1 || error "Should be able to write into $file1"
19221
19222         rm -rf $file1 $file2 $file3
19223 }
19224 run_test 184e "Recreate layout after stripeless layout swaps"
19225
19226 test_184f() {
19227         # Create a file with name longer than sizeof(struct stat) ==
19228         # 144 to see if we can get chars from the file name to appear
19229         # in the returned striping. Note that 'f' == 0x66.
19230         local file=$(for ((i = 0; i < 200; i++)); do echo -n f; done)
19231
19232         mkdir -p $DIR/$tdir
19233         mcreate $DIR/$tdir/$file
19234         if lfs find --stripe-count 0x6666 $DIR/$tdir | grep $file; then
19235                 error "IOC_MDC_GETFILEINFO returned garbage striping"
19236         fi
19237 }
19238 run_test 184f "IOC_MDC_GETFILEINFO for files with long names but no striping"
19239
19240 test_185() { # LU-2441
19241         # LU-3553 - no volatile file support in old servers
19242         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
19243                 skip "Need MDS version at least 2.3.60"
19244
19245         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
19246         touch $DIR/$tdir/spoo
19247         local mtime1=$(stat -c "%Y" $DIR/$tdir)
19248         local fid=$($MULTIOP $DIR/$tdir VFw4096c) ||
19249                 error "cannot create/write a volatile file"
19250         [ "$FILESET" == "" ] &&
19251         $CHECKSTAT -t file $MOUNT/.lustre/fid/$fid 2>/dev/null &&
19252                 error "FID is still valid after close"
19253
19254         multiop_bg_pause $DIR/$tdir vVw4096_c
19255         local multi_pid=$!
19256
19257         local OLD_IFS=$IFS
19258         IFS=":"
19259         local fidv=($fid)
19260         IFS=$OLD_IFS
19261         # assume that the next FID for this client is sequential, since stdout
19262         # is unfortunately eaten by multiop_bg_pause
19263         local n=$((${fidv[1]} + 1))
19264         local next_fid="${fidv[0]}:$(printf "0x%x" $n):${fidv[2]}"
19265         if [ "$FILESET" == "" ]; then
19266                 $CHECKSTAT -t file $MOUNT/.lustre/fid/$next_fid ||
19267                         error "FID is missing before close"
19268         fi
19269         kill -USR1 $multi_pid
19270         # 1 second delay, so if mtime change we will see it
19271         sleep 1
19272         local mtime2=$(stat -c "%Y" $DIR/$tdir)
19273         [[ $mtime1 == $mtime2 ]] || error "mtime has changed"
19274 }
19275 run_test 185 "Volatile file support"
19276
19277 function create_check_volatile() {
19278         local idx=$1
19279         local tgt
19280
19281         $MULTIOP $MOUNT/.lustre/fid V${idx}Fw4096_c >&/tmp/${tfile}.fid &
19282         local PID=$!
19283         sleep 1
19284         local FID=$(cat /tmp/${tfile}.fid)
19285         [ "$FID" == "" ] && error "can't get FID for volatile"
19286         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID || error "can't stat $FID"
19287         tgt=$($LFS getstripe -m $MOUNT/.lustre/fid/$FID)
19288         [ "$tgt" != "$idx" ] && error "wrong MDS $tgt, expected $idx"
19289         kill -USR1 $PID
19290         wait
19291         sleep 1
19292         cancel_lru_locks mdc # flush opencache
19293         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID && error "can stat $FID"
19294         return 0
19295 }
19296
19297 test_185a(){
19298         # LU-12516 - volatile creation via .lustre
19299         [[ $MDS1_VERSION -ge $(version_code 2.12.55) ]] ||
19300                 skip "Need MDS version at least 2.3.55"
19301
19302         create_check_volatile 0
19303         [ $MDSCOUNT -lt 2 ] && return 0
19304
19305         # DNE case
19306         create_check_volatile 1
19307
19308         return 0
19309 }
19310 run_test 185a "Volatile file creation in .lustre/fid/"
19311
19312 test_187a() {
19313         remote_mds_nodsh && skip "remote MDS with nodsh"
19314         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
19315                 skip "Need MDS version at least 2.3.0"
19316
19317         local dir0=$DIR/$tdir/$testnum
19318         mkdir -p $dir0 || error "creating dir $dir0"
19319
19320         local file=$dir0/file1
19321         dd if=/dev/urandom of=$file count=10 bs=1M conv=fsync
19322         stack_trap "rm -f $file"
19323         local dv1=$($LFS data_version $file)
19324         dd if=/dev/urandom of=$file seek=10 count=1 bs=1M conv=fsync
19325         local dv2=$($LFS data_version $file)
19326         [[ $dv1 != $dv2 ]] ||
19327                 error "data version did not change on write $dv1 == $dv2"
19328 }
19329 run_test 187a "Test data version change"
19330
19331 test_187b() {
19332         remote_mds_nodsh && skip "remote MDS with nodsh"
19333         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
19334                 skip "Need MDS version at least 2.3.0"
19335
19336         local dir0=$DIR/$tdir/$testnum
19337         mkdir -p $dir0 || error "creating dir $dir0"
19338
19339         declare -a DV=$($MULTIOP $dir0 Vw1000xYw1000xY | cut -f3 -d" ")
19340         [[ ${DV[0]} != ${DV[1]} ]] ||
19341                 error "data version did not change on write"\
19342                       " ${DV[0]} == ${DV[1]}"
19343
19344         # clean up
19345         rm -f $file1
19346 }
19347 run_test 187b "Test data version change on volatile file"
19348
19349 test_200() {
19350         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19351         remote_mgs_nodsh && skip "remote MGS with nodsh"
19352         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
19353
19354         local POOL=${POOL:-cea1}
19355         local POOL_ROOT=${POOL_ROOT:-$DIR/d200.pools}
19356         local POOL_DIR_NAME=${POOL_DIR_NAME:-dir_tst}
19357         # Pool OST targets
19358         local first_ost=0
19359         local last_ost=$(($OSTCOUNT - 1))
19360         local ost_step=2
19361         local ost_list=$(seq $first_ost $ost_step $last_ost)
19362         local ost_range="$first_ost $last_ost $ost_step"
19363         local test_path=$POOL_ROOT/$POOL_DIR_NAME
19364         local file_dir=$POOL_ROOT/file_tst
19365         local subdir=$test_path/subdir
19366         local rc=0
19367
19368         while : ; do
19369                 # former test_200a test_200b
19370                 pool_add $POOL                          || { rc=$? ; break; }
19371                 pool_add_targets  $POOL $ost_range      || { rc=$? ; break; }
19372                 # former test_200c test_200d
19373                 mkdir -p $test_path
19374                 pool_set_dir      $POOL $test_path      || { rc=$? ; break; }
19375                 pool_check_dir    $POOL $test_path      || { rc=$? ; break; }
19376                 mkdir -p $subdir
19377                 pool_check_dir    $POOL $subdir         || { rc=$? ; break; }
19378                 pool_dir_rel_path $POOL $POOL_DIR_NAME $POOL_ROOT \
19379                                                         || { rc=$? ; break; }
19380                 # former test_200e test_200f
19381                 local files=$((OSTCOUNT*3))
19382                 pool_alloc_files  $POOL $test_path $files "$ost_list" \
19383                                                         || { rc=$? ; break; }
19384                 pool_create_files $POOL $file_dir $files "$ost_list" \
19385                                                         || { rc=$? ; break; }
19386                 # former test_200g test_200h
19387                 pool_lfs_df $POOL                       || { rc=$? ; break; }
19388                 pool_file_rel_path $POOL $test_path     || { rc=$? ; break; }
19389
19390                 # former test_201a test_201b test_201c
19391                 pool_remove_first_target $POOL          || { rc=$? ; break; }
19392
19393                 local f=$test_path/$tfile
19394                 pool_remove_all_targets $POOL $f        || { rc=$? ; break; }
19395                 pool_remove $POOL $f                    || { rc=$? ; break; }
19396                 break
19397         done
19398
19399         destroy_test_pools
19400
19401         return $rc
19402 }
19403 run_test 200 "OST pools"
19404
19405 # usage: default_attr <count | size | offset>
19406 default_attr() {
19407         $LCTL get_param -n lov.$FSNAME-clilov-\*.stripe${1}
19408 }
19409
19410 # usage: check_default_stripe_attr
19411 check_default_stripe_attr() {
19412         ACTUAL=$($LFS getstripe $* $DIR/$tdir)
19413         case $1 in
19414         --stripe-count|-c)
19415                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr count);;
19416         --stripe-size|-S)
19417                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr size);;
19418         --stripe-index|-i)
19419                 EXPECTED=-1;;
19420         *)
19421                 error "unknown getstripe attr '$1'"
19422         esac
19423
19424         [ $ACTUAL == $EXPECTED ] ||
19425                 error "$DIR/$tdir has $1 '$ACTUAL', not '$EXPECTED'"
19426 }
19427
19428 test_204a() {
19429         test_mkdir $DIR/$tdir
19430         $LFS setstripe --stripe-count 0 --stripe-size 0 --stripe-index -1 $DIR/$tdir
19431
19432         check_default_stripe_attr --stripe-count
19433         check_default_stripe_attr --stripe-size
19434         check_default_stripe_attr --stripe-index
19435 }
19436 run_test 204a "Print default stripe attributes"
19437
19438 test_204b() {
19439         test_mkdir $DIR/$tdir
19440         $LFS setstripe --stripe-count 1 $DIR/$tdir
19441
19442         check_default_stripe_attr --stripe-size
19443         check_default_stripe_attr --stripe-index
19444 }
19445 run_test 204b "Print default stripe size and offset"
19446
19447 test_204c() {
19448         test_mkdir $DIR/$tdir
19449         $LFS setstripe --stripe-size 65536 $DIR/$tdir
19450
19451         check_default_stripe_attr --stripe-count
19452         check_default_stripe_attr --stripe-index
19453 }
19454 run_test 204c "Print default stripe count and offset"
19455
19456 test_204d() {
19457         test_mkdir $DIR/$tdir
19458         $LFS setstripe --stripe-index 0 $DIR/$tdir
19459
19460         check_default_stripe_attr --stripe-count
19461         check_default_stripe_attr --stripe-size
19462 }
19463 run_test 204d "Print default stripe count and size"
19464
19465 test_204e() {
19466         test_mkdir $DIR/$tdir
19467         $LFS setstripe -d $DIR/$tdir
19468
19469         check_default_stripe_attr --stripe-count --raw
19470         check_default_stripe_attr --stripe-size --raw
19471         check_default_stripe_attr --stripe-index --raw
19472 }
19473 run_test 204e "Print raw stripe attributes"
19474
19475 test_204f() {
19476         test_mkdir $DIR/$tdir
19477         $LFS setstripe --stripe-count 1 $DIR/$tdir
19478
19479         check_default_stripe_attr --stripe-size --raw
19480         check_default_stripe_attr --stripe-index --raw
19481 }
19482 run_test 204f "Print raw stripe size and offset"
19483
19484 test_204g() {
19485         test_mkdir $DIR/$tdir
19486         $LFS setstripe --stripe-size 65536 $DIR/$tdir
19487
19488         check_default_stripe_attr --stripe-count --raw
19489         check_default_stripe_attr --stripe-index --raw
19490 }
19491 run_test 204g "Print raw stripe count and offset"
19492
19493 test_204h() {
19494         test_mkdir $DIR/$tdir
19495         $LFS setstripe --stripe-index 0 $DIR/$tdir
19496
19497         check_default_stripe_attr --stripe-count --raw
19498         check_default_stripe_attr --stripe-size --raw
19499 }
19500 run_test 204h "Print raw stripe count and size"
19501
19502 # Figure out which job scheduler is being used, if any,
19503 # or use a fake one
19504 if [ -n "$SLURM_JOB_ID" ]; then # SLURM
19505         JOBENV=SLURM_JOB_ID
19506 elif [ -n "$LSB_JOBID" ]; then # Load Sharing Facility
19507         JOBENV=LSB_JOBID
19508 elif [ -n "$PBS_JOBID" ]; then # PBS/Maui/Moab
19509         JOBENV=PBS_JOBID
19510 elif [ -n "$LOADL_STEPID" ]; then # LoadLeveller
19511         JOBENV=LOADL_STEP_ID
19512 elif [ -n "$JOB_ID" ]; then # Sun Grid Engine
19513         JOBENV=JOB_ID
19514 else
19515         $LCTL list_param jobid_name > /dev/null 2>&1
19516         if [ $? -eq 0 ]; then
19517                 JOBENV=nodelocal
19518         else
19519                 JOBENV=FAKE_JOBID
19520         fi
19521 fi
19522 LUSTRE_JOBID_SIZE=31 # plus NUL terminator
19523
19524 verify_jobstats() {
19525         local cmd=($1)
19526         shift
19527         local facets="$@"
19528
19529 # we don't really need to clear the stats for this test to work, since each
19530 # command has a unique jobid, but it makes debugging easier if needed.
19531 #       for facet in $facets; do
19532 #               local dev=$(convert_facet2label $facet)
19533 #               # clear old jobstats
19534 #               do_facet $facet lctl set_param *.$dev.job_stats="clear"
19535 #       done
19536
19537         # use a new JobID for each test, or we might see an old one
19538         [ "$JOBENV" = "FAKE_JOBID" ] &&
19539                 FAKE_JOBID=id.$testnum.$(basename ${cmd[0]}).$RANDOM
19540
19541         JOBVAL=${!JOBENV:0:$LUSTRE_JOBID_SIZE}
19542
19543         [ "$JOBENV" = "nodelocal" ] && {
19544                 FAKE_JOBID=id.$testnum.%e.$RANDOM
19545                 $LCTL set_param jobid_name=$FAKE_JOBID
19546                 JOBVAL=${FAKE_JOBID/\%e/$(basename ${cmd[0]})}
19547         }
19548
19549         log "Test: ${cmd[*]}"
19550         log "Using JobID environment $($LCTL get_param -n jobid_var)=$JOBVAL"
19551
19552         if [ $JOBENV = "FAKE_JOBID" ]; then
19553                 FAKE_JOBID=$JOBVAL ${cmd[*]}
19554         else
19555                 ${cmd[*]}
19556         fi
19557
19558         # all files are created on OST0000
19559         for facet in $facets; do
19560                 local stats="*.$(convert_facet2label $facet).job_stats"
19561
19562                 # strip out libtool wrappers for in-tree executables
19563                 if (( $(do_facet $facet lctl get_param $stats |
19564                         sed -e 's/\.lt-/./' | grep -cw $JOBVAL) != 1 )); then
19565                         do_facet $facet lctl get_param $stats
19566                         error "No jobstats for $JOBVAL found on $facet::$stats"
19567                 fi
19568         done
19569 }
19570
19571 jobstats_set() {
19572         local new_jobenv=$1
19573
19574         set_persistent_param_and_check client "jobid_var" \
19575                 "$FSNAME.sys.jobid_var" $new_jobenv
19576 }
19577
19578 test_205a() { # Job stats
19579         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19580         [[ $MDS1_VERSION -ge $(version_code 2.7.1) ]] ||
19581                 skip "Need MDS version with at least 2.7.1"
19582         remote_mgs_nodsh && skip "remote MGS with nodsh"
19583         remote_mds_nodsh && skip "remote MDS with nodsh"
19584         remote_ost_nodsh && skip "remote OST with nodsh"
19585         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep jobstats)" ] &&
19586                 skip "Server doesn't support jobstats"
19587         [[ $JOBID_VAR = disable ]] && skip_env "jobstats is disabled"
19588
19589         local old_jobenv=$($LCTL get_param -n jobid_var)
19590         [ $old_jobenv != $JOBENV ] && jobstats_set $JOBENV
19591         stack_trap "jobstats_set $old_jobenv" EXIT
19592
19593         changelog_register
19594
19595         local old_jobid_name=$($LCTL get_param jobid_name)
19596         stack_trap "$LCTL set_param $old_jobid_name" EXIT
19597
19598         local old_interval=$(do_facet $SINGLEMDS lctl get_param -n \
19599                                 mdt.*.job_cleanup_interval | head -n 1)
19600         local new_interval=5
19601         do_facet $SINGLEMDS \
19602                 $LCTL set_param mdt.*.job_cleanup_interval=$new_interval
19603         stack_trap "do_facet $SINGLEMDS \
19604                 $LCTL set_param mdt.*.job_cleanup_interval=$old_interval" EXIT
19605         local start=$SECONDS
19606
19607         local cmd
19608         # mkdir
19609         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir"
19610         verify_jobstats "$cmd" "$SINGLEMDS"
19611         # rmdir
19612         cmd="rmdir $DIR/$tdir"
19613         verify_jobstats "$cmd" "$SINGLEMDS"
19614         # mkdir on secondary MDT
19615         if [ $MDSCOUNT -gt 1 ]; then
19616                 cmd="lfs mkdir -i 1 $DIR/$tdir.remote"
19617                 verify_jobstats "$cmd" "mds2"
19618         fi
19619         # mknod
19620         cmd="mknod $DIR/$tfile c 1 3"
19621         verify_jobstats "$cmd" "$SINGLEMDS"
19622         # unlink
19623         cmd="rm -f $DIR/$tfile"
19624         verify_jobstats "$cmd" "$SINGLEMDS"
19625         # create all files on OST0000 so verify_jobstats can find OST stats
19626         # open & close
19627         cmd="$LFS setstripe -i 0 -c 1 $DIR/$tfile"
19628         verify_jobstats "$cmd" "$SINGLEMDS"
19629         # setattr
19630         cmd="touch $DIR/$tfile"
19631         verify_jobstats "$cmd" "$SINGLEMDS ost1"
19632         # write
19633         cmd="dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=sync"
19634         verify_jobstats "$cmd" "ost1"
19635         # read
19636         cancel_lru_locks osc
19637         cmd="dd if=$DIR/$tfile of=/dev/null bs=1M count=1 iflag=direct"
19638         verify_jobstats "$cmd" "ost1"
19639         # truncate
19640         cmd="$TRUNCATE $DIR/$tfile 0"
19641         verify_jobstats "$cmd" "$SINGLEMDS ost1"
19642         # rename
19643         cmd="mv -f $DIR/$tfile $DIR/$tdir.rename"
19644         verify_jobstats "$cmd" "$SINGLEMDS"
19645         # jobstats expiry - sleep until old stats should be expired
19646         local left=$((new_interval + 5 - (SECONDS - start)))
19647         [ $left -ge 0 ] && wait_update_facet $SINGLEMDS \
19648                 "lctl get_param *.*.job_stats | grep -c 'job_id.*mkdir'" \
19649                         "0" $left
19650         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir.expire"
19651         verify_jobstats "$cmd" "$SINGLEMDS"
19652         [ $(do_facet $SINGLEMDS lctl get_param *.*.job_stats |
19653             grep -c "job_id.*mkdir") -gt 1 ] && error "old jobstats not expired"
19654
19655         # Ensure that jobid are present in changelog (if supported by MDS)
19656         if [ $MDS1_VERSION -ge $(version_code 2.6.52) ];then
19657                 changelog_dump | tail -10
19658                 jobids=$(changelog_dump | tail -9 | grep -c "j=")
19659                 [ $jobids -eq 9 ] ||
19660                         error "Wrong changelog jobid count $jobids != 9"
19661
19662                 # LU-5862
19663                 JOBENV="disable"
19664                 jobstats_set $JOBENV
19665                 touch $DIR/$tfile
19666                 changelog_dump | grep $tfile
19667                 jobids=$(changelog_dump | grep $tfile | tail -1 | grep -c "j=")
19668                 [ $jobids -eq 0 ] ||
19669                         error "Unexpected jobids when jobid_var=$JOBENV"
19670         fi
19671
19672         # test '%j' access to environment variable - if supported
19673         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%h.E"; then
19674                 JOBENV="JOBCOMPLEX"
19675                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
19676
19677                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
19678         fi
19679
19680         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%H.E"; then
19681                 JOBENV="JOBCOMPLEX"
19682                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname -s).E"
19683
19684                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
19685         fi
19686
19687         # test '%j' access to per-session jobid - if supported
19688         if lctl list_param jobid_this_session > /dev/null 2>&1
19689         then
19690                 lctl set_param jobid_var=session jobid_name="S.%j.%e.%u.%h.E"
19691                 lctl set_param jobid_this_session=$USER
19692
19693                 JOBENV="JOBCOMPLEX"
19694                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
19695
19696                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
19697         fi
19698 }
19699 run_test 205a "Verify job stats"
19700
19701 # LU-13117, LU-13597, LU-16599
19702 test_205b() {
19703         (( $MDS1_VERSION >= $(version_code 2.13.54.91) )) ||
19704                 skip "Need MDS version at least 2.13.54.91"
19705
19706         local job_stats="mdt.*.job_stats"
19707         local old_jobid=$(do_facet mds1 $LCTL get_param jobid_var)
19708
19709         do_facet mds1 $LCTL set_param $job_stats=clear
19710
19711         # Setting jobid_var to USER might not be supported
19712         [[ -n "$old_jobid" ]] && stack_trap "$LCTL set_param $old_jobid"
19713         $LCTL set_param jobid_var=USER || true
19714         stack_trap "$LCTL set_param $($LCTL get_param jobid_name)"
19715         $LCTL set_param jobid_name="%j.%e.%u"
19716
19717         env -i USERTESTJOBSTATS=foolish touch $DIR/$tfile.1
19718         do_facet mds1 $LCTL get_param $job_stats | grep "job_id:.*foolish" &&
19719                 { do_facet mds1 $LCTL get_param $job_stats;
19720                   error "Unexpected jobid found"; }
19721         do_facet mds1 $LCTL get_param $job_stats | grep "open:.*min.*max.*sum"||
19722                 { do_facet mds1 $LCTL get_param $job_stats;
19723                   error "wrong job_stats format found"; }
19724
19725         (( $MDS1_VERSION <= $(version_code 2.15.0) )) &&
19726                 echo "MDS does not yet escape jobid" && return 0
19727
19728         mkdir_on_mdt0 $DIR/$tdir
19729         $LCTL set_param jobid_var=TEST205b
19730         env -i TEST205b="has sp" touch $DIR/$tdir/$tfile.2
19731         local jobid=$(do_facet mds1 $LCTL get_param $job_stats |
19732                       awk '/has\\x20sp/ {print $3}')
19733         [[ -n "$jobid" ]] || { do_facet mds1 $LCTL get_param $job_stats;
19734                   error "jobid not escaped"; }
19735
19736         if (( $MDS1_VERSION >= $(version_code 2.15.53.139) )); then
19737                 # need to run such a command on mds1:
19738                 # lctl set_param mdt.$FSNAME-MDT0000.job_stats='"has\x20sp.touch.0"'
19739                 #
19740                 # there might be multiple MDTs on single mds server, so need to
19741                 # specifiy MDT0000. Or the command will fail due to other MDTs
19742                 do_facet_vp mds1 $LCTL set_param mdt.$FSNAME-MDT0000.job_stats=$jobid ||
19743                         error "cannot clear escaped jobid in job_stats";
19744         else
19745                 echo "MDS does not support clearing escaped jobid"
19746         fi
19747 }
19748 run_test 205b "Verify job stats jobid and output format"
19749
19750 # LU-13733
19751 test_205c() {
19752         $LCTL set_param llite.*.stats=0
19753         dd if=/dev/zero of=$DIR/$tfile.1 bs=4k count=1
19754         $LCTL get_param llite.*.stats
19755         $LCTL get_param llite.*.stats | grep \
19756                 "write_bytes *1 samples \[bytes\] 4096 4096 4096 16777216" ||
19757                         error "wrong client stats format found"
19758 }
19759 run_test 205c "Verify client stats format"
19760
19761 test_205d() {
19762         local file=$DIR/$tdir/$tfile
19763
19764         (( $MDS1_VERSION >= $(version_code 2.15.53) )) ||
19765                 skip "need lustre >= 2.15.53 for lljobstat"
19766         (( $OST1_VERSION >= $(version_code 2.15.53) )) ||
19767                 skip "need lustre >= 2.15.53 for lljobstat"
19768         verify_yaml_available || skip_env "YAML verification not installed"
19769
19770         test_mkdir -i 0 $DIR/$tdir
19771         $LFS setstripe -E 1M -L mdt -E -1 $file || error "create file failed"
19772         stack_trap "rm -rf $DIR/$tdir"
19773
19774         dd if=/dev/zero of=$file bs=1M count=10 conv=sync ||
19775                 error "failed to write data to $file"
19776         mv $file $file.2
19777
19778         do_facet mds1 "$LCTL get_param -n mdt.$FSNAME-MDT0000.rename_stats"
19779         echo -n 'verify rename_stats...'
19780         do_facet mds1 "$LCTL get_param -n mdt.$FSNAME-MDT0000.rename_stats" |
19781                 verify_yaml || error "rename_stats is not valid YAML"
19782         echo " OK"
19783
19784         echo -n 'verify mdt job_stats...'
19785         do_facet mds1 "$LCTL get_param -n mdt.$FSNAME-MDT0000.job_stats" |
19786                 verify_yaml || error "job_stats on mds1 is not valid YAML"
19787         echo " OK"
19788
19789         echo -n 'verify ost job_stats...'
19790         do_facet ost1 "$LCTL get_param -n obdfilter.$FSNAME-OST0000.job_stats" |
19791                 verify_yaml || error "job_stats on ost1 is not valid YAML"
19792         echo " OK"
19793 }
19794 run_test 205d "verify the format of some stats files"
19795
19796 test_205e() {
19797         local ops_comma
19798         local file=$DIR/$tdir/$tfile
19799         local -a cli_params
19800
19801         (( $MDS1_VERSION >= $(version_code 2.15.53) )) ||
19802                 skip "need lustre >= 2.15.53 for lljobstat"
19803         (( $OST1_VERSION >= $(version_code 2.15.53) )) ||
19804                 skip "need lustre >= 2.15.53 for lljobstat"
19805         verify_yaml_available || skip_env "YAML verification not installed"
19806
19807         cli_params=( $($LCTL get_param jobid_name jobid_var) )
19808         $LCTL set_param jobid_var=nodelocal jobid_name=205e.%e.%u
19809         stack_trap "$LCTL set_param ${cli_params[*]}" EXIT
19810
19811         mkdir_on_mdt0 $DIR/$tdir || error "failed to create dir"
19812         stack_trap "rm -rf $DIR/$tdir"
19813
19814         $LFS setstripe -E EOF -i 0 -c 1 $file ||
19815                 error "failed to create $file on ost1"
19816         dd if=/dev/zero of=$file bs=1M count=10 oflag=sync ||
19817                 error "failed to write data to $file"
19818
19819         do_facet mds1 "$LCTL get_param *.*.job_stats"
19820         do_facet ost1 "$LCTL get_param *.*.job_stats"
19821
19822         do_facet ost1 "lljobstat -n 1 -i 0 -c 1000"
19823         do_facet ost1 "lljobstat -n 1 -i 0 -c 1000" | verify_yaml ||
19824                 error "The output of lljobstat is not an valid YAML"
19825
19826         # verify that job dd.0 does exist and has some ops on ost1
19827         # typically this line is like:
19828         # - 205e.dd.0:            {ops: 20, ...}
19829         ops_comma=$(do_facet ost1 "lljobstat -n 1 -i 0 -c 1000" |
19830                     awk '$2=="205e.dd.0:" {print $4}')
19831
19832         (( ${ops_comma%,} >= 10 )) ||
19833                 error "cannot find job 205e.dd.0 with ops >= 10"
19834 }
19835 run_test 205e "verify the output of lljobstat"
19836
19837 test_205f() {
19838         verify_yaml_available || skip_env "YAML verification not installed"
19839
19840         # check both qos_ost_weights and qos_mdt_weights
19841         do_facet mds1 $LCTL get_param -n lod.*.qos*weights
19842         do_facet mds1 $LCTL get_param -n lod.*.qos*weights | verify_yaml ||
19843                 error "qos_ost_weights is not valid YAML"
19844 }
19845 run_test 205f "verify qos_ost_weights YAML format "
19846
19847 __test_205_jobstats_dump() {
19848         local -a pids
19849         local nbr_instance=$1
19850
19851         while true; do
19852                 if (( ${#pids[@]} >= nbr_instance )); then
19853                         wait ${pids[@]}
19854                         pids=()
19855                 fi
19856
19857                 do_facet mds1 "$LCTL get_param mdt.*.job_stats > /dev/null" &
19858                 pids+=( $! )
19859         done
19860 }
19861
19862 __test_205_cleanup() {
19863         kill $@
19864         # Clear all job entries
19865         do_facet mds1 "$LCTL set_param mdt.*.job_stats=clear"
19866 }
19867
19868 test_205g() {
19869         local -a mds1_params
19870         local -a cli_params
19871         local pids
19872         local interval=5
19873
19874         mds1_params=( $(do_facet mds1 $LCTL get_param mdt.*.job_cleanup_interval) )
19875         do_facet mds1 $LCTL set_param mdt.*.job_cleanup_interval=$interval
19876         stack_trap "do_facet mds1 $LCTL set_param ${mds1_params[*]}" EXIT
19877
19878         cli_params=( $($LCTL get_param jobid_name jobid_var) )
19879         $LCTL set_param jobid_var=TEST205G_ID jobid_name=%j.%p
19880         stack_trap "$LCTL set_param ${cli_params[*]}" EXIT
19881
19882         # start jobs loop
19883         export TEST205G_ID=205g
19884         stack_trap "unset TEST205G_ID" EXIT
19885         while true; do
19886                 printf $DIR/$tfile.{0001..1000} | xargs -P10 -n1 touch
19887         done & pids="$! "
19888
19889         __test_205_jobstats_dump 4 & pids+="$! "
19890         stack_trap "__test_205_cleanup $pids" EXIT INT
19891
19892         [[ $SLOW == "no" ]] && sleep 90 || sleep 240
19893 }
19894 run_test 205g "stress test for job_stats procfile"
19895
19896 # LU-1480, LU-1773 and LU-1657
19897 test_206() {
19898         mkdir -p $DIR/$tdir
19899         $LFS setstripe -c -1 $DIR/$tdir
19900 #define OBD_FAIL_LOV_INIT 0x1403
19901         $LCTL set_param fail_loc=0xa0001403
19902         $LCTL set_param fail_val=1
19903         touch $DIR/$tdir/$tfile || true
19904 }
19905 run_test 206 "fail lov_init_raid0() doesn't lbug"
19906
19907 test_207a() {
19908         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
19909         local fsz=`stat -c %s $DIR/$tfile`
19910         cancel_lru_locks mdc
19911
19912         # do not return layout in getattr intent
19913 #define OBD_FAIL_MDS_NO_LL_GETATTR 0x170
19914         $LCTL set_param fail_loc=0x170
19915         local sz=`stat -c %s $DIR/$tfile`
19916
19917         [ $fsz -eq $sz ] || error "file size expected $fsz, actual $sz"
19918
19919         rm -rf $DIR/$tfile
19920 }
19921 run_test 207a "can refresh layout at glimpse"
19922
19923 test_207b() {
19924         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
19925         local cksum=`md5sum $DIR/$tfile`
19926         local fsz=`stat -c %s $DIR/$tfile`
19927         cancel_lru_locks mdc
19928         cancel_lru_locks osc
19929
19930         # do not return layout in getattr intent
19931 #define OBD_FAIL_MDS_NO_LL_OPEN 0x171
19932         $LCTL set_param fail_loc=0x171
19933
19934         # it will refresh layout after the file is opened but before read issues
19935         echo checksum is "$cksum"
19936         echo "$cksum" |md5sum -c --quiet || error "file differs"
19937
19938         rm -rf $DIR/$tfile
19939 }
19940 run_test 207b "can refresh layout at open"
19941
19942 test_208() {
19943         # FIXME: in this test suite, only RD lease is used. This is okay
19944         # for now as only exclusive open is supported. After generic lease
19945         # is done, this test suite should be revised. - Jinshan
19946
19947         remote_mds_nodsh && skip "remote MDS with nodsh"
19948         [[ $MDS1_VERSION -ge $(version_code 2.4.52) ]] ||
19949                 skip "Need MDS version at least 2.4.52"
19950
19951         echo "==== test 1: verify get lease work"
19952         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eRE+eU || error "get lease error"
19953
19954         echo "==== test 2: verify lease can be broken by upcoming open"
19955         $MULTIOP $DIR/$tfile oO_RDWR:eR_E-eUc &
19956         local PID=$!
19957         sleep 2
19958
19959         $MULTIOP $DIR/$tfile oO_RDWR:c
19960         kill -USR1 $PID && wait $PID || error "break lease error"
19961
19962         echo "==== test 3: verify lease can't be granted if an open already exists"
19963         $MULTIOP $DIR/$tfile oO_RDWR:_c &
19964         local PID=$!
19965         sleep 2
19966
19967         $MULTIOP $DIR/$tfile oO_RDWR:eReUc && error "apply lease should fail"
19968         kill -USR1 $PID && wait $PID || error "open file error"
19969
19970         echo "==== test 4: lease can sustain over recovery"
19971         $MULTIOP $DIR/$tfile oO_RDWR:eR_E+eUc &
19972         PID=$!
19973         sleep 2
19974
19975         fail mds1
19976
19977         kill -USR1 $PID && wait $PID || error "lease broken over recovery"
19978
19979         echo "==== test 5: lease broken can't be regained by replay"
19980         $MULTIOP $DIR/$tfile oO_RDWR:eR_E-eUc &
19981         PID=$!
19982         sleep 2
19983
19984         # open file to break lease and then recovery
19985         $MULTIOP $DIR/$tfile oO_RDWR:c || error "open file error"
19986         fail mds1
19987
19988         kill -USR1 $PID && wait $PID || error "lease not broken over recovery"
19989
19990         rm -f $DIR/$tfile
19991 }
19992 run_test 208 "Exclusive open"
19993
19994 test_209() {
19995         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep disp_stripe)" ] &&
19996                 skip_env "must have disp_stripe"
19997
19998         touch $DIR/$tfile
19999         sync; sleep 5; sync;
20000
20001         echo 3 > /proc/sys/vm/drop_caches
20002         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
20003                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
20004         req_before=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
20005
20006         # open/close 500 times
20007         for i in $(seq 500); do
20008                 cat $DIR/$tfile
20009         done
20010
20011         echo 3 > /proc/sys/vm/drop_caches
20012         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
20013                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
20014         req_after=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
20015
20016         echo "before: $req_before, after: $req_after"
20017         [ $((req_after - req_before)) -ge 300 ] &&
20018                 error "open/close requests are not freed"
20019         return 0
20020 }
20021 run_test 209 "read-only open/close requests should be freed promptly"
20022
20023 test_210() {
20024         local pid
20025
20026         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eW_E+eUc &
20027         pid=$!
20028         sleep 1
20029
20030         $LFS getstripe $DIR/$tfile
20031         kill -USR1 $pid
20032         wait $pid || error "multiop failed"
20033
20034         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
20035         pid=$!
20036         sleep 1
20037
20038         $LFS getstripe $DIR/$tfile
20039         kill -USR1 $pid
20040         wait $pid || error "multiop failed"
20041 }
20042 run_test 210 "lfs getstripe does not break leases"
20043
20044 test_212() {
20045         size=`date +%s`
20046         size=$((size % 8192 + 1))
20047         dd if=/dev/urandom of=$DIR/f212 bs=1k count=$size
20048         sendfile $DIR/f212 $DIR/f212.xyz || error "sendfile wrong"
20049         rm -f $DIR/f212 $DIR/f212.xyz
20050 }
20051 run_test 212 "Sendfile test ============================================"
20052
20053 test_213() {
20054         dd if=/dev/zero of=$DIR/$tfile bs=4k count=4
20055         cancel_lru_locks osc
20056         lctl set_param fail_loc=0x8000040f
20057         # generate a read lock
20058         cat $DIR/$tfile > /dev/null
20059         # write to the file, it will try to cancel the above read lock.
20060         cat /etc/hosts >> $DIR/$tfile
20061 }
20062 run_test 213 "OSC lock completion and cancel race don't crash - bug 18829"
20063
20064 test_214() { # for bug 20133
20065         mkdir -p $DIR/$tdir/d214c || error "mkdir $DIR/$tdir/d214c failed"
20066         for (( i=0; i < 340; i++ )) ; do
20067                 touch $DIR/$tdir/d214c/a$i
20068         done
20069
20070         ls -l $DIR/$tdir || error "ls -l $DIR/d214p failed"
20071         mv $DIR/$tdir/d214c $DIR/ || error "mv $DIR/d214p/d214c $DIR/ failed"
20072         ls $DIR/d214c || error "ls $DIR/d214c failed"
20073         rm -rf $DIR/$tdir || error "rm -rf $DIR/d214* failed"
20074         rm -rf $DIR/d214* || error "rm -rf $DIR/d214* failed"
20075 }
20076 run_test 214 "hash-indexed directory test - bug 20133"
20077
20078 # having "abc" as 1st arg, creates $TMP/lnet_abc.out and $TMP/lnet_abc.sys
20079 create_lnet_proc_files() {
20080         lctl get_param -n $1 >$TMP/lnet_$1.sys || error "cannot read lnet.$1"
20081 }
20082
20083 # counterpart of create_lnet_proc_files
20084 remove_lnet_proc_files() {
20085         rm -f $TMP/lnet_$1.sys
20086 }
20087
20088 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
20089 # 3rd arg as regexp for body
20090 check_lnet_proc_stats() {
20091         local l=$(cat "$TMP/lnet_$1" |wc -l)
20092         [ $l = 1 ] || (cat "$TMP/lnet_$1" && error "$2 is not of 1 line: $l")
20093
20094         grep -E "$3" "$TMP/lnet_$1" || (cat "$TMP/lnet_$1" && error "$2 misformatted")
20095 }
20096
20097 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
20098 # 3rd arg as regexp for body, 4th arg as regexp for 1st line, 5th arg is
20099 # optional and can be regexp for 2nd line (lnet.routes case)
20100 check_lnet_proc_entry() {
20101         local blp=2          # blp stands for 'position of 1st line of body'
20102         [ -z "$5" ] || blp=3 # lnet.routes case
20103
20104         local l=$(cat "$TMP/lnet_$1" |wc -l)
20105         # subtracting one from $blp because the body can be empty
20106         [ "$l" -ge "$(($blp - 1))" ] || (cat "$TMP/lnet_$1" && error "$2 is too short: $l")
20107
20108         sed -n '1 p' "$TMP/lnet_$1" |grep -E "$4" >/dev/null ||
20109                 (cat "$TMP/lnet_$1" && error "1st line of $2 misformatted")
20110
20111         [ "$5" = "" ] || sed -n '2 p' "$TMP/lnet_$1" |grep -E "$5" >/dev/null ||
20112                 (cat "$TMP/lnet_$1" && error "2nd line of $2 misformatted")
20113
20114         # bail out if any unexpected line happened
20115         sed -n "$blp p" "$TMP/lnet_$1" | grep -Ev "$3"
20116         [ "$?" != 0 ] || error "$2 misformatted"
20117 }
20118
20119 test_215() { # for bugs 18102, 21079, 21517
20120         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20121
20122         local N='(0|[1-9][0-9]*)'       # non-negative numeric
20123         local P='[1-9][0-9]*'           # positive numeric
20124         local I='(0|-?[1-9][0-9]*|NA)'  # any numeric (0 | >0 | <0) or NA if no value
20125         local NET='[a-z][a-z0-9]*'      # LNET net like o2ib2
20126         local ADDR='[0-9.]+'            # LNET addr like 10.0.0.1
20127         local NID="$ADDR@$NET"          # LNET nid like 10.0.0.1@o2ib2
20128
20129         local L1 # regexp for 1st line
20130         local L2 # regexp for 2nd line (optional)
20131         local BR # regexp for the rest (body)
20132
20133         # lnet.stats should look as 11 space-separated non-negative numerics
20134         BR="^$N $N $N $N $N $N $N $N $N $N $N$"
20135         create_lnet_proc_files "stats"
20136         check_lnet_proc_stats "stats.sys" "lnet.stats" "$BR"
20137         remove_lnet_proc_files "stats"
20138
20139         # lnet.routes should look like this:
20140         # Routing disabled/enabled
20141         # net hops priority state router
20142         # where net is a string like tcp0, hops > 0, priority >= 0,
20143         # state is up/down,
20144         # router is a string like 192.168.1.1@tcp2
20145         L1="^Routing (disabled|enabled)$"
20146         L2="^net +hops +priority +state +router$"
20147         BR="^$NET +$N +(0|1) +(up|down) +$NID$"
20148         create_lnet_proc_files "routes"
20149         check_lnet_proc_entry "routes.sys" "lnet.routes" "$BR" "$L1" "$L2"
20150         remove_lnet_proc_files "routes"
20151
20152         # lnet.routers should look like this:
20153         # ref rtr_ref alive_cnt state last_ping ping_sent deadline down_ni router
20154         # where ref > 0, rtr_ref > 0, alive_cnt >= 0, state is up/down,
20155         # last_ping >= 0, ping_sent is boolean (0/1), deadline and down_ni are
20156         # numeric (0 or >0 or <0), router is a string like 192.168.1.1@tcp2
20157         L1="^ref +rtr_ref +alive +router$"
20158         BR="^$P +$P +(up|down) +$NID$"
20159         create_lnet_proc_files "routers"
20160         check_lnet_proc_entry "routers.sys" "lnet.routers" "$BR" "$L1"
20161         remove_lnet_proc_files "routers"
20162
20163         # lnet.peers should look like this:
20164         # nid refs state last max rtr min tx min queue
20165         # where nid is a string like 192.168.1.1@tcp2, refs > 0,
20166         # state is up/down/NA, max >= 0. last, rtr, min, tx, min are
20167         # numeric (0 or >0 or <0), queue >= 0.
20168         L1="^nid +refs +state +last +max +rtr +min +tx +min +queue$"
20169         BR="^$NID +$P +(up|down|NA) +$I +$N +$I +$I +$I +$I +$N$"
20170         create_lnet_proc_files "peers"
20171         check_lnet_proc_entry "peers.sys" "lnet.peers" "$BR" "$L1"
20172         remove_lnet_proc_files "peers"
20173
20174         # lnet.buffers  should look like this:
20175         # pages count credits min
20176         # where pages >=0, count >=0, credits and min are numeric (0 or >0 or <0)
20177         L1="^pages +count +credits +min$"
20178         BR="^ +$N +$N +$I +$I$"
20179         create_lnet_proc_files "buffers"
20180         check_lnet_proc_entry "buffers.sys" "lnet.buffers" "$BR" "$L1"
20181         remove_lnet_proc_files "buffers"
20182
20183         # lnet.nis should look like this:
20184         # nid status alive refs peer rtr max tx min
20185         # where nid is a string like 192.168.1.1@tcp2, status is up/down,
20186         # alive is numeric (0 or >0 or <0), refs >= 0, peer >= 0,
20187         # rtr >= 0, max >=0, tx and min are numeric (0 or >0 or <0).
20188         L1="^nid +status +alive +refs +peer +rtr +max +tx +min$"
20189         BR="^$NID +(up|down) +$I +$N +$N +$N +$N +$I +$I$"
20190         create_lnet_proc_files "nis"
20191         check_lnet_proc_entry "nis.sys" "lnet.nis" "$BR" "$L1"
20192         remove_lnet_proc_files "nis"
20193
20194         # can we successfully write to lnet.stats?
20195         lctl set_param -n stats=0 || error "cannot write to lnet.stats"
20196 }
20197 run_test 215 "lnet exists and has proper content - bugs 18102, 21079, 21517"
20198
20199 test_216() { # bug 20317
20200         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20201         remote_ost_nodsh && skip "remote OST with nodsh"
20202
20203         local node
20204         local facets=$(get_facets OST)
20205         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
20206
20207         save_lustre_params client "osc.*.contention_seconds" > $p
20208         save_lustre_params $facets \
20209                 "ldlm.namespaces.filter-*.max_nolock_bytes" >> $p
20210         save_lustre_params $facets \
20211                 "ldlm.namespaces.filter-*.contended_locks" >> $p
20212         save_lustre_params $facets \
20213                 "ldlm.namespaces.filter-*.contention_seconds" >> $p
20214         clear_stats osc.*.osc_stats
20215
20216         # agressive lockless i/o settings
20217         do_nodes $(comma_list $(osts_nodes)) \
20218                 "lctl set_param -n ldlm.namespaces.*.max_nolock_bytes=2000000 \
20219                         ldlm.namespaces.filter-*.contended_locks=0 \
20220                         ldlm.namespaces.filter-*.contention_seconds=60"
20221         lctl set_param -n osc.*.contention_seconds=60
20222
20223         $DIRECTIO write $DIR/$tfile 0 10 4096
20224         $CHECKSTAT -s 40960 $DIR/$tfile
20225
20226         # disable lockless i/o
20227         do_nodes $(comma_list $(osts_nodes)) \
20228                 "lctl set_param -n ldlm.namespaces.filter-*.max_nolock_bytes=0 \
20229                         ldlm.namespaces.filter-*.contended_locks=32 \
20230                         ldlm.namespaces.filter-*.contention_seconds=0"
20231         lctl set_param -n osc.*.contention_seconds=0
20232         clear_stats osc.*.osc_stats
20233
20234         dd if=/dev/zero of=$DIR/$tfile count=0
20235         $CHECKSTAT -s 0 $DIR/$tfile
20236
20237         restore_lustre_params <$p
20238         rm -f $p
20239         rm $DIR/$tfile
20240 }
20241 run_test 216 "check lockless direct write updates file size and kms correctly"
20242
20243 test_217() { # bug 22430
20244         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20245
20246         local node
20247
20248         for node in $(nodes_list); do
20249                 local nid=$(host_nids_address $node $NETTYPE)
20250                 local node_ip=$(do_node $node getent ahostsv4 $node |
20251                                 awk '{ print $1; exit; }')
20252
20253                 echo "node: '$node', nid: '$nid', node_ip='$node_ip'"
20254                 # if hostname matches any NID, use hostname for better testing
20255                 if [[ -z "$nid" || "$nid" =~ "$node_ip" ]]; then
20256                         echo "lctl ping node $node@$NETTYPE"
20257                         lctl ping $node@$NETTYPE
20258                 else # otherwise, at least test 'lctl ping' is working
20259                         echo "lctl ping nid $(h2nettype $nid)"
20260                         lctl ping $(h2nettype $nid)
20261                         echo "skipping $node (no hyphen detected)"
20262                 fi
20263         done
20264 }
20265 run_test 217 "check lctl ping for hostnames with embedded hyphen ('-')"
20266
20267 test_218() {
20268         # do directio so as not to populate the page cache
20269         log "creating a 10 Mb file"
20270         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c ||
20271                 error "multiop failed while creating a file"
20272         log "starting reads"
20273         dd if=$DIR/$tfile of=/dev/null bs=4096 &
20274         log "truncating the file"
20275         $MULTIOP $DIR/$tfile oO_TRUNC:c ||
20276                 error "multiop failed while truncating the file"
20277         log "killing dd"
20278         kill %+ || true # reads might have finished
20279         echo "wait until dd is finished"
20280         wait
20281         log "removing the temporary file"
20282         rm -rf $DIR/$tfile || error "tmp file removal failed"
20283 }
20284 run_test 218 "parallel read and truncate should not deadlock"
20285
20286 test_219() {
20287         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20288
20289         # write one partial page
20290         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1
20291         # set no grant so vvp_io_commit_write will do sync write
20292         $LCTL set_param fail_loc=0x411
20293         # write a full page at the end of file
20294         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=1 conv=notrunc
20295
20296         $LCTL set_param fail_loc=0
20297         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=3
20298         $LCTL set_param fail_loc=0x411
20299         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1 seek=2 conv=notrunc
20300
20301         # LU-4201
20302         dd if=/dev/zero of=$DIR/$tfile-2 bs=1024 count=1
20303         $CHECKSTAT -s 1024 $DIR/$tfile-2 || error "checkstat wrong size"
20304 }
20305 run_test 219 "LU-394: Write partial won't cause uncontiguous pages vec at LND"
20306
20307 test_220() { #LU-325
20308         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20309         remote_ost_nodsh && skip "remote OST with nodsh"
20310         remote_mds_nodsh && skip "remote MDS with nodsh"
20311         remote_mgs_nodsh && skip "remote MGS with nodsh"
20312
20313         local OSTIDX=0
20314
20315         # create on MDT0000 so the last_id and next_id are correct
20316         mkdir_on_mdt0 $DIR/$tdir
20317         local OST=$($LFS df $DIR | awk '/OST:'$OSTIDX'/ { print $1 }')
20318         OST=${OST%_UUID}
20319
20320         # on the mdt's osc
20321         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $OST)
20322         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
20323                         osp.$mdtosc_proc1.prealloc_last_id)
20324         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
20325                         osp.$mdtosc_proc1.prealloc_next_id)
20326
20327         $LFS df -i
20328
20329         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=-1
20330         #define OBD_FAIL_OST_ENOINO              0x229
20331         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0x229
20332         create_pool $FSNAME.$TESTNAME || return 1
20333         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $OST || return 2
20334
20335         $LFS setstripe $DIR/$tdir -i $OSTIDX -c 1 -p $FSNAME.$TESTNAME
20336
20337         MDSOBJS=$((last_id - next_id))
20338         echo "preallocated objects on MDS is $MDSOBJS" "($last_id - $next_id)"
20339
20340         blocks=$($LFS df $MOUNT | awk '($1 == '$OSTIDX') { print $4 }')
20341         echo "OST still has $count kbytes free"
20342
20343         echo "create $MDSOBJS files @next_id..."
20344         createmany -o $DIR/$tdir/f $MDSOBJS || return 3
20345
20346         local last_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
20347                         osp.$mdtosc_proc1.prealloc_last_id)
20348         local next_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
20349                         osp.$mdtosc_proc1.prealloc_next_id)
20350
20351         echo "after creation, last_id=$last_id2, next_id=$next_id2"
20352         $LFS df -i
20353
20354         echo "cleanup..."
20355
20356         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=0
20357         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0
20358
20359         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $OST ||
20360                 error "$LCTL pool_remove $FSNAME.$TESTNAME $OST failed"
20361         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
20362                 error "$LCTL pool_destroy $FSNAME.$TESTNAME failed"
20363         echo "unlink $MDSOBJS files @$next_id..."
20364         unlinkmany $DIR/$tdir/f $MDSOBJS || error "unlinkmany failed"
20365 }
20366 run_test 220 "preallocated MDS objects still used if ENOSPC from OST"
20367
20368 test_221() {
20369         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20370
20371         dd if=`which date` of=$MOUNT/date oflag=sync
20372         chmod +x $MOUNT/date
20373
20374         #define OBD_FAIL_LLITE_FAULT_TRUNC_RACE  0x1401
20375         $LCTL set_param fail_loc=0x80001401
20376
20377         $MOUNT/date > /dev/null
20378         rm -f $MOUNT/date
20379 }
20380 run_test 221 "make sure fault and truncate race to not cause OOM"
20381
20382 test_222a () {
20383         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20384
20385         rm -rf $DIR/$tdir
20386         test_mkdir $DIR/$tdir
20387         $LFS setstripe -c 1 -i 0 $DIR/$tdir
20388         createmany -o $DIR/$tdir/$tfile 10
20389         cancel_lru_locks mdc
20390         cancel_lru_locks osc
20391         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
20392         $LCTL set_param fail_loc=0x31a
20393         ls -l $DIR/$tdir > /dev/null || error "AGL for ls failed"
20394         $LCTL set_param fail_loc=0
20395         rm -r $DIR/$tdir
20396 }
20397 run_test 222a "AGL for ls should not trigger CLIO lock failure"
20398
20399 test_222b () {
20400         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20401
20402         rm -rf $DIR/$tdir
20403         test_mkdir $DIR/$tdir
20404         $LFS setstripe -c 1 -i 0 $DIR/$tdir
20405         createmany -o $DIR/$tdir/$tfile 10
20406         cancel_lru_locks mdc
20407         cancel_lru_locks osc
20408         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
20409         $LCTL set_param fail_loc=0x31a
20410         rm -r $DIR/$tdir || error "AGL for rmdir failed"
20411         $LCTL set_param fail_loc=0
20412 }
20413 run_test 222b "AGL for rmdir should not trigger CLIO lock failure"
20414
20415 test_223 () {
20416         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20417
20418         rm -rf $DIR/$tdir
20419         test_mkdir $DIR/$tdir
20420         $LFS setstripe -c 1 -i 0 $DIR/$tdir
20421         createmany -o $DIR/$tdir/$tfile 10
20422         cancel_lru_locks mdc
20423         cancel_lru_locks osc
20424         #define OBD_FAIL_LDLM_AGL_NOLOCK          0x31b
20425         $LCTL set_param fail_loc=0x31b
20426         ls -l $DIR/$tdir > /dev/null || error "reenqueue failed"
20427         $LCTL set_param fail_loc=0
20428         rm -r $DIR/$tdir
20429 }
20430 run_test 223 "osc reenqueue if without AGL lock granted ======================="
20431
20432 test_224a() { # LU-1039, MRP-303
20433         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20434         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB   0x508
20435         $LCTL set_param fail_loc=0x508
20436         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 conv=fsync
20437         $LCTL set_param fail_loc=0
20438         df $DIR
20439 }
20440 run_test 224a "Don't panic on bulk IO failure"
20441
20442 test_224bd_sub() { # LU-1039, MRP-303
20443         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20444         local timeout=$1
20445
20446         shift
20447         dd if=/dev/urandom of=$TMP/$tfile bs=1M count=1
20448
20449         $LFS setstripe -c 1 -i 0 $DIR/$tfile
20450
20451         dd if=$TMP/$tfile of=$DIR/$tfile bs=1M count=1
20452         cancel_lru_locks osc
20453         set_checksums 0
20454         stack_trap "set_checksums $ORIG_CSUM" EXIT
20455         local at_max_saved=0
20456
20457         # adaptive timeouts may prevent seeing the issue
20458         if at_is_enabled; then
20459                 at_max_saved=$(at_max_get mds)
20460                 at_max_set 0 mds client
20461                 stack_trap "at_max_set $at_max_saved mds client" EXIT
20462         fi
20463
20464         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB2   0x515
20465         do_facet ost1 $LCTL set_param fail_val=$timeout fail_loc=0x80000515
20466         dd of=$TMP/$tfile.new if=$DIR/$tfile bs=1M count=1 || "$@"
20467
20468         do_facet ost1 $LCTL set_param fail_loc=0
20469         cmp $TMP/$tfile $TMP/$tfile.new || error "file contents wrong"
20470         df $DIR
20471 }
20472
20473 test_224b() {
20474         test_224bd_sub 3 error "dd failed"
20475 }
20476 run_test 224b "Don't panic on bulk IO failure"
20477
20478 test_224c() { # LU-6441
20479         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20480         remote_mds_nodsh && skip "remote MDS with nodsh"
20481
20482         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
20483         save_writethrough $p
20484         set_cache writethrough on
20485
20486         local pages_per_rpc=$($LCTL get_param osc.*.max_pages_per_rpc)
20487         local at_max=$($LCTL get_param -n at_max)
20488         local timeout=$($LCTL get_param -n timeout)
20489         local test_at="at_max"
20490         local param_at="$FSNAME.sys.at_max"
20491         local test_timeout="timeout"
20492         local param_timeout="$FSNAME.sys.timeout"
20493
20494         $LCTL set_param -n osc.*.max_pages_per_rpc=1024
20495
20496         set_persistent_param_and_check client "$test_at" "$param_at" 0
20497         set_persistent_param_and_check client "$test_timeout" "$param_timeout" 5
20498
20499         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB3 0x520
20500         do_facet ost1 "$LCTL set_param fail_loc=0x520"
20501         $LFS setstripe -c 1 -i 0 $DIR/$tfile
20502         stack_trap "rm -f $DIR/$tfile"
20503         dd if=/dev/zero of=$DIR/$tfile bs=8MB count=1
20504         sync
20505         do_facet ost1 "$LCTL set_param fail_loc=0"
20506
20507         set_persistent_param_and_check client "$test_at" "$param_at" $at_max
20508         set_persistent_param_and_check client "$test_timeout" "$param_timeout" \
20509                 $timeout
20510
20511         $LCTL set_param -n $pages_per_rpc
20512         restore_lustre_params < $p
20513         rm -f $p
20514 }
20515 run_test 224c "Don't hang if one of md lost during large bulk RPC"
20516
20517 test_224d() { # LU-11169
20518         test_224bd_sub $((TIMEOUT + 2)) error "dd failed"
20519 }
20520 run_test 224d "Don't corrupt data on bulk IO timeout"
20521
20522 MDSSURVEY=${MDSSURVEY:-$(which mds-survey 2>/dev/null || true)}
20523 test_225a () {
20524         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20525         if [ -z ${MDSSURVEY} ]; then
20526                 skip_env "mds-survey not found"
20527         fi
20528         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
20529                 skip "Need MDS version at least 2.2.51"
20530
20531         local mds=$(facet_host $SINGLEMDS)
20532         local target=$(do_nodes $mds 'lctl dl' |
20533                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
20534
20535         local cmd1="file_count=1000 thrhi=4"
20536         local cmd2="dir_count=2 layer=mdd stripe_count=0"
20537         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
20538         local cmd="$cmd1 $cmd2 $cmd3"
20539
20540         rm -f ${TMP}/mds_survey*
20541         echo + $cmd
20542         eval $cmd || error "mds-survey with zero-stripe failed"
20543         cat ${TMP}/mds_survey*
20544         rm -f ${TMP}/mds_survey*
20545 }
20546 run_test 225a "Metadata survey sanity with zero-stripe"
20547
20548 test_225b () {
20549         if [ -z ${MDSSURVEY} ]; then
20550                 skip_env "mds-survey not found"
20551         fi
20552         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
20553                 skip "Need MDS version at least 2.2.51"
20554         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20555         remote_mds_nodsh && skip "remote MDS with nodsh"
20556         if [ $($LCTL dl | grep -c osc) -eq 0 ]; then
20557                 skip_env "Need to mount OST to test"
20558         fi
20559
20560         local mds=$(facet_host $SINGLEMDS)
20561         local target=$(do_nodes $mds 'lctl dl' |
20562                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
20563
20564         local cmd1="file_count=1000 thrhi=4"
20565         local cmd2="dir_count=2 layer=mdd stripe_count=1"
20566         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
20567         local cmd="$cmd1 $cmd2 $cmd3"
20568
20569         rm -f ${TMP}/mds_survey*
20570         echo + $cmd
20571         eval $cmd || error "mds-survey with stripe_count failed"
20572         cat ${TMP}/mds_survey*
20573         rm -f ${TMP}/mds_survey*
20574 }
20575 run_test 225b "Metadata survey sanity with stripe_count = 1"
20576
20577 mcreate_path2fid () {
20578         local mode=$1
20579         local major=$2
20580         local minor=$3
20581         local name=$4
20582         local desc=$5
20583         local path=$DIR/$tdir/$name
20584         local fid
20585         local rc
20586         local fid_path
20587
20588         $MCREATE --mode=$1 --major=$2 --minor=$3 $path ||
20589                 error "cannot create $desc"
20590
20591         fid=$($LFS path2fid $path | tr -d '[' | tr -d ']')
20592         rc=$?
20593         [ $rc -ne 0 ] && error "cannot get fid of a $desc"
20594
20595         fid_path=$($LFS fid2path $MOUNT $fid)
20596         rc=$?
20597         [ $rc -ne 0 ] && error "cannot get path of $desc by $DIR $path $fid"
20598
20599         [ "$path" == "$fid_path" ] ||
20600                 error "fid2path returned $fid_path, expected $path"
20601
20602         echo "pass with $path and $fid"
20603 }
20604
20605 test_226a () {
20606         rm -rf $DIR/$tdir
20607         mkdir -p $DIR/$tdir
20608
20609         mcreate_path2fid 0010666 0 0 fifo "FIFO"
20610         mcreate_path2fid 0020666 1 3 null "character special file (null)"
20611         mcreate_path2fid 0020666 1 255 none "character special file (no device)"
20612         mcreate_path2fid 0040666 0 0 dir "directory"
20613         mcreate_path2fid 0060666 7 0 loop0 "block special file (loop)"
20614         mcreate_path2fid 0100666 0 0 file "regular file"
20615         mcreate_path2fid 0120666 0 0 link "symbolic link"
20616         mcreate_path2fid 0140666 0 0 sock "socket"
20617 }
20618 run_test 226a "call path2fid and fid2path on files of all type"
20619
20620 test_226b () {
20621         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20622
20623         local MDTIDX=1
20624
20625         rm -rf $DIR/$tdir
20626         mkdir -p $DIR/$tdir
20627         $LFS setdirstripe -i $MDTIDX $DIR/$tdir/remote_dir ||
20628                 error "create remote directory failed"
20629         mcreate_path2fid 0010666 0 0 "remote_dir/fifo" "FIFO"
20630         mcreate_path2fid 0020666 1 3 "remote_dir/null" \
20631                                 "character special file (null)"
20632         mcreate_path2fid 0020666 1 255 "remote_dir/none" \
20633                                 "character special file (no device)"
20634         mcreate_path2fid 0040666 0 0 "remote_dir/dir" "directory"
20635         mcreate_path2fid 0060666 7 0 "remote_dir/loop0" \
20636                                 "block special file (loop)"
20637         mcreate_path2fid 0100666 0 0 "remote_dir/file" "regular file"
20638         mcreate_path2fid 0120666 0 0 "remote_dir/link" "symbolic link"
20639         mcreate_path2fid 0140666 0 0 "remote_dir/sock" "socket"
20640 }
20641 run_test 226b "call path2fid and fid2path on files of all type under remote dir"
20642
20643 test_226c () {
20644         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20645         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
20646                 skip "Need MDS version at least 2.13.55"
20647
20648         local submnt=/mnt/submnt
20649         local srcfile=/etc/passwd
20650         local dstfile=$submnt/passwd
20651         local path
20652         local fid
20653
20654         rm -rf $DIR/$tdir
20655         rm -rf $submnt
20656         $LFS setdirstripe -c -1 -i 1 $DIR/$tdir ||
20657                 error "create remote directory failed"
20658         mkdir -p $submnt || error "create $submnt failed"
20659         $MOUNT_CMD $MGSNID:/$FSNAME/$tdir $submnt ||
20660                 error "mount $submnt failed"
20661         stack_trap "umount $submnt" EXIT
20662
20663         cp $srcfile $dstfile
20664         fid=$($LFS path2fid $dstfile)
20665         path=$($LFS fid2path $submnt "$fid")
20666         [ "$path" = "$dstfile" ] ||
20667                 error "fid2path $submnt $fid failed ($path != $dstfile)"
20668 }
20669 run_test 226c "call path2fid and fid2path under remote dir with subdir mount"
20670
20671 # LU-1299 Executing or running ldd on a truncated executable does not
20672 # cause an out-of-memory condition.
20673 test_227() {
20674         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20675         [ -z "$(which ldd)" ] && skip_env "should have ldd tool"
20676
20677         dd if=$(which date) of=$MOUNT/date bs=1k count=1
20678         chmod +x $MOUNT/date
20679
20680         $MOUNT/date > /dev/null
20681         ldd $MOUNT/date > /dev/null
20682         rm -f $MOUNT/date
20683 }
20684 run_test 227 "running truncated executable does not cause OOM"
20685
20686 # LU-1512 try to reuse idle OI blocks
20687 test_228a() {
20688         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20689         remote_mds_nodsh && skip "remote MDS with nodsh"
20690         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
20691
20692         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
20693         local myDIR=$DIR/$tdir
20694
20695         mkdir -p $myDIR
20696         #define OBD_FAIL_SEQ_EXHAUST             0x1002
20697         $LCTL set_param fail_loc=0x80001002
20698         createmany -o $myDIR/t- 10000
20699         $LCTL set_param fail_loc=0
20700         # The guard is current the largest FID holder
20701         touch $myDIR/guard
20702         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
20703                     tr -d '[')
20704         local IDX=$(($SEQ % 64))
20705
20706         do_facet $SINGLEMDS sync
20707         # Make sure journal flushed.
20708         sleep 6
20709         local blk1=$(do_facet $SINGLEMDS \
20710                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
20711                      grep Blockcount | awk '{print $4}')
20712
20713         # Remove old files, some OI blocks will become idle.
20714         unlinkmany $myDIR/t- 10000
20715         # Create new files, idle OI blocks should be reused.
20716         createmany -o $myDIR/t- 2000
20717         do_facet $SINGLEMDS sync
20718         # Make sure journal flushed.
20719         sleep 6
20720         local blk2=$(do_facet $SINGLEMDS \
20721                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
20722                      grep Blockcount | awk '{print $4}')
20723
20724         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
20725 }
20726 run_test 228a "try to reuse idle OI blocks"
20727
20728 test_228b() {
20729         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20730         remote_mds_nodsh && skip "remote MDS with nodsh"
20731         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
20732
20733         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
20734         local myDIR=$DIR/$tdir
20735
20736         mkdir -p $myDIR
20737         #define OBD_FAIL_SEQ_EXHAUST             0x1002
20738         $LCTL set_param fail_loc=0x80001002
20739         createmany -o $myDIR/t- 10000
20740         $LCTL set_param fail_loc=0
20741         # The guard is current the largest FID holder
20742         touch $myDIR/guard
20743         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
20744                     tr -d '[')
20745         local IDX=$(($SEQ % 64))
20746
20747         do_facet $SINGLEMDS sync
20748         # Make sure journal flushed.
20749         sleep 6
20750         local blk1=$(do_facet $SINGLEMDS \
20751                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
20752                      grep Blockcount | awk '{print $4}')
20753
20754         # Remove old files, some OI blocks will become idle.
20755         unlinkmany $myDIR/t- 10000
20756
20757         # stop the MDT
20758         stop $SINGLEMDS || error "Fail to stop MDT."
20759         # remount the MDT
20760         start $SINGLEMDS $(facet_device $SINGLEMDS) $MDS_MOUNT_OPTS ||
20761                 error "Fail to start MDT."
20762
20763         client_up || error "Fail to df."
20764         # Create new files, idle OI blocks should be reused.
20765         createmany -o $myDIR/t- 2000
20766         do_facet $SINGLEMDS sync
20767         # Make sure journal flushed.
20768         sleep 6
20769         local blk2=$(do_facet $SINGLEMDS \
20770                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
20771                      grep Blockcount | awk '{print $4}')
20772
20773         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
20774 }
20775 run_test 228b "idle OI blocks can be reused after MDT restart"
20776
20777 #LU-1881
20778 test_228c() {
20779         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20780         remote_mds_nodsh && skip "remote MDS with nodsh"
20781         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
20782
20783         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
20784         local myDIR=$DIR/$tdir
20785
20786         mkdir -p $myDIR
20787         #define OBD_FAIL_SEQ_EXHAUST             0x1002
20788         $LCTL set_param fail_loc=0x80001002
20789         # 20000 files can guarantee there are index nodes in the OI file
20790         createmany -o $myDIR/t- 20000
20791         $LCTL set_param fail_loc=0
20792         # The guard is current the largest FID holder
20793         touch $myDIR/guard
20794         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
20795                     tr -d '[')
20796         local IDX=$(($SEQ % 64))
20797
20798         do_facet $SINGLEMDS sync
20799         # Make sure journal flushed.
20800         sleep 6
20801         local blk1=$(do_facet $SINGLEMDS \
20802                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
20803                      grep Blockcount | awk '{print $4}')
20804
20805         # Remove old files, some OI blocks will become idle.
20806         unlinkmany $myDIR/t- 20000
20807         rm -f $myDIR/guard
20808         # The OI file should become empty now
20809
20810         # Create new files, idle OI blocks should be reused.
20811         createmany -o $myDIR/t- 2000
20812         do_facet $SINGLEMDS sync
20813         # Make sure journal flushed.
20814         sleep 6
20815         local blk2=$(do_facet $SINGLEMDS \
20816                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
20817                      grep Blockcount | awk '{print $4}')
20818
20819         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
20820 }
20821 run_test 228c "NOT shrink the last entry in OI index node to recycle idle leaf"
20822
20823 test_229() { # LU-2482, LU-3448
20824         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20825         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
20826         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
20827                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
20828
20829         rm -f $DIR/$tfile
20830
20831         # Create a file with a released layout and stripe count 2.
20832         $MULTIOP $DIR/$tfile H2c ||
20833                 error "failed to create file with released layout"
20834
20835         $LFS getstripe -v $DIR/$tfile
20836
20837         local pattern=$($LFS getstripe -L $DIR/$tfile)
20838         [ X"$pattern" = X"released" ] || error "pattern error ($pattern)"
20839
20840         local stripe_count=$($LFS getstripe -c $DIR/$tfile) ||
20841                 error "getstripe"
20842         [ $stripe_count -eq 2 ] || error "stripe count not 2 ($stripe_count)"
20843         stat $DIR/$tfile || error "failed to stat released file"
20844
20845         chown $RUNAS_ID $DIR/$tfile ||
20846                 error "chown $RUNAS_ID $DIR/$tfile failed"
20847
20848         chgrp $RUNAS_ID $DIR/$tfile ||
20849                 error "chgrp $RUNAS_ID $DIR/$tfile failed"
20850
20851         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
20852         rm $DIR/$tfile || error "failed to remove released file"
20853 }
20854 run_test 229 "getstripe/stat/rm/attr changes work on released files"
20855
20856 test_230a() {
20857         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20858         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20859         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20860                 skip "Need MDS version at least 2.11.52"
20861
20862         local MDTIDX=1
20863
20864         test_mkdir $DIR/$tdir
20865         test_mkdir -i0 -c1 $DIR/$tdir/test_230_local
20866         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230_local)
20867         [ $mdt_idx -ne 0 ] &&
20868                 error "create local directory on wrong MDT $mdt_idx"
20869
20870         $LFS mkdir -i $MDTIDX $DIR/$tdir/test_230 ||
20871                         error "create remote directory failed"
20872         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230)
20873         [ $mdt_idx -ne $MDTIDX ] &&
20874                 error "create remote directory on wrong MDT $mdt_idx"
20875
20876         createmany -o $DIR/$tdir/test_230/t- 10 ||
20877                 error "create files on remote directory failed"
20878         mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230/t-0)
20879         [ $mdt_idx -ne $MDTIDX ] && error "create files on wrong MDT $mdt_idx"
20880         rm -r $DIR/$tdir || error "unlink remote directory failed"
20881 }
20882 run_test 230a "Create remote directory and files under the remote directory"
20883
20884 test_230b() {
20885         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20886         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20887         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20888                 skip "Need MDS version at least 2.11.52"
20889
20890         local MDTIDX=1
20891         local mdt_index
20892         local i
20893         local file
20894         local pid
20895         local stripe_count
20896         local migrate_dir=$DIR/$tdir/migrate_dir
20897         local other_dir=$DIR/$tdir/other_dir
20898
20899         test_mkdir $DIR/$tdir
20900         test_mkdir -i0 -c1 $migrate_dir
20901         test_mkdir -i0 -c1 $other_dir
20902         for ((i=0; i<10; i++)); do
20903                 mkdir -p $migrate_dir/dir_${i}
20904                 createmany -o $migrate_dir/dir_${i}/f 10 ||
20905                         error "create files under remote dir failed $i"
20906         done
20907
20908         cp /etc/passwd $migrate_dir/$tfile
20909         cp /etc/passwd $other_dir/$tfile
20910         chattr +SAD $migrate_dir
20911         chattr +SAD $migrate_dir/$tfile
20912
20913         local old_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
20914         local old_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
20915         local old_dir_mode=$(stat -c%f $migrate_dir)
20916         local old_file_mode=$(stat -c%f $migrate_dir/$tfile)
20917
20918         mkdir -p $migrate_dir/dir_default_stripe2
20919         $LFS setstripe -c 2 $migrate_dir/dir_default_stripe2
20920         $LFS setstripe -c 2 $migrate_dir/${tfile}_stripe2
20921
20922         mkdir -p $other_dir
20923         ln $migrate_dir/$tfile $other_dir/luna
20924         ln $migrate_dir/$tfile $migrate_dir/sofia
20925         ln $other_dir/$tfile $migrate_dir/david
20926         ln -s $migrate_dir/$tfile $other_dir/zachary
20927         ln -s $migrate_dir/$tfile $migrate_dir/${tfile}_ln
20928         ln -s $other_dir/$tfile $migrate_dir/${tfile}_ln_other
20929
20930         local len
20931         local lnktgt
20932
20933         # inline symlink
20934         for len in 58 59 60; do
20935                 lnktgt=$(str_repeat 'l' $len)
20936                 touch $migrate_dir/$lnktgt
20937                 ln -s $lnktgt $migrate_dir/${len}char_ln
20938         done
20939
20940         # PATH_MAX
20941         for len in 4094 4095; do
20942                 lnktgt=$(str_repeat 'l' $len)
20943                 ln -s $lnktgt $migrate_dir/${len}char_ln
20944         done
20945
20946         # NAME_MAX
20947         for len in 254 255; do
20948                 touch $migrate_dir/$(str_repeat 'l' $len)
20949         done
20950
20951         $LFS migrate -m $MDTIDX $migrate_dir ||
20952                 error "fails on migrating remote dir to MDT1"
20953
20954         echo "migratate to MDT1, then checking.."
20955         for ((i = 0; i < 10; i++)); do
20956                 for file in $(find $migrate_dir/dir_${i}); do
20957                         mdt_index=$($LFS getstripe -m $file)
20958                         # broken symlink getstripe will fail
20959                         [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
20960                                 error "$file is not on MDT${MDTIDX}"
20961                 done
20962         done
20963
20964         # the multiple link file should still in MDT0
20965         mdt_index=$($LFS getstripe -m $migrate_dir/$tfile)
20966         [ $mdt_index == 0 ] ||
20967                 error "$file is not on MDT${MDTIDX}"
20968
20969         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
20970         [ "$old_dir_flag" = "$new_dir_flag" ] ||
20971                 error " expect $old_dir_flag get $new_dir_flag"
20972
20973         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
20974         [ "$old_file_flag" = "$new_file_flag" ] ||
20975                 error " expect $old_file_flag get $new_file_flag"
20976
20977         local new_dir_mode=$(stat -c%f $migrate_dir)
20978         [ "$old_dir_mode" = "$new_dir_mode" ] ||
20979                 error "expect mode $old_dir_mode get $new_dir_mode"
20980
20981         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
20982         [ "$old_file_mode" = "$new_file_mode" ] ||
20983                 error "expect mode $old_file_mode get $new_file_mode"
20984
20985         diff /etc/passwd $migrate_dir/$tfile ||
20986                 error "$tfile different after migration"
20987
20988         diff /etc/passwd $other_dir/luna ||
20989                 error "luna different after migration"
20990
20991         diff /etc/passwd $migrate_dir/sofia ||
20992                 error "sofia different after migration"
20993
20994         diff /etc/passwd $migrate_dir/david ||
20995                 error "david different after migration"
20996
20997         diff /etc/passwd $other_dir/zachary ||
20998                 error "zachary different after migration"
20999
21000         diff /etc/passwd $migrate_dir/${tfile}_ln ||
21001                 error "${tfile}_ln different after migration"
21002
21003         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
21004                 error "${tfile}_ln_other different after migration"
21005
21006         stripe_count=$($LFS getstripe -c $migrate_dir/dir_default_stripe2)
21007         [ $stripe_count = 2 ] ||
21008                 error "dir strpe_count $d != 2 after migration."
21009
21010         stripe_count=$($LFS getstripe -c $migrate_dir/${tfile}_stripe2)
21011         [ $stripe_count = 2 ] ||
21012                 error "file strpe_count $d != 2 after migration."
21013
21014         #migrate back to MDT0
21015         MDTIDX=0
21016
21017         $LFS migrate -m $MDTIDX $migrate_dir ||
21018                 error "fails on migrating remote dir to MDT0"
21019
21020         echo "migrate back to MDT0, checking.."
21021         for file in $(find $migrate_dir); do
21022                 mdt_index=$($LFS getstripe -m $file)
21023                 [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
21024                         error "$file is not on MDT${MDTIDX}"
21025         done
21026
21027         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
21028         [ "$old_dir_flag" = "$new_dir_flag" ] ||
21029                 error " expect $old_dir_flag get $new_dir_flag"
21030
21031         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
21032         [ "$old_file_flag" = "$new_file_flag" ] ||
21033                 error " expect $old_file_flag get $new_file_flag"
21034
21035         local new_dir_mode=$(stat -c%f $migrate_dir)
21036         [ "$old_dir_mode" = "$new_dir_mode" ] ||
21037                 error "expect mode $old_dir_mode get $new_dir_mode"
21038
21039         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
21040         [ "$old_file_mode" = "$new_file_mode" ] ||
21041                 error "expect mode $old_file_mode get $new_file_mode"
21042
21043         diff /etc/passwd ${migrate_dir}/$tfile ||
21044                 error "$tfile different after migration"
21045
21046         diff /etc/passwd ${other_dir}/luna ||
21047                 error "luna different after migration"
21048
21049         diff /etc/passwd ${migrate_dir}/sofia ||
21050                 error "sofia different after migration"
21051
21052         diff /etc/passwd ${other_dir}/zachary ||
21053                 error "zachary different after migration"
21054
21055         diff /etc/passwd $migrate_dir/${tfile}_ln ||
21056                 error "${tfile}_ln different after migration"
21057
21058         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
21059                 error "${tfile}_ln_other different after migration"
21060
21061         stripe_count=$($LFS getstripe -c ${migrate_dir}/dir_default_stripe2)
21062         [ $stripe_count = 2 ] ||
21063                 error "dir strpe_count $d != 2 after migration."
21064
21065         stripe_count=$($LFS getstripe -c ${migrate_dir}/${tfile}_stripe2)
21066         [ $stripe_count = 2 ] ||
21067                 error "file strpe_count $d != 2 after migration."
21068
21069         rm -rf $DIR/$tdir || error "rm dir failed after migration"
21070 }
21071 run_test 230b "migrate directory"
21072
21073 test_230c() {
21074         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21075         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21076         remote_mds_nodsh && skip "remote MDS with nodsh"
21077         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21078                 skip "Need MDS version at least 2.11.52"
21079
21080         local MDTIDX=1
21081         local total=3
21082         local mdt_index
21083         local file
21084         local migrate_dir=$DIR/$tdir/migrate_dir
21085
21086         #If migrating directory fails in the middle, all entries of
21087         #the directory is still accessiable.
21088         test_mkdir $DIR/$tdir
21089         test_mkdir -i0 -c1 $migrate_dir
21090         test_mkdir -i1 -c1 $DIR/$tdir/remote_dir
21091         stat $migrate_dir
21092         createmany -o $migrate_dir/f $total ||
21093                 error "create files under ${migrate_dir} failed"
21094
21095         # fail after migrating top dir, and this will fail only once, so the
21096         # first sub file migration will fail (currently f3), others succeed.
21097         #OBD_FAIL_MIGRATE_ENTRIES       0x1801
21098         do_facet mds1 lctl set_param fail_loc=0x1801
21099         local t=$(ls $migrate_dir | wc -l)
21100         $LFS migrate --mdt-index $MDTIDX $migrate_dir &&
21101                 error "migrate should fail"
21102         local u=$(ls $migrate_dir | wc -l)
21103         [ "$u" == "$t" ] || error "$u != $t during migration"
21104
21105         # add new dir/file should succeed
21106         mkdir $migrate_dir/dir ||
21107                 error "mkdir failed under migrating directory"
21108         touch $migrate_dir/file ||
21109                 error "create file failed under migrating directory"
21110
21111         # add file with existing name should fail
21112         for file in $migrate_dir/f*; do
21113                 stat $file > /dev/null || error "stat $file failed"
21114                 $OPENFILE -f O_CREAT:O_EXCL $file &&
21115                         error "open(O_CREAT|O_EXCL) $file should fail"
21116                 $MULTIOP $file m && error "create $file should fail"
21117                 touch $DIR/$tdir/remote_dir/$tfile ||
21118                         error "touch $tfile failed"
21119                 ln $DIR/$tdir/remote_dir/$tfile $file &&
21120                         error "link $file should fail"
21121                 mdt_index=$($LFS getstripe -m $file)
21122                 if [ $mdt_index == 0 ]; then
21123                         # file failed to migrate is not allowed to rename to
21124                         mv $DIR/$tdir/remote_dir/$tfile $file &&
21125                                 error "rename to $file should fail"
21126                 else
21127                         mv $DIR/$tdir/remote_dir/$tfile $file ||
21128                                 error "rename to $file failed"
21129                 fi
21130                 echo hello >> $file || error "write $file failed"
21131         done
21132
21133         # resume migration with different options should fail
21134         $LFS migrate -m 0 $migrate_dir &&
21135                 error "migrate -m 0 $migrate_dir should fail"
21136
21137         $LFS migrate -m $MDTIDX -c 2 $migrate_dir &&
21138                 error "migrate -c 2 $migrate_dir should fail"
21139
21140         # resume migration should succeed
21141         $LFS migrate -m $MDTIDX $migrate_dir ||
21142                 error "migrate $migrate_dir failed"
21143
21144         echo "Finish migration, then checking.."
21145         for file in $(find $migrate_dir); do
21146                 mdt_index=$($LFS getstripe -m $file)
21147                 [ $mdt_index == $MDTIDX ] ||
21148                         error "$file is not on MDT${MDTIDX}"
21149         done
21150
21151         rm -rf $DIR/$tdir || error "rm dir failed after migration"
21152 }
21153 run_test 230c "check directory accessiblity if migration failed"
21154
21155 test_230d() {
21156         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21157         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21158         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21159                 skip "Need MDS version at least 2.11.52"
21160         # LU-11235
21161         [ "$mds1_FSTYPE" == "zfs" ] && skip "skip ZFS backend"
21162
21163         local migrate_dir=$DIR/$tdir/migrate_dir
21164         local old_index
21165         local new_index
21166         local old_count
21167         local new_count
21168         local new_hash
21169         local mdt_index
21170         local i
21171         local j
21172
21173         old_index=$((RANDOM % MDSCOUNT))
21174         old_count=$((MDSCOUNT - old_index))
21175         new_index=$((RANDOM % MDSCOUNT))
21176         new_count=$((MDSCOUNT - new_index))
21177         new_hash=1 # for all_char
21178
21179         [ $old_count -gt 1 ] && old_count=$((old_count - RANDOM % old_count))
21180         [ $new_count -gt 1 ] && new_count=$((new_count - RANDOM % new_count))
21181
21182         test_mkdir $DIR/$tdir
21183         test_mkdir -i $old_index -c $old_count $migrate_dir
21184
21185         for ((i=0; i<100; i++)); do
21186                 test_mkdir -i0 -c1 $migrate_dir/dir_${i}
21187                 createmany -o $migrate_dir/dir_${i}/f 100 ||
21188                         error "create files under remote dir failed $i"
21189         done
21190
21191         echo -n "Migrate from MDT$old_index "
21192         [ $old_count -gt 1 ] && echo -n "... MDT$((old_index + old_count - 1)) "
21193         echo -n "to MDT$new_index"
21194         [ $new_count -gt 1 ] && echo -n " ... MDT$((new_index + new_count - 1))"
21195         echo
21196
21197         echo "$LFS migrate -m$new_index -c$new_count -H $new_hash $migrate_dir"
21198         $LFS migrate -m $new_index -c $new_count -H $new_hash $migrate_dir ||
21199                 error "migrate remote dir error"
21200
21201         echo "Finish migration, then checking.."
21202         for file in $(find $migrate_dir -maxdepth 1); do
21203                 mdt_index=$($LFS getstripe -m $file)
21204                 if [ $mdt_index -lt $new_index ] ||
21205                    [ $mdt_index -gt $((new_index + new_count - 1)) ]; then
21206                         error "$file is on MDT$mdt_index"
21207                 fi
21208         done
21209
21210         rm -rf $DIR/$tdir || error "rm dir failed after migration"
21211 }
21212 run_test 230d "check migrate big directory"
21213
21214 test_230e() {
21215         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21216         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21217         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21218                 skip "Need MDS version at least 2.11.52"
21219
21220         local i
21221         local j
21222         local a_fid
21223         local b_fid
21224
21225         mkdir_on_mdt0 $DIR/$tdir
21226         mkdir $DIR/$tdir/migrate_dir
21227         mkdir $DIR/$tdir/other_dir
21228         touch $DIR/$tdir/migrate_dir/a
21229         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/b
21230         ls $DIR/$tdir/other_dir
21231
21232         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
21233                 error "migrate dir fails"
21234
21235         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
21236         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
21237
21238         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
21239         [ $mdt_index == 0 ] || error "a is not on MDT0"
21240
21241         $LFS migrate -m 1 $DIR/$tdir/other_dir ||
21242                 error "migrate dir fails"
21243
21244         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir)
21245         [ $mdt_index == 1 ] || error "other_dir is not on MDT1"
21246
21247         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
21248         [ $mdt_index == 1 ] || error "a is not on MDT1"
21249
21250         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir/b)
21251         [ $mdt_index == 1 ] || error "b is not on MDT1"
21252
21253         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
21254         b_fid=$($LFS path2fid $DIR/$tdir/other_dir/b)
21255
21256         [ "$a_fid" = "$b_fid" ] || error "different fid after migration"
21257
21258         rm -rf $DIR/$tdir || error "rm dir failed after migration"
21259 }
21260 run_test 230e "migrate mulitple local link files"
21261
21262 test_230f() {
21263         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21264         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21265         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21266                 skip "Need MDS version at least 2.11.52"
21267
21268         local a_fid
21269         local ln_fid
21270
21271         mkdir -p $DIR/$tdir
21272         mkdir $DIR/$tdir/migrate_dir
21273         $LFS mkdir -i1 $DIR/$tdir/other_dir
21274         touch $DIR/$tdir/migrate_dir/a
21275         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln1
21276         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln2
21277         ls $DIR/$tdir/other_dir
21278
21279         # a should be migrated to MDT1, since no other links on MDT0
21280         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
21281                 error "#1 migrate dir fails"
21282         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
21283         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
21284         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
21285         [ $mdt_index == 1 ] || error "a is not on MDT1"
21286
21287         # a should stay on MDT1, because it is a mulitple link file
21288         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
21289                 error "#2 migrate dir fails"
21290         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
21291         [ $mdt_index == 1 ] || error "a is not on MDT1"
21292
21293         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
21294                 error "#3 migrate dir fails"
21295
21296         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
21297         ln_fid=$($LFS path2fid $DIR/$tdir/other_dir/ln1)
21298         [ "$a_fid" = "$ln_fid" ] || error "different fid after migrate to MDT1"
21299
21300         rm -rf $DIR/$tdir/other_dir/ln1 || error "unlink ln1 fails"
21301         rm -rf $DIR/$tdir/other_dir/ln2 || error "unlink ln2 fails"
21302
21303         # a should be migrated to MDT0, since no other links on MDT1
21304         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
21305                 error "#4 migrate dir fails"
21306         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
21307         [ $mdt_index == 0 ] || error "a is not on MDT0"
21308
21309         rm -rf $DIR/$tdir || error "rm dir failed after migration"
21310 }
21311 run_test 230f "migrate mulitple remote link files"
21312
21313 test_230g() {
21314         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21315         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21316         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21317                 skip "Need MDS version at least 2.11.52"
21318
21319         mkdir -p $DIR/$tdir/migrate_dir
21320
21321         $LFS migrate -m 1000 $DIR/$tdir/migrate_dir &&
21322                 error "migrating dir to non-exist MDT succeeds"
21323         true
21324 }
21325 run_test 230g "migrate dir to non-exist MDT"
21326
21327 test_230h() {
21328         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21329         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21330         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21331                 skip "Need MDS version at least 2.11.52"
21332
21333         local mdt_index
21334
21335         mkdir -p $DIR/$tdir/migrate_dir
21336
21337         $LFS migrate -m1 $DIR &&
21338                 error "migrating mountpoint1 should fail"
21339
21340         $LFS migrate -m1 $DIR/$tdir/.. &&
21341                 error "migrating mountpoint2 should fail"
21342
21343         # same as mv
21344         $LFS migrate -m1 $DIR/$tdir/migrate_dir/.. &&
21345                 error "migrating $tdir/migrate_dir/.. should fail"
21346
21347         true
21348 }
21349 run_test 230h "migrate .. and root"
21350
21351 test_230i() {
21352         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21353         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21354         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21355                 skip "Need MDS version at least 2.11.52"
21356
21357         mkdir -p $DIR/$tdir/migrate_dir
21358
21359         $LFS migrate -m 1 $DIR/$tdir/migrate_dir/ ||
21360                 error "migration fails with a tailing slash"
21361
21362         $LFS migrate -m 0 $DIR/$tdir/migrate_dir// ||
21363                 error "migration fails with two tailing slashes"
21364 }
21365 run_test 230i "lfs migrate -m tolerates trailing slashes"
21366
21367 test_230j() {
21368         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
21369         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
21370                 skip "Need MDS version at least 2.11.52"
21371
21372         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
21373         $LFS setstripe -E 1M -L mdt $DIR/$tdir/$tfile ||
21374                 error "create $tfile failed"
21375         cat /etc/passwd > $DIR/$tdir/$tfile
21376
21377         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
21378
21379         cmp /etc/passwd $DIR/$tdir/$tfile ||
21380                 error "DoM file mismatch after migration"
21381 }
21382 run_test 230j "DoM file data not changed after dir migration"
21383
21384 test_230k() {
21385         [ $MDSCOUNT -lt 4 ] && skip "needs >= 4 MDTs"
21386         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
21387                 skip "Need MDS version at least 2.11.56"
21388
21389         local total=20
21390         local files_on_starting_mdt=0
21391
21392         $LFS mkdir -i -1 -c 2 $DIR/$tdir || error "mkdir failed"
21393         $LFS getdirstripe $DIR/$tdir
21394         for i in $(seq $total); do
21395                 echo $((i*i - i)) > $DIR/$tdir/$tfile.$i || error "write failed"
21396                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
21397                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
21398         done
21399
21400         echo "$files_on_starting_mdt files on MDT0"
21401
21402         $LFS migrate -m 1,3 $DIR/$tdir || error "migrate -m 1,3 failed"
21403         $LFS getdirstripe $DIR/$tdir
21404
21405         files_on_starting_mdt=0
21406         for i in $(seq $total); do
21407                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
21408                         error "file $tfile.$i mismatch after migration"
21409                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 1 ]] &&
21410                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
21411         done
21412
21413         echo "$files_on_starting_mdt files on MDT1 after migration"
21414         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT1"
21415
21416         $LFS migrate -m 0 -c 2 $DIR/$tdir || error "migrate -m 0 -c 2 failed"
21417         $LFS getdirstripe $DIR/$tdir
21418
21419         files_on_starting_mdt=0
21420         for i in $(seq $total); do
21421                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
21422                         error "file $tfile.$i mismatch after 2nd migration"
21423                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
21424                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
21425         done
21426
21427         echo "$files_on_starting_mdt files on MDT0 after 2nd migration"
21428         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT0"
21429
21430         true
21431 }
21432 run_test 230k "file data not changed after dir migration"
21433
21434 test_230l() {
21435         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
21436         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
21437                 skip "Need MDS version at least 2.11.56"
21438
21439         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir failed"
21440         createmany -o $DIR/$tdir/f___________________________________ 1000 ||
21441                 error "create files under remote dir failed $i"
21442         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
21443 }
21444 run_test 230l "readdir between MDTs won't crash"
21445
21446 test_230m() {
21447         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
21448         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
21449                 skip "Need MDS version at least 2.11.56"
21450
21451         local MDTIDX=1
21452         local mig_dir=$DIR/$tdir/migrate_dir
21453         local longstr="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
21454         local shortstr="b"
21455         local val
21456
21457         echo "Creating files and dirs with xattrs"
21458         test_mkdir $DIR/$tdir
21459         test_mkdir -i0 -c1 $mig_dir
21460         mkdir $mig_dir/dir
21461         setfattr -n user.attr1 -v $longstr $mig_dir/dir ||
21462                 error "cannot set xattr attr1 on dir"
21463         setfattr -n user.attr2 -v $shortstr $mig_dir/dir ||
21464                 error "cannot set xattr attr2 on dir"
21465         touch $mig_dir/dir/f0
21466         setfattr -n user.attr1 -v $longstr $mig_dir/dir/f0 ||
21467                 error "cannot set xattr attr1 on file"
21468         setfattr -n user.attr2 -v $shortstr $mig_dir/dir/f0 ||
21469                 error "cannot set xattr attr2 on file"
21470         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
21471         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
21472         [ "$val" = $longstr ] || error "xattr attr1 not set properly on dir"
21473         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
21474         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on dir"
21475         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
21476         [ "$val" = $longstr ] || error "xattr attr1 not set properly on file"
21477         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
21478         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on file"
21479
21480         echo "Migrating to MDT1"
21481         $LFS migrate -m $MDTIDX $mig_dir ||
21482                 error "fails on migrating dir to MDT1"
21483
21484         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
21485         echo "Checking xattrs"
21486         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
21487         [ "$val" = $longstr ] ||
21488                 error "expecting xattr1 $longstr on dir, found $val"
21489         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
21490         [ "$val" = $shortstr ] ||
21491                 error "expecting xattr2 $shortstr on dir, found $val"
21492         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
21493         [ "$val" = $longstr ] ||
21494                 error "expecting xattr1 $longstr on file, found $val"
21495         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
21496         [ "$val" = $shortstr ] ||
21497                 error "expecting xattr2 $shortstr on file, found $val"
21498 }
21499 run_test 230m "xattrs not changed after dir migration"
21500
21501 test_230n() {
21502         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
21503         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
21504                 skip "Need MDS version at least 2.13.53"
21505
21506         $LFS mkdir -i 0 $DIR/$tdir || error "mkdir $tdir failed"
21507         cat /etc/hosts > $DIR/$tdir/$tfile
21508         $LFS mirror extend -N1 $DIR/$tdir/$tfile || error "Mirroring failed"
21509         $LFS migrate -m 1 $DIR/$tdir || error "Migration failed"
21510
21511         cmp /etc/hosts $DIR/$tdir/$tfile ||
21512                 error "File data mismatch after migration"
21513 }
21514 run_test 230n "Dir migration with mirrored file"
21515
21516 test_230o() {
21517         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
21518         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
21519                 skip "Need MDS version at least 2.13.52"
21520
21521         local mdts=$(comma_list $(mdts_nodes))
21522         local timeout=100
21523         local restripe_status
21524         local delta
21525         local i
21526
21527         [[ $mds1_FSTYPE == zfs ]] && timeout=300
21528
21529         # in case "crush" hash type is not set
21530         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
21531
21532         restripe_status=$(do_facet mds1 $LCTL get_param -n \
21533                            mdt.*MDT0000.enable_dir_restripe)
21534         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
21535         stack_trap "do_nodes $mdts $LCTL set_param \
21536                     mdt.*.enable_dir_restripe=$restripe_status"
21537
21538         mkdir $DIR/$tdir
21539         createmany -m $DIR/$tdir/f 100 ||
21540                 error "create files under remote dir failed $i"
21541         createmany -d $DIR/$tdir/d 100 ||
21542                 error "create dirs under remote dir failed $i"
21543
21544         for i in $(seq 2 $MDSCOUNT); do
21545                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
21546                 $LFS setdirstripe -c $i $DIR/$tdir ||
21547                         error "split -c $i $tdir failed"
21548                 wait_update $HOSTNAME \
21549                         "$LFS getdirstripe -H $DIR/$tdir" "crush" $timeout ||
21550                         error "dir split not finished"
21551                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
21552                         awk '/migrate/ {sum += $2} END { print sum }')
21553                 echo "$delta migrated when dir split $((i - 1)) to $i stripes"
21554                 # delta is around total_files/stripe_count
21555                 (( $delta < 200 / (i - 1) + 4 )) ||
21556                         error "$delta files migrated >= $((200 / (i - 1) + 4))"
21557         done
21558 }
21559 run_test 230o "dir split"
21560
21561 test_230p() {
21562         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
21563         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
21564                 skip "Need MDS version at least 2.13.52"
21565
21566         local mdts=$(comma_list $(mdts_nodes))
21567         local timeout=100
21568         local restripe_status
21569         local delta
21570         local c
21571
21572         [[ $mds1_FSTYPE == zfs ]] && timeout=300
21573
21574         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
21575
21576         restripe_status=$(do_facet mds1 $LCTL get_param -n \
21577                            mdt.*MDT0000.enable_dir_restripe)
21578         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
21579         stack_trap "do_nodes $mdts $LCTL set_param \
21580                     mdt.*.enable_dir_restripe=$restripe_status"
21581
21582         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir
21583         createmany -m $DIR/$tdir/f 100 ||
21584                 error "create files under remote dir failed"
21585         createmany -d $DIR/$tdir/d 100 ||
21586                 error "create dirs under remote dir failed"
21587
21588         for c in $(seq $((MDSCOUNT - 1)) -1 1); do
21589                 local mdt_hash="crush"
21590
21591                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
21592                 $LFS setdirstripe -c $c $DIR/$tdir ||
21593                         error "split -c $c $tdir failed"
21594                 if (( MDS1_VERSION >= $(version_code 2.14.51) )); then
21595                         mdt_hash="$mdt_hash,fixed"
21596                 elif [ $c -eq 1 ]; then
21597                         mdt_hash="none"
21598                 fi
21599                 wait_update $HOSTNAME \
21600                         "$LFS getdirstripe -H $DIR/$tdir" $mdt_hash $timeout ||
21601                         error "dir merge not finished"
21602                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
21603                         awk '/migrate/ {sum += $2} END { print sum }')
21604                 echo "$delta migrated when dir merge $((c + 1)) to $c stripes"
21605                 # delta is around total_files/stripe_count
21606                 (( delta < 200 / c + 4 )) ||
21607                         error "$delta files migrated >= $((200 / c + 4))"
21608         done
21609 }
21610 run_test 230p "dir merge"
21611
21612 test_230q() {
21613         (( MDSCOUNT > 1)) || skip "needs >= 2 MDTs"
21614         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
21615                 skip "Need MDS version at least 2.13.52"
21616
21617         local mdts=$(comma_list $(mdts_nodes))
21618         local saved_threshold=$(do_facet mds1 \
21619                         $LCTL get_param -n mdt.*-MDT0000.dir_split_count)
21620         local saved_delta=$(do_facet mds1 \
21621                         $LCTL get_param -n mdt.*-MDT0000.dir_split_delta)
21622         local threshold=100
21623         local delta=2
21624         local total=0
21625         local stripe_count=0
21626         local stripe_index
21627         local nr_files
21628         local create
21629
21630         # test with fewer files on ZFS
21631         [ "$mds1_FSTYPE" == "zfs" ] && threshold=40
21632
21633         stack_trap "do_nodes $mdts $LCTL set_param \
21634                     mdt.*.dir_split_count=$saved_threshold"
21635         stack_trap "do_nodes $mdts $LCTL set_param \
21636                     mdt.*.dir_split_delta=$saved_delta"
21637         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.dir_restripe_nsonly=1"
21638         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_auto_split=1"
21639         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_count=$threshold"
21640         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_delta=$delta"
21641         do_nodes $mdts "$LCTL set_param mdt.*.dir_restripe_nsonly=0"
21642         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
21643
21644         $LFS mkdir -i -1 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
21645         stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
21646
21647         create=$((threshold * 3 / 2))
21648         while [ $stripe_count -lt $MDSCOUNT ]; do
21649                 createmany -m $DIR/$tdir/f $total $create ||
21650                         error "create sub files failed"
21651                 stat $DIR/$tdir > /dev/null
21652                 total=$((total + create))
21653                 stripe_count=$((stripe_count + delta))
21654                 [ $stripe_count -gt $MDSCOUNT ] && stripe_count=$MDSCOUNT
21655
21656                 wait_update $HOSTNAME \
21657                         "$LFS getdirstripe -c $DIR/$tdir" "$stripe_count" 40 ||
21658                         error "stripe count $($LFS getdirstripe -c $DIR/$tdir) != $stripe_count"
21659
21660                 wait_update $HOSTNAME \
21661                         "$LFS getdirstripe -H $DIR/$tdir" "crush" 200 ||
21662                         error "stripe hash $($LFS getdirstripe -H $DIR/$tdir) != crush"
21663
21664                 nr_files=$($LFS find -m 1 $DIR/$tdir | grep -c -w $stripe_index)
21665                 echo "$nr_files/$total files on MDT$stripe_index after split"
21666                 # allow 10% margin of imbalance with crush hash
21667                 (( $nr_files <= $total / $stripe_count + $create / 10)) ||
21668                         error "$nr_files files on MDT$stripe_index after split"
21669
21670                 nr_files=$($LFS find -type f $DIR/$tdir | wc -l)
21671                 [ $nr_files -eq $total ] ||
21672                         error "total sub files $nr_files != $total"
21673         done
21674
21675         (( MDS1_VERSION >= $(version_code 2.14.51) )) || return 0
21676
21677         echo "fixed layout directory won't auto split"
21678         $LFS migrate -m 0 $DIR/$tdir || error "migrate $tdir failed"
21679         wait_update $HOSTNAME "$LFS getdirstripe -H $DIR/$tdir" "crush,fixed" \
21680                 10 || error "stripe hash $($LFS getdirstripe -H $DIR/$tdir)"
21681         wait_update $HOSTNAME "$LFS getdirstripe -c $DIR/$tdir" 1 10 ||
21682                 error "stripe count $($LFS getdirstripe -c $DIR/$tdir)"
21683 }
21684 run_test 230q "dir auto split"
21685
21686 test_230r() {
21687         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
21688         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
21689         [[ $MDS1_VERSION -ge $(version_code 2.13.54) ]] ||
21690                 skip "Need MDS version at least 2.13.54"
21691
21692         # maximum amount of local locks:
21693         # parent striped dir - 2 locks
21694         # new stripe in parent to migrate to - 1 lock
21695         # source and target - 2 locks
21696         # Total 5 locks for regular file
21697         mkdir -p $DIR/$tdir
21698         $LFS mkdir -i1 -c2 $DIR/$tdir/dir1
21699         touch $DIR/$tdir/dir1/eee
21700
21701         # create 4 hardlink for 4 more locks
21702         # Total: 9 locks > RS_MAX_LOCKS (8)
21703         $LFS mkdir -i1 -c1 $DIR/$tdir/dir2
21704         $LFS mkdir -i1 -c1 $DIR/$tdir/dir3
21705         $LFS mkdir -i1 -c1 $DIR/$tdir/dir4
21706         $LFS mkdir -i1 -c1 $DIR/$tdir/dir5
21707         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir2/eee
21708         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir3/eee
21709         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir4/eee
21710         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir5/eee
21711
21712         cancel_lru_locks mdc
21713
21714         $LFS migrate -m1 -c1 $DIR/$tdir/dir1 ||
21715                 error "migrate dir fails"
21716
21717         rm -rf $DIR/$tdir || error "rm dir failed after migration"
21718 }
21719 run_test 230r "migrate with too many local locks"
21720
21721 test_230s() {
21722         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
21723                 skip "Need MDS version at least 2.14.52"
21724
21725         local mdts=$(comma_list $(mdts_nodes))
21726         local restripe_status=$(do_facet mds1 $LCTL get_param -n \
21727                                 mdt.*MDT0000.enable_dir_restripe)
21728
21729         stack_trap "do_nodes $mdts $LCTL set_param \
21730                     mdt.*.enable_dir_restripe=$restripe_status"
21731
21732         local st
21733         for st in 0 1; do
21734                 do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=$st"
21735                 test_mkdir $DIR/$tdir
21736                 $LFS mkdir $DIR/$tdir |& grep "File exists" ||
21737                         error "$LFS mkdir should return EEXIST if target exists"
21738                 rmdir $DIR/$tdir
21739         done
21740 }
21741 run_test 230s "lfs mkdir should return -EEXIST if target exists"
21742
21743 test_230t()
21744 {
21745         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
21746         [[ $MDS1_VERSION -ge $(version_code 2.14.50) ]] ||
21747                 skip "Need MDS version at least 2.14.50"
21748
21749         test_mkdir $DIR/$tdir || error "mkdir $tdir failed"
21750         test_mkdir $DIR/$tdir/subdir || error "mkdir subdir failed"
21751         $LFS project -p 1 -s $DIR/$tdir ||
21752                 error "set $tdir project id failed"
21753         $LFS project -p 2 -s $DIR/$tdir/subdir ||
21754                 error "set subdir project id failed"
21755         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir || error "migrate failed"
21756 }
21757 run_test 230t "migrate directory with project ID set"
21758
21759 test_230u()
21760 {
21761         (( MDSCOUNT > 3 )) || skip_env "needs >= 4 MDTs"
21762         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
21763                 skip "Need MDS version at least 2.14.53"
21764
21765         local count
21766
21767         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
21768         mkdir $DIR/$tdir/sub{0..99} || error "mkdir sub failed"
21769         $LFS migrate -m -1 $DIR/$tdir/sub{0..99} || error "migrate sub failed"
21770         for i in $(seq 0 $((MDSCOUNT - 1))); do
21771                 count=$($LFS getstripe -m $DIR/$tdir/sub* | grep -c ^$i)
21772                 echo "$count dirs migrated to MDT$i"
21773         done
21774         count=$($LFS getstripe -m $DIR/$tdir/sub* | sort -u | wc -l)
21775         (( count >= MDSCOUNT - 1 )) || error "dirs migrated to $count MDTs"
21776 }
21777 run_test 230u "migrate directory by QOS"
21778
21779 test_230v()
21780 {
21781         (( MDSCOUNT > 3 )) || skip_env "needs >= 4 MDTs"
21782         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
21783                 skip "Need MDS version at least 2.14.53"
21784
21785         local count
21786
21787         mkdir $DIR/$tdir || error "mkdir $tdir failed"
21788         mkdir $DIR/$tdir/sub{0..99} || error "mkdir sub failed"
21789         $LFS migrate -m 0,2,1 $DIR/$tdir || error "migrate $tdir failed"
21790         for i in $(seq 0 $((MDSCOUNT - 1))); do
21791                 count=$($LFS getstripe -m $DIR/$tdir/sub* | grep -c ^$i)
21792                 echo "$count subdirs migrated to MDT$i"
21793                 (( i == 3 )) && (( count > 0 )) &&
21794                         error "subdir shouldn't be migrated to MDT3"
21795         done
21796         count=$($LFS getstripe -m $DIR/$tdir/sub* | sort -u | wc -l)
21797         (( count == 3 )) || error "dirs migrated to $count MDTs"
21798 }
21799 run_test 230v "subdir migrated to the MDT where its parent is located"
21800
21801 test_230w() {
21802         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
21803         (( MDS1_VERSION >= $(version_code 2.15.0) )) ||
21804                 skip "Need MDS version at least 2.15.0"
21805
21806         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
21807         createmany -o $DIR/$tdir/f 10 || error "create files failed"
21808         createmany -d $DIR/$tdir/d 10 || error "create dirs failed"
21809
21810         $LFS migrate -m 1 -c $MDSCOUNT -d $DIR/$tdir ||
21811                 error "migrate failed"
21812
21813         (( $($LFS getdirstripe -c $DIR/$tdir) == MDSCOUNT )) ||
21814                 error "$tdir stripe count mismatch"
21815
21816         for i in $(seq 0 9); do
21817                 (( $($LFS getdirstripe -c $DIR/$tdir/d$i) == 0 )) ||
21818                         error "d$i is striped"
21819         done
21820 }
21821 run_test 230w "non-recursive mode dir migration"
21822
21823 test_230x() {
21824         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
21825         (( MDS1_VERSION >= $(version_code 2.15.0) )) ||
21826                 skip "Need MDS version at least 2.15.0"
21827
21828         mkdir -p $DIR/$tdir || error "mkdir failed"
21829         createmany -d $DIR/$tdir/sub 100 || error "createmany failed"
21830
21831         local mdt_name=$(mdtname_from_index 0)
21832         local low=$(do_facet mds2 $LCTL get_param -n \
21833                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low)
21834         local high=$(do_facet mds2 $LCTL get_param -n \
21835                 osp.*$mdt_name-osp-MDT0001.reserved_ino_high)
21836         local ffree=$($LFS df -i $MOUNT | awk "/$mdt_name/ { print \$4 }")
21837         local maxage=$(do_facet mds2 $LCTL get_param -n \
21838                 osp.*$mdt_name-osp-MDT0001.maxage)
21839
21840         stack_trap "do_facet mds2 $LCTL set_param -n \
21841                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low=$low \
21842                 osp.*$mdt_name-osp-MDT0001.reserved_ino_high=$high" EXIT
21843         stack_trap "do_facet mds2 $LCTL set_param -n \
21844                 osp.*$mdt_name-osp-MDT0001.maxage=$maxage" EXIT
21845
21846         do_facet mds2 $LCTL set_param -n \
21847                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low=$((ffree + 1))
21848         do_facet mds2 $LCTL set_param -n osp.*$mdt_name-osp-MDT0001.maxage=1
21849         sleep 4
21850         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir &&
21851                 error "migrate $tdir should fail"
21852
21853         do_facet mds2 $LCTL set_param -n \
21854                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low=$low
21855         do_facet mds2 $LCTL set_param -n \
21856                 osp.*$mdt_name-osp-MDT0001.reserved_ino_high=$high
21857         sleep 4
21858         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir ||
21859                 error "migrate failed"
21860         (( $($LFS getdirstripe -c $DIR/$tdir) == $MDSCOUNT )) ||
21861                 error "$tdir stripe count mismatch"
21862 }
21863 run_test 230x "dir migration check space"
21864
21865 test_230y() {
21866         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
21867         (( MDS1_VERSION >= $(version_code 2.15.55.45) )) ||
21868                 skip "Need MDS version at least 2.15.55.45"
21869
21870         local pid
21871
21872         test_mkdir -c -1 $DIR/$tdir || error "mkdir $tdir failed"
21873         $LFS getdirstripe $DIR/$tdir
21874         createmany -d $DIR/$tdir/d 100 || error "createmany failed"
21875         $LFS migrate -m 1 -c 2 $DIR/$tdir &
21876         pid=$!
21877         sleep 1
21878
21879         #OBD_FAIL_MIGRATE_BAD_HASH      0x1802
21880         do_facet mds2 lctl set_param fail_loc=0x1802
21881
21882         wait $pid
21883         do_facet mds2 lctl set_param fail_loc=0
21884         $LFS getdirstripe $DIR/$tdir
21885         unlinkmany -d $DIR/$tdir/d 100 || error "unlinkmany failed"
21886         rmdir $DIR/$tdir || error "rmdir $tdir failed"
21887 }
21888 run_test 230y "unlink dir with bad hash type"
21889
21890 test_230z() {
21891         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
21892         (( MDS1_VERSION >= $(version_code 2.15.55.45) )) ||
21893                 skip "Need MDS version at least 2.15.55.45"
21894
21895         local pid
21896
21897         test_mkdir -c -1 $DIR/$tdir || error "mkdir $tdir failed"
21898         $LFS getdirstripe $DIR/$tdir
21899         createmany -d $DIR/$tdir/d 100 || error "createmany failed"
21900         $LFS migrate -m 1 -c 2 -H fnv_1a_64 $DIR/$tdir &
21901         pid=$!
21902         sleep 1
21903
21904         #OBD_FAIL_MIGRATE_BAD_HASH      0x1802
21905         do_facet mds2 lctl set_param fail_loc=0x1802
21906
21907         wait $pid
21908         do_facet mds2 lctl set_param fail_loc=0
21909         $LFS getdirstripe $DIR/$tdir
21910
21911         # resume migration
21912         $LFS migrate -m 1 -c 2 -H fnv_1a_64 $DIR/$tdir ||
21913                 error "resume migration failed"
21914         $LFS getdirstripe $DIR/$tdir
21915         [ $($LFS getdirstripe -H $DIR/$tdir) == "fnv_1a_64,fixed" ] ||
21916                 error "migration is not finished"
21917 }
21918 run_test 230z "resume dir migration with bad hash type"
21919
21920 test_231a()
21921 {
21922         # For simplicity this test assumes that max_pages_per_rpc
21923         # is the same across all OSCs
21924         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
21925         local bulk_size=$((max_pages * PAGE_SIZE))
21926         local brw_size=$(do_facet ost1 $LCTL get_param -n obdfilter.*.brw_size |
21927                                        head -n 1)
21928
21929         mkdir -p $DIR/$tdir
21930         $LFS setstripe -S ${brw_size}M $DIR/$tdir ||
21931                 error "failed to set stripe with -S ${brw_size}M option"
21932         stack_trap "rm -rf $DIR/$tdir"
21933
21934         # clear the OSC stats
21935         $LCTL set_param osc.*.stats=0 &>/dev/null
21936         stop_writeback
21937
21938         # Client writes $bulk_size - there must be 1 rpc for $max_pages.
21939         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=$bulk_size count=1 \
21940                 oflag=direct &>/dev/null || error "dd failed"
21941
21942         sync; sleep 1; sync # just to be safe
21943         local nrpcs=$($LCTL get_param osc.*.stats |awk '/ost_write/ {print $2}')
21944         if [ x$nrpcs != "x1" ]; then
21945                 $LCTL get_param osc.*.stats
21946                 error "found $nrpcs ost_write RPCs, not 1 as expected"
21947         fi
21948
21949         start_writeback
21950         # Drop the OSC cache, otherwise we will read from it
21951         cancel_lru_locks osc
21952
21953         # clear the OSC stats
21954         $LCTL set_param osc.*.stats=0 &>/dev/null
21955
21956         # Client reads $bulk_size.
21957         dd if=$DIR/$tdir/$tfile of=/dev/null bs=$bulk_size count=1 \
21958                 iflag=direct &>/dev/null || error "dd failed"
21959
21960         nrpcs=$($LCTL get_param osc.*.stats | awk '/ost_read/ { print $2 }')
21961         if [ x$nrpcs != "x1" ]; then
21962                 $LCTL get_param osc.*.stats
21963                 error "found $nrpcs ost_read RPCs, not 1 as expected"
21964         fi
21965 }
21966 run_test 231a "checking that reading/writing of BRW RPC size results in one RPC"
21967
21968 test_231b() {
21969         mkdir -p $DIR/$tdir
21970         stack_trap "rm -rf $DIR/$tdir"
21971         local i
21972         for i in {0..1023}; do
21973                 dd if=/dev/zero of=$DIR/$tdir/$tfile conv=notrunc \
21974                         seek=$((2 * i)) bs=4096 count=1 &>/dev/null ||
21975                         error "dd of=$DIR/$tdir/$tfile seek=$((2 * i)) failed"
21976         done
21977         sync
21978 }
21979 run_test 231b "must not assert on fully utilized OST request buffer"
21980
21981 test_232a() {
21982         mkdir -p $DIR/$tdir
21983         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
21984
21985         #define OBD_FAIL_LDLM_OST_LVB            0x31c
21986         do_facet ost1 $LCTL set_param fail_loc=0x31c
21987
21988         # ignore dd failure
21989         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1 || true
21990         stack_trap "rm -f $DIR/$tdir/$tfile"
21991
21992         do_facet ost1 $LCTL set_param fail_loc=0
21993         umount_client $MOUNT || error "umount failed"
21994         mount_client $MOUNT || error "mount failed"
21995         stop ost1 || error "cannot stop ost1"
21996         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
21997 }
21998 run_test 232a "failed lock should not block umount"
21999
22000 test_232b() {
22001         [ $MDS1_VERSION -ge $(version_code 2.10.58) ] ||
22002                 skip "Need MDS version at least 2.10.58"
22003
22004         mkdir -p $DIR/$tdir
22005         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
22006         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1
22007         stack_trap "rm -f $DIR/$tdir/$tfile"
22008         sync
22009         cancel_lru_locks osc
22010
22011         #define OBD_FAIL_LDLM_OST_LVB            0x31c
22012         do_facet ost1 $LCTL set_param fail_loc=0x31c
22013
22014         # ignore failure
22015         $LFS data_version $DIR/$tdir/$tfile || true
22016
22017         do_facet ost1 $LCTL set_param fail_loc=0
22018         umount_client $MOUNT || error "umount failed"
22019         mount_client $MOUNT || error "mount failed"
22020         stop ost1 || error "cannot stop ost1"
22021         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
22022 }
22023 run_test 232b "failed data version lock should not block umount"
22024
22025 test_233a() {
22026         [ $MDS1_VERSION -ge $(version_code 2.3.64) ] ||
22027                 skip "Need MDS version at least 2.3.64"
22028         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
22029
22030         local fid=$($LFS path2fid $MOUNT)
22031
22032         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
22033                 error "cannot access $MOUNT using its FID '$fid'"
22034 }
22035 run_test 233a "checking that OBF of the FS root succeeds"
22036
22037 test_233b() {
22038         [ $MDS1_VERSION -ge $(version_code 2.5.90) ] ||
22039                 skip "Need MDS version at least 2.5.90"
22040         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
22041
22042         local fid=$($LFS path2fid $MOUNT/.lustre)
22043
22044         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
22045                 error "cannot access $MOUNT/.lustre using its FID '$fid'"
22046
22047         fid=$($LFS path2fid $MOUNT/.lustre/fid)
22048         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
22049                 error "cannot access $MOUNT/.lustre/fid using its FID '$fid'"
22050 }
22051 run_test 233b "checking that OBF of the FS .lustre succeeds"
22052
22053 test_234() {
22054         local p="$TMP/sanityN-$TESTNAME.parameters"
22055         save_lustre_params client "llite.*.xattr_cache" > $p
22056         lctl set_param llite.*.xattr_cache 1 ||
22057                 skip_env "xattr cache is not supported"
22058
22059         mkdir -p $DIR/$tdir || error "mkdir failed"
22060         touch $DIR/$tdir/$tfile || error "touch failed"
22061         # OBD_FAIL_LLITE_XATTR_ENOMEM
22062         $LCTL set_param fail_loc=0x1405
22063         getfattr -n user.attr $DIR/$tdir/$tfile &&
22064                 error "getfattr should have failed with ENOMEM"
22065         $LCTL set_param fail_loc=0x0
22066         rm -rf $DIR/$tdir
22067
22068         restore_lustre_params < $p
22069         rm -f $p
22070 }
22071 run_test 234 "xattr cache should not crash on ENOMEM"
22072
22073 test_235() {
22074         [ $MDS1_VERSION -lt $(version_code 2.4.52) ] &&
22075                 skip "Need MDS version at least 2.4.52"
22076
22077         flock_deadlock $DIR/$tfile
22078         local RC=$?
22079         case $RC in
22080                 0)
22081                 ;;
22082                 124) error "process hangs on a deadlock"
22083                 ;;
22084                 *) error "error executing flock_deadlock $DIR/$tfile"
22085                 ;;
22086         esac
22087 }
22088 run_test 235 "LU-1715: flock deadlock detection does not work properly"
22089
22090 #LU-2935
22091 test_236() {
22092         check_swap_layouts_support
22093
22094         local ref1=/etc/passwd
22095         local ref2=/etc/group
22096         local file1=$DIR/$tdir/f1
22097         local file2=$DIR/$tdir/f2
22098
22099         test_mkdir -c1 $DIR/$tdir
22100         $LFS setstripe -c 1 $file1 || error "cannot setstripe on '$file1': rc = $?"
22101         cp $ref1 $file1 || error "cp $ref1 $file1 failed: rc = $?"
22102         $LFS setstripe -c 2 $file2 || error "cannot setstripe on '$file2': rc = $?"
22103         cp $ref2 $file2 || error "cp $ref2 $file2 failed: rc = $?"
22104         local fd=$(free_fd)
22105         local cmd="exec $fd<>$file2"
22106         eval $cmd
22107         rm $file2
22108         $LFS swap_layouts $file1 /proc/self/fd/${fd} ||
22109                 error "cannot swap layouts of '$file1' and /proc/self/fd/${fd}"
22110         cmd="exec $fd>&-"
22111         eval $cmd
22112         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
22113
22114         #cleanup
22115         rm -rf $DIR/$tdir
22116 }
22117 run_test 236 "Layout swap on open unlinked file"
22118
22119 # LU-4659 linkea consistency
22120 test_238() {
22121         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
22122                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
22123                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
22124                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
22125
22126         touch $DIR/$tfile
22127         ln $DIR/$tfile $DIR/$tfile.lnk
22128         touch $DIR/$tfile.new
22129         mv $DIR/$tfile.new $DIR/$tfile
22130         local fid1=$($LFS path2fid $DIR/$tfile)
22131         local fid2=$($LFS path2fid $DIR/$tfile.lnk)
22132         local path1=$($LFS fid2path $FSNAME "$fid1")
22133         [ $tfile == $path1 ] || error "linkea inconsistent: $tfile $fid1 $path1"
22134         local path2=$($LFS fid2path $FSNAME "$fid2")
22135         [ $tfile.lnk == $path2 ] ||
22136                 error "linkea inconsistent: $tfile.lnk $fid2 $path2!"
22137         rm -f $DIR/$tfile*
22138 }
22139 run_test 238 "Verify linkea consistency"
22140
22141 test_239A() { # was test_239
22142         [ $MDS1_VERSION -lt $(version_code 2.5.60) ] &&
22143                 skip "Need MDS version at least 2.5.60"
22144
22145         local list=$(comma_list $(mdts_nodes))
22146
22147         mkdir -p $DIR/$tdir
22148         createmany -o $DIR/$tdir/f- 5000
22149         unlinkmany $DIR/$tdir/f- 5000
22150         [ $MDS1_VERSION -gt $(version_code 2.10.4) ] &&
22151                 do_nodes $list "lctl set_param -n osp.*.force_sync=1"
22152         changes=$(do_nodes $list "lctl get_param -n osp.*MDT*.sync_changes \
22153                         osp.*MDT*.sync_in_flight" | calc_sum)
22154         [ "$changes" -eq 0 ] || error "$changes not synced"
22155 }
22156 run_test 239A "osp_sync test"
22157
22158 test_239a() { #LU-5297
22159         remote_mds_nodsh && skip "remote MDS with nodsh"
22160
22161         touch $DIR/$tfile
22162         #define OBD_FAIL_OSP_CHECK_INVALID_REC     0x2100
22163         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2100
22164         chgrp $RUNAS_GID $DIR/$tfile
22165         wait_delete_completed
22166 }
22167 run_test 239a "process invalid osp sync record correctly"
22168
22169 test_239b() { #LU-5297
22170         remote_mds_nodsh && skip "remote MDS with nodsh"
22171
22172         touch $DIR/$tfile1
22173         #define OBD_FAIL_OSP_CHECK_ENOMEM     0x2101
22174         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2101
22175         chgrp $RUNAS_GID $DIR/$tfile1
22176         wait_delete_completed
22177         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
22178         touch $DIR/$tfile2
22179         chgrp $RUNAS_GID $DIR/$tfile2
22180         wait_delete_completed
22181 }
22182 run_test 239b "process osp sync record with ENOMEM error correctly"
22183
22184 test_240() {
22185         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22186         remote_mds_nodsh && skip "remote MDS with nodsh"
22187
22188         mkdir -p $DIR/$tdir
22189
22190         $LFS mkdir -i 0 $DIR/$tdir/d0 ||
22191                 error "failed to mkdir $DIR/$tdir/d0 on MDT0"
22192         $LFS mkdir -i 1 $DIR/$tdir/d0/d1 ||
22193                 error "failed to mkdir $DIR/$tdir/d0/d1 on MDT1"
22194
22195         umount_client $MOUNT || error "umount failed"
22196         #define OBD_FAIL_TGT_DELAY_CONDITIONAL   0x713
22197         do_facet mds2 lctl set_param fail_loc=0x713 fail_val=1
22198         mount_client $MOUNT || error "failed to mount client"
22199
22200         echo "stat $DIR/$tdir/d0/d1, should not fail/ASSERT"
22201         stat $DIR/$tdir/d0/d1 || error "fail to stat $DIR/$tdir/d0/d1"
22202 }
22203 run_test 240 "race between ldlm enqueue and the connection RPC (no ASSERT)"
22204
22205 test_241_bio() {
22206         local count=$1
22207         local bsize=$2
22208
22209         for LOOP in $(seq $count); do
22210                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 2>/dev/null
22211                 cancel_lru_locks $OSC || true
22212         done
22213 }
22214
22215 test_241_dio() {
22216         local count=$1
22217         local bsize=$2
22218
22219         for LOOP in $(seq $1); do
22220                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 iflag=direct \
22221                         2>/dev/null
22222         done
22223 }
22224
22225 test_241a() { # was test_241
22226         local bsize=$PAGE_SIZE
22227
22228         (( bsize < 40960 )) && bsize=40960
22229         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
22230         ls -la $DIR/$tfile
22231         cancel_lru_locks $OSC
22232         test_241_bio 1000 $bsize &
22233         PID=$!
22234         test_241_dio 1000 $bsize
22235         wait $PID
22236 }
22237 run_test 241a "bio vs dio"
22238
22239 test_241b() {
22240         local bsize=$PAGE_SIZE
22241
22242         (( bsize < 40960 )) && bsize=40960
22243         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
22244         ls -la $DIR/$tfile
22245         test_241_dio 1000 $bsize &
22246         PID=$!
22247         test_241_dio 1000 $bsize
22248         wait $PID
22249 }
22250 run_test 241b "dio vs dio"
22251
22252 test_242() {
22253         remote_mds_nodsh && skip "remote MDS with nodsh"
22254
22255         mkdir_on_mdt0 $DIR/$tdir
22256         touch $DIR/$tdir/$tfile
22257
22258         #define OBD_FAIL_MDS_READPAGE_PACK      0x105
22259         do_facet mds1 lctl set_param fail_loc=0x105
22260         /bin/ls $DIR/$tdir && error "ls $DIR/$tdir should fail"
22261
22262         do_facet mds1 lctl set_param fail_loc=0
22263         /bin/ls $DIR/$tdir || error "ls $DIR/$tdir failed"
22264 }
22265 run_test 242 "mdt_readpage failure should not cause directory unreadable"
22266
22267 test_243()
22268 {
22269         test_mkdir $DIR/$tdir
22270         group_lock_test -d $DIR/$tdir || error "A group lock test failed"
22271 }
22272 run_test 243 "various group lock tests"
22273
22274 test_244a()
22275 {
22276         test_mkdir $DIR/$tdir
22277         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=35
22278         sendfile_grouplock $DIR/$tdir/$tfile || \
22279                 error "sendfile+grouplock failed"
22280         rm -rf $DIR/$tdir
22281 }
22282 run_test 244a "sendfile with group lock tests"
22283
22284 test_244b()
22285 {
22286         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
22287
22288         local threads=50
22289         local size=$((1024*1024))
22290
22291         test_mkdir $DIR/$tdir
22292         for i in $(seq 1 $threads); do
22293                 local file=$DIR/$tdir/file_$((i / 10))
22294                 $MULTIOP $file OG1234w$size_$((i % 3))w$size_$((i % 4))g1234c &
22295                 local pids[$i]=$!
22296         done
22297         for i in $(seq 1 $threads); do
22298                 wait ${pids[$i]}
22299         done
22300 }
22301 run_test 244b "multi-threaded write with group lock"
22302
22303 test_245a() {
22304         local flagname="multi_mod_rpcs"
22305         local connect_data_name="max_mod_rpcs"
22306         local out
22307
22308         # check if multiple modify RPCs flag is set
22309         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import |
22310                 grep "connect_flags:")
22311         echo "$out"
22312
22313         echo "$out" | grep -qw $flagname
22314         if [ $? -ne 0 ]; then
22315                 echo "connect flag $flagname is not set"
22316                 return
22317         fi
22318
22319         # check if multiple modify RPCs data is set
22320         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import)
22321         echo "$out"
22322
22323         echo "$out" | grep -qw $connect_data_name ||
22324                 error "import should have connect data $connect_data_name"
22325 }
22326 run_test 245a "check mdc connection flag/data: multiple modify RPCs"
22327
22328 test_245b() {
22329         local flagname="multi_mod_rpcs"
22330         local connect_data_name="max_mod_rpcs"
22331         local out
22332
22333         remote_mds_nodsh && skip "remote MDS with nodsh"
22334         [[ $MDSCOUNT -ge 2 ]] || skip "needs >= 2 MDTs"
22335
22336         # check if multiple modify RPCs flag is set
22337         out=$(do_facet mds1 \
22338               $LCTL get_param osp.$FSNAME-MDT0001-osp-MDT0000.import |
22339               grep "connect_flags:")
22340         echo "$out"
22341
22342         [[ "$out" =~ $flagname ]] || skip "connect flag $flagname is not set"
22343
22344         # check if multiple modify RPCs data is set
22345         out=$(do_facet mds1 \
22346               $LCTL get_param osp.$FSNAME-MDT0001-osp-MDT0000.import)
22347
22348         [[ "$out" =~ $connect_data_name ]] ||
22349                 {
22350                         echo "$out"
22351                         error "missing connect data $connect_data_name"
22352                 }
22353 }
22354 run_test 245b "check osp connection flag/data: multiple modify RPCs"
22355
22356 cleanup_247() {
22357         local submount=$1
22358
22359         trap 0
22360         umount_client $submount
22361         rmdir $submount
22362 }
22363
22364 test_247a() {
22365         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
22366                 grep -q subtree ||
22367                 skip_env "Fileset feature is not supported"
22368
22369         local submount=${MOUNT}_$tdir
22370
22371         mkdir $MOUNT/$tdir
22372         mkdir -p $submount || error "mkdir $submount failed"
22373         FILESET="$FILESET/$tdir" mount_client $submount ||
22374                 error "mount $submount failed"
22375         trap "cleanup_247 $submount" EXIT
22376         echo foo > $submount/$tfile || error "write $submount/$tfile failed"
22377         [ $(cat $MOUNT/$tdir/$tfile) = "foo" ] ||
22378                 error "read $MOUNT/$tdir/$tfile failed"
22379         cleanup_247 $submount
22380 }
22381 run_test 247a "mount subdir as fileset"
22382
22383 test_247b() {
22384         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
22385                 skip_env "Fileset feature is not supported"
22386
22387         local submount=${MOUNT}_$tdir
22388
22389         rm -rf $MOUNT/$tdir
22390         mkdir -p $submount || error "mkdir $submount failed"
22391         SKIP_FILESET=1
22392         FILESET="$FILESET/$tdir" mount_client $submount &&
22393                 error "mount $submount should fail"
22394         rmdir $submount
22395 }
22396 run_test 247b "mount subdir that dose not exist"
22397
22398 test_247c() {
22399         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
22400                 skip_env "Fileset feature is not supported"
22401
22402         local submount=${MOUNT}_$tdir
22403
22404         mkdir -p $MOUNT/$tdir/dir1
22405         mkdir -p $submount || error "mkdir $submount failed"
22406         trap "cleanup_247 $submount" EXIT
22407         FILESET="$FILESET/$tdir" mount_client $submount ||
22408                 error "mount $submount failed"
22409         local fid=$($LFS path2fid $MOUNT/)
22410         $LFS fid2path $submount $fid && error "fid2path should fail"
22411         cleanup_247 $submount
22412 }
22413 run_test 247c "running fid2path outside subdirectory root"
22414
22415 test_247d() {
22416         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
22417                 skip "Fileset feature is not supported"
22418
22419         local submount=${MOUNT}_$tdir
22420
22421         mkdir -p $MOUNT/$tdir/dir1
22422         mkdir -p $submount || error "mkdir $submount failed"
22423         FILESET="$FILESET/$tdir" mount_client $submount ||
22424                 error "mount $submount failed"
22425         trap "cleanup_247 $submount" EXIT
22426
22427         local td=$submount/dir1
22428         local fid=$($LFS path2fid $td)
22429         [ -z "$fid" ] && error "path2fid unable to get $td FID"
22430
22431         # check that we get the same pathname back
22432         local rootpath
22433         local found
22434         for rootpath in "$submount" "$submount///" "$submount/dir1"; do
22435                 echo "$rootpath $fid"
22436                 found=$($LFS fid2path $rootpath "$fid")
22437                 [ -n "$found" ] || error "fid2path should succeed"
22438                 [ "$found" == "$td" ] || error "fid2path $found != $td"
22439         done
22440         # check wrong root path format
22441         rootpath=$submount"_wrong"
22442         found=$($LFS fid2path $rootpath "$fid")
22443         [ -z "$found" ] || error "fid2path should fail ($rootpath != $submount)"
22444
22445         cleanup_247 $submount
22446 }
22447 run_test 247d "running fid2path inside subdirectory root"
22448
22449 # LU-8037
22450 test_247e() {
22451         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
22452                 grep -q subtree ||
22453                 skip "Fileset feature is not supported"
22454
22455         local submount=${MOUNT}_$tdir
22456
22457         mkdir $MOUNT/$tdir
22458         mkdir -p $submount || error "mkdir $submount failed"
22459         FILESET="$FILESET/.." mount_client $submount &&
22460                 error "mount $submount should fail"
22461         rmdir $submount
22462 }
22463 run_test 247e "mount .. as fileset"
22464
22465 test_247f() {
22466         (( $MDSCOUNT > 1 )) || skip_env "needs >= 2 MDTs"
22467         (( $MDS1_VERSION >= $(version_code 2.14.50.162) )) ||
22468                 skip "Need at least version 2.14.50.162"
22469         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
22470                 skip "Fileset feature is not supported"
22471
22472         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
22473         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote ||
22474                 error "mkdir remote failed"
22475         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote/subdir ||
22476                 error "mkdir remote/subdir failed"
22477         $LFS mkdir -i 0 -c $MDSCOUNT $DIR/$tdir/striped ||
22478                 error "mkdir striped failed"
22479         mkdir $DIR/$tdir/striped/subdir || error "mkdir striped/subdir failed"
22480
22481         local submount=${MOUNT}_$tdir
22482
22483         mkdir -p $submount || error "mkdir $submount failed"
22484         stack_trap "rmdir $submount"
22485
22486         local dir
22487         local fileset=$FILESET
22488         local mdts=$(comma_list $(mdts_nodes))
22489
22490         do_nodes $mdts "$LCTL set_param mdt.*.enable_remote_subdir_mount=1"
22491         for dir in $tdir/remote $tdir/remote/subdir $tdir/striped \
22492                 $tdir/striped/subdir $tdir/striped/.; do
22493                 FILESET="$fileset/$dir" mount_client $submount ||
22494                         error "mount $dir failed"
22495                 umount_client $submount
22496         done
22497 }
22498 run_test 247f "mount striped or remote directory as fileset"
22499
22500 test_subdir_mount_lock()
22501 {
22502         local testdir=$1
22503         local submount=${MOUNT}_$(basename $testdir)
22504
22505         touch $DIR/$testdir/$tfile || error "touch $tfile failed"
22506
22507         mkdir -p $submount || error "mkdir $submount failed"
22508         stack_trap "rmdir $submount"
22509
22510         FILESET="$fileset/$testdir" mount_client $submount ||
22511                 error "mount $FILESET failed"
22512         stack_trap "umount $submount"
22513
22514         local mdts=$(comma_list $(mdts_nodes))
22515
22516         local nrpcs
22517
22518         stat $submount > /dev/null || error "stat $submount failed"
22519         cancel_lru_locks $MDC
22520         stat $submount > /dev/null || error "stat $submount failed"
22521         stat $submount/$tfile > /dev/null || error "stat $tfile failed"
22522         do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear > /dev/null"
22523         stat $submount/$tfile > /dev/null || error "stat $tfile failed"
22524         nrpcs=$(do_nodes $mdts "lctl get_param -n mdt.*.md_stats" |
22525                 awk '/getattr/ {sum += $2} END {print sum}')
22526
22527         [ -z "$nrpcs" ] || error "$nrpcs extra getattr sent"
22528 }
22529
22530 test_247g() {
22531         (( $MDSCOUNT > 1 )) || skip_env "needs > 1 MDTs"
22532
22533         $LFS mkdir -i 0 -c 4 -H fnv_1a_64 $DIR/$tdir ||
22534                 error "mkdir $tdir failed"
22535         test_subdir_mount_lock $tdir
22536 }
22537 run_test 247g "striped directory submount revalidate ROOT from cache"
22538
22539 test_247h() {
22540         (( $MDSCOUNT > 1 )) || skip_env "needs > 1 MDTs"
22541         (( $MDS1_VERSION >= $(version_code 2.15.51) )) ||
22542                 skip "Need MDS version at least 2.15.51"
22543
22544         $LFS mkdir -i 1 -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
22545         test_subdir_mount_lock $tdir
22546         mkdir_on_mdt -i 0 $DIR/$tdir/$tdir.0 || error "mkdir $tdir.0 failed"
22547         mkdir_on_mdt -i 1 $DIR/$tdir/$tdir.0/$tdir.1 ||
22548                 error "mkdir $tdir.1 failed"
22549         test_subdir_mount_lock $tdir/$tdir.0/$tdir.1
22550 }
22551 run_test 247h "remote directory submount revalidate ROOT from cache"
22552
22553 test_248a() {
22554         local fast_read_sav=$($LCTL get_param -n llite.*.fast_read 2>/dev/null)
22555         [ -z "$fast_read_sav" ] && skip "no fast read support"
22556
22557         # create a large file for fast read verification
22558         dd if=/dev/zero of=$DIR/$tfile bs=1M count=128 > /dev/null 2>&1
22559
22560         # make sure the file is created correctly
22561         $CHECKSTAT -s $((128*1024*1024)) $DIR/$tfile ||
22562                 { rm -f $DIR/$tfile; skip "file creation error"; }
22563
22564         echo "Test 1: verify that fast read is 4 times faster on cache read"
22565
22566         # small read with fast read enabled
22567         $LCTL set_param -n llite.*.fast_read=1
22568         local t_fast=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
22569                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
22570                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
22571         # small read with fast read disabled
22572         $LCTL set_param -n llite.*.fast_read=0
22573         local t_slow=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
22574                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
22575                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
22576
22577         # verify that fast read is 4 times faster for cache read
22578         [ $(bc <<< "4 * $t_fast < $t_slow") -eq 1 ] ||
22579                 error_not_in_vm "fast read was not 4 times faster: " \
22580                            "$t_fast vs $t_slow"
22581
22582         echo "Test 2: verify the performance between big and small read"
22583         $LCTL set_param -n llite.*.fast_read=1
22584
22585         # 1k non-cache read
22586         cancel_lru_locks osc
22587         local t_1k=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
22588                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
22589                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
22590
22591         # 1M non-cache read
22592         cancel_lru_locks osc
22593         local t_1m=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
22594                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
22595                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
22596
22597         # verify that big IO is not 4 times faster than small IO
22598         [ $(bc <<< "4 * $t_1k >= $t_1m") -eq 1 ] ||
22599                 error_not_in_vm "bigger IO is way too fast: $t_1k vs $t_1m"
22600
22601         $LCTL set_param -n llite.*.fast_read=$fast_read_sav
22602         rm -f $DIR/$tfile
22603 }
22604 run_test 248a "fast read verification"
22605
22606 test_248b() {
22607         # Default short_io_bytes=16384, try both smaller and larger sizes.
22608         # Lustre O_DIRECT read and write needs to be a multiple of PAGE_SIZE.
22609         # 6017024 = 2^12*13*113 = 47008*128 = 11752*512 = 4096*1469 = 53248*113
22610         echo "bs=53248 count=113 normal buffered write"
22611         dd if=/dev/urandom of=$TMP/$tfile.0 bs=53248 count=113 ||
22612                 error "dd of initial data file failed"
22613         stack_trap "rm -f $DIR/$tfile.[0-3] $TMP/$tfile.[0-3]" EXIT
22614
22615         echo "bs=47008 count=128 oflag=dsync normal write $tfile.0"
22616         dd if=$TMP/$tfile.0 of=$DIR/$tfile.0 bs=47008 count=128 oflag=dsync ||
22617                 error "dd with sync normal writes failed"
22618         cmp $TMP/$tfile.0 $DIR/$tfile.0 || error "compare $DIR/$tfile.0 failed"
22619
22620         echo "bs=11752 count=512 oflag=dsync small write $tfile.1"
22621         dd if=$TMP/$tfile.0 of=$DIR/$tfile.1 bs=11752 count=512 oflag=dsync ||
22622                 error "dd with sync small writes failed"
22623         cmp $TMP/$tfile.0 $DIR/$tfile.1 || error "compare $DIR/$tfile.1 failed"
22624
22625         cancel_lru_locks osc
22626
22627         # calculate the small O_DIRECT size and count for the client PAGE_SIZE
22628         local num=$((13 * 113 / (PAGE_SIZE / 4096)))
22629         echo "bs=$PAGE_SIZE count=$num iflag=direct small read $tfile.1"
22630         dd if=$DIR/$tfile.1 of=$TMP/$tfile.1 bs=$PAGE_SIZE count=$num \
22631                 iflag=direct || error "dd with O_DIRECT small read failed"
22632         # adjust bytes checked to handle larger PAGE_SIZE for ARM/PPC
22633         cmp --bytes=$((PAGE_SIZE * num)) $TMP/$tfile.0 $TMP/$tfile.1 ||
22634                 error "compare $TMP/$tfile.1 failed"
22635
22636         local save=$($LCTL get_param -n osc.*OST000*.short_io_bytes | head -n 1)
22637         stack_trap "$LCTL set_param osc.$FSNAME-*.short_io_bytes=$save" EXIT
22638
22639         # just to see what the maximum tunable value is, and test parsing
22640         echo "test invalid parameter 2MB"
22641         $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=2M &&
22642                 error "too-large short_io_bytes allowed"
22643         echo "test maximum parameter 512KB"
22644         # if we can set a larger short_io_bytes, run test regardless of version
22645         if ! $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=512K; then
22646                 # older clients may not allow setting it this large, that's OK
22647                 [ $CLIENT_VERSION -ge $(version_code 2.13.50) ] ||
22648                         skip "Need at least client version 2.13.50"
22649                 error "medium short_io_bytes failed"
22650         fi
22651         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
22652         size=$($LCTL get_param -n osc.$FSNAME-OST0000*.short_io_bytes)
22653
22654         echo "test large parameter 64KB"
22655         $LCTL set_param osc.$FSNAME-*.short_io_bytes=65536
22656         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
22657
22658         echo "bs=47008 count=128 oflag=dsync large write $tfile.2"
22659         dd if=$TMP/$tfile.0 of=$DIR/$tfile.2 bs=47008 count=128 oflag=dsync ||
22660                 error "dd with sync large writes failed"
22661         cmp $TMP/$tfile.0 $DIR/$tfile.2 || error "compare $DIR/$tfile.2 failed"
22662
22663         # calculate the large O_DIRECT size and count for the client PAGE_SIZE
22664         local size=$(((4096 * 13 + PAGE_SIZE - 1) / PAGE_SIZE * PAGE_SIZE))
22665         num=$((113 * 4096 / PAGE_SIZE))
22666         echo "bs=$size count=$num oflag=direct large write $tfile.3"
22667         dd if=$TMP/$tfile.0 of=$DIR/$tfile.3 bs=$size count=$num oflag=direct ||
22668                 error "dd with O_DIRECT large writes failed"
22669         cmp --bytes=$((size * num)) $TMP/$tfile.0 $DIR/$tfile.3 ||
22670                 error "compare $DIR/$tfile.3 failed"
22671
22672         cancel_lru_locks osc
22673
22674         echo "bs=$size count=$num iflag=direct large read $tfile.2"
22675         dd if=$DIR/$tfile.2 of=$TMP/$tfile.2 bs=$size count=$num iflag=direct ||
22676                 error "dd with O_DIRECT large read failed"
22677         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.2 ||
22678                 error "compare $TMP/$tfile.2 failed"
22679
22680         echo "bs=$size count=$num iflag=direct large read $tfile.3"
22681         dd if=$DIR/$tfile.3 of=$TMP/$tfile.3 bs=$size count=$num iflag=direct ||
22682                 error "dd with O_DIRECT large read failed"
22683         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.3 ||
22684                 error "compare $TMP/$tfile.3 failed"
22685 }
22686 run_test 248b "test short_io read and write for both small and large sizes"
22687
22688 test_249() { # LU-7890
22689         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
22690                 skip "Need at least version 2.8.54"
22691
22692         rm -f $DIR/$tfile
22693         $LFS setstripe -c 1 $DIR/$tfile
22694         # Offset 2T == 4k * 512M
22695         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 seek=512M ||
22696                 error "dd to 2T offset failed"
22697 }
22698 run_test 249 "Write above 2T file size"
22699
22700 test_250() {
22701         [ "$(facet_fstype ost$(($($LFS getstripe -i $DIR/$tfile) + 1)))" = "zfs" ] \
22702          && skip "no 16TB file size limit on ZFS"
22703
22704         $LFS setstripe -c 1 $DIR/$tfile
22705         # ldiskfs extent file size limit is (16TB - 4KB - 1) bytes
22706         local size=$((16 * 1024 * 1024 * 1024 * 1024 - 4096 - 1))
22707         $TRUNCATE $DIR/$tfile $size || error "truncate $tfile to $size failed"
22708         dd if=/dev/zero of=$DIR/$tfile bs=10 count=1 oflag=append \
22709                 conv=notrunc,fsync && error "append succeeded"
22710         return 0
22711 }
22712 run_test 250 "Write above 16T limit"
22713
22714 test_251() {
22715         $LFS setstripe -c -1 -S 1048576 $DIR/$tfile
22716
22717         #define OBD_FAIL_LLITE_LOST_LAYOUT 0x1407
22718         #Skip once - writing the first stripe will succeed
22719         $LCTL set_param fail_loc=0xa0001407 fail_val=1
22720         $MULTIOP $DIR/$tfile o:O_RDWR:w2097152c 2>&1 | grep -q "short write" &&
22721                 error "short write happened"
22722
22723         $LCTL set_param fail_loc=0xa0001407 fail_val=1
22724         $MULTIOP $DIR/$tfile or2097152c 2>&1 | grep -q "short read" &&
22725                 error "short read happened"
22726
22727         rm -f $DIR/$tfile
22728 }
22729 run_test 251 "Handling short read and write correctly"
22730
22731 test_252() {
22732         remote_mds_nodsh && skip "remote MDS with nodsh"
22733         remote_ost_nodsh && skip "remote OST with nodsh"
22734         if [ "$ost1_FSTYPE" != ldiskfs ] || [ "$mds1_FSTYPE" != ldiskfs ]; then
22735                 skip_env "ldiskfs only test"
22736         fi
22737
22738         local tgt
22739         local dev
22740         local out
22741         local uuid
22742         local num
22743         local gen
22744
22745         # check lr_reader on OST0000
22746         tgt=ost1
22747         dev=$(facet_device $tgt)
22748         out=$(do_facet $tgt $LR_READER $dev)
22749         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
22750         echo "$out"
22751         uuid=$(echo "$out" | grep -i uuid | awk '{ print $2 }')
22752         [ "$uuid" == "$(ostuuid_from_index 0)" ] ||
22753                 error "Invalid uuid returned by $LR_READER on target $tgt"
22754         echo -e "uuid returned by $LR_READER is '$uuid'\n"
22755
22756         # check lr_reader -c on MDT0000
22757         tgt=mds1
22758         dev=$(facet_device $tgt)
22759         if ! do_facet $tgt $LR_READER -h | grep -q OPTIONS; then
22760                 skip "$LR_READER does not support additional options"
22761         fi
22762         out=$(do_facet $tgt $LR_READER -c $dev)
22763         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
22764         echo "$out"
22765         num=$(echo "$out" | grep -c "mdtlov")
22766         [ "$num" -eq $((MDSCOUNT - 1)) ] ||
22767                 error "Invalid number of mdtlov clients returned by $LR_READER"
22768         echo -e "Number of mdtlov clients returned by $LR_READER is '$num'\n"
22769
22770         # check lr_reader -cr on MDT0000
22771         out=$(do_facet $tgt $LR_READER -cr $dev)
22772         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
22773         echo "$out"
22774         echo "$out" | grep -q "^reply_data:$" ||
22775                 error "$LR_READER should have returned 'reply_data' section"
22776         num=$(echo "$out" | grep -c "client_generation")
22777         echo -e "Number of reply data returned by $LR_READER is '$num'\n"
22778 }
22779 run_test 252 "check lr_reader tool"
22780
22781 test_253() {
22782         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22783         remote_mds_nodsh && skip "remote MDS with nodsh"
22784         remote_mgs_nodsh && skip "remote MGS with nodsh"
22785
22786         local ostidx=0
22787         local rc=0
22788         local ost_name=$(ostname_from_index $ostidx)
22789
22790         # on the mdt's osc
22791         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $ost_name)
22792         do_facet $SINGLEMDS $LCTL get_param -n \
22793                 osp.$mdtosc_proc1.reserved_mb_high ||
22794                 skip  "remote MDS does not support reserved_mb_high"
22795
22796         rm -rf $DIR/$tdir
22797         wait_mds_ost_sync
22798         wait_delete_completed
22799         mkdir $DIR/$tdir
22800         stack_trap "rm -rf $DIR/$tdir"
22801
22802         pool_add $TESTNAME || error "Pool creation failed"
22803         pool_add_targets $TESTNAME 0 || error "Pool add targets failed"
22804
22805         $LFS setstripe $DIR/$tdir -i $ostidx -c 1 -p $FSNAME.$TESTNAME ||
22806                 error "Setstripe failed"
22807
22808         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M count=10
22809
22810         local wms=$(ost_watermarks_set_enospc $tfile $ostidx |
22811                     grep "watermarks")
22812         stack_trap "ost_watermarks_clear_enospc $tfile $ostidx $wms" EXIT
22813
22814         local oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
22815                         osp.$mdtosc_proc1.prealloc_status)
22816         echo "prealloc_status $oa_status"
22817
22818         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1M count=1 &&
22819                 error "File creation should fail"
22820
22821         #object allocation was stopped, but we still able to append files
22822         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M seek=6 count=5 \
22823                 oflag=append || error "Append failed"
22824
22825         rm -f $DIR/$tdir/$tfile.0
22826
22827         # For this test, we want to delete the files we created to go out of
22828         # space but leave the watermark, so we remain nearly out of space
22829         ost_watermarks_enospc_delete_files $tfile $ostidx
22830
22831         wait_delete_completed
22832
22833         sleep_maxage
22834
22835         for i in $(seq 10 12); do
22836                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$i bs=1M count=1 \
22837                         2>/dev/null || error "File creation failed after rm"
22838         done
22839
22840         oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
22841                         osp.$mdtosc_proc1.prealloc_status)
22842         echo "prealloc_status $oa_status"
22843
22844         if (( oa_status != 0 )); then
22845                 error "Object allocation still disable after rm"
22846         fi
22847 }
22848 run_test 253 "Check object allocation limit"
22849
22850 test_254() {
22851         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22852         remote_mds_nodsh && skip "remote MDS with nodsh"
22853
22854         local mdt=$(facet_svc $SINGLEMDS)
22855
22856         do_facet $SINGLEMDS $LCTL get_param -n mdd.$mdt.changelog_size ||
22857                 skip "MDS does not support changelog_size"
22858
22859         local cl_user
22860
22861         changelog_register || error "changelog_register failed"
22862
22863         changelog_clear 0 || error "changelog_clear failed"
22864
22865         local size1=$(do_facet $SINGLEMDS \
22866                       $LCTL get_param -n mdd.$mdt.changelog_size)
22867         echo "Changelog size $size1"
22868
22869         rm -rf $DIR/$tdir
22870         $LFS mkdir -i 0 $DIR/$tdir
22871         # change something
22872         mkdir -p $DIR/$tdir/pics/2008/zachy
22873         touch $DIR/$tdir/pics/2008/zachy/timestamp
22874         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg
22875         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
22876         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
22877         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
22878         rm $DIR/$tdir/pics/desktop.jpg
22879
22880         local size2=$(do_facet $SINGLEMDS \
22881                       $LCTL get_param -n mdd.$mdt.changelog_size)
22882         echo "Changelog size after work $size2"
22883
22884         (( $size2 > $size1 )) ||
22885                 error "new Changelog size=$size2 less than old size=$size1"
22886 }
22887 run_test 254 "Check changelog size"
22888
22889 ladvise_no_type()
22890 {
22891         local type=$1
22892         local file=$2
22893
22894         lfs ladvise -a invalid $file 2>&1 | grep "Valid types" |
22895                 awk -F: '{print $2}' | grep $type > /dev/null
22896         if [ $? -ne 0 ]; then
22897                 return 0
22898         fi
22899         return 1
22900 }
22901
22902 ladvise_no_ioctl()
22903 {
22904         local file=$1
22905
22906         lfs ladvise -a willread $file > /dev/null 2>&1
22907         if [ $? -eq 0 ]; then
22908                 return 1
22909         fi
22910
22911         lfs ladvise -a willread $file 2>&1 |
22912                 grep "Inappropriate ioctl for device" > /dev/null
22913         if [ $? -eq 0 ]; then
22914                 return 0
22915         fi
22916         return 1
22917 }
22918
22919 percent() {
22920         bc <<<"scale=2; ($1 - $2) * 100 / $2"
22921 }
22922
22923 # run a random read IO workload
22924 # usage: random_read_iops <filename> <filesize> <iosize>
22925 random_read_iops() {
22926         local file=$1
22927         local fsize=$2
22928         local iosize=${3:-4096}
22929
22930         $READS -f $file -s $fsize -b $iosize -n $((fsize / iosize)) -t 60 |
22931                 sed -e '/^$/d' -e 's#.*s, ##' -e 's#MB/s##'
22932 }
22933
22934 drop_file_oss_cache() {
22935         local file="$1"
22936         local nodes="$2"
22937
22938         $LFS ladvise -a dontneed $file 2>/dev/null ||
22939                 do_nodes $nodes "echo 3 > /proc/sys/vm/drop_caches"
22940 }
22941
22942 ladvise_willread_performance()
22943 {
22944         local repeat=10
22945         local average_origin=0
22946         local average_cache=0
22947         local average_ladvise=0
22948
22949         for ((i = 1; i <= $repeat; i++)); do
22950                 echo "Iter $i/$repeat: reading without willread hint"
22951                 cancel_lru_locks osc
22952                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
22953                 local speed_origin=$(random_read_iops $DIR/$tfile $size)
22954                 echo "Iter $i/$repeat: uncached speed: $speed_origin"
22955                 average_origin=$(bc <<<"$average_origin + $speed_origin")
22956
22957                 cancel_lru_locks osc
22958                 local speed_cache=$(random_read_iops $DIR/$tfile $size)
22959                 echo "Iter $i/$repeat: OSS cache speed: $speed_cache"
22960                 average_cache=$(bc <<<"$average_cache + $speed_cache")
22961
22962                 cancel_lru_locks osc
22963                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
22964                 $LFS ladvise -a willread $DIR/$tfile || error "ladvise failed"
22965                 local speed_ladvise=$(random_read_iops $DIR/$tfile $size)
22966                 echo "Iter $i/$repeat: ladvise speed: $speed_ladvise"
22967                 average_ladvise=$(bc <<<"$average_ladvise + $speed_ladvise")
22968         done
22969         average_origin=$(bc <<<"scale=2; $average_origin / $repeat")
22970         average_cache=$(bc <<<"scale=2; $average_cache / $repeat")
22971         average_ladvise=$(bc <<<"scale=2; $average_ladvise / $repeat")
22972
22973         speedup_cache=$(percent $average_cache $average_origin)
22974         speedup_ladvise=$(percent $average_ladvise $average_origin)
22975
22976         echo "Average uncached read: $average_origin"
22977         echo "Average speedup with OSS cached read: " \
22978                 "$average_cache = +$speedup_cache%"
22979         echo "Average speedup with ladvise willread: " \
22980                 "$average_ladvise = +$speedup_ladvise%"
22981
22982         local lowest_speedup=20
22983         if (( ${average_cache%.*} < $lowest_speedup )); then
22984                 echo "Speedup with OSS cached read less than $lowest_speedup%,"\
22985                      " got $average_cache%. Skipping ladvise willread check."
22986                 return 0
22987         fi
22988
22989         # the test won't work on ZFS until it supports 'ladvise dontneed', but
22990         # it is still good to run until then to exercise 'ladvise willread'
22991         ! $LFS ladvise -a dontneed $DIR/$tfile &&
22992                 [ "$ost1_FSTYPE" = "zfs" ] &&
22993                 echo "osd-zfs does not support dontneed or drop_caches" &&
22994                 return 0
22995
22996         lowest_speedup=$(bc <<<"scale=2; $average_cache / 2")
22997         (( ${average_ladvise%.*} > ${lowest_speedup%.*} )) ||
22998                 error_not_in_vm "Speedup with willread is less than " \
22999                         "$lowest_speedup%, got $average_ladvise%"
23000 }
23001
23002 test_255a() {
23003         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
23004                 skip "lustre < 2.8.54 does not support ladvise "
23005         remote_ost_nodsh && skip "remote OST with nodsh"
23006
23007         stack_trap "rm -f $DIR/$tfile"
23008         lfs setstripe -c -1 -i 0 $DIR/$tfile || error "$tfile failed"
23009
23010         ladvise_no_type willread $DIR/$tfile &&
23011                 skip "willread ladvise is not supported"
23012
23013         ladvise_no_ioctl $DIR/$tfile &&
23014                 skip "ladvise ioctl is not supported"
23015
23016         local size_mb=100
23017         local size=$((size_mb * 1048576))
23018         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
23019                 error "dd to $DIR/$tfile failed"
23020
23021         lfs ladvise -a willread $DIR/$tfile ||
23022                 error "Ladvise failed with no range argument"
23023
23024         lfs ladvise -a willread -s 0 $DIR/$tfile ||
23025                 error "Ladvise failed with no -l or -e argument"
23026
23027         lfs ladvise -a willread -e 1 $DIR/$tfile ||
23028                 error "Ladvise failed with only -e argument"
23029
23030         lfs ladvise -a willread -l 1 $DIR/$tfile ||
23031                 error "Ladvise failed with only -l argument"
23032
23033         lfs ladvise -a willread -s 2 -e 1 $DIR/$tfile &&
23034                 error "End offset should not be smaller than start offset"
23035
23036         lfs ladvise -a willread -s 2 -e 2 $DIR/$tfile &&
23037                 error "End offset should not be equal to start offset"
23038
23039         lfs ladvise -a willread -s $size -l 1 $DIR/$tfile ||
23040                 error "Ladvise failed with overflowing -s argument"
23041
23042         lfs ladvise -a willread -s 1 -e $((size + 1)) $DIR/$tfile ||
23043                 error "Ladvise failed with overflowing -e argument"
23044
23045         lfs ladvise -a willread -s 1 -l $size $DIR/$tfile ||
23046                 error "Ladvise failed with overflowing -l argument"
23047
23048         lfs ladvise -a willread -l 1 -e 2 $DIR/$tfile &&
23049                 error "Ladvise succeeded with conflicting -l and -e arguments"
23050
23051         echo "Synchronous ladvise should wait"
23052         local delay=4
23053 #define OBD_FAIL_OST_LADVISE_PAUSE       0x237
23054         do_nodes $(comma_list $(osts_nodes)) \
23055                 $LCTL set_param fail_val=$delay fail_loc=0x237
23056
23057         local start_ts=$SECONDS
23058         lfs ladvise -a willread $DIR/$tfile ||
23059                 error "Ladvise failed with no range argument"
23060         local end_ts=$SECONDS
23061         local inteval_ts=$((end_ts - start_ts))
23062
23063         if [ $inteval_ts -lt $(($delay - 1)) ]; then
23064                 error "Synchronous advice didn't wait reply"
23065         fi
23066
23067         echo "Asynchronous ladvise shouldn't wait"
23068         local start_ts=$SECONDS
23069         lfs ladvise -a willread -b $DIR/$tfile ||
23070                 error "Ladvise failed with no range argument"
23071         local end_ts=$SECONDS
23072         local inteval_ts=$((end_ts - start_ts))
23073
23074         if [ $inteval_ts -gt $(($delay / 2)) ]; then
23075                 error "Asynchronous advice blocked"
23076         fi
23077
23078         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param fail_loc=0
23079         ladvise_willread_performance
23080 }
23081 run_test 255a "check 'lfs ladvise -a willread'"
23082
23083 facet_meminfo() {
23084         local facet=$1
23085         local info=$2
23086
23087         do_facet $facet "cat /proc/meminfo | grep ^${info}:" | awk '{print $2}'
23088 }
23089
23090 test_255b() {
23091         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
23092                 skip "lustre < 2.8.54 does not support ladvise "
23093         remote_ost_nodsh && skip "remote OST with nodsh"
23094
23095         stack_trap "rm -f $DIR/$tfile"
23096         lfs setstripe -c 1 -i 0 $DIR/$tfile
23097
23098         ladvise_no_type dontneed $DIR/$tfile &&
23099                 skip "dontneed ladvise is not supported"
23100
23101         ladvise_no_ioctl $DIR/$tfile &&
23102                 skip "ladvise ioctl is not supported"
23103
23104         ! $LFS ladvise -a dontneed $DIR/$tfile &&
23105                 [ "$ost1_FSTYPE" = "zfs" ] &&
23106                 skip "zfs-osd does not support 'ladvise dontneed'"
23107
23108         local size_mb=100
23109         local size=$((size_mb * 1048576))
23110         # In order to prevent disturbance of other processes, only check 3/4
23111         # of the memory usage
23112         local kibibytes=$((size_mb * 1024 * 3 / 4))
23113
23114         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
23115                 error "dd to $DIR/$tfile failed"
23116
23117         #force write to complete before dropping OST cache & checking memory
23118         sync
23119
23120         local total=$(facet_meminfo ost1 MemTotal)
23121         echo "Total memory: $total KiB"
23122
23123         do_facet ost1 "sync && echo 3 > /proc/sys/vm/drop_caches"
23124         local before_read=$(facet_meminfo ost1 Cached)
23125         echo "Cache used before read: $before_read KiB"
23126
23127         lfs ladvise -a willread $DIR/$tfile ||
23128                 error "Ladvise willread failed"
23129         local after_read=$(facet_meminfo ost1 Cached)
23130         echo "Cache used after read: $after_read KiB"
23131
23132         lfs ladvise -a dontneed $DIR/$tfile ||
23133                 error "Ladvise dontneed again failed"
23134         local no_read=$(facet_meminfo ost1 Cached)
23135         echo "Cache used after dontneed ladvise: $no_read KiB"
23136
23137         if [ $total -lt $((before_read + kibibytes)) ]; then
23138                 echo "Memory is too small, abort checking"
23139                 return 0
23140         fi
23141
23142         if [ $((before_read + kibibytes)) -gt $after_read ]; then
23143                 error "Ladvise willread should use more memory" \
23144                         "than $kibibytes KiB"
23145         fi
23146
23147         if [ $((no_read + kibibytes)) -gt $after_read ]; then
23148                 error "Ladvise dontneed should release more memory" \
23149                         "than $kibibytes KiB"
23150         fi
23151 }
23152 run_test 255b "check 'lfs ladvise -a dontneed'"
23153
23154 test_255c() {
23155         [ $OST1_VERSION -lt $(version_code 2.10.50) ] &&
23156                 skip "lustre < 2.10.50 does not support lockahead"
23157
23158         local ost1_imp=$(get_osc_import_name client ost1)
23159         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
23160                          cut -d'.' -f2)
23161         local count
23162         local new_count
23163         local difference
23164         local i
23165         local rc
23166
23167         test_mkdir -p $DIR/$tdir
23168         $LFS setstripe -i 0 -c 1 $DIR/$tdir
23169
23170         #test 10 returns only success/failure
23171         i=10
23172         lockahead_test -d $DIR/$tdir -t $i -f $tfile
23173         rc=$?
23174         if [ $rc -eq 255 ]; then
23175                 error "Ladvise test${i} failed, ${rc}"
23176         fi
23177
23178         #test 11 counts lock enqueue requests, all others count new locks
23179         i=11
23180         count=$(do_facet ost1 \
23181                 $LCTL get_param -n ost.OSS.ost.stats)
23182         count=$(echo "$count" | grep ldlm_extent_enqueue | awk '{ print $2 }')
23183
23184         lockahead_test -d $DIR/$tdir -t $i -f $tfile
23185         rc=$?
23186         if [ $rc -eq 255 ]; then
23187                 error "Ladvise test${i} failed, ${rc}"
23188         fi
23189
23190         new_count=$(do_facet ost1 \
23191                 $LCTL get_param -n ost.OSS.ost.stats)
23192         new_count=$(echo "$new_count" | grep ldlm_extent_enqueue | \
23193                    awk '{ print $2 }')
23194
23195         difference="$((new_count - count))"
23196         if [ $difference -ne $rc ]; then
23197                 error "Ladvise test${i}, bad enqueue count, returned " \
23198                       "${rc}, actual ${difference}"
23199         fi
23200
23201         for i in $(seq 12 21); do
23202                 # If we do not do this, we run the risk of having too many
23203                 # locks and starting lock cancellation while we are checking
23204                 # lock counts.
23205                 cancel_lru_locks osc
23206
23207                 count=$($LCTL get_param -n \
23208                        ldlm.namespaces.$imp_name.lock_unused_count)
23209
23210                 lockahead_test -d $DIR/$tdir -t $i -f $tfile
23211                 rc=$?
23212                 if [ $rc -eq 255 ]; then
23213                         error "Ladvise test ${i} failed, ${rc}"
23214                 fi
23215
23216                 new_count=$($LCTL get_param -n \
23217                        ldlm.namespaces.$imp_name.lock_unused_count)
23218                 difference="$((new_count - count))"
23219
23220                 # Test 15 output is divided by 100 to map down to valid return
23221                 if [ $i -eq 15 ]; then
23222                         rc="$((rc * 100))"
23223                 fi
23224
23225                 if [ $difference -ne $rc ]; then
23226                         error "Ladvise test ${i}, bad lock count, returned " \
23227                               "${rc}, actual ${difference}"
23228                 fi
23229         done
23230
23231         #test 22 returns only success/failure
23232         i=22
23233         lockahead_test -d $DIR/$tdir -t $i -f $tfile
23234         rc=$?
23235         if [ $rc -eq 255 ]; then
23236                 error "Ladvise test${i} failed, ${rc}"
23237         fi
23238 }
23239 run_test 255c "suite of ladvise lockahead tests"
23240
23241 test_256() {
23242         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23243         remote_mds_nodsh && skip "remote MDS with nodsh"
23244         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
23245         changelog_users $SINGLEMDS | grep "^cl" &&
23246                 skip "active changelog user"
23247
23248         local cl_user
23249         local cat_sl
23250         local mdt_dev
23251
23252         mdt_dev=$(facet_device $SINGLEMDS)
23253         echo $mdt_dev
23254
23255         changelog_register || error "changelog_register failed"
23256
23257         rm -rf $DIR/$tdir
23258         mkdir_on_mdt -i$(($(facet_number $SINGLEMDS) - 1)) $DIR/$tdir
23259
23260         changelog_clear 0 || error "changelog_clear failed"
23261
23262         # change something
23263         touch $DIR/$tdir/{1..10}
23264
23265         # stop the MDT
23266         stop $SINGLEMDS || error "Fail to stop MDT"
23267
23268         # remount the MDT
23269         start $SINGLEMDS $(facet_device $SINGLEMDS) $MDS_MOUNT_OPTS ||
23270                 error "Fail to start MDT"
23271
23272         #after mount new plainllog is used
23273         touch $DIR/$tdir/{11..19}
23274         local tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
23275         stack_trap "rm -f $tmpfile"
23276         cat_sl=$(do_facet $SINGLEMDS "sync; \
23277                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
23278                  llog_reader $tmpfile | grep -c type=1064553b")
23279         do_facet $SINGLEMDS llog_reader $tmpfile
23280
23281         [ $cat_sl != 2 ] && error "Changelog catalog has $cat_sl != 2 slots"
23282
23283         changelog_clear 0 || error "changelog_clear failed"
23284
23285         cat_sl=$(do_facet $SINGLEMDS "sync; \
23286                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
23287                  llog_reader $tmpfile | grep -c type=1064553b")
23288
23289         if (( cat_sl == 2 )); then
23290                 error "Empty plain llog was not deleted from changelog catalog"
23291         elif (( cat_sl != 1 )); then
23292                 error "Active plain llog shouldn't be deleted from catalog"
23293         fi
23294 }
23295 run_test 256 "Check llog delete for empty and not full state"
23296
23297 test_257() {
23298         remote_mds_nodsh && skip "remote MDS with nodsh"
23299         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
23300                 skip "Need MDS version at least 2.8.55"
23301
23302         test_mkdir $DIR/$tdir
23303
23304         setfattr -n trusted.name1 -v value1 $DIR/$tdir ||
23305                 error "setfattr -n trusted.name1=value1 $DIR/$tdir failed"
23306         stat $DIR/$tdir
23307
23308 #define OBD_FAIL_MDS_XATTR_REP                  0x161
23309         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
23310         local facet=mds$((mdtidx + 1))
23311         set_nodes_failloc $(facet_active_host $facet) 0x80000161
23312         getfattr -n trusted.name1 $DIR/$tdir 2> /dev/null
23313
23314         stop $facet || error "stop MDS failed"
23315         start $facet $(mdsdevname $((mdtidx + 1))) $MDS_MOUNT_OPTS ||
23316                 error "start MDS fail"
23317         wait_recovery_complete $facet
23318 }
23319 run_test 257 "xattr locks are not lost"
23320
23321 # Verify we take the i_mutex when security requires it
23322 test_258a() {
23323 #define OBD_FAIL_IMUTEX_SEC 0x141c
23324         $LCTL set_param fail_loc=0x141c
23325         touch $DIR/$tfile
23326         chmod u+s $DIR/$tfile
23327         chmod a+rwx $DIR/$tfile
23328         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
23329         RC=$?
23330         if [ $RC -ne 0 ]; then
23331                 error "error, failed to take i_mutex, rc=$?"
23332         fi
23333         rm -f $DIR/$tfile
23334 }
23335 run_test 258a "verify i_mutex security behavior when suid attributes is set"
23336
23337 # Verify we do NOT take the i_mutex in the normal case
23338 test_258b() {
23339 #define OBD_FAIL_IMUTEX_NOSEC 0x141d
23340         $LCTL set_param fail_loc=0x141d
23341         touch $DIR/$tfile
23342         chmod a+rwx $DIR
23343         chmod a+rw $DIR/$tfile
23344         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
23345         RC=$?
23346         if [ $RC -ne 0 ]; then
23347                 error "error, took i_mutex unnecessarily, rc=$?"
23348         fi
23349         rm -f $DIR/$tfile
23350
23351 }
23352 run_test 258b "verify i_mutex security behavior"
23353
23354 test_259() {
23355         local file=$DIR/$tfile
23356         local before
23357         local after
23358
23359         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
23360
23361         stack_trap "rm -f $file" EXIT
23362
23363         wait_delete_completed
23364         before=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
23365         echo "before: $before"
23366
23367         $LFS setstripe -i 0 -c 1 $file
23368         dd if=/dev/zero of=$file bs=1M count=10 || error "couldn't write"
23369         sync_all_data
23370         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
23371         echo "after write: $after"
23372
23373 #define OBD_FAIL_OSD_FAIL_AT_TRUNCATE          0x2301
23374         do_facet ost1 $LCTL set_param fail_loc=0x2301
23375         $TRUNCATE $file 0
23376         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
23377         echo "after truncate: $after"
23378
23379         stop ost1
23380         do_facet ost1 $LCTL set_param fail_loc=0
23381         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
23382         sleep 2
23383         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
23384         echo "after restart: $after"
23385         [ $((after - before)) -ge $(fs_log_size ost1) ] &&
23386                 error "missing truncate?"
23387
23388         return 0
23389 }
23390 run_test 259 "crash at delayed truncate"
23391
23392 test_260() {
23393 #define OBD_FAIL_MDC_CLOSE               0x806
23394         $LCTL set_param fail_loc=0x80000806
23395         touch $DIR/$tfile
23396
23397 }
23398 run_test 260 "Check mdc_close fail"
23399
23400 ### Data-on-MDT sanity tests ###
23401 test_270a() {
23402         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23403                 skip "Need MDS version at least 2.10.55 for DoM"
23404
23405         # create DoM file
23406         local dom=$DIR/$tdir/dom_file
23407         local tmp=$DIR/$tdir/tmp_file
23408
23409         mkdir_on_mdt0 $DIR/$tdir
23410
23411         # basic checks for DoM component creation
23412         $LFS setstripe -E 1024K -E 2048K -L mdt $dom 2>/dev/null &&
23413                 error "Can set MDT layout to non-first entry"
23414
23415         $LFS setstripe -E 1024K -L mdt -E 2048K -L mdt $dom 2>/dev/null &&
23416                 error "Can define multiple entries as MDT layout"
23417
23418         $LFS setstripe -E 1M -L mdt $dom || error "Can't create DoM layout"
23419
23420         [ $($LFS getstripe -L $dom) == "mdt" ] || error "bad pattern"
23421         [ $($LFS getstripe -c $dom) == 0 ] || error "bad stripe count"
23422         [ $($LFS getstripe -S $dom) == 1048576 ] || error "bad stripe size"
23423
23424         local mdtidx=$($LFS getstripe -m $dom)
23425         local mdtname=MDT$(printf %04x $mdtidx)
23426         local facet=mds$((mdtidx + 1))
23427         local space_check=1
23428
23429         # Skip free space checks with ZFS
23430         [ "$(facet_fstype $facet)" == "zfs" ] && space_check=0
23431
23432         # write
23433         sync
23434         local size_tmp=$((65536 * 3))
23435         local mdtfree1=$(do_facet $facet \
23436                          lctl get_param -n osd*.*$mdtname.kbytesfree)
23437
23438         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
23439         # check also direct IO along write
23440         # IO size must be a multiple of PAGE_SIZE on all platforms (ARM=64KB)
23441         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
23442         sync
23443         cmp $tmp $dom || error "file data is different"
23444         [ $(stat -c%s $dom) == $size_tmp ] ||
23445                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
23446         if [ $space_check == 1 ]; then
23447                 local mdtfree2=$(do_facet $facet \
23448                                  lctl get_param -n osd*.*$mdtname.kbytesfree)
23449
23450                 # increase in usage from by $size_tmp
23451                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
23452                         error "MDT free space wrong after write: " \
23453                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
23454         fi
23455
23456         # truncate
23457         local size_dom=10000
23458
23459         $TRUNCATE $dom $size_dom
23460         [ $(stat -c%s $dom) == $size_dom ] ||
23461                 error "bad size after truncate: $(stat -c%s $dom) != $size_dom"
23462         if [ $space_check == 1 ]; then
23463                 mdtfree1=$(do_facet $facet \
23464                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23465                 # decrease in usage from $size_tmp to new $size_dom
23466                 [ $(($mdtfree1 - $mdtfree2)) -ge \
23467                   $(((size_tmp - size_dom) / 1024)) ] ||
23468                         error "MDT free space is wrong after truncate: " \
23469                               "$mdtfree1 >= $mdtfree2 + ($size_tmp - $size_dom) / 1024"
23470         fi
23471
23472         # append
23473         cat $tmp >> $dom
23474         sync
23475         size_dom=$((size_dom + size_tmp))
23476         [ $(stat -c%s $dom) == $size_dom ] ||
23477                 error "bad size after append: $(stat -c%s $dom) != $size_dom"
23478         if [ $space_check == 1 ]; then
23479                 mdtfree2=$(do_facet $facet \
23480                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23481                 # increase in usage by $size_tmp from previous
23482                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
23483                         error "MDT free space is wrong after append: " \
23484                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
23485         fi
23486
23487         # delete
23488         rm $dom
23489         if [ $space_check == 1 ]; then
23490                 mdtfree1=$(do_facet $facet \
23491                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23492                 # decrease in usage by $size_dom from previous
23493                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_dom / 1024)) ] ||
23494                         error "MDT free space is wrong after removal: " \
23495                               "$mdtfree1 >= $mdtfree2 + $size_dom/1024"
23496         fi
23497
23498         # combined striping
23499         $LFS setstripe -E 1024K -L mdt -E EOF $dom ||
23500                 error "Can't create DoM + OST striping"
23501
23502         size_tmp=2031616 # must be a multiple of PAGE_SIZE=65536 on ARM
23503         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
23504         # check also direct IO along write
23505         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
23506         sync
23507         cmp $tmp $dom || error "file data is different"
23508         [ $(stat -c%s $dom) == $size_tmp ] ||
23509                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
23510         rm $dom $tmp
23511
23512         return 0
23513 }
23514 run_test 270a "DoM: basic functionality tests"
23515
23516 test_270b() {
23517         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23518                 skip "Need MDS version at least 2.10.55"
23519
23520         local dom=$DIR/$tdir/dom_file
23521         local max_size=1048576
23522
23523         mkdir -p $DIR/$tdir
23524         $LFS setstripe -E $max_size -L mdt $dom
23525
23526         # truncate over the limit
23527         $TRUNCATE $dom $(($max_size + 1)) &&
23528                 error "successful truncate over the maximum size"
23529         # write over the limit
23530         dd if=/dev/zero of=$dom bs=$max_size seek=1 count=1 &&
23531                 error "successful write over the maximum size"
23532         # append over the limit
23533         dd if=/dev/zero of=$dom bs=$(($max_size - 3)) count=1
23534         echo "12345" >> $dom && error "successful append over the maximum size"
23535         rm $dom
23536
23537         return 0
23538 }
23539 run_test 270b "DoM: maximum size overflow checks for DoM-only file"
23540
23541 test_270c() {
23542         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23543                 skip "Need MDS version at least 2.10.55"
23544
23545         mkdir -p $DIR/$tdir
23546         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
23547
23548         # check files inherit DoM EA
23549         touch $DIR/$tdir/first
23550         [ $($LFS getstripe -L $DIR/$tdir/first) == "mdt" ] ||
23551                 error "bad pattern"
23552         [ $($LFS getstripe -c $DIR/$tdir/first) == 0 ] ||
23553                 error "bad stripe count"
23554         [ $($LFS getstripe -S $DIR/$tdir/first) == 1048576 ] ||
23555                 error "bad stripe size"
23556
23557         # check directory inherits DoM EA and uses it as default
23558         mkdir $DIR/$tdir/subdir
23559         touch $DIR/$tdir/subdir/second
23560         [ $($LFS getstripe -L $DIR/$tdir/subdir/second) == "mdt" ] ||
23561                 error "bad pattern in sub-directory"
23562         [ $($LFS getstripe -c $DIR/$tdir/subdir/second) == 0 ] ||
23563                 error "bad stripe count in sub-directory"
23564         [ $($LFS getstripe -S $DIR/$tdir/subdir/second) == 1048576 ] ||
23565                 error "bad stripe size in sub-directory"
23566         return 0
23567 }
23568 run_test 270c "DoM: DoM EA inheritance tests"
23569
23570 test_270d() {
23571         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23572                 skip "Need MDS version at least 2.10.55"
23573
23574         mkdir -p $DIR/$tdir
23575         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
23576
23577         # inherit default DoM striping
23578         mkdir $DIR/$tdir/subdir
23579         touch $DIR/$tdir/subdir/f1
23580
23581         # change default directory striping
23582         $LFS setstripe -c 1 $DIR/$tdir/subdir
23583         touch $DIR/$tdir/subdir/f2
23584         [ $($LFS getstripe -c $DIR/$tdir/subdir/f2) == 1 ] ||
23585                 error "wrong default striping in file 2"
23586         [ $($LFS getstripe -L $DIR/$tdir/subdir/f2) == "raid0" ] ||
23587                 error "bad pattern in file 2"
23588         return 0
23589 }
23590 run_test 270d "DoM: change striping from DoM to RAID0"
23591
23592 test_270e() {
23593         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23594                 skip "Need MDS version at least 2.10.55"
23595
23596         mkdir -p $DIR/$tdir/dom
23597         mkdir -p $DIR/$tdir/norm
23598         DOMFILES=20
23599         NORMFILES=10
23600         $LFS setstripe -E 1M -L mdt $DIR/$tdir/dom
23601         $LFS setstripe -i 0 -S 2M $DIR/$tdir/norm
23602
23603         createmany -o $DIR/$tdir/dom/dom- $DOMFILES
23604         createmany -o $DIR/$tdir/norm/norm- $NORMFILES
23605
23606         # find DoM files by layout
23607         NUM=$($LFS find -L mdt -type f $DIR/$tdir 2>/dev/null | wc -l)
23608         [ $NUM -eq  $DOMFILES ] ||
23609                 error "lfs find -L: found $NUM, expected $DOMFILES"
23610         echo "Test 1: lfs find 20 DOM files by layout: OK"
23611
23612         # there should be 1 dir with default DOM striping
23613         NUM=$($LFS find -L mdt -type d $DIR/$tdir 2>/dev/null | wc -l)
23614         [ $NUM -eq  1 ] ||
23615                 error "lfs find -L: found $NUM, expected 1 dir"
23616         echo "Test 2: lfs find 1 DOM dir by layout: OK"
23617
23618         # find DoM files by stripe size
23619         NUM=$($LFS find -S -1200K -type f $DIR/$tdir 2>/dev/null | wc -l)
23620         [ $NUM -eq  $DOMFILES ] ||
23621                 error "lfs find -S: found $NUM, expected $DOMFILES"
23622         echo "Test 4: lfs find 20 DOM files by stripe size: OK"
23623
23624         # find files by stripe offset except DoM files
23625         NUM=$($LFS find -i 0 -type f $DIR/$tdir 2>/dev/null | wc -l)
23626         [ $NUM -eq  $NORMFILES ] ||
23627                 error "lfs find -i: found $NUM, expected $NORMFILES"
23628         echo "Test 5: lfs find no DOM files by stripe index: OK"
23629         return 0
23630 }
23631 run_test 270e "DoM: lfs find with DoM files test"
23632
23633 test_270f() {
23634         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23635                 skip "Need MDS version at least 2.10.55"
23636
23637         local mdtname=${FSNAME}-MDT0000-mdtlov
23638         local dom=$DIR/$tdir/dom_file
23639         local dom_limit_saved=$(do_facet mds1 $LCTL get_param -n \
23640                                                 lod.$mdtname.dom_stripesize)
23641         local dom_limit=131072
23642
23643         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=$dom_limit
23644         local dom_current=$(do_facet mds1 $LCTL get_param -n \
23645                                                 lod.$mdtname.dom_stripesize)
23646         [ ${dom_limit} -eq ${dom_current} ] ||
23647                 error "Cannot change per-MDT DoM stripe limit to $dom_limit"
23648
23649         $LFS mkdir -i 0 -c 1 $DIR/$tdir
23650         $LFS setstripe -d $DIR/$tdir
23651         $LFS setstripe -E $dom_limit -L mdt $DIR/$tdir ||
23652                 error "Can't set directory default striping"
23653
23654         # exceed maximum stripe size
23655         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
23656                 error "Can't create file with $((dom_limit * 2)) DoM stripe"
23657         [ $($LFS getstripe -S $dom) -eq $((dom_limit * 2)) ] &&
23658                 error "Able to create DoM component size more than LOD limit"
23659
23660         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
23661         dom_current=$(do_facet mds1 $LCTL get_param -n \
23662                                                 lod.$mdtname.dom_stripesize)
23663         [ 0 -eq ${dom_current} ] ||
23664                 error "Can't set zero DoM stripe limit"
23665         rm $dom
23666
23667         # attempt to create DoM file on server with disabled DoM should
23668         # remove DoM entry from layout and be succeed
23669         $LFS setstripe -E $dom_limit -L mdt -E -1 $dom ||
23670                 error "Can't create DoM file (DoM is disabled)"
23671         [ $($LFS getstripe -L $dom) == "mdt" ] &&
23672                 error "File has DoM component while DoM is disabled"
23673         rm $dom
23674
23675         # attempt to create DoM file with only DoM stripe should return error
23676         $LFS setstripe -E $dom_limit -L mdt $dom &&
23677                 error "Able to create DoM-only file while DoM is disabled"
23678
23679         # too low values to be aligned with smallest stripe size 64K
23680         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=30000
23681         dom_current=$(do_facet mds1 $LCTL get_param -n \
23682                                                 lod.$mdtname.dom_stripesize)
23683         [ 30000 -eq ${dom_current} ] &&
23684                 error "Can set too small DoM stripe limit"
23685
23686         # 64K is a minimal stripe size in Lustre, expect limit of that size
23687         [ 65536 -eq ${dom_current} ] ||
23688                 error "Limit is not set to 64K but ${dom_current}"
23689
23690         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=2147483648
23691         dom_current=$(do_facet mds1 $LCTL get_param -n \
23692                                                 lod.$mdtname.dom_stripesize)
23693         echo $dom_current
23694         [ 2147483648 -eq ${dom_current} ] &&
23695                 error "Can set too large DoM stripe limit"
23696
23697         do_facet mds1 $LCTL set_param -n \
23698                                 lod.$mdtname.dom_stripesize=$((dom_limit * 2))
23699         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
23700                 error "Can't create DoM component size after limit change"
23701         do_facet mds1 $LCTL set_param -n \
23702                                 lod.$mdtname.dom_stripesize=$((dom_limit / 2))
23703         $LFS setstripe -E $dom_limit -L mdt ${dom}_big ||
23704                 error "Can't create DoM file after limit decrease"
23705         [ $($LFS getstripe -S ${dom}_big) -eq $((dom_limit / 2)) ] ||
23706                 error "Can create big DoM component after limit decrease"
23707         touch ${dom}_def ||
23708                 error "Can't create file with old default layout"
23709
23710         do_facet mds1 $LCTL set_param -n lod.*.dom_stripesize=$dom_limit_saved
23711         return 0
23712 }
23713 run_test 270f "DoM: maximum DoM stripe size checks"
23714
23715 test_270g() {
23716         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
23717                 skip "Need MDS version at least 2.13.52"
23718         local dom=$DIR/$tdir/$tfile
23719
23720         $LFS mkdir -i 0 -c 1 $DIR/$tdir
23721         local lodname=${FSNAME}-MDT0000-mdtlov
23722
23723         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
23724         save_lustre_params mds1 "lod.${lodname}.dom_stripesize_max_kb" > $save
23725         save_lustre_params mds1 "lod.${lodname}.dom_threshold_free_mb" >> $save
23726         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
23727
23728         local dom_limit=1024
23729         local dom_threshold="50%"
23730
23731         $LFS setstripe -d $DIR/$tdir
23732         $LFS setstripe -E ${dom_limit}K -L mdt $DIR/$tdir ||
23733                 error "Can't set directory default striping"
23734
23735         do_facet mds1 $LCTL set_param -n \
23736                                 lod.${lodname}.dom_stripesize_max_kb=$dom_limit
23737         # set 0 threshold and create DOM file to change tunable stripesize
23738         do_facet mds1 $LCTL set_param -n lod.${lodname}.dom_threshold_free_mb=0
23739         $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
23740                 error "Failed to create $dom file"
23741         # now tunable dom_cur_stripesize should reach maximum
23742         local dom_current=$(do_facet mds1 $LCTL get_param -n \
23743                                         lod.${lodname}.dom_stripesize_cur_kb)
23744         [[ $dom_current == $dom_limit ]] ||
23745                 error "Current DOM stripesize is not maximum"
23746         rm $dom
23747
23748         # set threshold for further tests
23749         do_facet mds1 $LCTL set_param -n \
23750                         lod.${lodname}.dom_threshold_free_mb=$dom_threshold
23751         echo "DOM threshold is $dom_threshold free space"
23752         local dom_def
23753         local dom_set
23754         # Spoof bfree to exceed threshold
23755         #define OBD_FAIL_MDS_STATFS_SPOOF   0x168
23756         do_facet mds1 $LCTL set_param -n fail_loc=0x0168
23757         for spfree in 40 20 0 15 30 55; do
23758                 do_facet mds1 $LCTL set_param -n fail_val=$spfree
23759                 $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
23760                         error "Failed to create $dom file"
23761                 dom_def=$(do_facet mds1 $LCTL get_param -n \
23762                                         lod.${lodname}.dom_stripesize_cur_kb)
23763                 echo "Free space: ${spfree}%, default DOM stripe: ${dom_def}K"
23764                 [[ $dom_def != $dom_current ]] ||
23765                         error "Default stripe size was not changed"
23766                 if (( spfree > 0 )) ; then
23767                         dom_set=$($LFS getstripe -S $dom)
23768                         (( dom_set == dom_def * 1024 )) ||
23769                                 error "DOM component size is still old"
23770                 else
23771                         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
23772                                 error "DoM component is set with no free space"
23773                 fi
23774                 rm $dom
23775                 dom_current=$dom_def
23776         done
23777 }
23778 run_test 270g "DoM: default DoM stripe size depends on free space"
23779
23780 test_270h() {
23781         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
23782                 skip "Need MDS version at least 2.13.53"
23783
23784         local mdtname=${FSNAME}-MDT0000-mdtlov
23785         local dom=$DIR/$tdir/$tfile
23786         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
23787
23788         save_lustre_params mds1 "lod.*.dom_stripesize" > $save
23789         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
23790
23791         $LFS mkdir -i 0 -c 1 $DIR/$tdir
23792         $LFS setstripe -E 1M -c1  -E -1 -c2 ${dom}_1 ||
23793                 error "can't create OST file"
23794         # mirrored file with DOM entry in the second mirror
23795         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 ${dom}_1 ||
23796                 error "can't create mirror with DoM component"
23797
23798         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
23799
23800         # DOM component in the middle and has other enries in the same mirror,
23801         # should succeed but lost DoM component
23802         $LFS setstripe --copy=${dom}_1 $dom ||
23803                 error "Can't create file from OST|DOM mirror layout"
23804         # check new file has no DoM layout after all
23805         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
23806                 error "File has DoM component while DoM is disabled"
23807 }
23808 run_test 270h "DoM: DoM stripe removal when disabled on server"
23809
23810 test_270i() {
23811         (( $MDS1_VERSION >= $(version_code 2.14.54) )) ||
23812                 skip "Need MDS version at least 2.14.54"
23813
23814         mkdir $DIR/$tdir
23815         # DoM with plain layout
23816         $LFS setstripe -L mdt -S 128k -c -1 $DIR/$tdir &&
23817                 error "default plain layout with DoM must fail"
23818         $LFS setstripe -L mdt -S 128k -c -1 $DIR/$tdir/$tfile &&
23819                 error "setstripe plain file layout with DoM must fail"
23820         $LFS setstripe -E 1M -L mdt -S 128k -c -1 -E eof $DIR/$tdir &&
23821                 error "default DoM layout with bad striping must fail"
23822         $LFS setstripe -E 1M -L mdt -S 128k -c -1 -E eof $DIR/$tdir/$tfile &&
23823                 error "setstripe to DoM layout with bad striping must fail"
23824         return 0
23825 }
23826 run_test 270i "DoM: setting invalid DoM striping should fail"
23827
23828 test_271a() {
23829         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23830                 skip "Need MDS version at least 2.10.55"
23831
23832         local dom=$DIR/$tdir/dom
23833
23834         mkdir -p $DIR/$tdir
23835
23836         $LFS setstripe -E 1024K -L mdt $dom
23837
23838         lctl set_param -n mdc.*.stats=clear
23839         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
23840         cat $dom > /dev/null
23841         local reads=$(lctl get_param -n mdc.*.stats | grep -c ost_read)
23842         [ $reads -eq 0 ] || error "Unexpected $reads READ RPCs"
23843         ls $dom
23844         rm -f $dom
23845 }
23846 run_test 271a "DoM: data is cached for read after write"
23847
23848 test_271b() {
23849         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23850                 skip "Need MDS version at least 2.10.55"
23851
23852         local dom=$DIR/$tdir/dom
23853
23854         mkdir -p $DIR/$tdir
23855
23856         $LFS setstripe -E 1024K -L mdt -E EOF $dom
23857
23858         lctl set_param -n mdc.*.stats=clear
23859         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
23860         cancel_lru_locks mdc
23861         $CHECKSTAT -t file -s 4096 $dom || error "stat #1 fails"
23862         # second stat to check size is cached on client
23863         $CHECKSTAT -t file -s 4096 $dom || error "stat #2 fails"
23864         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
23865         [ $gls -eq 0 ] || error "Unexpected $gls glimpse RPCs"
23866         rm -f $dom
23867 }
23868 run_test 271b "DoM: no glimpse RPC for stat (DoM only file)"
23869
23870 test_271ba() {
23871         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23872                 skip "Need MDS version at least 2.10.55"
23873
23874         local dom=$DIR/$tdir/dom
23875
23876         mkdir -p $DIR/$tdir
23877
23878         $LFS setstripe -E 1024K -L mdt -E EOF $dom
23879
23880         lctl set_param -n mdc.*.stats=clear
23881         lctl set_param -n osc.*.stats=clear
23882         dd if=/dev/zero of=$dom bs=2048K count=1 || return 1
23883         cancel_lru_locks mdc
23884         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
23885         # second stat to check size is cached on client
23886         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
23887         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
23888         [ $gls == 0 ] || error "Unexpected $gls glimpse RPCs"
23889         local gls=$(lctl get_param -n osc.*.stats | grep -c ldlm_glimpse)
23890         [ $gls == 0 ] || error "Unexpected $gls OSC glimpse RPCs"
23891         rm -f $dom
23892 }
23893 run_test 271ba "DoM: no glimpse RPC for stat (combined file)"
23894
23895
23896 get_mdc_stats() {
23897         local mdtidx=$1
23898         local param=$2
23899         local mdt=MDT$(printf %04x $mdtidx)
23900
23901         if [ -z $param ]; then
23902                 lctl get_param -n mdc.*$mdt*.stats
23903         else
23904                 lctl get_param -n mdc.*$mdt*.stats | awk "/$param/"'{print $2}'
23905         fi
23906 }
23907
23908 test_271c() {
23909         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23910                 skip "Need MDS version at least 2.10.55"
23911
23912         local dom=$DIR/$tdir/dom
23913
23914         mkdir -p $DIR/$tdir
23915
23916         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
23917
23918         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
23919         local facet=mds$((mdtidx + 1))
23920
23921         cancel_lru_locks mdc
23922         do_facet $facet lctl set_param -n mdt.*.dom_lock=0
23923         createmany -o $dom 1000
23924         lctl set_param -n mdc.*.stats=clear
23925         smalliomany -w $dom 1000 200
23926         get_mdc_stats $mdtidx
23927         local enq=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
23928         # Each file has 1 open, 1 IO enqueues, total 2000
23929         # but now we have also +1 getxattr for security.capability, total 3000
23930         [ $enq -ge 2000 ] || error "Too few enqueues $enq, expected > 2000"
23931         unlinkmany $dom 1000
23932
23933         cancel_lru_locks mdc
23934         do_facet $facet lctl set_param -n mdt.*.dom_lock=1
23935         createmany -o $dom 1000
23936         lctl set_param -n mdc.*.stats=clear
23937         smalliomany -w $dom 1000 200
23938         local enq_2=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
23939         # Expect to see reduced amount of RPCs by 1000 due to single enqueue
23940         # for OPEN and IO lock.
23941         [ $((enq - enq_2)) -ge 1000 ] ||
23942                 error "Too many enqueues $enq_2, expected about $((enq - 1000))"
23943         unlinkmany $dom 1000
23944         return 0
23945 }
23946 run_test 271c "DoM: IO lock at open saves enqueue RPCs"
23947
23948 cleanup_271def_tests() {
23949         trap 0
23950         rm -f $1
23951 }
23952
23953 test_271d() {
23954         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
23955                 skip "Need MDS version at least 2.10.57"
23956
23957         local dom=$DIR/$tdir/dom
23958         local tmp=$TMP/$tfile
23959         trap "cleanup_271def_tests $tmp" EXIT
23960
23961         mkdir -p $DIR/$tdir
23962
23963         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
23964
23965         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
23966
23967         cancel_lru_locks mdc
23968         dd if=/dev/urandom of=$tmp bs=1000 count=1
23969         dd if=$tmp of=$dom bs=1000 count=1
23970         cancel_lru_locks mdc
23971
23972         cat /etc/hosts >> $tmp
23973         lctl set_param -n mdc.*.stats=clear
23974
23975         # append data to the same file it should update local page
23976         echo "Append to the same page"
23977         cat /etc/hosts >> $dom
23978         local num=$(get_mdc_stats $mdtidx ost_read)
23979         local ra=$(get_mdc_stats $mdtidx req_active)
23980         local rw=$(get_mdc_stats $mdtidx req_waittime)
23981
23982         [ -z $num ] || error "$num READ RPC occured"
23983         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
23984         echo "... DONE"
23985
23986         # compare content
23987         cmp $tmp $dom || error "file miscompare"
23988
23989         cancel_lru_locks mdc
23990         lctl set_param -n mdc.*.stats=clear
23991
23992         echo "Open and read file"
23993         cat $dom > /dev/null
23994         local num=$(get_mdc_stats $mdtidx ost_read)
23995         local ra=$(get_mdc_stats $mdtidx req_active)
23996         local rw=$(get_mdc_stats $mdtidx req_waittime)
23997
23998         [ -z $num ] || error "$num READ RPC occured"
23999         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
24000         echo "... DONE"
24001
24002         # compare content
24003         cmp $tmp $dom || error "file miscompare"
24004
24005         return 0
24006 }
24007 run_test 271d "DoM: read on open (1K file in reply buffer)"
24008
24009 test_271f() {
24010         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
24011                 skip "Need MDS version at least 2.10.57"
24012
24013         local dom=$DIR/$tdir/dom
24014         local tmp=$TMP/$tfile
24015         trap "cleanup_271def_tests $tmp" EXIT
24016
24017         mkdir -p $DIR/$tdir
24018
24019         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
24020
24021         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
24022
24023         cancel_lru_locks mdc
24024         dd if=/dev/urandom of=$tmp bs=265000 count=1
24025         dd if=$tmp of=$dom bs=265000 count=1
24026         cancel_lru_locks mdc
24027         cat /etc/hosts >> $tmp
24028         lctl set_param -n mdc.*.stats=clear
24029
24030         echo "Append to the same page"
24031         cat /etc/hosts >> $dom
24032         local num=$(get_mdc_stats $mdtidx ost_read)
24033         local ra=$(get_mdc_stats $mdtidx req_active)
24034         local rw=$(get_mdc_stats $mdtidx req_waittime)
24035
24036         [ -z $num ] || error "$num READ RPC occured"
24037         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
24038         echo "... DONE"
24039
24040         # compare content
24041         cmp $tmp $dom || error "file miscompare"
24042
24043         cancel_lru_locks mdc
24044         lctl set_param -n mdc.*.stats=clear
24045
24046         echo "Open and read file"
24047         cat $dom > /dev/null
24048         local num=$(get_mdc_stats $mdtidx ost_read)
24049         local ra=$(get_mdc_stats $mdtidx req_active)
24050         local rw=$(get_mdc_stats $mdtidx req_waittime)
24051
24052         [ -z $num ] && num=0
24053         [ $num -eq 1 ] || error "expect 1 READ RPC, $num occured"
24054         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
24055         echo "... DONE"
24056
24057         # compare content
24058         cmp $tmp $dom || error "file miscompare"
24059
24060         return 0
24061 }
24062 run_test 271f "DoM: read on open (200K file and read tail)"
24063
24064 test_271g() {
24065         [[ $($LCTL get_param mdc.*.import) =~ async_discard ]] ||
24066                 skip "Skipping due to old client or server version"
24067
24068         $LFS setstripe -E 1024K -L mdt -E EOF $DIR1/$tfile
24069         # to get layout
24070         $CHECKSTAT -t file $DIR1/$tfile
24071
24072         $MULTIOP $DIR1/$tfile Ow40960_w4096c &
24073         MULTIOP_PID=$!
24074         sleep 1
24075         #define OBD_FAIL_LDLM_CANCEL_BL_CB_RACE
24076         $LCTL set_param fail_loc=0x80000314
24077         rm $DIR1/$tfile || error "Unlink fails"
24078         RC=$?
24079         kill -USR1 $MULTIOP_PID && wait $MULTIOP_PID || error "multiop failure"
24080         [ $RC -eq 0 ] || error "Failed write to stale object"
24081 }
24082 run_test 271g "Discard DoM data vs client flush race"
24083
24084 test_272a() {
24085         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
24086                 skip "Need MDS version at least 2.11.50"
24087
24088         local dom=$DIR/$tdir/dom
24089         mkdir -p $DIR/$tdir
24090
24091         $LFS setstripe -E 256K -L mdt -E -1 -c1 $dom
24092         dd if=/dev/urandom of=$dom bs=512K count=1 ||
24093                 error "failed to write data into $dom"
24094         local old_md5=$(md5sum $dom)
24095
24096         $LFS migrate -E 256K -L mdt -E -1 -c2 $dom ||
24097                 error "failed to migrate to the same DoM component"
24098
24099         local new_md5=$(md5sum $dom)
24100
24101         [ "$old_md5" == "$new_md5" ] ||
24102                 error "md5sum differ: $old_md5, $new_md5"
24103
24104         [ $($LFS getstripe -c $dom) -eq 2 ] ||
24105                 error "bad final stripe count: $($LFS getstripe -c $dom) != 2"
24106 }
24107 run_test 272a "DoM migration: new layout with the same DOM component"
24108
24109 test_272b() {
24110         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
24111                 skip "Need MDS version at least 2.11.50"
24112
24113         local dom=$DIR/$tdir/dom
24114         mkdir -p $DIR/$tdir
24115         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
24116         stack_trap "rm -rf $DIR/$tdir"
24117
24118         local mdtidx=$($LFS getstripe -m $dom)
24119         local mdtname=MDT$(printf %04x $mdtidx)
24120         local facet=mds$((mdtidx + 1))
24121
24122         local mdtfree1=$(do_facet $facet \
24123                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24124         dd if=/dev/urandom of=$dom bs=2M count=1 ||
24125                 error "failed to write data into $dom"
24126         local old_md5=$(md5sum $dom)
24127         cancel_lru_locks mdc
24128         local mdtfree1=$(do_facet $facet \
24129                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24130
24131         $LFS migrate -c2 $dom ||
24132                 error "failed to migrate to the new composite layout"
24133         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
24134                 error "MDT stripe was not removed"
24135
24136         cancel_lru_locks mdc
24137         local new_md5=$(md5sum $dom)
24138         [ "$old_md5" == "$new_md5" ] ||
24139                 error "$old_md5 != $new_md5"
24140
24141         # Skip free space checks with ZFS
24142         if [ "$(facet_fstype $facet)" != "zfs" ]; then
24143                 local mdtfree2=$(do_facet $facet \
24144                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24145                 [ $mdtfree2 -gt $mdtfree1 ] ||
24146                         error "MDT space is not freed after migration"
24147         fi
24148         return 0
24149 }
24150 run_test 272b "DoM migration: DOM file to the OST-striped file (plain)"
24151
24152 test_272c() {
24153         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
24154                 skip "Need MDS version at least 2.11.50"
24155
24156         local dom=$DIR/$tdir/$tfile
24157         mkdir -p $DIR/$tdir
24158         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
24159         stack_trap "rm -rf $DIR/$tdir"
24160
24161         local mdtidx=$($LFS getstripe -m $dom)
24162         local mdtname=MDT$(printf %04x $mdtidx)
24163         local facet=mds$((mdtidx + 1))
24164
24165         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
24166                 error "failed to write data into $dom"
24167         local old_md5=$(md5sum $dom)
24168         cancel_lru_locks mdc
24169         local mdtfree1=$(do_facet $facet \
24170                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24171
24172         $LFS migrate -E 2M -c1 -E -1 -c2 $dom ||
24173                 error "failed to migrate to the new composite layout"
24174         [ $($LFS getstripe -L $dom) == 'mdt' ] &&
24175                 error "MDT stripe was not removed"
24176
24177         cancel_lru_locks mdc
24178         local new_md5=$(md5sum $dom)
24179         [ "$old_md5" == "$new_md5" ] ||
24180                 error "$old_md5 != $new_md5"
24181
24182         # Skip free space checks with ZFS
24183         if [ "$(facet_fstype $facet)" != "zfs" ]; then
24184                 local mdtfree2=$(do_facet $facet \
24185                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24186                 [ $mdtfree2 -gt $mdtfree1 ] ||
24187                         error "MDS space is not freed after migration"
24188         fi
24189         return 0
24190 }
24191 run_test 272c "DoM migration: DOM file to the OST-striped file (composite)"
24192
24193 test_272d() {
24194         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
24195                 skip "Need MDS version at least 2.12.55"
24196
24197         local dom=$DIR/$tdir/$tfile
24198         mkdir -p $DIR/$tdir
24199         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
24200
24201         local mdtidx=$($LFS getstripe -m $dom)
24202         local mdtname=MDT$(printf %04x $mdtidx)
24203         local facet=mds$((mdtidx + 1))
24204
24205         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
24206                 error "failed to write data into $dom"
24207         local old_md5=$(md5sum $dom)
24208         cancel_lru_locks mdc
24209         local mdtfree1=$(do_facet $facet \
24210                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24211
24212         $LFS mirror extend -N -E 2M -c1 -E -1 -c2 $dom ||
24213                 error "failed mirroring to the new composite layout"
24214         $LFS mirror resync $dom ||
24215                 error "failed mirror resync"
24216         $LFS mirror split --mirror-id 1 -d $dom ||
24217                 error "failed mirror split"
24218
24219         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
24220                 error "MDT stripe was not removed"
24221
24222         cancel_lru_locks mdc
24223         local new_md5=$(md5sum $dom)
24224         [ "$old_md5" == "$new_md5" ] ||
24225                 error "$old_md5 != $new_md5"
24226
24227         # Skip free space checks with ZFS
24228         if [ "$(facet_fstype $facet)" != "zfs" ]; then
24229                 local mdtfree2=$(do_facet $facet \
24230                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24231                 [ $mdtfree2 -gt $mdtfree1 ] ||
24232                         error "MDS space is not freed after DOM mirror deletion"
24233         fi
24234         return 0
24235 }
24236 run_test 272d "DoM mirroring: OST-striped mirror to DOM file"
24237
24238 test_272e() {
24239         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
24240                 skip "Need MDS version at least 2.12.55"
24241
24242         local dom=$DIR/$tdir/$tfile
24243         mkdir -p $DIR/$tdir
24244         $LFS setstripe -c 2 $dom
24245
24246         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
24247                 error "failed to write data into $dom"
24248         local old_md5=$(md5sum $dom)
24249         cancel_lru_locks
24250
24251         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 $dom ||
24252                 error "failed mirroring to the DOM layout"
24253         $LFS mirror resync $dom ||
24254                 error "failed mirror resync"
24255         $LFS mirror split --mirror-id 1 -d $dom ||
24256                 error "failed mirror split"
24257
24258         [[ $($LFS getstripe -L --component-start=0 $dom) == 'mdt' ]] ||
24259                 error "MDT stripe wasn't set"
24260
24261         cancel_lru_locks
24262         local new_md5=$(md5sum $dom)
24263         [ "$old_md5" == "$new_md5" ] ||
24264                 error "$old_md5 != $new_md5"
24265
24266         return 0
24267 }
24268 run_test 272e "DoM mirroring: DOM mirror to the OST-striped file"
24269
24270 test_272f() {
24271         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
24272                 skip "Need MDS version at least 2.12.55"
24273
24274         local dom=$DIR/$tdir/$tfile
24275         mkdir -p $DIR/$tdir
24276         $LFS setstripe -c 2 $dom
24277
24278         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
24279                 error "failed to write data into $dom"
24280         local old_md5=$(md5sum $dom)
24281         cancel_lru_locks
24282
24283         $LFS migrate -E 1M -L mdt -E eof -c2 -v $dom ||
24284                 error "failed migrating to the DOM file"
24285
24286         [[ $($LFS getstripe -L --component-start=0 $dom) == 'mdt' ]] ||
24287                 error "MDT stripe wasn't set"
24288
24289         cancel_lru_locks
24290         local new_md5=$(md5sum $dom)
24291         [ "$old_md5" != "$new_md5" ] &&
24292                 error "$old_md5 != $new_md5"
24293
24294         return 0
24295 }
24296 run_test 272f "DoM migration: OST-striped file to DOM file"
24297
24298 test_273a() {
24299         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
24300                 skip "Need MDS version at least 2.11.50"
24301
24302         # Layout swap cannot be done if either file has DOM component,
24303         # this will never be supported, migration should be used instead
24304
24305         local dom=$DIR/$tdir/$tfile
24306         mkdir -p $DIR/$tdir
24307
24308         $LFS setstripe -c2 ${dom}_plain
24309         $LFS setstripe -E 1M -L mdt -E -1 -c2 ${dom}_dom
24310         $LFS swap_layouts ${dom}_plain ${dom}_dom &&
24311                 error "can swap layout with DoM component"
24312         $LFS swap_layouts ${dom}_dom ${dom}_plain &&
24313                 error "can swap layout with DoM component"
24314
24315         $LFS setstripe -E 1M -c1 -E -1 -c2 ${dom}_comp
24316         $LFS swap_layouts ${dom}_comp ${dom}_dom &&
24317                 error "can swap layout with DoM component"
24318         $LFS swap_layouts ${dom}_dom ${dom}_comp &&
24319                 error "can swap layout with DoM component"
24320         return 0
24321 }
24322 run_test 273a "DoM: layout swapping should fail with DOM"
24323
24324 test_273b() {
24325         mkdir -p $DIR/$tdir
24326         $LFS setstripe -E 1M -L mdt -E -1 -c -1 $DIR/$tdir
24327
24328 #define OBD_FAIL_MDS_COMMITRW_DELAY      0x16b
24329         do_facet mds1 $LCTL set_param fail_loc=0x8000016b fail_val=2
24330
24331         $MULTIOP $DIR/$tdir/$tfile Ouw2097152c
24332 }
24333 run_test 273b "DoM: race writeback and object destroy"
24334
24335 test_273c() {
24336         mkdir -p $DIR/$tdir
24337         $LFS setstripe -E 1M -E-1 -c-1 $DIR/$tdir
24338
24339         #define OBD_FAIL_OFD_COMMITRW_DELAY      0x1e1
24340         do_facet ost1 $LCTL set_param fail_loc=0x800001e1 fail_val=2
24341
24342         $MULTIOP $DIR/$tdir/$tfile Ouw2097152c
24343 }
24344 run_test 273c "race writeback and object destroy"
24345
24346 test_275() {
24347         remote_ost_nodsh && skip "remote OST with nodsh"
24348         [ $OST1_VERSION -lt $(version_code 2.10.57) ] &&
24349                 skip "Need OST version >= 2.10.57"
24350
24351         local file=$DIR/$tfile
24352         local oss
24353
24354         oss=$(comma_list $(osts_nodes))
24355
24356         dd if=/dev/urandom of=$file bs=1M count=2 ||
24357                 error "failed to create a file"
24358         stack_trap "rm -f $file"
24359         cancel_lru_locks osc
24360
24361         #lock 1
24362         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
24363                 error "failed to read a file"
24364
24365 #define OBD_FAIL_LDLM_PAUSE_CANCEL2      0x31f
24366         $LCTL set_param fail_loc=0x8000031f
24367
24368         cancel_lru_locks osc &
24369         sleep 1
24370
24371 #define OBD_FAIL_LDLM_PROLONG_PAUSE      0x32b
24372         do_nodes $oss $LCTL set_param fail_loc=0x8000032b
24373         #IO takes another lock, but matches the PENDING one
24374         #and places it to the IO RPC
24375         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
24376                 error "failed to read a file with PENDING lock"
24377 }
24378 run_test 275 "Read on a canceled duplicate lock"
24379
24380 test_276() {
24381         remote_ost_nodsh && skip "remote OST with nodsh"
24382         local pid
24383
24384         do_facet ost1 "(while true; do \
24385                 $LCTL get_param obdfilter.*.filesfree > /dev/null 2>&1; \
24386                 done) & pid=\\\$!; echo \\\$pid > $TMP/sanity_276_pid" &
24387         pid=$!
24388
24389         for LOOP in $(seq 20); do
24390                 stop ost1
24391                 start ost1 $(ostdevname 1) $OST_MOUNT_OPTS
24392         done
24393         kill -9 $pid
24394         do_facet ost1 "pid=\\\$(cat $TMP/sanity_276_pid); kill -9 \\\$pid; \
24395                 rm $TMP/sanity_276_pid"
24396 }
24397 run_test 276 "Race between mount and obd_statfs"
24398
24399 test_277() {
24400         $LCTL set_param ldlm.namespaces.*.lru_size=0
24401         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
24402         local cached_mb=$($LCTL get_param llite.*.max_cached_mb |
24403                         grep ^used_mb | awk '{print $2}')
24404         [ $cached_mb -eq 1 ] || error "expected mb 1 got $cached_mb"
24405         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 \
24406                 oflag=direct conv=notrunc
24407         cached_mb=$($LCTL get_param llite.*.max_cached_mb |
24408                         grep ^used_mb | awk '{print $2}')
24409         [ $cached_mb -eq 0 ] || error "expected mb 0 got $cached_mb"
24410 }
24411 run_test 277 "Direct IO shall drop page cache"
24412
24413 test_278() {
24414         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
24415         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
24416         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] &&
24417                 skip "needs the same host for mdt1 mdt2" && return
24418
24419         local pid1
24420         local pid2
24421
24422 #define OBD_FAIL_OBD_STOP_MDS_RACE     0x60b
24423         do_facet mds2 $LCTL set_param fail_loc=0x8000060c
24424         stop mds2 &
24425         pid2=$!
24426
24427         stop mds1
24428
24429         echo "Starting MDTs"
24430         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
24431         wait $pid2
24432 #For the error assertion will happen. lu_env_get_key(..., &mdt_thread_key)
24433 #will return NULL
24434         do_facet mds2 $LCTL set_param fail_loc=0
24435
24436         start mds2 $(mdsdevname 2) $MDS_MOUNT_OPTS
24437         wait_recovery_complete mds2
24438 }
24439 run_test 278 "Race starting MDS between MDTs stop/start"
24440
24441 test_280() {
24442         [ $MGS_VERSION -lt $(version_code 2.13.52) ] &&
24443                 skip "Need MGS version at least 2.13.52"
24444         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24445         combined_mgs_mds || skip "needs combined MGS/MDT"
24446
24447         umount_client $MOUNT
24448 #define OBD_FAIL_MDS_LLOG_UMOUNT_RACE   0x15e
24449         do_facet mgs $LCTL set_param fail_loc=0x8000015e fail_val=0
24450
24451         mount_client $MOUNT &
24452         sleep 1
24453         stop mgs || error "stop mgs failed"
24454         #for a race mgs would crash
24455         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
24456         # make sure we unmount client before remounting
24457         wait
24458         umount_client $MOUNT
24459         mount_client $MOUNT || error "mount client failed"
24460 }
24461 run_test 280 "Race between MGS umount and client llog processing"
24462
24463 cleanup_test_300() {
24464         trap 0
24465         umask $SAVE_UMASK
24466 }
24467 test_striped_dir() {
24468         local mdt_index=$1
24469         local stripe_count
24470         local stripe_index
24471
24472         mkdir -p $DIR/$tdir
24473
24474         SAVE_UMASK=$(umask)
24475         trap cleanup_test_300 RETURN EXIT
24476
24477         $LFS setdirstripe -i $mdt_index -c 2 -H all_char -o 755 \
24478                                                 $DIR/$tdir/striped_dir ||
24479                 error "set striped dir error"
24480
24481         local mode=$(stat -c%a $DIR/$tdir/striped_dir)
24482         [ "$mode" = "755" ] || error "expect 755 got $mode"
24483
24484         $LFS getdirstripe $DIR/$tdir/striped_dir > /dev/null 2>&1 ||
24485                 error "getdirstripe failed"
24486         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir)
24487         if [ "$stripe_count" != "2" ]; then
24488                 error "1:stripe_count is $stripe_count, expect 2"
24489         fi
24490         stripe_count=$($LFS getdirstripe -T $DIR/$tdir/striped_dir)
24491         if [ "$stripe_count" != "2" ]; then
24492                 error "2:stripe_count is $stripe_count, expect 2"
24493         fi
24494
24495         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir)
24496         if [ "$stripe_index" != "$mdt_index" ]; then
24497                 error "stripe_index is $stripe_index, expect $mdt_index"
24498         fi
24499
24500         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
24501                 error "nlink error after create striped dir"
24502
24503         mkdir $DIR/$tdir/striped_dir/a
24504         mkdir $DIR/$tdir/striped_dir/b
24505
24506         stat $DIR/$tdir/striped_dir/a ||
24507                 error "create dir under striped dir failed"
24508         stat $DIR/$tdir/striped_dir/b ||
24509                 error "create dir under striped dir failed"
24510
24511         [ $(stat -c%h $DIR/$tdir/striped_dir) == '4' ] ||
24512                 error "nlink error after mkdir"
24513
24514         rmdir $DIR/$tdir/striped_dir/a
24515         [ $(stat -c%h $DIR/$tdir/striped_dir) == '3' ] ||
24516                 error "nlink error after rmdir"
24517
24518         rmdir $DIR/$tdir/striped_dir/b
24519         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
24520                 error "nlink error after rmdir"
24521
24522         chattr +i $DIR/$tdir/striped_dir
24523         createmany -o $DIR/$tdir/striped_dir/f 10 &&
24524                 error "immutable flags not working under striped dir!"
24525         chattr -i $DIR/$tdir/striped_dir
24526
24527         rmdir $DIR/$tdir/striped_dir ||
24528                 error "rmdir striped dir error"
24529
24530         cleanup_test_300
24531
24532         true
24533 }
24534
24535 test_300a() {
24536         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
24537                 skip "skipped for lustre < 2.7.0"
24538         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24539         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24540
24541         test_striped_dir 0 || error "failed on striped dir on MDT0"
24542         test_striped_dir 1 || error "failed on striped dir on MDT0"
24543 }
24544 run_test 300a "basic striped dir sanity test"
24545
24546 test_300b() {
24547         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
24548                 skip "skipped for lustre < 2.7.0"
24549         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24550         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24551
24552         local i
24553         local mtime1
24554         local mtime2
24555         local mtime3
24556
24557         test_mkdir $DIR/$tdir || error "mkdir fail"
24558         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
24559                 error "set striped dir error"
24560         for i in {0..9}; do
24561                 mtime1=$(stat -c %Y $DIR/$tdir/striped_dir)
24562                 sleep 1
24563                 touch $DIR/$tdir/striped_dir/file_$i || error "touch error $i"
24564                 mtime2=$(stat -c %Y $DIR/$tdir/striped_dir)
24565                 [ $mtime1 -eq $mtime2 ] && error "mtime unchanged after create"
24566                 sleep 1
24567                 rm -f $DIR/$tdir/striped_dir/file_$i || error "unlink error $i"
24568                 mtime3=$(stat -c %Y $DIR/$tdir/striped_dir)
24569                 [ $mtime2 -eq $mtime3 ] && error "mtime unchanged after unlink"
24570         done
24571         true
24572 }
24573 run_test 300b "check ctime/mtime for striped dir"
24574
24575 test_300c() {
24576         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
24577                 skip "skipped for lustre < 2.7.0"
24578         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24579         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24580
24581         local file_count
24582
24583         mkdir_on_mdt0 $DIR/$tdir
24584         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir ||
24585                 error "set striped dir error"
24586
24587         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/striped_dir ||
24588                 error "chown striped dir failed"
24589
24590         $RUNAS createmany -o $DIR/$tdir/striped_dir/f 5000 ||
24591                 error "create 5k files failed"
24592
24593         file_count=$(ls $DIR/$tdir/striped_dir | wc -l)
24594
24595         [ "$file_count" = 5000 ] || error "file count $file_count != 5000"
24596
24597         rm -rf $DIR/$tdir
24598 }
24599 run_test 300c "chown && check ls under striped directory"
24600
24601 test_300d() {
24602         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
24603                 skip "skipped for lustre < 2.7.0"
24604         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24605         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24606
24607         local stripe_count
24608         local file
24609
24610         mkdir -p $DIR/$tdir
24611         $LFS setstripe -c 2 $DIR/$tdir
24612
24613         #local striped directory
24614         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
24615                 error "set striped dir error"
24616         #look at the directories for debug purposes
24617         ls -l $DIR/$tdir
24618         $LFS getdirstripe $DIR/$tdir
24619         ls -l $DIR/$tdir/striped_dir
24620         $LFS getdirstripe $DIR/$tdir/striped_dir
24621         createmany -o $DIR/$tdir/striped_dir/f 10 ||
24622                 error "create 10 files failed"
24623
24624         #remote striped directory
24625         $LFS setdirstripe -i 1 -c 2 $DIR/$tdir/remote_striped_dir ||
24626                 error "set striped dir error"
24627         #look at the directories for debug purposes
24628         ls -l $DIR/$tdir
24629         $LFS getdirstripe $DIR/$tdir
24630         ls -l $DIR/$tdir/remote_striped_dir
24631         $LFS getdirstripe $DIR/$tdir/remote_striped_dir
24632         createmany -o $DIR/$tdir/remote_striped_dir/f 10 ||
24633                 error "create 10 files failed"
24634
24635         for file in $(find $DIR/$tdir); do
24636                 stripe_count=$($LFS getstripe -c $file)
24637                 [ $stripe_count -eq 2 ] ||
24638                         error "wrong stripe $stripe_count for $file"
24639         done
24640
24641         rm -rf $DIR/$tdir
24642 }
24643 run_test 300d "check default stripe under striped directory"
24644
24645 test_300e() {
24646         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24647                 skip "Need MDS version at least 2.7.55"
24648         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24649         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24650
24651         local stripe_count
24652         local file
24653
24654         mkdir -p $DIR/$tdir
24655
24656         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
24657                 error "set striped dir error"
24658
24659         touch $DIR/$tdir/striped_dir/a
24660         touch $DIR/$tdir/striped_dir/b
24661         touch $DIR/$tdir/striped_dir/c
24662
24663         mkdir $DIR/$tdir/striped_dir/dir_a
24664         mkdir $DIR/$tdir/striped_dir/dir_b
24665         mkdir $DIR/$tdir/striped_dir/dir_c
24666
24667         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_a ||
24668                 error "set striped adir under striped dir error"
24669
24670         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_b ||
24671                 error "set striped bdir under striped dir error"
24672
24673         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_c ||
24674                 error "set striped cdir under striped dir error"
24675
24676         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir/dir_b ||
24677                 error "rename dir under striped dir fails"
24678
24679         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir/stp_b ||
24680                 error "rename dir under different stripes fails"
24681
24682         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir/c ||
24683                 error "rename file under striped dir should succeed"
24684
24685         mrename $DIR/$tdir/striped_dir/dir_b $DIR/$tdir/striped_dir/dir_c ||
24686                 error "rename dir under striped dir should succeed"
24687
24688         rm -rf $DIR/$tdir
24689 }
24690 run_test 300e "check rename under striped directory"
24691
24692 test_300f() {
24693         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24694         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24695         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24696                 skip "Need MDS version at least 2.7.55"
24697
24698         local stripe_count
24699         local file
24700
24701         rm -rf $DIR/$tdir
24702         mkdir -p $DIR/$tdir
24703
24704         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
24705                 error "set striped dir error"
24706
24707         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir1 ||
24708                 error "set striped dir error"
24709
24710         touch $DIR/$tdir/striped_dir/a
24711         mkdir $DIR/$tdir/striped_dir/dir_a
24712         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_a ||
24713                 error "create striped dir under striped dir fails"
24714
24715         touch $DIR/$tdir/striped_dir1/b
24716         mkdir $DIR/$tdir/striped_dir1/dir_b
24717         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_b ||
24718                 error "create striped dir under striped dir fails"
24719
24720         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir1/dir_b ||
24721                 error "rename dir under different striped dir should fail"
24722
24723         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir1/stp_b ||
24724                 error "rename striped dir under diff striped dir should fail"
24725
24726         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir1/a ||
24727                 error "rename file under diff striped dirs fails"
24728
24729         rm -rf $DIR/$tdir
24730 }
24731 run_test 300f "check rename cross striped directory"
24732
24733 test_300_check_default_striped_dir()
24734 {
24735         local dirname=$1
24736         local default_count=$2
24737         local default_index=$3
24738         local stripe_count
24739         local stripe_index
24740         local dir_stripe_index
24741         local dir
24742
24743         echo "checking $dirname $default_count $default_index"
24744         $LFS setdirstripe -D -c $default_count -i $default_index \
24745                                 -H all_char $DIR/$tdir/$dirname ||
24746                 error "set default stripe on striped dir error"
24747         stripe_count=$($LFS getdirstripe -D -c $DIR/$tdir/$dirname)
24748         [ $stripe_count -eq $default_count ] ||
24749                 error "expect $default_count get $stripe_count for $dirname"
24750
24751         stripe_index=$($LFS getdirstripe -D -i $DIR/$tdir/$dirname)
24752         [ $stripe_index -eq $default_index ] ||
24753                 error "expect $default_index get $stripe_index for $dirname"
24754
24755         mkdir $DIR/$tdir/$dirname/{test1,test2,test3,test4} ||
24756                                                 error "create dirs failed"
24757
24758         createmany -o $DIR/$tdir/$dirname/f- 10 || error "create files failed"
24759         unlinkmany $DIR/$tdir/$dirname/f- 10    || error "unlink files failed"
24760         for dir in $(find $DIR/$tdir/$dirname/*); do
24761                 stripe_count=$($LFS getdirstripe -c $dir)
24762                 (( $stripe_count == $default_count )) ||
24763                 (( $stripe_count == $MDSCOUNT && $default_count == -1 )) ||
24764                 (( $stripe_count == 0 )) || (( $default_count == 1 )) ||
24765                 error "stripe count $default_count != $stripe_count for $dir"
24766
24767                 stripe_index=$($LFS getdirstripe -i $dir)
24768                 [ $default_index -eq -1 ] ||
24769                         [ $stripe_index -eq $default_index ] ||
24770                         error "$stripe_index != $default_index for $dir"
24771
24772                 #check default stripe
24773                 stripe_count=$($LFS getdirstripe -D -c $dir)
24774                 [ $stripe_count -eq $default_count ] ||
24775                 error "default count $default_count != $stripe_count for $dir"
24776
24777                 stripe_index=$($LFS getdirstripe -D -i $dir)
24778                 [ $stripe_index -eq $default_index ] ||
24779                 error "default index $default_index != $stripe_index for $dir"
24780         done
24781         rmdir $DIR/$tdir/$dirname/* || error "rmdir failed"
24782 }
24783
24784 test_300g() {
24785         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24786         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24787                 skip "Need MDS version at least 2.7.55"
24788
24789         local dir
24790         local stripe_count
24791         local stripe_index
24792
24793         mkdir_on_mdt0 $DIR/$tdir
24794         mkdir $DIR/$tdir/normal_dir
24795
24796         #Checking when client cache stripe index
24797         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
24798         $LFS setdirstripe -D -i1 $DIR/$tdir/striped_dir ||
24799                 error "create striped_dir failed"
24800
24801         $LFS setdirstripe -i0 $DIR/$tdir/striped_dir/dir0 ||
24802                 error "create dir0 fails"
24803         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir0)
24804         [ $stripe_index -eq 0 ] ||
24805                 error "dir0 expect index 0 got $stripe_index"
24806
24807         mkdir $DIR/$tdir/striped_dir/dir1 ||
24808                 error "create dir1 fails"
24809         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir1)
24810         [ $stripe_index -eq 1 ] ||
24811                 error "dir1 expect index 1 got $stripe_index"
24812
24813         #check default stripe count/stripe index
24814         test_300_check_default_striped_dir normal_dir $MDSCOUNT 1
24815         test_300_check_default_striped_dir normal_dir 1 0
24816         test_300_check_default_striped_dir normal_dir -1 1
24817         test_300_check_default_striped_dir normal_dir 2 -1
24818
24819         #delete default stripe information
24820         echo "delete default stripeEA"
24821         $LFS setdirstripe -d $DIR/$tdir/normal_dir ||
24822                 error "set default stripe on striped dir error"
24823
24824         mkdir -p $DIR/$tdir/normal_dir/{test1,test2,test3,test4}
24825         for dir in $(find $DIR/$tdir/normal_dir/*); do
24826                 stripe_count=$($LFS getdirstripe -c $dir)
24827                 [ $stripe_count -eq 0 ] ||
24828                         error "expect 1 get $stripe_count for $dir"
24829         done
24830 }
24831 run_test 300g "check default striped directory for normal directory"
24832
24833 test_300h() {
24834         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24835         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24836                 skip "Need MDS version at least 2.7.55"
24837
24838         local dir
24839         local stripe_count
24840
24841         mkdir $DIR/$tdir
24842         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
24843                 error "set striped dir error"
24844
24845         test_300_check_default_striped_dir striped_dir $MDSCOUNT 1
24846         test_300_check_default_striped_dir striped_dir 1 0
24847         test_300_check_default_striped_dir striped_dir -1 1
24848         test_300_check_default_striped_dir striped_dir 2 -1
24849
24850         #delete default stripe information
24851         $LFS setdirstripe -d $DIR/$tdir/striped_dir ||
24852                 error "set default stripe on striped dir error"
24853
24854         mkdir -p $DIR/$tdir/striped_dir/{test1,test2,test3,test4}
24855         for dir in $(find $DIR/$tdir/striped_dir/*); do
24856                 stripe_count=$($LFS getdirstripe -c $dir)
24857                 [ $stripe_count -eq 0 ] ||
24858                         error "expect 1 get $stripe_count for $dir"
24859         done
24860 }
24861 run_test 300h "check default striped directory for striped directory"
24862
24863 test_300i() {
24864         [[ $PARALLEL == "yes" ]] && skip "skip parallel run"
24865         (( $MDSCOUNT >= 2 )) || skip_env "needs >= 2 MDTs"
24866         (( $MDS1_VERSION >= $(version_code 2.7.55) )) ||
24867                 skip "Need MDS version at least 2.7.55"
24868
24869         local stripe_count
24870         local file
24871
24872         mkdir $DIR/$tdir
24873
24874         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
24875                 error "set striped dir error"
24876
24877         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
24878                 error "create files under striped dir failed"
24879
24880         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir ||
24881                 error "set striped hashdir error"
24882
24883         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir/d0 ||
24884                 error "create dir0 under hash dir failed"
24885         $LFS setdirstripe -i0 -c$MDSCOUNT -H fnv_1a_64 $DIR/$tdir/hashdir/d1 ||
24886                 error "create dir1 under hash dir failed"
24887         $LFS setdirstripe -i0 -c$MDSCOUNT -H crush $DIR/$tdir/hashdir/d2 ||
24888                 error "create dir2 under hash dir failed"
24889
24890         # unfortunately, we need to umount to clear dir layout cache for now
24891         # once we fully implement dir layout, we can drop this
24892         umount_client $MOUNT || error "umount failed"
24893         mount_client $MOUNT || error "mount failed"
24894
24895         $LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir
24896         local dircnt=$($LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir | wc -l)
24897         (( $dircnt == 2 )) || error "lfs find striped dir got $dircnt != 2"
24898
24899         if (( $MDS1_VERSION > $(version_code 2.15.0) )); then
24900                 $LFS mkdir -i0 -c$MDSCOUNT -H crush2 $DIR/$tdir/hashdir/d3 ||
24901                         error "create crush2 dir $tdir/hashdir/d3 failed"
24902                 $LFS find -H crush2 $DIR/$tdir/hashdir
24903                 dircnt=$($LFS find -H crush2 $DIR/$tdir/hashdir | wc -l)
24904                 (( $dircnt == 1 )) || error "find crush2 dir got $dircnt != 1"
24905
24906                 # mkdir with an invalid hash type (hash=fail_val) from client
24907                 # should be replaced on MDS with a valid (default) hash type
24908                 #define OBD_FAIL_LMV_UNKNOWN_STRIPE     0x1901
24909                 $LCTL set_param fail_loc=0x1901 fail_val=99
24910                 $LFS mkdir -c2 $DIR/$tdir/hashdir/d99
24911
24912                 local hash=$($LFS getdirstripe -H $DIR/$tdir/hashdir/d99)
24913                 local expect=$(do_facet mds1 \
24914                         $LCTL get_param -n lod.$FSNAME-MDT0000-mdtlov.mdt_hash)
24915                 [[ $hash == $expect ]] ||
24916                         error "d99 hash '$hash' != expected hash '$expect'"
24917         fi
24918
24919         #set the stripe to be unknown hash type on read
24920         #define OBD_FAIL_LMV_UNKNOWN_STRIPE     0x1901
24921         $LCTL set_param fail_loc=0x1901 fail_val=99
24922         for ((i = 0; i < 10; i++)); do
24923                 $CHECKSTAT -t file $DIR/$tdir/striped_dir/f-$i ||
24924                         error "stat f-$i failed"
24925                 rm $DIR/$tdir/striped_dir/f-$i || error "unlink f-$i failed"
24926         done
24927
24928         touch $DIR/$tdir/striped_dir/f0 &&
24929                 error "create under striped dir with unknown hash should fail"
24930
24931         $LCTL set_param fail_loc=0
24932
24933         umount_client $MOUNT || error "umount failed"
24934         mount_client $MOUNT || error "mount failed"
24935
24936         return 0
24937 }
24938 run_test 300i "client handle unknown hash type striped directory"
24939
24940 test_300j() {
24941         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24942         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24943         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24944                 skip "Need MDS version at least 2.7.55"
24945
24946         local stripe_count
24947         local file
24948
24949         mkdir $DIR/$tdir
24950
24951         #define OBD_FAIL_SPLIT_UPDATE_REC       0x1702
24952         $LCTL set_param fail_loc=0x1702
24953         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
24954                 error "set striped dir error"
24955
24956         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
24957                 error "create files under striped dir failed"
24958
24959         $LCTL set_param fail_loc=0
24960
24961         rm -rf $DIR/$tdir || error "unlink striped dir fails"
24962
24963         return 0
24964 }
24965 run_test 300j "test large update record"
24966
24967 test_300k() {
24968         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24969         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24970         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24971                 skip "Need MDS version at least 2.7.55"
24972
24973         # this test needs a huge transaction
24974         local kb
24975         kb=$(do_facet $SINGLEMDS "$LCTL get_param -n \
24976              osd*.$FSNAME-MDT0000.kbytestotal")
24977         [ $kb -lt $((1024*1024)) ] && skip "MDT0 too small: $kb"
24978
24979         local stripe_count
24980         local file
24981
24982         mkdir $DIR/$tdir
24983
24984         #define OBD_FAIL_LARGE_STRIPE   0x1703
24985         $LCTL set_param fail_loc=0x1703
24986         $LFS setdirstripe -i 0 -c192 $DIR/$tdir/striped_dir ||
24987                 error "set striped dir error"
24988         $LCTL set_param fail_loc=0
24989
24990         $LFS getdirstripe $DIR/$tdir/striped_dir ||
24991                 error "getstripeddir fails"
24992         rm -rf $DIR/$tdir/striped_dir ||
24993                 error "unlink striped dir fails"
24994
24995         return 0
24996 }
24997 run_test 300k "test large striped directory"
24998
24999 test_300l() {
25000         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25001         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25002         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25003                 skip "Need MDS version at least 2.7.55"
25004
25005         local stripe_index
25006
25007         test_mkdir -p $DIR/$tdir/striped_dir
25008         chown $RUNAS_ID $DIR/$tdir/striped_dir ||
25009                         error "chown $RUNAS_ID failed"
25010         $LFS setdirstripe -i 1 -D $DIR/$tdir/striped_dir ||
25011                 error "set default striped dir failed"
25012
25013         #define OBD_FAIL_MDS_STALE_DIR_LAYOUT    0x158
25014         $LCTL set_param fail_loc=0x80000158
25015         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir || error "create dir fails"
25016
25017         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/test_dir)
25018         [ $stripe_index -eq 1 ] ||
25019                 error "expect 1 get $stripe_index for $dir"
25020 }
25021 run_test 300l "non-root user to create dir under striped dir with stale layout"
25022
25023 test_300m() {
25024         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25025         [ $MDSCOUNT -ge 2 ] && skip_env "Only for single MDT"
25026         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25027                 skip "Need MDS version at least 2.7.55"
25028
25029         mkdir -p $DIR/$tdir/striped_dir
25030         $LFS setdirstripe -D -c 1 $DIR/$tdir/striped_dir ||
25031                 error "set default stripes dir error"
25032
25033         mkdir $DIR/$tdir/striped_dir/a || error "mkdir a fails"
25034
25035         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/a)
25036         [ $stripe_count -eq 0 ] ||
25037                         error "expect 0 get $stripe_count for a"
25038
25039         $LFS setdirstripe -D -c 2 $DIR/$tdir/striped_dir ||
25040                 error "set default stripes dir error"
25041
25042         mkdir $DIR/$tdir/striped_dir/b || error "mkdir b fails"
25043
25044         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/b)
25045         [ $stripe_count -eq 0 ] ||
25046                         error "expect 0 get $stripe_count for b"
25047
25048         $LFS setdirstripe -D -c1 -i2 $DIR/$tdir/striped_dir ||
25049                 error "set default stripes dir error"
25050
25051         mkdir $DIR/$tdir/striped_dir/c &&
25052                 error "default stripe_index is invalid, mkdir c should fails"
25053
25054         rm -rf $DIR/$tdir || error "rmdir fails"
25055 }
25056 run_test 300m "setstriped directory on single MDT FS"
25057
25058 cleanup_300n() {
25059         local list=$(comma_list $(mdts_nodes))
25060
25061         trap 0
25062         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
25063 }
25064
25065 test_300n() {
25066         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25067         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25068         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25069                 skip "Need MDS version at least 2.7.55"
25070         remote_mds_nodsh && skip "remote MDS with nodsh"
25071
25072         local stripe_index
25073         local list=$(comma_list $(mdts_nodes))
25074
25075         trap cleanup_300n RETURN EXIT
25076         mkdir -p $DIR/$tdir
25077         chmod 777 $DIR/$tdir
25078         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT \
25079                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
25080                 error "create striped dir succeeds with gid=0"
25081
25082         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
25083         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
25084                 error "create striped dir fails with gid=-1"
25085
25086         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
25087         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D \
25088                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
25089                 error "set default striped dir succeeds with gid=0"
25090
25091
25092         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
25093         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D $DIR/$tdir/striped_dir ||
25094                 error "set default striped dir fails with gid=-1"
25095
25096
25097         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
25098         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir ||
25099                                         error "create test_dir fails"
25100         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir1 ||
25101                                         error "create test_dir1 fails"
25102         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir2 ||
25103                                         error "create test_dir2 fails"
25104         cleanup_300n
25105 }
25106 run_test 300n "non-root user to create dir under striped dir with default EA"
25107
25108 test_300o() {
25109         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25110         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25111         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25112                 skip "Need MDS version at least 2.7.55"
25113
25114         local numfree1
25115         local numfree2
25116
25117         mkdir -p $DIR/$tdir
25118
25119         numfree1=$(lctl get_param -n mdc.*MDT0000*.filesfree)
25120         numfree2=$(lctl get_param -n mdc.*MDT0001*.filesfree)
25121         if [ $numfree1 -lt 66000 ] || [ $numfree2 -lt 66000 ]; then
25122                 skip "not enough free inodes $numfree1 $numfree2"
25123         fi
25124
25125         numfree1=$(lctl get_param -n mdc.*MDT0000-mdc-*.kbytesfree)
25126         numfree2=$(lctl get_param -n mdc.*MDT0001-mdc-*.kbytesfree)
25127         if [ $numfree1 -lt 300000 ] || [ $numfree2 -lt 300000 ]; then
25128                 skip "not enough free space $numfree1 $numfree2"
25129         fi
25130
25131         $LFS setdirstripe -c2 $DIR/$tdir/striped_dir ||
25132                 error "setdirstripe fails"
25133
25134         createmany -d $DIR/$tdir/striped_dir/d 131000 ||
25135                 error "create dirs fails"
25136
25137         $LCTL set_param ldlm.namespaces.*mdc-*.lru_size=0
25138         ls $DIR/$tdir/striped_dir > /dev/null ||
25139                 error "ls striped dir fails"
25140         unlinkmany -d $DIR/$tdir/striped_dir/d 131000 ||
25141                 error "unlink big striped dir fails"
25142 }
25143 run_test 300o "unlink big sub stripe(> 65000 subdirs)"
25144
25145 test_300p() {
25146         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25147         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25148         remote_mds_nodsh && skip "remote MDS with nodsh"
25149
25150         mkdir_on_mdt0 $DIR/$tdir
25151
25152         #define OBD_FAIL_OUT_ENOSPC     0x1704
25153         do_facet mds2 lctl set_param fail_loc=0x80001704
25154         $LFS setdirstripe -i 0 -c2 $DIR/$tdir/bad_striped_dir > /dev/null 2>&1 \
25155                  && error "create striped directory should fail"
25156
25157         [ -e $DIR/$tdir/bad_striped_dir ] && error "striped dir exists"
25158
25159         $LFS setdirstripe -c2 $DIR/$tdir/bad_striped_dir
25160         true
25161 }
25162 run_test 300p "create striped directory without space"
25163
25164 test_300q() {
25165         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25166         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25167
25168         local fd=$(free_fd)
25169         local cmd="exec $fd<$tdir"
25170         cd $DIR
25171         $LFS mkdir -c $MDSCOUNT $tdir || error "create $tdir fails"
25172         eval $cmd
25173         cmd="exec $fd<&-"
25174         trap "eval $cmd" EXIT
25175         cd $tdir || error "cd $tdir fails"
25176         rmdir  ../$tdir || error "rmdir $tdir fails"
25177         mkdir local_dir && error "create dir succeeds"
25178         $LFS setdirstripe -i1 remote_dir && error "create remote dir succeeds"
25179         eval $cmd
25180         return 0
25181 }
25182 run_test 300q "create remote directory under orphan directory"
25183
25184 test_300r() {
25185         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25186                 skip "Need MDS version at least 2.7.55" && return
25187         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
25188
25189         mkdir $DIR/$tdir
25190
25191         $LFS setdirstripe -i 0 -c -1 $DIR/$tdir/striped_dir ||
25192                 error "set striped dir error"
25193
25194         $LFS getdirstripe $DIR/$tdir/striped_dir ||
25195                 error "getstripeddir fails"
25196
25197         local stripe_count
25198         stripe_count=$($LFS getdirstripe $DIR/$tdir/striped_dir |
25199                       awk '/lmv_stripe_count:/ { print $2 }')
25200
25201         [ $MDSCOUNT -ne $stripe_count ] &&
25202                 error "wrong stripe count $stripe_count expected $MDSCOUNT"
25203
25204         rm -rf $DIR/$tdir/striped_dir ||
25205                 error "unlink striped dir fails"
25206 }
25207 run_test 300r "test -1 striped directory"
25208
25209 test_300s_helper() {
25210         local count=$1
25211
25212         local stripe_dir=$DIR/$tdir/striped_dir.$count
25213
25214         $LFS mkdir -c $count $stripe_dir ||
25215                 error "lfs mkdir -c error"
25216
25217         $LFS getdirstripe $stripe_dir ||
25218                 error "lfs getdirstripe fails"
25219
25220         local stripe_count
25221         stripe_count=$($LFS getdirstripe $stripe_dir |
25222                       awk '/lmv_stripe_count:/ { print $2 }')
25223
25224         [ $count -ne $stripe_count ] &&
25225                 error_noexit "bad stripe count $stripe_count expected $count"
25226
25227         local dupe_stripes
25228         dupe_stripes=$($LFS getdirstripe $stripe_dir |
25229                 awk '/0x/ {count[$1] += 1}; END {
25230                         for (idx in count) {
25231                                 if (count[idx]>1) {
25232                                         print "index " idx " count " count[idx]
25233                                 }
25234                         }
25235                 }')
25236
25237         if [[ -n "$dupe_stripes" ]] ; then
25238                 lfs getdirstripe $stripe_dir
25239                 error_noexit "Dupe MDT above: $dupe_stripes "
25240         fi
25241
25242         rm -rf $stripe_dir ||
25243                 error_noexit "unlink $stripe_dir fails"
25244 }
25245
25246 test_300s() {
25247         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25248                 skip "Need MDS version at least 2.7.55" && return
25249         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
25250
25251         mkdir $DIR/$tdir
25252         for count in $(seq 2 $MDSCOUNT); do
25253                 test_300s_helper $count
25254         done
25255 }
25256 run_test 300s "test lfs mkdir -c without -i"
25257
25258 test_300t() {
25259         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
25260                 skip "need MDS 2.14.55 or later"
25261         (( $MDSCOUNT >= 2 )) || skip "needs at least 2 MDTs"
25262
25263         local testdir="$DIR/$tdir/striped_dir"
25264         local dir1=$testdir/dir1
25265         local dir2=$testdir/dir2
25266
25267         mkdir -p $testdir
25268
25269         $LFS setdirstripe -D -c -1 --max-inherit=3 $testdir ||
25270                 error "failed to set default stripe count for $testdir"
25271
25272         mkdir $dir1
25273         local stripe_count=$($LFS getdirstripe -c $dir1)
25274
25275         (( $stripe_count == $MDSCOUNT )) || error "wrong stripe count"
25276
25277         local max_count=$((MDSCOUNT - 1))
25278         local mdts=$(comma_list $(mdts_nodes))
25279
25280         do_nodes $mdts $LCTL set_param lod.*.max_mdt_stripecount=$max_count
25281         stack_trap "do_nodes $mdts $LCTL set_param lod.*.max_mdt_stripecount=0"
25282
25283         mkdir $dir2
25284         stripe_count=$($LFS getdirstripe -c $dir2)
25285
25286         (( $stripe_count == $max_count )) || error "wrong stripe count"
25287 }
25288 run_test 300t "test max_mdt_stripecount"
25289
25290 prepare_remote_file() {
25291         mkdir $DIR/$tdir/src_dir ||
25292                 error "create remote source failed"
25293
25294         cp /etc/hosts $DIR/$tdir/src_dir/a ||
25295                  error "cp to remote source failed"
25296         touch $DIR/$tdir/src_dir/a
25297
25298         $LFS mkdir -i 1 $DIR/$tdir/tgt_dir ||
25299                 error "create remote target dir failed"
25300
25301         touch $DIR/$tdir/tgt_dir/b
25302
25303         mrename $DIR/$tdir/src_dir/a $DIR/$tdir/tgt_dir/b ||
25304                 error "rename dir cross MDT failed!"
25305
25306         $CHECKSTAT -t file $DIR/$tdir/src_dir/a &&
25307                 error "src_child still exists after rename"
25308
25309         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/b ||
25310                 error "missing file(a) after rename"
25311
25312         diff /etc/hosts $DIR/$tdir/tgt_dir/b ||
25313                 error "diff after rename"
25314 }
25315
25316 test_310a() {
25317         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
25318         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25319
25320         local remote_file=$DIR/$tdir/tgt_dir/b
25321
25322         mkdir -p $DIR/$tdir
25323
25324         prepare_remote_file || error "prepare remote file failed"
25325
25326         #open-unlink file
25327         $OPENUNLINK $remote_file $remote_file ||
25328                 error "openunlink $remote_file failed"
25329         $CHECKSTAT -a $remote_file || error "$remote_file exists"
25330 }
25331 run_test 310a "open unlink remote file"
25332
25333 test_310b() {
25334         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
25335         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25336
25337         local remote_file=$DIR/$tdir/tgt_dir/b
25338
25339         mkdir -p $DIR/$tdir
25340
25341         prepare_remote_file || error "prepare remote file failed"
25342
25343         ln $remote_file $DIR/$tfile || error "link failed for remote file"
25344         $MULTIOP $DIR/$tfile Ouc || error "mulitop failed"
25345         $CHECKSTAT -t file $remote_file || error "check file failed"
25346 }
25347 run_test 310b "unlink remote file with multiple links while open"
25348
25349 test_310c() {
25350         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25351         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
25352
25353         local remote_file=$DIR/$tdir/tgt_dir/b
25354
25355         mkdir -p $DIR/$tdir
25356
25357         prepare_remote_file || error "prepare remote file failed"
25358
25359         ln $remote_file $DIR/$tfile || error "link failed for remote file"
25360         multiop_bg_pause $remote_file O_uc ||
25361                         error "mulitop failed for remote file"
25362         MULTIPID=$!
25363         $MULTIOP $DIR/$tfile Ouc
25364         kill -USR1 $MULTIPID
25365         wait $MULTIPID
25366 }
25367 run_test 310c "open-unlink remote file with multiple links"
25368
25369 #LU-4825
25370 test_311() {
25371         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25372         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
25373         [ $MDS1_VERSION -lt $(version_code 2.8.54) ] &&
25374                 skip "lustre < 2.8.54 does not contain LU-4825 fix"
25375         remote_mds_nodsh && skip "remote MDS with nodsh"
25376
25377         local old_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
25378         local mdts=$(comma_list $(mdts_nodes))
25379
25380         mkdir -p $DIR/$tdir
25381         $LFS setstripe -i 0 -c 1 $DIR/$tdir
25382         createmany -o $DIR/$tdir/$tfile. 1000
25383
25384         # statfs data is not real time, let's just calculate it
25385         old_iused=$((old_iused + 1000))
25386
25387         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
25388                         osp.*OST0000*MDT0000.create_count")
25389         local max_count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
25390                                 osp.*OST0000*MDT0000.max_create_count")
25391         do_nodes $mdts "$LCTL set_param -n osp.*OST0000*.max_create_count=0"
25392
25393         $LFS setstripe -i 0 $DIR/$tdir/$tfile || error "setstripe failed"
25394         local index=$($LFS getstripe -i $DIR/$tdir/$tfile)
25395         [ $index -ne 0 ] || error "$tfile stripe index is 0"
25396
25397         unlinkmany $DIR/$tdir/$tfile. 1000
25398
25399         do_nodes $mdts "$LCTL set_param -n \
25400                         osp.*OST0000*.max_create_count=$max_count"
25401         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
25402                 do_nodes $mdts "$LCTL set_param -n \
25403                                 osp.*OST0000*.create_count=$count"
25404         do_nodes $mdts "$LCTL get_param osp.*OST0000*.create_count" |
25405                         grep "=0" && error "create_count is zero"
25406
25407         local new_iused
25408         for i in $(seq 120); do
25409                 new_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
25410                 # system may be too busy to destroy all objs in time, use
25411                 # a somewhat small value to not fail autotest
25412                 [ $((old_iused - new_iused)) -gt 400 ] && break
25413                 sleep 1
25414         done
25415
25416         echo "waited $i sec, old Iused $old_iused, new Iused $new_iused"
25417         [ $((old_iused - new_iused)) -gt 400 ] ||
25418                 error "objs not destroyed after unlink"
25419 }
25420 run_test 311 "disable OSP precreate, and unlink should destroy objs"
25421
25422 zfs_get_objid()
25423 {
25424         local ost=$1
25425         local tf=$2
25426         local fid=($($LFS getstripe $tf | grep 0x))
25427         local seq=${fid[3]#0x}
25428         local objid=${fid[1]}
25429
25430         local vdevdir=$(dirname $(facet_vdevice $ost))
25431         local cmd="$ZDB -e -p $vdevdir -ddddd $(facet_device $ost)"
25432         local zfs_zapid=$(do_facet $ost $cmd |
25433                           grep -w "/O/$seq/d$((objid%32))" -C 5 |
25434                           awk '/Object/{getline; print $1}')
25435         local zfs_objid=$(do_facet $ost $cmd $zfs_zapid |
25436                           awk "/$objid = /"'{printf $3}')
25437
25438         echo $zfs_objid
25439 }
25440
25441 zfs_object_blksz() {
25442         local ost=$1
25443         local objid=$2
25444
25445         local vdevdir=$(dirname $(facet_vdevice $ost))
25446         local cmd="$ZDB -e -p $vdevdir -dddd $(facet_device $ost)"
25447         local blksz=$(do_facet $ost $cmd $objid |
25448                       awk '/dblk/{getline; printf $4}')
25449
25450         case "${blksz: -1}" in
25451                 k|K) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024)) ;;
25452                 m|M) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024*1024)) ;;
25453                 *) ;;
25454         esac
25455
25456         echo $blksz
25457 }
25458
25459 test_312() { # LU-4856
25460         remote_ost_nodsh && skip "remote OST with nodsh"
25461         [[ "$ost1_FSTYPE" == "zfs" ]] || skip "the test only applies to zfs"
25462
25463         local max_blksz=$(do_facet ost1 \
25464                           $ZFS get -p recordsize $(facet_device ost1) |
25465                           awk '!/VALUE/{print $3}')
25466         local tf=$DIR/$tfile
25467
25468         $LFS setstripe -c1 $tf
25469         local facet="ost$(($($LFS getstripe -i $tf) + 1))"
25470
25471         # Get ZFS object id
25472         local zfs_objid=$(zfs_get_objid $facet $tf)
25473         # block size change by sequential overwrite
25474         local bs
25475
25476         for ((bs=$PAGE_SIZE; bs <= max_blksz; bs *= 4)) ; do
25477                 dd if=/dev/zero of=$tf bs=$bs count=1 oflag=sync conv=notrunc
25478
25479                 local blksz=$(zfs_object_blksz $facet $zfs_objid)
25480                 [[ $blksz -eq $bs ]] || error "blksz error: $blksz, expected: $bs"
25481         done
25482         rm -f $tf
25483
25484         $LFS setstripe -c1 $tf
25485         facet="ost$(($($LFS getstripe -i $tf) + 1))"
25486
25487         # block size change by sequential append write
25488         dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=1 oflag=sync conv=notrunc
25489         zfs_objid=$(zfs_get_objid $facet $tf)
25490         local count
25491
25492         for ((count = 1; count < $((max_blksz / PAGE_SIZE)); count *= 2)); do
25493                 dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=$count seek=$count \
25494                         oflag=sync conv=notrunc
25495
25496                 blksz=$(zfs_object_blksz $facet $zfs_objid)
25497                 (( $blksz == 2 * count * PAGE_SIZE )) ||
25498                         error "blksz error, actual $blksz, " \
25499                                 "expected: 2 * $count * $PAGE_SIZE"
25500         done
25501         rm -f $tf
25502
25503         # random write
25504         $LFS setstripe -c1 $tf
25505         facet="ost$(($($LFS getstripe -i $tf) + 1))"
25506         zfs_objid=$(zfs_get_objid $facet $tf)
25507
25508         dd if=/dev/zero of=$tf bs=1K count=1 oflag=sync conv=notrunc
25509         blksz=$(zfs_object_blksz $facet $zfs_objid)
25510         (( blksz == PAGE_SIZE )) ||
25511                 error "blksz error: $blksz, expected: $PAGE_SIZE"
25512
25513         dd if=/dev/zero of=$tf bs=64K count=1 oflag=sync conv=notrunc seek=128
25514         blksz=$(zfs_object_blksz $facet $zfs_objid)
25515         (( blksz == 65536 )) || error "blksz error: $blksz, expected: 64k"
25516
25517         dd if=/dev/zero of=$tf bs=1M count=1 oflag=sync conv=notrunc
25518         blksz=$(zfs_object_blksz $facet $zfs_objid)
25519         (( blksz == 65536 )) || error "rewrite error: $blksz, expected: 64k"
25520 }
25521 run_test 312 "make sure ZFS adjusts its block size by write pattern"
25522
25523 test_313() {
25524         remote_ost_nodsh && skip "remote OST with nodsh"
25525
25526         local file=$DIR/$tfile
25527
25528         rm -f $file
25529         $LFS setstripe -c 1 -i 0 $file || error "setstripe failed"
25530
25531         # define OBD_FAIL_TGT_RCVD_EIO           0x720
25532         do_facet ost1 "$LCTL set_param fail_loc=0x720"
25533         dd if=/dev/zero of=$file bs=$PAGE_SIZE oflag=direct count=1 &&
25534                 error "write should failed"
25535         do_facet ost1 "$LCTL set_param fail_loc=0"
25536         rm -f $file
25537 }
25538 run_test 313 "io should fail after last_rcvd update fail"
25539
25540 test_314() {
25541         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
25542
25543         $LFS setstripe -c 2 -i 0 $DIR/$tfile || error "setstripe failed"
25544         do_facet ost1 "$LCTL set_param fail_loc=0x720"
25545         rm -f $DIR/$tfile
25546         wait_delete_completed
25547         do_facet ost1 "$LCTL set_param fail_loc=0"
25548 }
25549 run_test 314 "OSP shouldn't fail after last_rcvd update failure"
25550
25551 test_315() { # LU-618
25552         [ -f /proc/$$/io ] || skip_env "no IO accounting in kernel"
25553
25554         local file=$DIR/$tfile
25555         rm -f $file
25556
25557         $MULTIOP $file oO_CREAT:O_DIRECT:O_RDWR:w4063232c ||
25558                 error "multiop file write failed"
25559         $MULTIOP $file oO_RDONLY:r4063232_c &
25560         PID=$!
25561
25562         sleep 2
25563
25564         local rbytes=$(awk '/read_bytes/ { print $2 }' /proc/$PID/io)
25565         kill -USR1 $PID
25566
25567         [ $rbytes -gt 4000000 ] || error "read is not accounted ($rbytes)"
25568         rm -f $file
25569 }
25570 run_test 315 "read should be accounted"
25571
25572 test_316() {
25573         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
25574         large_xattr_enabled || skip "ea_inode feature disabled"
25575
25576         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
25577         mkdir $DIR/$tdir/d || error "mkdir $tdir/d failed"
25578         chown nobody $DIR/$tdir/d || error "chown $tdir/d failed"
25579         touch $DIR/$tdir/d/$tfile || error "touch $tdir/d/$tfile failed"
25580
25581         $LFS migrate -m1 $DIR/$tdir/d || error "lfs migrate -m1 failed"
25582 }
25583 run_test 316 "lfs migrate of file with large_xattr enabled"
25584
25585 test_317() {
25586         [ $MDS1_VERSION -lt $(version_code 2.11.53) ] &&
25587                 skip "Need MDS version at least 2.11.53"
25588         if [ "$ost1_FSTYPE" == "zfs" ]; then
25589                 skip "LU-10370: no implementation for ZFS"
25590         fi
25591
25592         local trunc_sz
25593         local grant_blk_size
25594
25595         grant_blk_size=$($LCTL get_param osc.$FSNAME*.import |
25596                         awk '/grant_block_size:/ { print $2; exit; }')
25597         #
25598         # Create File of size 5M. Truncate it to below size's and verify
25599         # blocks count.
25600         #
25601         dd if=/dev/zero of=$DIR/$tfile bs=5M count=1 conv=fsync ||
25602                 error "Create file $DIR/$tfile failed"
25603         stack_trap "rm -f $DIR/$tfile" EXIT
25604
25605         for trunc_sz in 2097152 4097 4000 509 0; do
25606                 $TRUNCATE $DIR/$tfile $trunc_sz ||
25607                         error "truncate $tfile to $trunc_sz failed"
25608                 local sz=$(stat --format=%s $DIR/$tfile)
25609                 local blk=$(stat --format=%b $DIR/$tfile)
25610                 local trunc_blk=$((((trunc_sz + (grant_blk_size - 1) ) /
25611                                      grant_blk_size) * 8))
25612
25613                 if [[ $blk -ne $trunc_blk ]]; then
25614                         $(which stat) $DIR/$tfile
25615                         error "Expected Block $trunc_blk got $blk for $tfile"
25616                 fi
25617
25618                 $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
25619                         error "Expected Size $trunc_sz got $sz for $tfile"
25620         done
25621
25622         #
25623         # sparse file test
25624         # Create file with a hole and write actual 65536 bytes which aligned
25625         # with 4K and 64K PAGE_SIZE. Block count must be 128.
25626         #
25627         local bs=65536
25628         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 seek=5 conv=fsync ||
25629                 error "Create file : $DIR/$tfile"
25630
25631         #
25632         # Truncate to size $trunc_sz bytes. Strip tail blocks and leave only 8
25633         # blocks. The block count must drop to 8.
25634         #
25635         trunc_sz=$(($(stat --format=%s $DIR/$tfile) -
25636                 ((bs - grant_blk_size) + 1)))
25637         $TRUNCATE $DIR/$tfile $trunc_sz ||
25638                 error "truncate $tfile to $trunc_sz failed"
25639
25640         local trunc_bsz=$((grant_blk_size / $(stat --format=%B $DIR/$tfile)))
25641         sz=$(stat --format=%s $DIR/$tfile)
25642         blk=$(stat --format=%b $DIR/$tfile)
25643
25644         if [[ $blk -ne $trunc_bsz ]]; then
25645                 $(which stat) $DIR/$tfile
25646                 error "Expected Block $trunc_bsz got $blk for $tfile"
25647         fi
25648
25649         $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
25650                 error "Expected Size $trunc_sz got $sz for $tfile"
25651 }
25652 run_test 317 "Verify blocks get correctly update after truncate"
25653
25654 test_318() {
25655         local llite_name="llite.$($LFS getname $MOUNT | awk '{print $1}')"
25656         local old_max_active=$($LCTL get_param -n \
25657                             ${llite_name}.max_read_ahead_async_active \
25658                             2>/dev/null)
25659
25660         $LCTL set_param llite.*.max_read_ahead_async_active=256
25661         local max_active=$($LCTL get_param -n \
25662                            ${llite_name}.max_read_ahead_async_active \
25663                            2>/dev/null)
25664         [ $max_active -ne 256 ] && error "expected 256 but got $max_active"
25665
25666         $LCTL set_param llite.*.max_read_ahead_async_active=0 ||
25667                 error "set max_read_ahead_async_active should succeed"
25668
25669         $LCTL set_param llite.*.max_read_ahead_async_active=512
25670         max_active=$($LCTL get_param -n \
25671                      ${llite_name}.max_read_ahead_async_active 2>/dev/null)
25672         [ $max_active -eq 512 ] || error "expected 512 but got $max_active"
25673
25674         # restore @max_active
25675         [ $old_max_active -ne 0 ] && $LCTL set_param \
25676                 llite.*.max_read_ahead_async_active=$old_max_active
25677
25678         local old_threshold=$($LCTL get_param -n \
25679                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
25680         local max_per_file_mb=$($LCTL get_param -n \
25681                 ${llite_name}.max_read_ahead_per_file_mb 2>/dev/null)
25682
25683         local invalid=$(($max_per_file_mb + 1))
25684         $LCTL set_param \
25685                 llite.*.read_ahead_async_file_threshold_mb=$invalid\
25686                         && error "set $invalid should fail"
25687
25688         local valid=$(($invalid - 1))
25689         $LCTL set_param \
25690                 llite.*.read_ahead_async_file_threshold_mb=$valid ||
25691                         error "set $valid should succeed"
25692         local threshold=$($LCTL get_param -n \
25693                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
25694         [ $threshold -eq $valid ] || error \
25695                 "expect threshold $valid got $threshold"
25696         $LCTL set_param \
25697                 llite.*.read_ahead_async_file_threshold_mb=$old_threshold
25698 }
25699 run_test 318 "Verify async readahead tunables"
25700
25701 test_319() {
25702         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
25703
25704         local before=$(date +%s)
25705         local evict
25706         local mdir=$DIR/$tdir
25707         local file=$mdir/xxx
25708
25709         $LFS mkdir -i0 $mdir || error "mkdir $mdir fails"
25710         touch $file
25711
25712 #define OBD_FAIL_LDLM_LOCAL_CANCEL_PAUSE 0x32c
25713         $LCTL set_param fail_val=5 fail_loc=0x8000032c
25714         $LFS migrate -m1 $mdir &
25715
25716         sleep 1
25717         dd if=$file of=/dev/null
25718         wait
25719         evict=$($LCTL get_param mdc.$FSNAME-MDT*.state |
25720           awk -F"[ [,]" '/EVICTED ]$/ { if (mx<$5) {mx=$5;} } END { print mx }')
25721
25722         [ -z "$evict" ] || [[ $evict -le $before ]] || error "eviction happened"
25723 }
25724 run_test 319 "lost lease lock on migrate error"
25725
25726 test_398a() { # LU-4198
25727         local ost1_imp=$(get_osc_import_name client ost1)
25728         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
25729                          cut -d'.' -f2)
25730
25731         $LFS setstripe -c 1 -i 0 $DIR/$tfile
25732         stack_trap "rm -f $DIR/$tfile"
25733         $LCTL set_param ldlm.namespaces.*.lru_size=clear
25734
25735         # request a new lock on client
25736         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
25737
25738         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
25739         local lock_count=$($LCTL get_param -n \
25740                            ldlm.namespaces.$imp_name.lru_size)
25741         [[ $lock_count -eq 0 ]] || error "lock should be cancelled by direct IO"
25742
25743         $LCTL set_param ldlm.namespaces.*-OST0000-osc-ffff*.lru_size=clear
25744
25745         # no lock cached, should use lockless DIO and not enqueue new lock
25746         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
25747         lock_count=$($LCTL get_param -n \
25748                      ldlm.namespaces.$imp_name.lru_size)
25749         [[ $lock_count -eq 0 ]] || error "no lock should be held by direct IO"
25750
25751         $LCTL set_param ldlm.namespaces.*-OST0000-osc-ffff*.lru_size=clear
25752
25753         # no lock cached, should use locked DIO append
25754         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct oflag=append \
25755                 conv=notrunc || error "DIO append failed"
25756         lock_count=$($LCTL get_param -n \
25757                      ldlm.namespaces.*-OST0000-osc-ffff*.lru_size)
25758         [[ $lock_count -ne 0 ]] || error "lock still must be held by DIO append"
25759 }
25760 run_test 398a "direct IO should cancel lock otherwise lockless"
25761
25762 test_398b() { # LU-4198
25763         local before=$(date +%s)
25764         local njobs=4
25765         local size=48
25766
25767         which fio || skip_env "no fio installed"
25768         $LFS setstripe -c -1 -S 1M $DIR/$tfile
25769         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size
25770
25771         # Single page, multiple pages, stripe size, 4*stripe size
25772         for bsize in $(( $PAGE_SIZE )) $(( 4*$PAGE_SIZE )) 1048576 4194304; do
25773                 echo "mix direct rw ${bsize} by fio with $njobs jobs..."
25774                 fio --name=rand-rw --rw=randrw --bs=$bsize --direct=1 \
25775                         --numjobs=$njobs --fallocate=none \
25776                         --iodepth=16 --allow_file_create=0 \
25777                         --size=$((size/njobs))M \
25778                         --filename=$DIR/$tfile &
25779                 bg_pid=$!
25780
25781                 echo "mix buffer rw ${bsize} by fio with $njobs jobs..."
25782                 fio --name=rand-rw --rw=randrw --bs=$bsize \
25783                         --numjobs=$njobs --fallocate=none \
25784                         --iodepth=16 --allow_file_create=0 \
25785                         --size=$((size/njobs))M \
25786                         --filename=$DIR/$tfile || true
25787                 wait $bg_pid
25788         done
25789
25790         evict=$(do_facet client $LCTL get_param \
25791                 osc.$FSNAME-OST*-osc-*/state |
25792             awk -F"[ [,]" '/EVICTED ]$/ { if (t<$5) {t=$5;} } END { print t }')
25793
25794         [ -z "$evict" ] || [[ $evict -le $before ]] ||
25795                 (do_facet client $LCTL get_param \
25796                         osc.$FSNAME-OST*-osc-*/state;
25797                     error "eviction happened: $evict before:$before")
25798
25799         rm -f $DIR/$tfile
25800 }
25801 run_test 398b "DIO and buffer IO race"
25802
25803 test_398c() { # LU-4198
25804         local ost1_imp=$(get_osc_import_name client ost1)
25805         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
25806                          cut -d'.' -f2)
25807
25808         which fio || skip_env "no fio installed"
25809
25810         saved_debug=$($LCTL get_param -n debug)
25811         $LCTL set_param debug=0
25812
25813         local size=$(lctl get_param -n osc.$FSNAME-OST0000*.kbytesavail | head -1)
25814         ((size /= 1024)) # by megabytes
25815         ((size /= 2)) # write half of the OST at most
25816         [ $size -gt 40 ] && size=40 #reduce test time anyway
25817
25818         $LFS setstripe -c 1 $DIR/$tfile
25819
25820         # it seems like ldiskfs reserves more space than necessary if the
25821         # writing blocks are not mapped, so it extends the file firstly
25822         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size && sync
25823         cancel_lru_locks osc
25824
25825         # clear and verify rpc_stats later
25826         $LCTL set_param osc.${FSNAME}-OST0000-osc-ffff*.rpc_stats=clear
25827
25828         local njobs=4
25829         echo "writing ${size}M to OST0 by fio with $njobs jobs..."
25830         fio --name=rand-write --rw=randwrite --bs=$PAGE_SIZE --direct=1 \
25831                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
25832                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
25833                 --filename=$DIR/$tfile
25834         [ $? -eq 0 ] || error "fio write error"
25835
25836         [ $($LCTL get_param -n ldlm.namespaces.$imp_name.lock_count) -eq 0 ] ||
25837                 error "Locks were requested while doing AIO"
25838
25839         # get the percentage of 1-page I/O
25840         pct=$($LCTL get_param osc.${imp_name}.rpc_stats |
25841                 grep -A 1 'pages per rpc' | grep -v 'pages per rpc' |
25842                 awk '{print $7}')
25843         [ $pct -le 50 ] || error "$pct% of I/O are 1-page"
25844
25845         echo "mix rw ${size}M to OST0 by fio with $njobs jobs..."
25846         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
25847                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
25848                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
25849                 --filename=$DIR/$tfile
25850         [ $? -eq 0 ] || error "fio mixed read write error"
25851
25852         echo "AIO with large block size ${size}M"
25853         fio --name=rand-rw --rw=randrw --bs=${size}M --direct=1 \
25854                 --numjobs=1 --fallocate=none --ioengine=libaio \
25855                 --iodepth=16 --allow_file_create=0 --size=${size}M \
25856                 --filename=$DIR/$tfile
25857         [ $? -eq 0 ] || error "fio large block size failed"
25858
25859         rm -f $DIR/$tfile
25860         $LCTL set_param debug="$saved_debug"
25861 }
25862 run_test 398c "run fio to test AIO"
25863
25864 test_398d() { #  LU-13846
25865         which aiocp || skip_env "no aiocp installed"
25866         local aio_file=$DIR/$tfile.aio
25867
25868         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
25869
25870         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=64
25871         aiocp -a $PAGE_SIZE -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file
25872         stack_trap "rm -f $DIR/$tfile $aio_file"
25873
25874         diff $DIR/$tfile $aio_file || error "file diff after aiocp"
25875
25876         # make sure we don't crash and fail properly
25877         aiocp -a 512 -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
25878                 error "aio not aligned with PAGE SIZE should fail"
25879
25880         rm -f $DIR/$tfile $aio_file
25881 }
25882 run_test 398d "run aiocp to verify block size > stripe size"
25883
25884 test_398e() {
25885         dd if=/dev/zero of=$DIR/$tfile bs=1234 count=1
25886         touch $DIR/$tfile.new
25887         dd if=$DIR/$tfile of=$DIR/$tfile.new bs=1M count=1 oflag=direct
25888 }
25889 run_test 398e "O_Direct open cleared by fcntl doesn't cause hang"
25890
25891 test_398f() { #  LU-14687
25892         which aiocp || skip_env "no aiocp installed"
25893         local aio_file=$DIR/$tfile.aio
25894
25895         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
25896
25897         dd if=/dev/zero of=$DIR/$tfile bs=1M count=64
25898         stack_trap "rm -f $DIR/$tfile $aio_file"
25899
25900         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
25901         $LCTL set_param fail_loc=0x1418
25902         # make sure we don't crash and fail properly
25903         aiocp -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
25904                 error "aio with page allocation failure succeeded"
25905         $LCTL set_param fail_loc=0
25906         diff $DIR/$tfile $aio_file
25907         [[ $? != 0 ]] || error "no diff after failed aiocp"
25908 }
25909 run_test 398f "verify aio handles ll_direct_rw_pages errors correctly"
25910
25911 # NB: To get the parallel DIO behavior in LU-13798, there must be > 1
25912 # stripe and i/o size must be > stripe size
25913 # Old style synchronous DIO waits after submitting each chunk, resulting in a
25914 # single RPC in flight.  This test shows async DIO submission is working by
25915 # showing multiple RPCs in flight.
25916 test_398g() { #  LU-13798
25917         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
25918
25919         # We need to do some i/o first to acquire enough grant to put our RPCs
25920         # in flight; otherwise a new connection may not have enough grant
25921         # available
25922         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
25923                 error "parallel dio failed"
25924         stack_trap "rm -f $DIR/$tfile"
25925
25926         # Reduce RPC size to 1M to avoid combination in to larger RPCs
25927         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
25928         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
25929         stack_trap "$LCTL set_param -n $pages_per_rpc"
25930
25931         # Recreate file so it's empty
25932         rm -f $DIR/$tfile
25933         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
25934         #Pause rpc completion to guarantee we see multiple rpcs in flight
25935         #define OBD_FAIL_OST_BRW_PAUSE_BULK
25936         do_facet ost1 $LCTL set_param fail_loc=0x214 fail_val=2
25937         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
25938
25939         # Clear rpc stats
25940         $LCTL set_param osc.*.rpc_stats=c
25941
25942         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
25943                 error "parallel dio failed"
25944         stack_trap "rm -f $DIR/$tfile"
25945
25946         $LCTL get_param osc.*-OST0000-*.rpc_stats
25947         pct=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
25948                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
25949                 grep "8:" | awk '{print $8}')
25950         # We look at the "8 rpcs in flight" field, and verify A) it is present
25951         # and B) it includes all RPCs.  This proves we had 8 RPCs in flight,
25952         # as expected for an 8M DIO to a file with 1M stripes.
25953         [ $pct -eq 100 ] || error "we should see 8 RPCs in flight"
25954
25955         # Verify turning off parallel dio works as expected
25956         # Clear rpc stats
25957         $LCTL set_param osc.*.rpc_stats=c
25958         $LCTL set_param llite.*.parallel_dio=0
25959         stack_trap '$LCTL set_param llite.*.parallel_dio=1'
25960
25961         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
25962                 error "dio with parallel dio disabled failed"
25963
25964         # Ideally, we would see only one RPC in flight here, but there is an
25965         # unavoidable race between i/o completion and RPC in flight counting,
25966         # so while only 1 i/o is in flight at a time, the RPC in flight counter
25967         # will sometimes exceed 1 (3 or 4 is not rare on VM testing).
25968         # So instead we just verify it's always < 8.
25969         $LCTL get_param osc.*-OST0000-*.rpc_stats
25970         ret=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
25971                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
25972                 grep '^$' -B1 | grep . | awk '{print $1}')
25973         [ $ret != "8:" ] ||
25974                 error "we should see fewer than 8 RPCs in flight (saw $ret)"
25975 }
25976 run_test 398g "verify parallel dio async RPC submission"
25977
25978 test_398h() { #  LU-13798
25979         local dio_file=$DIR/$tfile.dio
25980
25981         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
25982
25983         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
25984         stack_trap "rm -f $DIR/$tfile $dio_file"
25985
25986         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct ||
25987                 error "parallel dio failed"
25988         diff $DIR/$tfile $dio_file
25989         [[ $? == 0 ]] || error "file diff after aiocp"
25990 }
25991 run_test 398h "verify correctness of read & write with i/o size >> stripe size"
25992
25993 test_398i() { #  LU-13798
25994         local dio_file=$DIR/$tfile.dio
25995
25996         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
25997
25998         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
25999         stack_trap "rm -f $DIR/$tfile $dio_file"
26000
26001         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
26002         $LCTL set_param fail_loc=0x1418
26003         # make sure we don't crash and fail properly
26004         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct &&
26005                 error "parallel dio page allocation failure succeeded"
26006         diff $DIR/$tfile $dio_file
26007         [[ $? != 0 ]] || error "no diff after failed aiocp"
26008 }
26009 run_test 398i "verify parallel dio handles ll_direct_rw_pages errors correctly"
26010
26011 test_398j() { #  LU-13798
26012         # Stripe size > RPC size but less than i/o size tests split across
26013         # stripes and RPCs for individual i/o op
26014         $LFS setstripe -o 0,0 -S 4M $DIR/$tfile $DIR/$tfile.2
26015
26016         # Reduce RPC size to 1M to guarantee split to multiple RPCs per stripe
26017         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
26018         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
26019         stack_trap "$LCTL set_param -n $pages_per_rpc"
26020
26021         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
26022                 error "parallel dio write failed"
26023         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.2"
26024
26025         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct ||
26026                 error "parallel dio read failed"
26027         diff $DIR/$tfile $DIR/$tfile.2
26028         [[ $? == 0 ]] || error "file diff after parallel dio read"
26029 }
26030 run_test 398j "test parallel dio where stripe size > rpc_size"
26031
26032 test_398k() { #  LU-13798
26033         wait_delete_completed
26034         wait_mds_ost_sync
26035
26036         # 4 stripe file; we will cause out of space on OST0
26037         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
26038
26039         # Fill OST0 (if it's not too large)
26040         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
26041                    head -n1)
26042         if [[ $ORIGFREE -gt $MAXFREE ]]; then
26043                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
26044         fi
26045         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
26046         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
26047                 error "dd should fill OST0"
26048         stack_trap "rm -f $DIR/$tfile.1"
26049
26050         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
26051         err=$?
26052
26053         ls -la $DIR/$tfile
26054         $CHECKSTAT -t file -s 0 $DIR/$tfile ||
26055                 error "file is not 0 bytes in size"
26056
26057         # dd above should not succeed, but don't error until here so we can
26058         # get debug info above
26059         [[ $err != 0 ]] ||
26060                 error "parallel dio write with enospc succeeded"
26061         stack_trap "rm -f $DIR/$tfile"
26062 }
26063 run_test 398k "test enospc on first stripe"
26064
26065 test_398l() { #  LU-13798
26066         wait_delete_completed
26067         wait_mds_ost_sync
26068
26069         # 4 stripe file; we will cause out of space on OST0
26070         # Note the 1M stripe size and the > 1M i/o size mean this ENOSPC
26071         # happens on the second i/o chunk we issue
26072         $LFS setstripe -o 1,0,1,0 -S 1M $DIR/$tfile $DIR/$tfile.2
26073
26074         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=2 oflag=direct
26075         stack_trap "rm -f $DIR/$tfile"
26076
26077         # Fill OST0 (if it's not too large)
26078         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
26079                    head -n1)
26080         if [[ $ORIGFREE -gt $MAXFREE ]]; then
26081                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
26082         fi
26083         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
26084         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
26085                 error "dd should fill OST0"
26086         stack_trap "rm -f $DIR/$tfile.1"
26087
26088         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 oflag=direct
26089         err=$?
26090         stack_trap "rm -f $DIR/$tfile.2"
26091
26092         # Check that short write completed as expected
26093         ls -la $DIR/$tfile.2
26094         $CHECKSTAT -t file -s 1048576 $DIR/$tfile.2 ||
26095                 error "file is not 1M in size"
26096
26097         # dd above should not succeed, but don't error until here so we can
26098         # get debug info above
26099         [[ $err != 0 ]] ||
26100                 error "parallel dio write with enospc succeeded"
26101
26102         # Truncate source file to same length as output file and diff them
26103         $TRUNCATE $DIR/$tfile 1048576
26104         diff $DIR/$tfile $DIR/$tfile.2
26105         [[ $? == 0 ]] || error "data incorrect after short write"
26106 }
26107 run_test 398l "test enospc on intermediate stripe/RPC"
26108
26109 test_398m() { #  LU-13798
26110         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
26111
26112         # Set up failure on OST0, the first stripe:
26113         #define OBD_FAIL_OST_BRW_WRITE_BULK     0x20e
26114         #NB: Fail val is ost # + 1, because we cannot use cfs_fail_val = 0
26115         # OST0 is on ost1, OST1 is on ost2.
26116         # So this fail_val specifies OST0
26117         do_facet ost1 $LCTL set_param fail_loc=0x20e fail_val=1
26118         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
26119
26120         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
26121                 error "parallel dio write with failure on first stripe succeeded"
26122         stack_trap "rm -f $DIR/$tfile"
26123         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
26124
26125         # Place data in file for read
26126         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
26127                 error "parallel dio write failed"
26128
26129         # Fail read on OST0, first stripe
26130         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
26131         do_facet ost1 $LCTL set_param fail_loc=0x20f fail_val=1
26132         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
26133                 error "parallel dio read with error on first stripe succeeded"
26134         rm -f $DIR/$tfile.2
26135         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
26136
26137         # Switch to testing on OST1, second stripe
26138         # Clear file contents, maintain striping
26139         echo > $DIR/$tfile
26140         # Set up failure on OST1, second stripe:
26141         do_facet ost2 $LCTL set_param fail_loc=0x20e fail_val=2
26142         stack_trap "do_facet ost2 $LCTL set_param fail_loc=0"
26143
26144         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
26145                 error "parallel dio write with failure on second stripe succeeded"
26146         stack_trap "rm -f $DIR/$tfile"
26147         do_facet ost2 $LCTL set_param fail_loc=0 fail_val=0
26148
26149         # Place data in file for read
26150         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
26151                 error "parallel dio write failed"
26152
26153         # Fail read on OST1, second stripe
26154         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
26155         do_facet ost2 $LCTL set_param fail_loc=0x20f fail_val=2
26156         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
26157                 error "parallel dio read with error on second stripe succeeded"
26158         rm -f $DIR/$tfile.2
26159         do_facet ost2 $LCTL set_param fail_loc=0 fail_val=0
26160 }
26161 run_test 398m "test RPC failures with parallel dio"
26162
26163 # Parallel submission of DIO should not cause problems for append, but it's
26164 # important to verify.
26165 test_398n() { #  LU-13798
26166         $LFS setstripe -C 2 -S 1M $DIR/$tfile
26167
26168         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 ||
26169                 error "dd to create source file failed"
26170         stack_trap "rm -f $DIR/$tfile"
26171
26172         dd if=$DIR/$tfile of=$DIR/$tfile.1 bs=8M count=8 oflag=direct oflag=append ||
26173                 error "parallel dio write with failure on second stripe succeeded"
26174         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.1"
26175         diff $DIR/$tfile $DIR/$tfile.1
26176         [[ $? == 0 ]] || error "data incorrect after append"
26177
26178 }
26179 run_test 398n "test append with parallel DIO"
26180
26181 test_398o() {
26182         directio rdwr $DIR/$tfile 0 1 1 || error "bad KMS"
26183 }
26184 run_test 398o "right kms with DIO"
26185
26186 test_398p()
26187 {
26188         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
26189         which aiocp || skip_env "no aiocp installed"
26190
26191         local stripe_size=$((1024 * 1024)) #1 MiB
26192         # Max i/o below is ~ 4 * stripe_size, so this gives ~5 i/os
26193         local file_size=$((25 * stripe_size))
26194
26195         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
26196         stack_trap "rm -f $DIR/$tfile*"
26197         # Just a bit bigger than the largest size in the test set below
26198         dd if=/dev/urandom bs=$file_size count=1 of=$DIR/$tfile.1 ||
26199                 error "buffered i/o to create file failed"
26200
26201         for bs in $PAGE_SIZE $((PAGE_SIZE * 4)) $stripe_size \
26202                 $((stripe_size * 4)); do
26203
26204                 $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.2
26205
26206                 echo "bs: $bs, file_size $file_size"
26207                 aiocp -a $PAGE_SIZE -b $bs -s $file_size -f O_DIRECT \
26208                         $DIR/$tfile.1 $DIR/$tfile.2 &
26209                 pid_dio1=$!
26210                 # Buffered I/O with similar but not the same block size
26211                 dd if=$DIR/$tfile.1 bs=$((bs * 2)) of=$DIR/$tfile.2 \
26212                         conv=notrunc &
26213                 pid_bio2=$!
26214                 wait $pid_dio1
26215                 rc1=$?
26216                 wait $pid_bio2
26217                 rc2=$?
26218                 if (( rc1 != 0 )); then
26219                         error "aio copy 1 w/bsize $bs failed: $rc1"
26220                 fi
26221                 if (( rc2 != 0 )); then
26222                         error "buffered copy 2 w/bsize $bs failed: $rc2"
26223                 fi
26224
26225                 $CHECKSTAT -t file -s $file_size $DIR/$tfile.2 ||
26226                         error "size incorrect"
26227                 cmp --verbose $DIR/$tfile.1 $DIR/$tfile.2 ||
26228                         error "files differ, bsize $bs"
26229                 rm -f $DIR/$tfile.2
26230         done
26231 }
26232 run_test 398p "race aio with buffered i/o"
26233
26234 test_fake_rw() {
26235         local read_write=$1
26236         if [ "$read_write" = "write" ]; then
26237                 local dd_cmd="dd if=/dev/zero of=$DIR/$tfile"
26238         elif [ "$read_write" = "read" ]; then
26239                 local dd_cmd="dd of=/dev/null if=$DIR/$tfile"
26240         else
26241                 error "argument error"
26242         fi
26243
26244         # turn off debug for performance testing
26245         local saved_debug=$($LCTL get_param -n debug)
26246         $LCTL set_param debug=0
26247
26248         $LFS setstripe -c 1 -i 0 $DIR/$tfile
26249
26250         # get ost1 size - $FSNAME-OST0000
26251         local ost1_avail_size=$($LFS df $DIR | awk /${ost1_svc}/'{ print $4 }')
26252         local blocks=$((ost1_avail_size/2/1024)) # half avail space by megabytes
26253         [ $blocks -gt 1000 ] && blocks=1000 # 1G in maximum
26254
26255         if [ "$read_write" = "read" ]; then
26256                 $TRUNCATE $DIR/$tfile $(expr 1048576 \* $blocks)
26257         fi
26258
26259         local start_time=$(date +%s.%N)
26260         $dd_cmd bs=1M count=$blocks oflag=sync ||
26261                 error "real dd $read_write error"
26262         local duration=$(bc <<< "$(date +%s.%N) - $start_time")
26263
26264         if [ "$read_write" = "write" ]; then
26265                 rm -f $DIR/$tfile
26266         fi
26267
26268         # define OBD_FAIL_OST_FAKE_RW           0x238
26269         do_facet ost1 $LCTL set_param fail_loc=0x238
26270
26271         local start_time=$(date +%s.%N)
26272         $dd_cmd bs=1M count=$blocks oflag=sync ||
26273                 error "fake dd $read_write error"
26274         local duration_fake=$(bc <<< "$(date +%s.%N) - $start_time")
26275
26276         if [ "$read_write" = "write" ]; then
26277                 # verify file size
26278                 cancel_lru_locks osc
26279                 $CHECKSTAT -t file -s $((blocks * 1024 * 1024)) $DIR/$tfile ||
26280                         error "$tfile size not $blocks MB"
26281         fi
26282         do_facet ost1 $LCTL set_param fail_loc=0
26283
26284         echo "fake $read_write $duration_fake vs. normal $read_write" \
26285                 "$duration in seconds"
26286         [ $(bc <<< "$duration_fake < $duration") -eq 1 ] ||
26287                 error_not_in_vm "fake write is slower"
26288
26289         $LCTL set_param -n debug="$saved_debug"
26290         rm -f $DIR/$tfile
26291 }
26292 test_399a() { # LU-7655 for OST fake write
26293         remote_ost_nodsh && skip "remote OST with nodsh"
26294
26295         test_fake_rw write
26296 }
26297 run_test 399a "fake write should not be slower than normal write"
26298
26299 test_399b() { # LU-8726 for OST fake read
26300         remote_ost_nodsh && skip "remote OST with nodsh"
26301         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
26302                 skip_env "ldiskfs only test"
26303         fi
26304
26305         test_fake_rw read
26306 }
26307 run_test 399b "fake read should not be slower than normal read"
26308
26309 test_400a() { # LU-1606, was conf-sanity test_74
26310         if ! which $CC > /dev/null 2>&1; then
26311                 skip_env "$CC is not installed"
26312         fi
26313
26314         local extra_flags=''
26315         local out=$TMP/$tfile
26316         local prefix=/usr/include/lustre
26317         local prog
26318
26319         # Oleg removes .c files in his test rig so test if any c files exist
26320         [[ -n "$(ls -A $LUSTRE_TESTS_API_DIR)" ]] ||
26321                 skip_env "Needed .c test files are missing"
26322
26323         if ! [[ -d $prefix ]]; then
26324                 # Assume we're running in tree and fixup the include path.
26325                 extra_flags+=" -I$LUSTRE/../lnet/include/uapi"
26326                 extra_flags+=" -I$LUSTRE/include/uapi -I$LUSTRE/include"
26327                 extra_flags+=" -L$LUSTRE/utils/.libs"
26328         fi
26329
26330         for prog in $LUSTRE_TESTS_API_DIR/*.c; do
26331                 $CC -Wall -Werror $extra_flags -o $out $prog -llustreapi ||
26332                         error "client api broken"
26333         done
26334         rm -f $out
26335 }
26336 run_test 400a "Lustre client api program can compile and link"
26337
26338 test_400b() { # LU-1606, LU-5011
26339         local header
26340         local out=$TMP/$tfile
26341         local prefix=/usr/include/linux/lustre
26342
26343         # We use a hard coded prefix so that this test will not fail
26344         # when run in tree. There are headers in lustre/include/lustre/
26345         # that are not packaged (like lustre_idl.h) and have more
26346         # complicated include dependencies (like config.h and lnet/types.h).
26347         # Since this test about correct packaging we just skip them when
26348         # they don't exist (see below) rather than try to fixup cppflags.
26349
26350         if ! which $CC > /dev/null 2>&1; then
26351                 skip_env "$CC is not installed"
26352         fi
26353
26354         for header in $prefix/*.h; do
26355                 if ! [[ -f "$header" ]]; then
26356                         continue
26357                 fi
26358
26359                 if [[ "$(basename $header)" == lustre_ioctl.h ]]; then
26360                         continue # lustre_ioctl.h is internal header
26361                 fi
26362
26363                 $CC -Wall -Werror -include $header -c -x c /dev/null -o $out ||
26364                         error "cannot compile '$header'"
26365         done
26366         rm -f $out
26367 }
26368 run_test 400b "packaged headers can be compiled"
26369
26370 test_401a() { #LU-7437
26371         local printf_arg=$(find -printf 2>&1 | grep "unrecognized:")
26372         [ -n "$printf_arg" ] && skip_env "find does not support -printf"
26373
26374         #count the number of parameters by "list_param -R"
26375         local params=$($LCTL list_param -R '*' 2>/dev/null | wc -l)
26376         #count the number of parameters by listing proc files
26377         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
26378         echo "proc_dirs='$proc_dirs'"
26379         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
26380         local procs=$(find -L $proc_dirs -mindepth 1 -printf '%P\n' 2>/dev/null|
26381                       sort -u | wc -l)
26382
26383         [ $params -eq $procs ] ||
26384                 error "found $params parameters vs. $procs proc files"
26385
26386         # test the list_param -D option only returns directories
26387         params=$($LCTL list_param -R -D '*' 2>/dev/null | wc -l)
26388         #count the number of parameters by listing proc directories
26389         procs=$(find -L $proc_dirs -mindepth 1 -type d -printf '%P\n' 2>/dev/null |
26390                 sort -u | wc -l)
26391
26392         [ $params -eq $procs ] ||
26393                 error "found $params parameters vs. $procs proc files"
26394 }
26395 run_test 401a "Verify if 'lctl list_param -R' can list parameters recursively"
26396
26397 test_401b() {
26398         # jobid_var may not allow arbitrary values, so use jobid_name
26399         # if available
26400         if $LCTL list_param jobid_name > /dev/null 2>&1; then
26401                 local testname=jobid_name tmp='testing%p'
26402         else
26403                 local testname=jobid_var tmp=testing
26404         fi
26405
26406         local save=$($LCTL get_param -n $testname)
26407
26408         $LCTL set_param foo=bar $testname=$tmp bar=baz &&
26409                 error "no error returned when setting bad parameters"
26410
26411         local jobid_new=$($LCTL get_param -n foe $testname baz)
26412         [[ "$jobid_new" == "$tmp" ]] || error "jobid tmp $jobid_new != $tmp"
26413
26414         $LCTL set_param -n fog=bam $testname=$save bat=fog
26415         local jobid_old=$($LCTL get_param -n foe $testname bag)
26416         [[ "$jobid_old" == "$save" ]] || error "jobid new $jobid_old != $save"
26417 }
26418 run_test 401b "Verify 'lctl {get,set}_param' continue after error"
26419
26420 test_401c() {
26421         # jobid_var may not allow arbitrary values, so use jobid_name
26422         # if available
26423         if $LCTL list_param jobid_name > /dev/null 2>&1; then
26424                 local testname=jobid_name
26425         else
26426                 local testname=jobid_var
26427         fi
26428
26429         local jobid_var_old=$($LCTL get_param -n $testname)
26430         local jobid_var_new
26431
26432         $LCTL set_param $testname= &&
26433                 error "no error returned for 'set_param a='"
26434
26435         jobid_var_new=$($LCTL get_param -n $testname)
26436         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
26437                 error "$testname was changed by setting without value"
26438
26439         $LCTL set_param $testname &&
26440                 error "no error returned for 'set_param a'"
26441
26442         jobid_var_new=$($LCTL get_param -n $testname)
26443         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
26444                 error "$testname was changed by setting without value"
26445 }
26446 run_test 401c "Verify 'lctl set_param' without value fails in either format."
26447
26448 test_401d() {
26449         # jobid_var may not allow arbitrary values, so use jobid_name
26450         # if available
26451         if $LCTL list_param jobid_name > /dev/null 2>&1; then
26452                 local testname=jobid_name new_value='foo=bar%p'
26453         else
26454                 local testname=jobid_var new_valuie=foo=bar
26455         fi
26456
26457         local jobid_var_old=$($LCTL get_param -n $testname)
26458         local jobid_var_new
26459
26460         $LCTL set_param $testname=$new_value ||
26461                 error "'set_param a=b' did not accept a value containing '='"
26462
26463         jobid_var_new=$($LCTL get_param -n $testname)
26464         [[ "$jobid_var_new" == "$new_value" ]] ||
26465                 error "'set_param a=b' failed on a value containing '='"
26466
26467         # Reset the $testname to test the other format
26468         $LCTL set_param $testname=$jobid_var_old
26469         jobid_var_new=$($LCTL get_param -n $testname)
26470         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
26471                 error "failed to reset $testname"
26472
26473         $LCTL set_param $testname $new_value ||
26474                 error "'set_param a b' did not accept a value containing '='"
26475
26476         jobid_var_new=$($LCTL get_param -n $testname)
26477         [[ "$jobid_var_new" == "$new_value" ]] ||
26478                 error "'set_param a b' failed on a value containing '='"
26479
26480         $LCTL set_param $testname $jobid_var_old
26481         jobid_var_new=$($LCTL get_param -n $testname)
26482         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
26483                 error "failed to reset $testname"
26484 }
26485 run_test 401d "Verify 'lctl set_param' accepts values containing '='"
26486
26487 test_401e() { # LU-14779
26488         $LCTL list_param -R "ldlm.namespaces.MGC*" ||
26489                 error "lctl list_param MGC* failed"
26490         $LCTL get_param "ldlm.namespaces.MGC*" || error "lctl get_param failed"
26491         $LCTL get_param "ldlm.namespaces.MGC*.lru_size" ||
26492                 error "lctl get_param lru_size failed"
26493 }
26494 run_test 401e "verify 'lctl get_param' works with NID in parameter"
26495
26496 test_402() {
26497         [[ $MDS1_VERSION -ge $(version_code 2.7.66) ]] ||
26498         [[ $MDS1_VERSION -ge $(version_code 2.7.18.4) &&
26499                 $MDS1_VERSION -lt $(version_code 2.7.50) ]] ||
26500         [[ $MDS1_VERSION -ge $(version_code 2.7.2) &&
26501                 $MDS1_VERSION -lt $(version_code 2.7.11) ]] ||
26502                 skip "Need MDS version 2.7.2+ or 2.7.18.4+ or 2.7.66+"
26503         remote_mds_nodsh && skip "remote MDS with nodsh"
26504
26505         $LFS setdirstripe -i 0 $DIR/$tdir || error "setdirstripe -i 0 failed"
26506 #define OBD_FAIL_MDS_FLD_LOOKUP 0x15c
26507         do_facet mds1 "lctl set_param fail_loc=0x8000015c"
26508         touch $DIR/$tdir/$tfile && error "touch should fail with ENOENT" ||
26509                 echo "Touch failed - OK"
26510 }
26511 run_test 402 "Return ENOENT to lod_generate_and_set_lovea"
26512
26513 test_403() {
26514         local file1=$DIR/$tfile.1
26515         local file2=$DIR/$tfile.2
26516         local tfile=$TMP/$tfile
26517
26518         rm -f $file1 $file2 $tfile
26519
26520         touch $file1
26521         ln $file1 $file2
26522
26523         # 30 sec OBD_TIMEOUT in ll_getattr()
26524         # right before populating st_nlink
26525         $LCTL set_param fail_loc=0x80001409
26526         stat -c %h $file1 > $tfile &
26527
26528         # create an alias, drop all locks and reclaim the dentry
26529         < $file2
26530         cancel_lru_locks mdc
26531         cancel_lru_locks osc
26532         sysctl -w vm.drop_caches=2
26533
26534         wait
26535
26536         [ $(cat $tfile) -gt 0 ] || error "wrong nlink count: $(cat $tfile)"
26537
26538         rm -f $tfile $file1 $file2
26539 }
26540 run_test 403 "i_nlink should not drop to zero due to aliasing"
26541
26542 test_404() { # LU-6601
26543         [[ $MDS1_VERSION -ge $(version_code 2.8.53) ]] ||
26544                 skip "Need server version newer than 2.8.52"
26545         remote_mds_nodsh && skip "remote MDS with nodsh"
26546
26547         local mosps=$(do_facet $SINGLEMDS $LCTL dl |
26548                 awk '/osp .*-osc-MDT/ { print $4}')
26549
26550         local osp
26551         for osp in $mosps; do
26552                 echo "Deactivate: " $osp
26553                 do_facet $SINGLEMDS $LCTL --device %$osp deactivate
26554                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
26555                         awk -vp=$osp '$4 == p { print $2 }')
26556                 [ $stat = IN ] || {
26557                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
26558                         error "deactivate error"
26559                 }
26560                 echo "Activate: " $osp
26561                 do_facet $SINGLEMDS $LCTL --device %$osp activate
26562                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
26563                         awk -vp=$osp '$4 == p { print $2 }')
26564                 [ $stat = UP ] || {
26565                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
26566                         error "activate error"
26567                 }
26568         done
26569 }
26570 run_test 404 "validate manual {de}activated works properly for OSPs"
26571
26572 test_405() {
26573         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
26574         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] ||
26575                 [ $CLIENT_VERSION -lt $(version_code 2.6.99) ] &&
26576                         skip "Layout swap lock is not supported"
26577
26578         check_swap_layouts_support
26579         check_swap_layout_no_dom $DIR
26580
26581         test_mkdir $DIR/$tdir
26582         swap_lock_test -d $DIR/$tdir ||
26583                 error "One layout swap locked test failed"
26584 }
26585 run_test 405 "Various layout swap lock tests"
26586
26587 test_406() {
26588         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26589         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
26590         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
26591         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26592         [ $MDS1_VERSION -lt $(version_code 2.8.50) ] &&
26593                 skip "Need MDS version at least 2.8.50"
26594
26595         local def_stripe_size=$($LFS getstripe -S $MOUNT)
26596         local test_pool=$TESTNAME
26597
26598         pool_add $test_pool || error "pool_add failed"
26599         pool_add_targets $test_pool 0 $(($OSTCOUNT - 1)) 1 ||
26600                 error "pool_add_targets failed"
26601
26602         save_layout_restore_at_exit $MOUNT
26603
26604         # parent set default stripe count only, child will stripe from both
26605         # parent and fs default
26606         $LFS setstripe -c 1 -i 1 -S $((def_stripe_size * 2)) -p $test_pool $MOUNT ||
26607                 error "setstripe $MOUNT failed"
26608         $LFS mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
26609         $LFS setstripe -c $OSTCOUNT $DIR/$tdir || error "setstripe $tdir failed"
26610         for i in $(seq 10); do
26611                 local f=$DIR/$tdir/$tfile.$i
26612                 touch $f || error "touch failed"
26613                 local count=$($LFS getstripe -c $f)
26614                 [ $count -eq $OSTCOUNT ] ||
26615                         error "$f stripe count $count != $OSTCOUNT"
26616                 local offset=$($LFS getstripe -i $f)
26617                 [ $offset -eq 1 ] || error "$f stripe offset $offset != 1"
26618                 local size=$($LFS getstripe -S $f)
26619                 [ $size -eq $((def_stripe_size * 2)) ] ||
26620                         error "$f stripe size $size != $((def_stripe_size * 2))"
26621                 local pool=$($LFS getstripe -p $f)
26622                 [ $pool == $test_pool ] || error "$f pool $pool != $test_pool"
26623         done
26624
26625         # change fs default striping, delete parent default striping, now child
26626         # will stripe from new fs default striping only
26627         $LFS setstripe -c 1 -S $def_stripe_size -i 0 $MOUNT ||
26628                 error "change $MOUNT default stripe failed"
26629         $LFS setstripe -c 0 $DIR/$tdir ||
26630                 error "delete $tdir default stripe failed"
26631         for i in $(seq 11 20); do
26632                 local f=$DIR/$tdir/$tfile.$i
26633                 touch $f || error "touch $f failed"
26634                 local count=$($LFS getstripe -c $f)
26635                 [ $count -eq 1 ] || error "$f stripe count $count != 1"
26636                 local offset=$($LFS getstripe -i $f)
26637                 [ $offset -eq 0 ] || error "$f stripe offset $offset != 0"
26638                 local size=$($LFS getstripe -S $f)
26639                 [ $size -eq $def_stripe_size ] ||
26640                         error "$f stripe size $size != $def_stripe_size"
26641                 local pool=$($LFS getstripe -p $f)
26642                 [ $pool == $test_pool ] || error "$f pool $pool isn't set"
26643         done
26644
26645         unlinkmany $DIR/$tdir/$tfile. 1 20
26646
26647         local f=$DIR/$tdir/$tfile
26648         pool_remove_all_targets $test_pool $f
26649         pool_remove $test_pool $f
26650 }
26651 run_test 406 "DNE support fs default striping"
26652
26653 test_407() {
26654         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26655         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
26656                 skip "Need MDS version at least 2.8.55"
26657         remote_mds_nodsh && skip "remote MDS with nodsh"
26658
26659         $LFS mkdir -i 0 -c 1 $DIR/$tdir.0 ||
26660                 error "$LFS mkdir -i 0 -c 1 $tdir.0 failed"
26661         $LFS mkdir -i 1 -c 1 $DIR/$tdir.1 ||
26662                 error "$LFS mkdir -i 1 -c 1 $tdir.1 failed"
26663         touch $DIR/$tdir.0/$tfile.0 || error "touch $tdir.0/$tfile.0 failed"
26664
26665         #define OBD_FAIL_DT_TXN_STOP    0x2019
26666         for idx in $(seq $MDSCOUNT); do
26667                 do_facet mds$idx "lctl set_param fail_loc=0x2019"
26668         done
26669         $LFS mkdir -c 2 $DIR/$tdir && error "$LFS mkdir -c 2 $tdir should fail"
26670         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1/$tfile.1 &&
26671                 error "mv $tdir.0/$tfile.0 $tdir.1/$tfile.1 should fail"
26672         true
26673 }
26674 run_test 407 "transaction fail should cause operation fail"
26675
26676 test_408() {
26677         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
26678
26679         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
26680         lctl set_param fail_loc=0x8000040a
26681         # let ll_prepare_partial_page() fail
26682         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 conv=notrunc || true
26683
26684         rm -f $DIR/$tfile
26685
26686         # create at least 100 unused inodes so that
26687         # shrink_icache_memory(0) should not return 0
26688         touch $DIR/$tfile-{0..100}
26689         rm -f $DIR/$tfile-{0..100}
26690         sync
26691
26692         echo 2 > /proc/sys/vm/drop_caches
26693 }
26694 run_test 408 "drop_caches should not hang due to page leaks"
26695
26696 test_409()
26697 {
26698         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
26699
26700         mkdir -p $DIR/$tdir || error "(0) Fail to mkdir"
26701         $LFS mkdir -i 1 -c 2 $DIR/$tdir/foo || error "(1) Fail to mkdir"
26702         touch $DIR/$tdir/guard || error "(2) Fail to create"
26703
26704         local PREFIX=$(str_repeat 'A' 128)
26705         echo "Create 1K hard links start at $(date)"
26706         createmany -l $DIR/$tdir/guard $DIR/$tdir/foo/${PREFIX}_ 1000 ||
26707                 error "(3) Fail to hard link"
26708
26709         echo "Links count should be right although linkEA overflow"
26710         stat $DIR/$tdir/guard || error "(4) Fail to stat"
26711         local linkcount=$(stat --format=%h $DIR/$tdir/guard)
26712         [ $linkcount -eq 1001 ] ||
26713                 error "(5) Unexpected hard links count: $linkcount"
26714
26715         echo "List all links start at $(date)"
26716         ls -l $DIR/$tdir/foo > /dev/null ||
26717                 error "(6) Fail to list $DIR/$tdir/foo"
26718
26719         echo "Unlink hard links start at $(date)"
26720         unlinkmany $DIR/$tdir/foo/${PREFIX}_ 1000 ||
26721                 error "(7) Fail to unlink"
26722         echo "Unlink hard links finished at $(date)"
26723 }
26724 run_test 409 "Large amount of cross-MDTs hard links on the same file"
26725
26726 test_410()
26727 {
26728         [[ $CLIENT_VERSION -lt $(version_code 2.9.59) ]] &&
26729                 skip "Need client version at least 2.9.59"
26730         [ -f $LUSTRE/tests/kernel/kinode.ko ] ||
26731                 skip "Need MODULES build"
26732
26733         # Create a file, and stat it from the kernel
26734         local testfile=$DIR/$tfile
26735         touch $testfile
26736
26737         local run_id=$RANDOM
26738         local my_ino=$(stat --format "%i" $testfile)
26739
26740         # Try to insert the module. This will always fail as the
26741         # module is designed to not be inserted.
26742         insmod $LUSTRE/tests/kernel/kinode.ko run_id=$run_id fname=$testfile \
26743             &> /dev/null
26744
26745         # Anything but success is a test failure
26746         dmesg | grep -q \
26747             "lustre_kinode_$run_id: inode numbers are identical: $my_ino" ||
26748             error "no inode match"
26749 }
26750 run_test 410 "Test inode number returned from kernel thread"
26751
26752 cleanup_test411_cgroup() {
26753         trap 0
26754         rmdir "$1"
26755 }
26756
26757 test_411() {
26758         local cg_basedir=/sys/fs/cgroup/memory
26759         # LU-9966
26760         test -f "$cg_basedir/memory.kmem.limit_in_bytes" ||
26761                 skip "no setup for cgroup"
26762
26763         dd if=/dev/zero of=$DIR/$tfile bs=1M count=100 conv=fsync ||
26764                 error "test file creation failed"
26765         cancel_lru_locks osc
26766
26767         # Create a very small memory cgroup to force a slab allocation error
26768         local cgdir=$cg_basedir/osc_slab_alloc
26769         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
26770         trap "cleanup_test411_cgroup $cgdir" EXIT
26771         echo 2M > $cgdir/memory.kmem.limit_in_bytes
26772         echo 1M > $cgdir/memory.limit_in_bytes
26773
26774         # Should not LBUG, just be killed by oom-killer
26775         # dd will return 0 even allocation failure in some environment.
26776         # So don't check return value
26777         bash -c "echo \$$ > $cgdir/tasks && dd if=$DIR/$tfile of=/dev/null"
26778         cleanup_test411_cgroup $cgdir
26779
26780         return 0
26781 }
26782 run_test 411 "Slab allocation error with cgroup does not LBUG"
26783
26784 test_412() {
26785         (( $MDSCOUNT > 1 )) || skip_env "needs >= 2 MDTs"
26786         (( $MDS1_VERSION >= $(version_code 2.10.55) )) ||
26787                 skip "Need server version at least 2.10.55"
26788
26789         $LFS mkdir -i $((MDSCOUNT - 1)),$((MDSCOUNT - 2)) $DIR/$tdir ||
26790                 error "mkdir failed"
26791         $LFS getdirstripe $DIR/$tdir
26792         local stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
26793         [ $stripe_index -eq $((MDSCOUNT - 1)) ] ||
26794                 error "expect $((MDSCOUT - 1)) get $stripe_index"
26795         local stripe_count=$($LFS getdirstripe -T $DIR/$tdir)
26796         [ $stripe_count -eq 2 ] ||
26797                 error "expect 2 get $stripe_count"
26798
26799         (( $MDS1_VERSION >= $(version_code 2.14.55) )) || return 0
26800
26801         local index
26802         local index2
26803
26804         # subdirs should be on the same MDT as parent
26805         for i in $(seq 0 $((MDSCOUNT - 1))); do
26806                 $LFS mkdir -i $i $DIR/$tdir/mdt$i || error "mkdir mdt$i failed"
26807                 mkdir $DIR/$tdir/mdt$i/sub || error "mkdir sub failed"
26808                 index=$($LFS getstripe -m $DIR/$tdir/mdt$i/sub)
26809                 (( index == i )) || error "mdt$i/sub on MDT$index"
26810         done
26811
26812         # stripe offset -1, ditto
26813         for i in {1..10}; do
26814                 $LFS mkdir -i -1 $DIR/$tdir/qos$i || error "mkdir qos$i failed"
26815                 index=$($LFS getstripe -m $DIR/$tdir/qos$i)
26816                 mkdir $DIR/$tdir/qos$i/sub || error "mkdir sub failed"
26817                 index2=$($LFS getstripe -m $DIR/$tdir/qos$i/sub)
26818                 (( index == index2 )) ||
26819                         error "qos$i on MDT$index, sub on MDT$index2"
26820         done
26821
26822         local testdir=$DIR/$tdir/inherit
26823
26824         $LFS mkdir -i 1 --max-inherit=3 $testdir || error "mkdir inherit failed"
26825         # inherit 2 levels
26826         for i in 1 2; do
26827                 testdir=$testdir/s$i
26828                 mkdir $testdir || error "mkdir $testdir failed"
26829                 index=$($LFS getstripe -m $testdir)
26830                 (( index == 1 )) ||
26831                         error "$testdir on MDT$index"
26832         done
26833
26834         # not inherit any more
26835         testdir=$testdir/s3
26836         mkdir $testdir || error "mkdir $testdir failed"
26837         getfattr -d -m dmv $testdir | grep dmv &&
26838                 error "default LMV set on $testdir" || true
26839 }
26840 run_test 412 "mkdir on specific MDTs"
26841
26842 TEST413_COUNT=${TEST413_COUNT:-200}
26843
26844 #
26845 # set_maxage() is used by test_413 only.
26846 # This is a helper function to set maxage. Does not return any value.
26847 # Input: maxage to set
26848 #
26849 set_maxage() {
26850         local lmv_qos_maxage
26851         local lod_qos_maxage
26852         local new_maxage=$1
26853
26854         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
26855         $LCTL set_param lmv.*.qos_maxage=$new_maxage
26856         stack_trap "$LCTL set_param \
26857                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null"
26858         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
26859                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
26860         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
26861                 lod.*.mdt_qos_maxage=$new_maxage
26862         stack_trap "do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
26863                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null"
26864 }
26865
26866 generate_uneven_mdts() {
26867         local threshold=$1
26868         local ffree
26869         local bavail
26870         local max
26871         local min
26872         local max_index
26873         local min_index
26874         local tmp
26875         local i
26876
26877         echo
26878         echo "Check for uneven MDTs: "
26879
26880         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
26881         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
26882         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
26883
26884         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
26885         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
26886         max_index=0
26887         min_index=0
26888         for ((i = 1; i < ${#ffree[@]}; i++)); do
26889                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
26890                 if [ $tmp -gt $max ]; then
26891                         max=$tmp
26892                         max_index=$i
26893                 fi
26894                 if [ $tmp -lt $min ]; then
26895                         min=$tmp
26896                         min_index=$i
26897                 fi
26898         done
26899
26900         (( min > 0 )) || skip "low space on MDT$min_index"
26901         (( ${ffree[min_index]} > 0 )) ||
26902                 skip "no free files on MDT$min_index"
26903         (( ${ffree[min_index]} < 10000000 )) ||
26904                 skip "too many free files on MDT$min_index"
26905
26906         # Check if we need to generate uneven MDTs
26907         local diff=$(((max - min) * 100 / min))
26908         local testdirp=$DIR/$tdir-fillmdt # parent fill folder
26909         local testdir # individual folder within $testdirp
26910         local start
26911         local cmd
26912
26913         # fallocate is faster to consume space on MDT, if available
26914         if check_fallocate_supported mds$((min_index + 1)); then
26915                 cmd="fallocate -l 128K "
26916         else
26917                 cmd="dd if=/dev/zero bs=128K count=1 of="
26918         fi
26919
26920         echo "using cmd $cmd"
26921         for (( i = 0; diff < threshold; i++ )); do
26922                 testdir=${testdirp}/$i
26923                 [ -d $testdir ] && continue
26924
26925                 (( i % 10 > 0 )) || { $LFS df; $LFS df -i; }
26926
26927                 mkdir -p $testdirp
26928                 # generate uneven MDTs, create till $threshold% diff
26929                 echo -n "weight diff=$diff% must be > $threshold% ..."
26930                 echo "Fill MDT$min_index with $TEST413_COUNT files: loop $i"
26931                 $LFS mkdir -i $min_index $testdir ||
26932                         error "mkdir $testdir failed"
26933                 $LFS setstripe -E 1M -L mdt $testdir ||
26934                         error "setstripe $testdir failed"
26935                 start=$SECONDS
26936                 for (( f = 0; f < TEST413_COUNT; f++ )); do
26937                         $cmd$testdir/f.$f &> /dev/null || error "$cmd $f failed"
26938                 done
26939                 sync; sleep 1; sync
26940
26941                 # wait for QOS to update
26942                 (( SECONDS < start + 2 )) && sleep $((start + 2 - SECONDS))
26943
26944                 ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-*.filesfree))
26945                 bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-*.kbytesavail))
26946                 max=$(((${ffree[max_index]} >> 8) *
26947                         (${bavail[max_index]} * bsize >> 16)))
26948                 min=$(((${ffree[min_index]} >> 8) *
26949                         (${bavail[min_index]} * bsize >> 16)))
26950                 (( min > 0 )) || skip "low space on MDT$min_index"
26951                 diff=$(((max - min) * 100 / min))
26952         done
26953
26954         echo "MDT filesfree available: ${ffree[*]}"
26955         echo "MDT blocks available: ${bavail[*]}"
26956         echo "weight diff=$diff%"
26957 }
26958
26959 test_qos_mkdir() {
26960         local mkdir_cmd=$1
26961         local stripe_count=$2
26962         local mdts=$(comma_list $(mdts_nodes))
26963
26964         local testdir
26965         local lmv_qos_prio_free
26966         local lmv_qos_threshold_rr
26967         local lod_qos_prio_free
26968         local lod_qos_threshold_rr
26969         local total
26970         local count
26971         local i
26972
26973         # @total is total directories created if it's testing plain
26974         # directories, otherwise it's total stripe object count for
26975         # striped directories test.
26976         # remote/striped directory unlinking is slow on zfs and may
26977         # timeout, test with fewer directories
26978         [ "$mds1_FSTYPE" = "zfs" ] && total=120 || total=240
26979
26980         lmv_qos_prio_free=$($LCTL get_param -n lmv.*.qos_prio_free | head -n1)
26981         lmv_qos_prio_free=${lmv_qos_prio_free%%%}
26982         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
26983                 head -n1)
26984         lmv_qos_threshold_rr=${lmv_qos_threshold_rr%%%}
26985         stack_trap "$LCTL set_param \
26986                 lmv.*.qos_prio_free=$lmv_qos_prio_free > /dev/null"
26987         stack_trap "$LCTL set_param \
26988                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null"
26989
26990         lod_qos_prio_free=$(do_facet mds1 $LCTL get_param -n \
26991                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_prio_free | head -n1)
26992         lod_qos_prio_free=${lod_qos_prio_free%%%}
26993         lod_qos_threshold_rr=$(do_facet mds1 $LCTL get_param -n \
26994                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_threshold_rr | head -n1)
26995         lod_qos_threshold_rr=${lod_qos_threshold_rr%%%}
26996         stack_trap "do_nodes $mdts $LCTL set_param \
26997                 lod.*.mdt_qos_prio_free=$lod_qos_prio_free > /dev/null"
26998         stack_trap "do_nodes $mdts $LCTL set_param \
26999                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null"
27000
27001         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
27002         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=100 > /dev/null
27003
27004         testdir=$DIR/$tdir-s$stripe_count/rr
27005
27006         local stripe_index=$($LFS getstripe -m $testdir)
27007         local test_mkdir_rr=true
27008
27009         getfattr -d -m dmv -e hex $testdir | grep dmv
27010         if (( $? == 0 && $MDS1_VERSION >= $(version_code 2.14.51) )); then
27011                 echo "defstripe: '$($LFS getdirstripe -D $testdir)'"
27012                 (( $($LFS getdirstripe -D --max-inherit-rr $testdir) == 0 )) &&
27013                         test_mkdir_rr=false
27014         fi
27015
27016         echo
27017         $test_mkdir_rr &&
27018                 echo "Mkdir (stripe_count $stripe_count) roundrobin:" ||
27019                 echo "Mkdir (stripe_count $stripe_count) on stripe $stripe_index"
27020
27021         stack_trap "unlinkmany -d $testdir/subdir $((total / stripe_count))"
27022         for (( i = 0; i < total / stripe_count; i++ )); do
27023                 eval $mkdir_cmd $testdir/subdir$i ||
27024                         error "$mkdir_cmd subdir$i failed"
27025         done
27026
27027         for (( i = 0; i < $MDSCOUNT; i++ )); do
27028                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
27029                 echo "$count directories created on MDT$i"
27030                 if $test_mkdir_rr; then
27031                         (( count == total / stripe_count / MDSCOUNT )) ||
27032                                 error "subdirs are not evenly distributed"
27033                 elif (( i == stripe_index )); then
27034                         (( count == total / stripe_count )) ||
27035                                 error "$count subdirs created on MDT$i"
27036                 else
27037                         (( count == 0 )) ||
27038                                 error "$count subdirs created on MDT$i"
27039                 fi
27040
27041                 if $test_mkdir_rr && [ $stripe_count -gt 1 ]; then
27042                         count=$($LFS getdirstripe $testdir/* |
27043                                 grep -c -P "^\s+$i\t")
27044                         echo "$count stripes created on MDT$i"
27045                         # deviation should < 5% of average
27046                         delta=$((count - total / MDSCOUNT))
27047                         (( ${delta#-} <= total / MDSCOUNT / 20 )) ||
27048                                 error "stripes are not evenly distributed"
27049                 fi
27050         done
27051
27052         echo
27053         echo "Check for uneven MDTs: "
27054
27055         local ffree
27056         local bavail
27057         local max
27058         local min
27059         local max_index
27060         local min_index
27061         local tmp
27062
27063         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
27064         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
27065         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
27066
27067         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
27068         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
27069         max_index=0
27070         min_index=0
27071         for ((i = 1; i < ${#ffree[@]}; i++)); do
27072                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
27073                 if [ $tmp -gt $max ]; then
27074                         max=$tmp
27075                         max_index=$i
27076                 fi
27077                 if [ $tmp -lt $min ]; then
27078                         min=$tmp
27079                         min_index=$i
27080                 fi
27081         done
27082         echo "stripe_count=$stripe_count min_idx=$min_index max_idx=$max_index"
27083
27084         (( min > 0 )) || skip "low space on MDT$min_index"
27085         (( ${ffree[min_index]} < 10000000 )) ||
27086                 skip "too many free files on MDT$min_index"
27087
27088         generate_uneven_mdts 120
27089
27090         echo "MDT filesfree available: ${ffree[*]}"
27091         echo "MDT blocks available: ${bavail[*]}"
27092         echo "weight diff=$(((max - min) * 100 / min))%"
27093         echo
27094         echo "Mkdir (stripe_count $stripe_count) with balanced space usage:"
27095
27096         $LCTL set_param lmv.*.qos_threshold_rr=0 > /dev/null
27097         $LCTL set_param lmv.*.qos_prio_free=100 > /dev/null
27098         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=0 > /dev/null
27099         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_prio_free=100 > /dev/null
27100         # decrease statfs age, so that it can be updated in time
27101         $LCTL set_param lmv.*.qos_maxage=1 > /dev/null
27102         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_maxage=1 > /dev/null
27103
27104         sleep 1
27105
27106         testdir=$DIR/$tdir-s$stripe_count/qos
27107
27108         stack_trap "unlinkmany -d $testdir/subdir $((total / stripe_count))"
27109         for (( i = 0; i < total / stripe_count; i++ )); do
27110                 eval $mkdir_cmd $testdir/subdir$i ||
27111                         error "$mkdir_cmd subdir$i failed"
27112         done
27113
27114         max=0
27115         for (( i = 0; i < $MDSCOUNT; i++ )); do
27116                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
27117                 (( count > max )) && max=$count
27118                 echo "$count directories created on MDT$i : curmax=$max"
27119         done
27120
27121         min=$($LFS getdirstripe -i $testdir/* | grep -c "^$min_index$")
27122
27123         # D-value should > 10% of average
27124         (( max - min > total / stripe_count / MDSCOUNT / 10 )) ||
27125                 error "subdirs shouldn't be evenly distributed: $max - $min <= $((total / stripe_count / MDSCOUNT / 10))"
27126
27127         # ditto for stripes
27128         if (( stripe_count > 1 )); then
27129                 max=0
27130                 for (( i = 0; i < $MDSCOUNT; i++ )); do
27131                         count=$($LFS getdirstripe $testdir/* |
27132                                 grep -c -P "^\s+$i\t")
27133                         (( count > max )) && max=$count
27134                         echo "$count stripes created on MDT$i"
27135                 done
27136
27137                 min=$($LFS getdirstripe $testdir/* |
27138                         grep -c -P "^\s+$min_index\t")
27139                 (( max - min > total / MDSCOUNT / 10 )) ||
27140                         error "stripes shouldn't be evenly distributed: $max - $min <= $((total / MDSCOUNT / 10))"
27141         fi
27142 }
27143
27144 most_full_mdt() {
27145         local ffree
27146         local bavail
27147         local bsize
27148         local min
27149         local min_index
27150         local tmp
27151
27152         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
27153         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
27154         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
27155
27156         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
27157         min_index=0
27158         for ((i = 1; i < ${#ffree[@]}; i++)); do
27159                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
27160                 (( tmp < min )) && min=$tmp && min_index=$i
27161         done
27162
27163         echo -n $min_index
27164 }
27165
27166 test_413a() {
27167         [ $MDSCOUNT -lt 2 ] &&
27168                 skip "We need at least 2 MDTs for this test"
27169
27170         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
27171                 skip "Need server version at least 2.12.52"
27172
27173         local stripe_max=$((MDSCOUNT - 1))
27174         local stripe_count
27175
27176         # let caller set maxage for latest result
27177         set_maxage 1
27178
27179         # fill MDT unevenly
27180         generate_uneven_mdts 120
27181
27182         # test 4-stripe directory at most, otherwise it's too slow
27183         # We are being very defensive. Although Autotest uses 4 MDTs.
27184         # We make sure stripe_max does not go over 4.
27185         (( stripe_max > 4 )) && stripe_max=4
27186         # unlinking striped directory is slow on zfs, and may timeout, only test
27187         # plain directory
27188         [ "$mds1_FSTYPE" == "zfs" ] && stripe_max=1
27189         for stripe_count in $(seq 1 $stripe_max); do
27190                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
27191                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
27192                 $LFS mkdir -i $(most_full_mdt) $DIR/$tdir-s$stripe_count/qos ||
27193                         error "mkdir failed"
27194                 test_qos_mkdir "$LFS mkdir -i -1 -c $stripe_count" $stripe_count
27195         done
27196 }
27197 run_test 413a "QoS mkdir with 'lfs mkdir -i -1'"
27198
27199 test_413b() {
27200         [ $MDSCOUNT -lt 2 ] &&
27201                 skip "We need at least 2 MDTs for this test"
27202
27203         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
27204                 skip "Need server version at least 2.12.52"
27205
27206         local stripe_max=$((MDSCOUNT - 1))
27207         local testdir
27208         local stripe_count
27209
27210         # let caller set maxage for latest result
27211         set_maxage 1
27212
27213         # fill MDT unevenly
27214         generate_uneven_mdts 120
27215
27216         # test 4-stripe directory at most, otherwise it's too slow
27217         # We are being very defensive. Although Autotest uses 4 MDTs.
27218         # We make sure stripe_max does not go over 4.
27219         (( stripe_max > 4 )) && stripe_max=4
27220         [ "$mds1_FSTYPE" == "zfs" ] && stripe_max=1
27221         for stripe_count in $(seq 1 $stripe_max); do
27222                 testdir=$DIR/$tdir-s$stripe_count
27223                 mkdir $testdir || error "mkdir $testdir failed"
27224                 mkdir $testdir/rr || error "mkdir rr failed"
27225                 $LFS mkdir -i $(most_full_mdt) $testdir/qos ||
27226                         error "mkdir qos failed"
27227                 $LFS setdirstripe -D -c $stripe_count --max-inherit-rr 2 \
27228                         $testdir/rr || error "setdirstripe rr failed"
27229                 $LFS setdirstripe -D -c $stripe_count $testdir/qos ||
27230                         error "setdirstripe failed"
27231                 test_qos_mkdir "mkdir" $stripe_count
27232         done
27233 }
27234 run_test 413b "QoS mkdir under dir whose default LMV starting MDT offset is -1"
27235
27236 test_413c() {
27237         (( $MDSCOUNT >= 2 )) ||
27238                 skip "We need at least 2 MDTs for this test"
27239
27240         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
27241                 skip "Need server version at least 2.14.51"
27242
27243         local testdir
27244         local inherit
27245         local inherit_rr
27246         local lmv_qos_maxage
27247         local lod_qos_maxage
27248
27249         # let caller set maxage for latest result
27250         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
27251         $LCTL set_param lmv.*.qos_maxage=1
27252         stack_trap "$LCTL set_param \
27253                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null" RETURN
27254         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
27255                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
27256         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
27257                 lod.*.mdt_qos_maxage=1
27258         stack_trap "do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
27259                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null" RETURN
27260
27261         # fill MDT unevenly
27262         generate_uneven_mdts 120
27263
27264         testdir=$DIR/${tdir}-s1
27265         mkdir $testdir || error "mkdir $testdir failed"
27266         mkdir $testdir/rr || error "mkdir rr failed"
27267         $LFS mkdir -i $(most_full_mdt) $testdir/qos || error "mkdir qos failed"
27268         # default max_inherit is -1, default max_inherit_rr is 0
27269         $LFS setdirstripe -D -c 1 $testdir/rr ||
27270                 error "setdirstripe rr failed"
27271         $LFS setdirstripe -D -c 1 -i -1 -X 2 --max-inherit-rr 1 $testdir/qos ||
27272                 error "setdirstripe qos failed"
27273         test_qos_mkdir "mkdir" 1
27274
27275         mkdir $testdir/rr/level1 || error "mkdir rr/level1 failed"
27276         inherit=$($LFS getdirstripe -D -X $testdir/rr/level1)
27277         (( $inherit == -1 )) || error "rr/level1 inherit $inherit != -1"
27278         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/rr/level1)
27279         (( $inherit_rr == 0 )) || error "rr/level1 inherit-rr $inherit_rr != 0"
27280
27281         mkdir $testdir/qos/level1 || error "mkdir qos/level1 failed"
27282         inherit=$($LFS getdirstripe -D -X $testdir/qos/level1)
27283         (( $inherit == 1 )) || error "qos/level1 inherit $inherit != 1"
27284         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/qos/level1)
27285         (( $inherit_rr == 0 )) || error "qos/level1 inherit-rr $inherit_rr != 0"
27286         mkdir $testdir/qos/level1/level2 || error "mkdir level2 failed"
27287         getfattr -d -m dmv -e hex $testdir/qos/level1/level2 | grep dmv &&
27288                 error "level2 shouldn't have default LMV" || true
27289 }
27290 run_test 413c "mkdir with default LMV max inherit rr"
27291
27292 test_413d() {
27293         (( MDSCOUNT >= 2 )) ||
27294                 skip "We need at least 2 MDTs for this test"
27295
27296         (( MDS1_VERSION >= $(version_code 2.14.51) )) ||
27297                 skip "Need server version at least 2.14.51"
27298
27299         local lmv_qos_threshold_rr
27300
27301         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
27302                 head -n1)
27303         stack_trap "$LCTL set_param \
27304                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null" EXIT
27305
27306         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
27307         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
27308         getfattr -d -m dmv -e hex $DIR/$tdir | grep dmv &&
27309                 error "$tdir shouldn't have default LMV"
27310         createmany -d $DIR/$tdir/sub $((100 * MDSCOUNT)) ||
27311                 error "mkdir sub failed"
27312
27313         local count=$($LFS getstripe -m $DIR/$tdir/* | grep -c ^0)
27314
27315         (( count == 100 )) || error "$count subdirs on MDT0"
27316 }
27317 run_test 413d "inherit ROOT default LMV"
27318
27319 test_413e() {
27320         (( MDSCOUNT >= 2 )) ||
27321                 skip "We need at least 2 MDTs for this test"
27322         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
27323                 skip "Need server version at least 2.14.55"
27324
27325         local testdir=$DIR/$tdir
27326         local tmpfile=$TMP/temp.setdirstripe.stderr.$$
27327         local max_inherit
27328         local sub_max_inherit
27329
27330         mkdir -p $testdir || error "failed to create $testdir"
27331
27332         # set default max-inherit to -1 if stripe count is 0 or 1
27333         $LFS setdirstripe -D -c 1 $testdir ||
27334                 error "failed to set default LMV"
27335         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
27336         (( max_inherit == -1 )) ||
27337                 error "wrong max_inherit value $max_inherit"
27338
27339         # set default max_inherit to a fixed value if stripe count is not 0 or 1
27340         $LFS setdirstripe -D -c -1 $testdir ||
27341                 error "failed to set default LMV"
27342         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
27343         (( max_inherit > 0 )) ||
27344                 error "wrong max_inherit value $max_inherit"
27345
27346         # and the subdir will decrease the max_inherit by 1
27347         mkdir -p $testdir/subdir-1 || error "failed to make subdir"
27348         sub_max_inherit=$($LFS getdirstripe -D --max-inherit $testdir/subdir-1)
27349         (( sub_max_inherit == max_inherit - 1)) ||
27350                 error "wrong max-inherit of subdir $sub_max_inherit"
27351
27352         # check specified --max-inherit and warning message
27353         stack_trap "rm -f $tmpfile"
27354         $LFS setdirstripe -D -c 2 --max-inherit=-1 $testdir 2> $tmpfile ||
27355                 error "failed to set default LMV"
27356         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
27357         (( max_inherit == -1 )) ||
27358                 error "wrong max_inherit value $max_inherit"
27359
27360         # check the warning messages
27361         if ! [[ $(cat $tmpfile) =~ "max-inherit=" ]]; then
27362                 error "failed to detect warning string"
27363         fi
27364 }
27365 run_test 413e "check default max-inherit value"
27366
27367 test_fs_dmv_inherit()
27368 {
27369         local testdir=$DIR/$tdir
27370
27371         local count
27372         local inherit
27373         local inherit_rr
27374
27375         for i in 1 2; do
27376                 mkdir $testdir || error "mkdir $testdir failed"
27377                 count=$($LFS getdirstripe -D -c $testdir)
27378                 (( count == 1 )) ||
27379                         error "$testdir default LMV count mismatch $count != 1"
27380                 inherit=$($LFS getdirstripe -D -X $testdir)
27381                 (( inherit == 3 - i )) ||
27382                         error "$testdir default LMV max-inherit $inherit != $((3 - i))"
27383                 inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir)
27384                 (( inherit_rr == 3 - i )) ||
27385                         error "$testdir default LMV max-inherit-rr $inherit_rr != $((3 - i))"
27386                 testdir=$testdir/sub
27387         done
27388
27389         mkdir $testdir || error "mkdir $testdir failed"
27390         count=$($LFS getdirstripe -D -c $testdir)
27391         (( count == 0 )) ||
27392                 error "$testdir default LMV count not zero: $count"
27393 }
27394
27395 test_413f() {
27396         (( MDSCOUNT >= 2 )) || skip "We need at least 2 MDTs for this test"
27397
27398         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
27399                 skip "Need server version at least 2.14.55"
27400
27401         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
27402                 error "dump $DIR default LMV failed"
27403         stack_trap "setfattr --restore=$TMP/dmv.ea"
27404
27405         $LFS setdirstripe -D -i -1 -c 1 -X 3 --max-inherit-rr 3 $DIR ||
27406                 error "set $DIR default LMV failed"
27407
27408         test_fs_dmv_inherit
27409 }
27410 run_test 413f "lfs getdirstripe -D list ROOT default LMV if it's not set on dir"
27411
27412 test_413g() {
27413         (( MDSCOUNT >= 2 )) || skip "We need at least 2 MDTs for this test"
27414
27415         mkdir -p $DIR/$tdir/l2/l3/l4 || error "mkdir $tdir/l1/l2/l3 failed"
27416         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
27417                 error "dump $DIR default LMV failed"
27418         stack_trap "setfattr --restore=$TMP/dmv.ea"
27419
27420         $LFS setdirstripe -D -i -1 -c 1 -X 3 --max-inherit-rr 3 $DIR ||
27421                 error "set $DIR default LMV failed"
27422
27423         FILESET="$FILESET/$tdir/l2/l3/l4" mount_client $MOUNT2 ||
27424                 error "mount $MOUNT2 failed"
27425         stack_trap "umount_client $MOUNT2"
27426
27427         local saved_DIR=$DIR
27428
27429         export DIR=$MOUNT2
27430
27431         stack_trap "export DIR=$saved_DIR"
27432
27433         # first check filesystem-wide default LMV inheritance
27434         test_fs_dmv_inherit || error "incorrect fs default LMV inheritance"
27435
27436         # then check subdirs are spread to all MDTs
27437         createmany -d $DIR/s $((MDSCOUNT * 100)) || error "createmany failed"
27438
27439         local count=$($LFS getstripe -m $DIR/s* | sort -u | wc -l)
27440
27441         (( $count == $MDSCOUNT )) || error "dirs are spread to $count MDTs"
27442 }
27443 run_test 413g "enforce ROOT default LMV on subdir mount"
27444
27445 test_413h() {
27446         (( MDSCOUNT >= 2 )) ||
27447                 skip "We need at least 2 MDTs for this test"
27448
27449         (( MDS1_VERSION >= $(version_code 2.15.50.6) )) ||
27450                 skip "Need server version at least 2.15.50.6"
27451
27452         local lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
27453
27454         stack_trap "$LCTL set_param \
27455                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null"
27456         $LCTL set_param lmv.*.qos_maxage=1
27457
27458         local depth=5
27459         local rr_depth=4
27460         local dir=$DIR/$tdir/l1/l2/l3/l4/l5
27461         local count=$((MDSCOUNT * 20))
27462
27463         generate_uneven_mdts 50
27464
27465         mkdir -p $dir || error "mkdir $dir failed"
27466         stack_trap "rm -rf $dir"
27467         $LFS setdirstripe -D -c 1 -i -1 --max-inherit=$depth \
27468                 --max-inherit-rr=$rr_depth $dir
27469
27470         for ((d=0; d < depth + 2; d++)); do
27471                 log "dir=$dir:"
27472                 for ((sub=0; sub < count; sub++)); do
27473                         mkdir $dir/d$sub
27474                 done
27475                 $LFS getdirstripe -i $dir/d* | sort | uniq -c | sort -nr
27476                 local num=($($LFS getdirstripe -i $dir/d* | sort | uniq -c))
27477                 # subdirs within $rr_depth should be created round-robin
27478                 if (( d < rr_depth )); then
27479                         (( ${num[0]} != count )) ||
27480                                 error "all objects created on MDT ${num[1]}"
27481                 fi
27482
27483                 dir=$dir/d0
27484         done
27485 }
27486 run_test 413h "don't stick to parent for round-robin dirs"
27487
27488 test_413i() {
27489         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
27490
27491         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
27492                 skip "Need server version at least 2.14.55"
27493
27494         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
27495                 error "dump $DIR default LMV failed"
27496         stack_trap "setfattr --restore=$TMP/dmv.ea"
27497
27498         local testdir=$DIR/$tdir
27499         local def_max_rr=1
27500         local def_max=3
27501         local count
27502
27503         $LFS setdirstripe -D -i-1 -c1 --max-inherit=$def_max \
27504                 --max-inherit-rr=$def_max_rr $DIR ||
27505                 error "set $DIR default LMV failed"
27506
27507         for i in $(seq 2 3); do
27508                 def_max=$((def_max - 1))
27509                 (( def_max_rr == 0 )) || def_max_rr=$((def_max_rr - 1))
27510
27511                 mkdir $testdir
27512                 # RR is decremented and keeps zeroed once exhausted
27513                 count=$($LFS getdirstripe -D --max-inherit-rr $testdir)
27514                 (( count == def_max_rr )) ||
27515                         error_noexit "$testdir: max-inherit-rr $count != $def_max_rr"
27516
27517                 # max-inherit is decremented
27518                 count=$($LFS getdirstripe -D --max-inherit $testdir)
27519                 (( count == def_max )) ||
27520                         error_noexit "$testdir: max-inherit $count != $def_max"
27521
27522                 testdir=$testdir/d$i
27523         done
27524
27525         # d3 is the last inherited from ROOT, no inheritance anymore
27526         # i.e. no the default layout anymore
27527         mkdir -p $testdir/d4/d5
27528         count=$($LFS getdirstripe -D --max-inherit $testdir)
27529         (( count == -1 )) ||
27530                 error_noexit "$testdir: max-inherit $count != -1"
27531
27532         local p_count=$($LFS getdirstripe -i $testdir)
27533
27534         for i in $(seq 4 5); do
27535                 testdir=$testdir/d$i
27536
27537                 # the root default layout is not applied once exhausted
27538                 count=$($LFS getdirstripe -i $testdir)
27539                 (( count == p_count )) ||
27540                         error_noexit "$testdir: stripe-offset $count != parent offset $p_count"
27541         done
27542
27543         $LFS setdirstripe -i 0 $DIR/d2
27544         count=$($LFS getdirstripe -D --max-inherit $DIR/d2)
27545         (( count == -1 )) ||
27546                 error_noexit "$DIR/d2: max-inherit non-striped default $count != -1"
27547 }
27548 run_test 413i "check default layout inheritance"
27549
27550 test_413z() {
27551         local pids=""
27552         local subdir
27553         local pid
27554
27555         for subdir in $(\ls -1 -d $DIR/d413*-fillmdt/*); do
27556                 unlinkmany $subdir/f. $TEST413_COUNT &
27557                 pids="$pids $!"
27558         done
27559
27560         for pid in $pids; do
27561                 wait $pid
27562         done
27563
27564         true
27565 }
27566 run_test 413z "413 test cleanup"
27567
27568 test_414() {
27569 #define OBD_FAIL_PTLRPC_BULK_ATTACH      0x521
27570         $LCTL set_param fail_loc=0x80000521
27571         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
27572         rm -f $DIR/$tfile
27573 }
27574 run_test 414 "simulate ENOMEM in ptlrpc_register_bulk()"
27575
27576 test_415() {
27577         [[ $PARALLEL == "yes" ]] && skip "skip parallel run"
27578         (( $MDS1_VERSION >= $(version_code 2.11.52) )) ||
27579                 skip "Need server version at least 2.11.52"
27580
27581         # LU-11102
27582         local total=500
27583         local max=120
27584
27585         # this test may be slow on ZFS
27586         [[ "$mds1_FSTYPE" == "zfs" ]] && total=50
27587
27588         # though this test is designed for striped directory, let's test normal
27589         # directory too since lock is always saved as CoS lock.
27590         test_mkdir $DIR/$tdir || error "mkdir $tdir"
27591         createmany -o $DIR/$tdir/$tfile. $total || error "createmany"
27592         stack_trap "unlinkmany $DIR/$tdir/$tfile. $total || true"
27593         # if looping with ONLY_REPEAT, wait for previous deletions to finish
27594         wait_delete_completed_mds
27595
27596         # run a loop without concurrent touch to measure rename duration.
27597         # only for test debug/robustness, NOT part of COS functional test.
27598         local start_time=$SECONDS
27599         for ((i = 0; i < total; i++)); do
27600                 mrename $DIR/$tdir/$tfile.$i $DIR/$tdir/$tfile-new.$i \
27601                         > /dev/null
27602         done
27603         local baseline=$((SECONDS - start_time))
27604         echo "rename $total files without 'touch' took $baseline sec"
27605
27606         (
27607                 while true; do
27608                         touch $DIR/$tdir
27609                 done
27610         ) &
27611         local setattr_pid=$!
27612
27613         # rename files back to original name so unlinkmany works
27614         start_time=$SECONDS
27615         for ((i = 0; i < total; i++)); do
27616                 mrename $DIR/$tdir/$tfile-new.$i $DIR/$tdir/$tfile.$i\
27617                         > /dev/null
27618         done
27619         local duration=$((SECONDS - start_time))
27620
27621         kill -9 $setattr_pid
27622
27623         echo "rename $total files with 'touch' took $duration sec"
27624         (( max > 2 * baseline )) || max=$((2 * baseline + 5))
27625         (( duration <= max )) ||
27626                 error_not_in_vm "rename took $duration > $max sec"
27627 }
27628 run_test 415 "lock revoke is not missing"
27629
27630 test_416() {
27631         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
27632                 skip "Need server version at least 2.11.55"
27633
27634         # define OBD_FAIL_OSD_TXN_START    0x19a
27635         do_facet mds1 lctl set_param fail_loc=0x19a
27636
27637         lfs mkdir -c $MDSCOUNT $DIR/$tdir
27638
27639         true
27640 }
27641 run_test 416 "transaction start failure won't cause system hung"
27642
27643 cleanup_417() {
27644         trap 0
27645         do_nodes $(comma_list $(mdts_nodes)) \
27646                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=1"
27647         do_nodes $(comma_list $(mdts_nodes)) \
27648                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=1"
27649         do_nodes $(comma_list $(mdts_nodes)) \
27650                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=1"
27651 }
27652
27653 test_417() {
27654         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
27655         [[ $MDS1_VERSION -lt $(version_code 2.11.56) ]] &&
27656                 skip "Need MDS version at least 2.11.56"
27657
27658         trap cleanup_417 RETURN EXIT
27659
27660         $LFS mkdir -i 1 $DIR/$tdir.1 || error "create remote dir $tdir.1 failed"
27661         do_nodes $(comma_list $(mdts_nodes)) \
27662                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=0"
27663         $LFS migrate -m 0 $DIR/$tdir.1 &&
27664                 error "migrate dir $tdir.1 should fail"
27665
27666         do_nodes $(comma_list $(mdts_nodes)) \
27667                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=0"
27668         $LFS mkdir -i 1 $DIR/$tdir.2 &&
27669                 error "create remote dir $tdir.2 should fail"
27670
27671         do_nodes $(comma_list $(mdts_nodes)) \
27672                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=0"
27673         $LFS mkdir -c 2 $DIR/$tdir.3 &&
27674                 error "create striped dir $tdir.3 should fail"
27675         true
27676 }
27677 run_test 417 "disable remote dir, striped dir and dir migration"
27678
27679 # Checks that the outputs of df [-i] and lfs df [-i] match
27680 #
27681 # usage: check_lfs_df <blocks | inodes> <mountpoint>
27682 check_lfs_df() {
27683         local dir=$2
27684         local inodes
27685         local df_out
27686         local lfs_df_out
27687         local count
27688         local passed=false
27689
27690         # blocks or inodes
27691         [ "$1" == "blocks" ] && inodes= || inodes="-i"
27692
27693         for count in {1..100}; do
27694                 do_nodes "$CLIENTS" \
27695                         $LCTL set_param ldlm.namespaces.*.lru_size=clear
27696                 sync; sleep 0.2
27697
27698                 # read the lines of interest
27699                 df_out=($(df -P $inodes $dir | tail -n +2)) ||
27700                         error "df $inodes $dir | tail -n +2 failed"
27701                 lfs_df_out=($($LFS df $inodes $dir | grep summary:)) ||
27702                         error "lfs df $inodes $dir | grep summary: failed"
27703
27704                 # skip first substrings of each output as they are different
27705                 # "<NID>:/<fsname>" for df, "filesystem_summary:" for lfs df
27706                 # compare the two outputs
27707                 passed=true
27708                 #  skip "available" on MDT until LU-13997 is fixed.
27709                 #for i in {1..5}; do
27710                 for i in 1 2 4 5; do
27711                         [ "${df_out[i]}" != "${lfs_df_out[i]}" ] && passed=false
27712                 done
27713                 $passed && break
27714         done
27715
27716         if ! $passed; then
27717                 df -P $inodes $dir
27718                 echo
27719                 lfs df $inodes $dir
27720                 error "df and lfs df $1 output mismatch: "      \
27721                       "df ${inodes}: ${df_out[*]}, "            \
27722                       "lfs df ${inodes}: ${lfs_df_out[*]}"
27723         fi
27724 }
27725
27726 test_418() {
27727         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27728
27729         local dir=$DIR/$tdir
27730         local numfiles=$((RANDOM % 4096 + 2))
27731         local numblocks=$((RANDOM % 256 + 1))
27732
27733         wait_delete_completed
27734         test_mkdir $dir
27735
27736         # check block output
27737         check_lfs_df blocks $dir
27738         # check inode output
27739         check_lfs_df inodes $dir
27740
27741         # create a single file and retest
27742         echo "Creating a single file and testing"
27743         createmany -o $dir/$tfile- 1 &>/dev/null ||
27744                 error "creating 1 file in $dir failed"
27745         check_lfs_df blocks $dir
27746         check_lfs_df inodes $dir
27747
27748         # create a random number of files
27749         echo "Creating $((numfiles - 1)) files and testing"
27750         createmany -o $dir/$tfile- 1 $((numfiles - 1)) &>/dev/null ||
27751                 error "creating $((numfiles - 1)) files in $dir failed"
27752
27753         # write a random number of blocks to the first test file
27754         echo "Writing $numblocks 4K blocks and testing"
27755         dd if=/dev/urandom of=$dir/${tfile}-0 bs=4K conv=fsync \
27756                 count=$numblocks &>/dev/null ||
27757                 error "dd to $dir/${tfile}-0 failed"
27758
27759         # retest
27760         check_lfs_df blocks $dir
27761         check_lfs_df inodes $dir
27762
27763         unlinkmany $dir/$tfile- $numfiles &>/dev/null ||
27764                 error "unlinking $numfiles files in $dir failed"
27765 }
27766 run_test 418 "df and lfs df outputs match"
27767
27768 test_419()
27769 {
27770         local dir=$DIR/$tdir
27771
27772         mkdir -p $dir
27773         touch $dir/file
27774
27775         cancel_lru_locks mdc
27776
27777         #OBD_FAIL_LLITE_OPEN_BY_NAME    0x1410
27778         $LCTL set_param fail_loc=0x1410
27779         cat $dir/file
27780         $LCTL set_param fail_loc=0
27781         rm -rf $dir
27782 }
27783 run_test 419 "Verify open file by name doesn't crash kernel"
27784
27785 test_420()
27786 {
27787         [[ $MDS1_VERSION -ge $(version_code 2.12.53) ]] ||
27788                 skip "Need MDS version at least 2.12.53"
27789
27790         local SAVE_UMASK=$(umask)
27791         local dir=$DIR/$tdir
27792         local uname=$(getent passwd $RUNAS_ID | cut -d: -f1)
27793
27794         mkdir -p $dir
27795         umask 0000
27796         mkdir -m03777 $dir/testdir
27797         ls -dn $dir/testdir
27798         # Need to remove trailing '.' when SELinux is enabled
27799         local dirperms=$(ls -dn $dir/testdir |
27800                          awk '{ sub(/\.$/, "", $1); print $1}')
27801         [ $dirperms == "drwxrwsrwt" ] ||
27802                 error "incorrect perms on $dir/testdir"
27803
27804         su - $uname -c "PATH=$LUSTRE/tests:\$PATH; \
27805                 openfile -f O_RDONLY:O_CREAT -m 02755 $dir/testdir/testfile"
27806         ls -n $dir/testdir/testfile
27807         local fileperms=$(ls -n $dir/testdir/testfile |
27808                           awk '{ sub(/\.$/, "", $1); print $1}')
27809         [ $fileperms == "-rwxr-xr-x" ] ||
27810                 error "incorrect perms on $dir/testdir/testfile"
27811
27812         umask $SAVE_UMASK
27813 }
27814 run_test 420 "clear SGID bit on non-directories for non-members"
27815
27816 test_421a() {
27817         local cnt
27818         local fid1
27819         local fid2
27820
27821         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
27822                 skip "Need MDS version at least 2.12.54"
27823
27824         test_mkdir $DIR/$tdir
27825         createmany -o $DIR/$tdir/f 3
27826         cnt=$(ls -1 $DIR/$tdir | wc -l)
27827         [ $cnt != 3 ] && error "unexpected #files: $cnt"
27828
27829         fid1=$(lfs path2fid $DIR/$tdir/f1)
27830         fid2=$(lfs path2fid $DIR/$tdir/f2)
27831         $LFS rmfid $DIR $fid1 $fid2 || error "rmfid failed"
27832
27833         stat $DIR/$tdir/f1 && error "f1 still visible on the client"
27834         stat $DIR/$tdir/f2 && error "f2 still visible on the client"
27835
27836         cnt=$(ls -1 $DIR/$tdir | wc -l)
27837         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
27838
27839         rm -f $DIR/$tdir/f3 || error "can't remove f3"
27840         createmany -o $DIR/$tdir/f 3
27841         cnt=$(ls -1 $DIR/$tdir | wc -l)
27842         [ $cnt != 3 ] && error "unexpected #files: $cnt"
27843
27844         fid1=$(lfs path2fid $DIR/$tdir/f1)
27845         fid2=$(lfs path2fid $DIR/$tdir/f2)
27846         echo "remove using fsname $FSNAME"
27847         $LFS rmfid $FSNAME $fid1 $fid2 || error "rmfid with fsname failed"
27848
27849         cnt=$(ls -1 $DIR/$tdir | wc -l)
27850         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
27851 }
27852 run_test 421a "simple rm by fid"
27853
27854 test_421b() {
27855         local cnt
27856         local FID1
27857         local FID2
27858
27859         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
27860                 skip "Need MDS version at least 2.12.54"
27861
27862         test_mkdir $DIR/$tdir
27863         createmany -o $DIR/$tdir/f 3
27864         multiop_bg_pause $DIR/$tdir/f1 o_c || error "multiop failed to start"
27865         MULTIPID=$!
27866
27867         FID1=$(lfs path2fid $DIR/$tdir/f1)
27868         FID2=$(lfs path2fid $DIR/$tdir/f2)
27869         $LFS rmfid $DIR $FID1 $FID2 && error "rmfid didn't fail"
27870
27871         kill -USR1 $MULTIPID
27872         wait
27873
27874         cnt=$(ls $DIR/$tdir | wc -l)
27875         [ $cnt == 2 ] || error "unexpected #files after: $cnt"
27876 }
27877 run_test 421b "rm by fid on open file"
27878
27879 test_421c() {
27880         local cnt
27881         local FIDS
27882
27883         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
27884                 skip "Need MDS version at least 2.12.54"
27885
27886         test_mkdir $DIR/$tdir
27887         createmany -o $DIR/$tdir/f 3
27888         touch $DIR/$tdir/$tfile
27889         createmany -l$DIR/$tdir/$tfile $DIR/$tdir/h 180
27890         cnt=$(ls -1 $DIR/$tdir | wc -l)
27891         [ $cnt != 184 ] && error "unexpected #files: $cnt"
27892
27893         FID1=$(lfs path2fid $DIR/$tdir/$tfile)
27894         $LFS rmfid $DIR $FID1 || error "rmfid failed"
27895
27896         cnt=$(ls $DIR/$tdir | wc -l)
27897         [ $cnt == 3 ] || error "unexpected #files after: $cnt"
27898 }
27899 run_test 421c "rm by fid against hardlinked files"
27900
27901 test_421d() {
27902         local cnt
27903         local FIDS
27904
27905         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
27906                 skip "Need MDS version at least 2.12.54"
27907
27908         test_mkdir $DIR/$tdir
27909         createmany -o $DIR/$tdir/f 4097
27910         cnt=$(ls -1 $DIR/$tdir | wc -l)
27911         [ $cnt != 4097 ] && error "unexpected #files: $cnt"
27912
27913         FIDS=$(lfs path2fid $DIR/$tdir/f* | sed "s/[/][^:]*://g")
27914         $LFS rmfid $DIR $FIDS || error "rmfid failed"
27915
27916         cnt=$(ls $DIR/$tdir | wc -l)
27917         rm -rf $DIR/$tdir
27918         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
27919 }
27920 run_test 421d "rmfid en masse"
27921
27922 test_421e() {
27923         local cnt
27924         local FID
27925
27926         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
27927         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
27928                 skip "Need MDS version at least 2.12.54"
27929
27930         mkdir -p $DIR/$tdir
27931         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
27932         createmany -o $DIR/$tdir/striped_dir/f 512
27933         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
27934         [ $cnt != 512 ] && error "unexpected #files: $cnt"
27935
27936         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
27937                 sed "s/[/][^:]*://g")
27938         $LFS rmfid $DIR $FIDS || error "rmfid failed"
27939
27940         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
27941         rm -rf $DIR/$tdir
27942         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
27943 }
27944 run_test 421e "rmfid in DNE"
27945
27946 test_421f() {
27947         local cnt
27948         local FID
27949
27950         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
27951                 skip "Need MDS version at least 2.12.54"
27952
27953         test_mkdir $DIR/$tdir
27954         touch $DIR/$tdir/f
27955         cnt=$(ls -1 $DIR/$tdir | wc -l)
27956         [ $cnt != 1 ] && error "unexpected #files: $cnt"
27957
27958         FID=$(lfs path2fid $DIR/$tdir/f)
27959         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (1)"
27960         # rmfid should fail
27961         cnt=$(ls -1 $DIR/$tdir | wc -l)
27962         [ $cnt != 1 ] && error "unexpected #files after (2): $cnt"
27963
27964         chmod a+rw $DIR/$tdir
27965         ls -la $DIR/$tdir
27966         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (2)"
27967         # rmfid should fail
27968         cnt=$(ls -1 $DIR/$tdir | wc -l)
27969         [ $cnt != 1 ] && error "unexpected #files after (3): $cnt"
27970
27971         rm -f $DIR/$tdir/f
27972         $RUNAS touch $DIR/$tdir/f
27973         FID=$(lfs path2fid $DIR/$tdir/f)
27974         echo "rmfid as root"
27975         $LFS rmfid $DIR $FID || error "rmfid as root failed"
27976         cnt=$(ls -1 $DIR/$tdir | wc -l)
27977         [ $cnt == 0 ] || error "unexpected #files after (4): $cnt"
27978
27979         rm -f $DIR/$tdir/f
27980         $RUNAS touch $DIR/$tdir/f
27981         cnt=$(ls -1 $DIR/$tdir | wc -l)
27982         [ $cnt != 1 ] && error "unexpected #files (4): $cnt"
27983         FID=$(lfs path2fid $DIR/$tdir/f)
27984         # rmfid w/o user_fid2path mount option should fail
27985         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail(3)"
27986         cnt=$(ls -1 $DIR/$tdir | wc -l)
27987         [ $cnt == 1 ] || error "unexpected #files after (5): $cnt"
27988
27989         tmpdir=$(mktemp -d /tmp/lustre-XXXXXX)
27990         stack_trap "rmdir $tmpdir"
27991         mount_client $tmpdir "$MOUNT_OPTS,user_fid2path" ||
27992                 error "failed to mount client'"
27993         stack_trap "umount_client $tmpdir"
27994
27995         $RUNAS $LFS rmfid $tmpdir $FID || error "rmfid failed"
27996         # rmfid should succeed
27997         cnt=$(ls -1 $tmpdir/$tdir | wc -l)
27998         [ $cnt == 0 ] || error "unexpected #files after (6): $cnt"
27999
28000         # rmfid shouldn't allow to remove files due to dir's permission
28001         chmod a+rwx $tmpdir/$tdir
28002         touch $tmpdir/$tdir/f
28003         ls -la $tmpdir/$tdir
28004         FID=$(lfs path2fid $tmpdir/$tdir/f)
28005         $RUNAS $LFS rmfid $tmpdir $FID && error "rmfid didn't fail"
28006         return 0
28007 }
28008 run_test 421f "rmfid checks permissions"
28009
28010 test_421g() {
28011         local cnt
28012         local FIDS
28013
28014         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
28015         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
28016                 skip "Need MDS version at least 2.12.54"
28017
28018         mkdir -p $DIR/$tdir
28019         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
28020         createmany -o $DIR/$tdir/striped_dir/f 512
28021         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
28022         [ $cnt != 512 ] && error "unexpected #files: $cnt"
28023
28024         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
28025                 sed "s/[/][^:]*://g")
28026
28027         rm -f $DIR/$tdir/striped_dir/f1*
28028         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
28029         removed=$((512 - cnt))
28030
28031         # few files have been just removed, so we expect
28032         # rmfid to fail on their fids
28033         errors=$($LFS rmfid $DIR $FIDS 2>&1 | wc -l)
28034         [ $removed != $errors ] && error "$errors != $removed"
28035
28036         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
28037         rm -rf $DIR/$tdir
28038         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
28039 }
28040 run_test 421g "rmfid to return errors properly"
28041
28042 test_421h() {
28043         local mount_other
28044         local mount_ret
28045         local rmfid_ret
28046         local old_fid
28047         local fidA
28048         local fidB
28049         local fidC
28050         local fidD
28051
28052         (( MDS1_VERSION >= $(version_code 2.15.53) )) ||
28053                 skip "Need MDS version at least 2.15.53"
28054
28055         test_mkdir $DIR/$tdir
28056         test_mkdir $DIR/$tdir/subdir
28057         touch $DIR/$tdir/subdir/file0
28058         old_fid=$(lfs path2fid $DIR/$tdir/subdir/file0 | sed "s/[/][^:]*://g")
28059         echo File $DIR/$tdir/subdir/file0 FID $old_fid
28060         rm -f $DIR/$tdir/subdir/file0
28061         touch $DIR/$tdir/subdir/fileA
28062         fidA=$(lfs path2fid $DIR/$tdir/subdir/fileA | sed "s/[/][^:]*://g")
28063         echo File $DIR/$tdir/subdir/fileA FID $fidA
28064         touch $DIR/$tdir/subdir/fileB
28065         fidB=$(lfs path2fid $DIR/$tdir/subdir/fileB | sed "s/[/][^:]*://g")
28066         echo File $DIR/$tdir/subdir/fileB FID $fidB
28067         ln $DIR/$tdir/subdir/fileB $DIR/$tdir/subdir/fileB_hl
28068         touch $DIR/$tdir/subdir/fileC
28069         fidC=$(lfs path2fid $DIR/$tdir/subdir/fileC | sed "s/[/][^:]*://g")
28070         echo File $DIR/$tdir/subdir/fileC FID $fidC
28071         ln $DIR/$tdir/subdir/fileC $DIR/$tdir/fileC
28072         touch $DIR/$tdir/fileD
28073         fidD=$(lfs path2fid $DIR/$tdir/fileD | sed "s/[/][^:]*://g")
28074         echo File $DIR/$tdir/fileD FID $fidD
28075
28076         # mount another client mount point with subdirectory mount
28077         export FILESET=/$tdir/subdir
28078         mount_other=${MOUNT}_other
28079         mount_client $mount_other ${MOUNT_OPTS}
28080         mount_ret=$?
28081         export FILESET=""
28082         (( mount_ret == 0 )) || error "mount $mount_other failed"
28083
28084         echo Removing FIDs:
28085         echo $LFS rmfid $mount_other $old_fid $fidA $fidD $fidB $fidC
28086         $LFS rmfid $mount_other $old_fid $fidA $fidD $fidB $fidC
28087         rmfid_ret=$?
28088
28089         umount_client $mount_other || error "umount $mount_other failed"
28090
28091         (( rmfid_ret != 0 )) || error "rmfid should have failed"
28092
28093         # fileA should have been deleted
28094         stat $DIR/$tdir/subdir/fileA && error "fileA not deleted"
28095
28096         # fileB should have been deleted
28097         stat $DIR/$tdir/subdir/fileB && error "fileB not deleted"
28098
28099         # fileC should not have been deleted, fid also exists outside of fileset
28100         stat $DIR/$tdir/subdir/fileC || error "fileC deleted"
28101
28102         # fileD should not have been deleted, it exists outside of fileset
28103         stat $DIR/$tdir/fileD || error "fileD deleted"
28104 }
28105 run_test 421h "rmfid with fileset mount"
28106
28107 test_422() {
28108         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d1
28109         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d2
28110         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d3
28111         dd if=/dev/zero of=$DIR/$tdir/d1/file1 bs=1k count=1
28112         dd if=/dev/zero of=$DIR/$tdir/d2/file1 bs=1k count=1
28113
28114         local amc=$(at_max_get client)
28115         local amo=$(at_max_get mds1)
28116         local timeout=`lctl get_param -n timeout`
28117
28118         at_max_set 0 client
28119         at_max_set 0 mds1
28120
28121 #define OBD_FAIL_PTLRPC_PAUSE_REQ        0x50a
28122         do_facet mds1 $LCTL set_param fail_loc=0x8000050a \
28123                         fail_val=$(((2*timeout + 10)*1000))
28124         touch $DIR/$tdir/d3/file &
28125         sleep 2
28126 #define OBD_FAIL_TGT_REPLY_DATA_RACE     0x722
28127         do_facet mds1 $LCTL set_param fail_loc=0x80000722 \
28128                         fail_val=$((2*timeout + 5))
28129         mv $DIR/$tdir/d1/file1 $DIR/$tdir/d1/file2 &
28130         local pid=$!
28131         sleep 1
28132         kill -9 $pid
28133         sleep $((2 * timeout))
28134         echo kill $pid
28135         kill -9 $pid
28136         lctl mark touch
28137         touch $DIR/$tdir/d2/file3
28138         touch $DIR/$tdir/d2/file4
28139         touch $DIR/$tdir/d2/file5
28140
28141         wait
28142         at_max_set $amc client
28143         at_max_set $amo mds1
28144
28145         # LU-12838 - verify the ptlrpc thread watchdog is not always throttled
28146         do_facet mds1 "dmesg | grep 'Dumping the stack trace for debugging'" ||
28147                 error "Watchdog is always throttled"
28148 }
28149 run_test 422 "kill a process with RPC in progress"
28150
28151 stat_test() {
28152     df -h $MOUNT &
28153     df -h $MOUNT &
28154     df -h $MOUNT &
28155     df -h $MOUNT &
28156     df -h $MOUNT &
28157     df -h $MOUNT &
28158 }
28159
28160 test_423() {
28161     local _stats
28162     # ensure statfs cache is expired
28163     sleep 2;
28164
28165     _stats=$(stat_test | grep $MOUNT | sort -u | wc -l)
28166     [[ ${_stats} -ne 1 ]] && error "statfs wrong"
28167
28168     return 0
28169 }
28170 run_test 423 "statfs should return a right data"
28171
28172 test_424() {
28173 #define OBD_FAIL_PTLRPC_BULK_REPLY_ATTACH      0x522 | CFS_FAIL_ONCE
28174         $LCTL set_param fail_loc=0x80000522
28175         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
28176         rm -f $DIR/$tfile
28177 }
28178 run_test 424 "simulate ENOMEM in ptl_send_rpc bulk reply ME attach"
28179
28180 test_425() {
28181         test_mkdir -c -1 $DIR/$tdir
28182         $LFS setstripe -c -1 $DIR/$tdir
28183
28184         lru_resize_disable "" 100
28185         stack_trap "lru_resize_enable" EXIT
28186
28187         sleep 5
28188
28189         for i in $(seq $((MDSCOUNT * 125))); do
28190                 local t=$DIR/$tdir/$tfile_$i
28191
28192                 dd if=/dev/zero of=$t bs=4K count=1 > /dev/null 2>&1 ||
28193                         error_noexit "Create file $t"
28194         done
28195         stack_trap "rm -rf $DIR/$tdir" EXIT
28196
28197         for oscparam in $($LCTL list_param ldlm.namespaces.*osc-[-0-9a-f]*); do
28198                 local lru_size=$($LCTL get_param -n $oscparam.lru_size)
28199                 local lock_count=$($LCTL get_param -n $oscparam.lock_count)
28200
28201                 [ $lock_count -le $lru_size ] ||
28202                         error "osc lock count $lock_count > lru size $lru_size"
28203         done
28204
28205         for mdcparam in $($LCTL list_param ldlm.namespaces.*mdc-*); do
28206                 local lru_size=$($LCTL get_param -n $mdcparam.lru_size)
28207                 local lock_count=$($LCTL get_param -n $mdcparam.lock_count)
28208
28209                 [ $lock_count -le $lru_size ] ||
28210                         error "mdc lock count $lock_count > lru size $lru_size"
28211         done
28212 }
28213 run_test 425 "lock count should not exceed lru size"
28214
28215 test_426() {
28216         splice-test -r $DIR/$tfile
28217         splice-test -rd $DIR/$tfile
28218         splice-test $DIR/$tfile
28219         splice-test -d $DIR/$tfile
28220 }
28221 run_test 426 "splice test on Lustre"
28222
28223 test_427() {
28224         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
28225         (( $MDS1_VERSION >= $(version_code 2.12.4) )) ||
28226                 skip "Need MDS version at least 2.12.4"
28227         local log
28228
28229         mkdir $DIR/$tdir
28230         mkdir $DIR/$tdir/1
28231         mkdir $DIR/$tdir/2
28232         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/1/dir
28233         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/2/dir2
28234
28235         $LFS getdirstripe $DIR/$tdir/1/dir
28236
28237         #first setfattr for creating updatelog
28238         setfattr -n user.attr0 -v "some text" $DIR/$tdir/1/dir
28239
28240 #define OBD_FAIL_OUT_OBJECT_MISS        0x1708
28241         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param fail_loc=0x80001708
28242         setfattr -n user.attr1 -v "some text" $DIR/$tdir/1/dir &
28243         setfattr -n user.attr2 -v "another attr"  $DIR/$tdir/2/dir2 &
28244
28245         sleep 2
28246         fail mds2
28247         wait_recovery_complete mds2 $((2*TIMEOUT))
28248
28249         log=$(do_facet mds1 dmesg | tac | sed "/${TESTNAME//_/ }/,$ d")
28250         echo $log | grep "get update log failed" &&
28251                 error "update log corruption is detected" || true
28252 }
28253 run_test 427 "Failed DNE2 update request shouldn't corrupt updatelog"
28254
28255 test_428() {
28256         [ $PARALLEL == "yes" ] && skip "skip parallel run"
28257         local cache_limit=$CACHE_MAX
28258
28259         stack_trap "$LCTL set_param -n llite.*.max_cached_mb=$cache_limit"
28260         $LCTL set_param -n llite.*.max_cached_mb=64
28261
28262         mkdir $DIR/$tdir
28263         $LFS setstripe -c 1 $DIR/$tdir
28264         eval touch $DIR/$tdir/$tfile.{1..$OSTCOUNT}
28265         stack_trap "rm -f $DIR/$tdir/$tfile.*"
28266         #test write
28267         for f in $(seq 4); do
28268                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$f bs=128M count=1 &
28269         done
28270         wait
28271
28272         cancel_lru_locks osc
28273         # Test read
28274         for f in $(seq 4); do
28275                 dd if=$DIR/$tdir/$tfile.$f of=/dev/null bs=128M count=1 &
28276         done
28277         wait
28278 }
28279 run_test 428 "large block size IO should not hang"
28280
28281 test_429() { # LU-7915 / LU-10948
28282         local ll_opencache_threshold_count="llite.*.opencache_threshold_count"
28283         local testfile=$DIR/$tfile
28284         local mdc_rpcstats="mdc.$FSNAME-MDT0000-*.stats"
28285         local new_flag=1
28286         local first_rpc
28287         local second_rpc
28288         local third_rpc
28289
28290         $LCTL get_param $ll_opencache_threshold_count ||
28291                 skip "client does not have opencache parameter"
28292
28293         set_opencache $new_flag
28294         stack_trap "restore_opencache"
28295         [ $($LCTL get_param -n $ll_opencache_threshold_count) == $new_flag ] ||
28296                 error "enable opencache failed"
28297         touch $testfile
28298         # drop MDC DLM locks
28299         cancel_lru_locks mdc
28300         # clear MDC RPC stats counters
28301         $LCTL set_param $mdc_rpcstats=clear
28302
28303         # According to the current implementation, we need to run 3 times
28304         # open & close file to verify if opencache is enabled correctly.
28305         # 1st, RPCs are sent for lookup/open and open handle is released on
28306         #      close finally.
28307         # 2nd, RPC is sent for open, MDS_OPEN_LOCK is fetched automatically,
28308         #      so open handle won't be released thereafter.
28309         # 3rd, No RPC is sent out.
28310         $MULTIOP $testfile oc || error "multiop failed"
28311         first_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
28312         echo "1st: $first_rpc RPCs in flight"
28313
28314         $MULTIOP $testfile oc || error "multiop failed"
28315         second_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
28316         echo "2nd: $second_rpc RPCs in flight"
28317
28318         $MULTIOP $testfile oc || error "multiop failed"
28319         third_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
28320         echo "3rd: $third_rpc RPCs in flight"
28321
28322         #verify no MDC RPC is sent
28323         [[ $second_rpc == $third_rpc ]] || error "MDC RPC is still sent"
28324 }
28325 run_test 429 "verify if opencache flag on client side does work"
28326
28327 lseek_test_430() {
28328         local offset
28329         local file=$1
28330
28331         # data at [200K, 400K)
28332         dd if=/dev/urandom of=$file bs=256K count=1 seek=1 ||
28333                 error "256K->512K dd fails"
28334         # data at [2M, 3M)
28335         dd if=/dev/urandom of=$file bs=1M count=1 seek=2 ||
28336                 error "2M->3M dd fails"
28337         # data at [4M, 5M)
28338         dd if=/dev/urandom of=$file bs=1M count=1 seek=4 ||
28339                 error "4M->5M dd fails"
28340         echo "Data at 256K...512K, 2M...3M and 4M...5M"
28341         # start at first component hole #1
28342         printf "Seeking hole from 1000 ... "
28343         offset=$(lseek_test -l 1000 $file)
28344         echo $offset
28345         [[ $offset == 1000 ]] || error "offset $offset != 1000"
28346         printf "Seeking data from 1000 ... "
28347         offset=$(lseek_test -d 1000 $file)
28348         echo $offset
28349         [[ $offset == 262144 ]] || error "offset $offset != 262144"
28350
28351         # start at first component data block
28352         printf "Seeking hole from 300000 ... "
28353         offset=$(lseek_test -l 300000 $file)
28354         echo $offset
28355         [[ $offset == 524288 ]] || error "offset $offset != 524288"
28356         printf "Seeking data from 300000 ... "
28357         offset=$(lseek_test -d 300000 $file)
28358         echo $offset
28359         [[ $offset == 300000 ]] || error "offset $offset != 300000"
28360
28361         # start at the first component but beyond end of object size
28362         printf "Seeking hole from 1000000 ... "
28363         offset=$(lseek_test -l 1000000 $file)
28364         echo $offset
28365         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
28366         printf "Seeking data from 1000000 ... "
28367         offset=$(lseek_test -d 1000000 $file)
28368         echo $offset
28369         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
28370
28371         # start at second component stripe 2 (empty file)
28372         printf "Seeking hole from 1500000 ... "
28373         offset=$(lseek_test -l 1500000 $file)
28374         echo $offset
28375         [[ $offset == 1500000 ]] || error "offset $offset != 1500000"
28376         printf "Seeking data from 1500000 ... "
28377         offset=$(lseek_test -d 1500000 $file)
28378         echo $offset
28379         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
28380
28381         # start at second component stripe 1 (all data)
28382         printf "Seeking hole from 3000000 ... "
28383         offset=$(lseek_test -l 3000000 $file)
28384         echo $offset
28385         [[ $offset == 3145728 ]] || error "offset $offset != 3145728"
28386         printf "Seeking data from 3000000 ... "
28387         offset=$(lseek_test -d 3000000 $file)
28388         echo $offset
28389         [[ $offset == 3000000 ]] || error "offset $offset != 3000000"
28390
28391         dd if=/dev/urandom of=$file bs=640K count=1 seek=1 ||
28392                 error "2nd dd fails"
28393         echo "Add data block at 640K...1280K"
28394
28395         # start at before new data block, in hole
28396         printf "Seeking hole from 600000 ... "
28397         offset=$(lseek_test -l 600000 $file)
28398         echo $offset
28399         [[ $offset == 600000 ]] || error "offset $offset != 600000"
28400         printf "Seeking data from 600000 ... "
28401         offset=$(lseek_test -d 600000 $file)
28402         echo $offset
28403         [[ $offset == 655360 ]] || error "offset $offset != 655360"
28404
28405         # start at the first component new data block
28406         printf "Seeking hole from 1000000 ... "
28407         offset=$(lseek_test -l 1000000 $file)
28408         echo $offset
28409         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
28410         printf "Seeking data from 1000000 ... "
28411         offset=$(lseek_test -d 1000000 $file)
28412         echo $offset
28413         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
28414
28415         # start at second component stripe 2, new data
28416         printf "Seeking hole from 1200000 ... "
28417         offset=$(lseek_test -l 1200000 $file)
28418         echo $offset
28419         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
28420         printf "Seeking data from 1200000 ... "
28421         offset=$(lseek_test -d 1200000 $file)
28422         echo $offset
28423         [[ $offset == 1200000 ]] || error "offset $offset != 1200000"
28424
28425         # start beyond file end
28426         printf "Using offset > filesize ... "
28427         lseek_test -l 4000000 $file && error "lseek should fail"
28428         printf "Using offset > filesize ... "
28429         lseek_test -d 4000000 $file && error "lseek should fail"
28430
28431         printf "Done\n\n"
28432 }
28433
28434 test_430a() {
28435         $LCTL get_param mdc.*.import | grep -q 'connect_flags:.*seek' ||
28436                 skip "MDT does not support SEEK_HOLE"
28437
28438         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
28439                 skip "OST does not support SEEK_HOLE"
28440
28441         local file=$DIR/$tdir/$tfile
28442
28443         mkdir -p $DIR/$tdir
28444
28445         $LFS setstripe -E 1M -L mdt -E eof -c2 $file
28446         # OST stripe #1 will have continuous data at [1M, 3M)
28447         # OST stripe #2 is empty
28448         echo "Component #1: 1M DoM, component #2: EOF, 2 stripes 1M"
28449         lseek_test_430 $file
28450         rm $file
28451         $LFS setstripe -E 1M -c2 -S 64K -E 10M -c2 -S 1M $file
28452         echo "Component #1: 1M, 2 stripes 64K, component #2: EOF, 2 stripes 1M"
28453         lseek_test_430 $file
28454         rm $file
28455         $LFS setstripe -c2 -S 512K $file
28456         echo "Two stripes, stripe size 512K"
28457         lseek_test_430 $file
28458         rm $file
28459         # FLR with stale mirror
28460         $LFS setstripe -N -E 512K -c1 -S 64K -E eof -c2 -S 512K \
28461                        -N -c2 -S 1M $file
28462         echo "Mirrored file:"
28463         echo "Component #1: 512K, stripe 64K, component #2: EOF, 2 stripes 512K"
28464         echo "Plain 2 stripes 1M"
28465         lseek_test_430 $file
28466         rm $file
28467 }
28468 run_test 430a "lseek: SEEK_DATA/SEEK_HOLE basic functionality"
28469
28470 test_430b() {
28471         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
28472                 skip "OST does not support SEEK_HOLE"
28473
28474         local offset
28475         local file=$DIR/$tdir/$tfile
28476
28477         mkdir -p $DIR/$tdir
28478         # Empty layout lseek should fail
28479         $MCREATE $file
28480         # seek from 0
28481         printf "Seeking hole from 0 ... "
28482         lseek_test -l 0 $file && error "lseek should fail"
28483         printf "Seeking data from 0 ... "
28484         lseek_test -d 0 $file && error "lseek should fail"
28485         rm $file
28486
28487         # 1M-hole file
28488         $LFS setstripe -E 1M -c2 -E eof $file
28489         $TRUNCATE $file 1048576
28490         printf "Seeking hole from 1000000 ... "
28491         offset=$(lseek_test -l 1000000 $file)
28492         echo $offset
28493         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
28494         printf "Seeking data from 1000000 ... "
28495         lseek_test -d 1000000 $file && error "lseek should fail"
28496         rm $file
28497
28498         # full component followed by non-inited one
28499         $LFS setstripe -E 1M -c2 -E eof $file
28500         dd if=/dev/urandom of=$file bs=1M count=1
28501         printf "Seeking hole from 1000000 ... "
28502         offset=$(lseek_test -l 1000000 $file)
28503         echo $offset
28504         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
28505         printf "Seeking hole from 1048576 ... "
28506         lseek_test -l 1048576 $file && error "lseek should fail"
28507         # init second component and truncate back
28508         echo "123" >> $file
28509         $TRUNCATE $file 1048576
28510         printf "Seeking hole from 1000000 ... "
28511         offset=$(lseek_test -l 1000000 $file)
28512         echo $offset
28513         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
28514         printf "Seeking hole from 1048576 ... "
28515         lseek_test -l 1048576 $file && error "lseek should fail"
28516         # boundary checks for big values
28517         dd if=/dev/urandom of=$file.10g bs=1 count=1 seek=10G
28518         offset=$(lseek_test -d 0 $file.10g)
28519         [[ $offset == 10737418240 ]] || error "offset $offset != 10737418240"
28520         dd if=/dev/urandom of=$file.100g bs=1 count=1 seek=100G
28521         offset=$(lseek_test -d 0 $file.100g)
28522         [[ $offset == 107374182400 ]] || error "offset $offset != 107374182400"
28523         return 0
28524 }
28525 run_test 430b "lseek: SEEK_DATA/SEEK_HOLE special cases"
28526
28527 test_430c() {
28528         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
28529                 skip "OST does not support SEEK_HOLE"
28530
28531         local file=$DIR/$tdir/$tfile
28532         local start
28533
28534         mkdir -p $DIR/$tdir
28535         stack_trap "rm -f $file $file.tmp"
28536         dd if=/dev/urandom of=$file bs=1k count=1 seek=5M || error "dd failed"
28537
28538         # cp version 8.33+ prefers lseek over fiemap
28539         local ver=$(cp --version | awk '{ print $4; exit; }')
28540
28541         echo "cp $ver installed"
28542         if (( $(version_code $ver) >= $(version_code 8.33) )); then
28543                 start=$SECONDS
28544                 time cp -v $file $file.tmp || error "cp $file failed"
28545                 (( SECONDS - start < 5 )) || {
28546                         strace cp $file $file.tmp |&
28547                                 grep -E "open|read|seek|FIEMAP" |
28548                                 grep -A 100 $file
28549                         error "cp: too long runtime $((SECONDS - start))"
28550                 }
28551         else
28552                 echo "cp test skipped due to $ver < 8.33"
28553         fi
28554
28555         # tar version 1.29+ supports SEEK_HOLE/DATA
28556         ver=$(tar --version | awk '{ print $4; exit; }')
28557         echo "tar $ver installed"
28558         if (( $(version_code $ver) >= $(version_code 1.29) )); then
28559                 start=$SECONDS
28560                 time tar cvf $file.tmp --sparse $file || error "tar $file error"
28561                 (( SECONDS - start < 5 )) || {
28562                         strace tar cf $file.tmp --sparse $file |&
28563                                 grep -E "open|read|seek|FIEMAP" |
28564                                 grep -A 100 $file
28565                         error "tar: too long runtime $((SECONDS - start))"
28566                 }
28567         else
28568                 echo "tar test skipped due to $ver < 1.29"
28569         fi
28570 }
28571 run_test 430c "lseek: external tools check"
28572
28573 test_431() { # LU-14187
28574         local file=$DIR/$tdir/$tfile
28575
28576         mkdir -p $DIR/$tdir
28577         $LFS setstripe -c 1 -i 0 $file || error "lfs setstripe failed"
28578         dd if=/dev/urandom of=$file bs=4k count=1
28579         dd if=/dev/urandom of=$file bs=4k count=1 seek=10 conv=notrunc
28580         dd if=/dev/urandom of=$file bs=4k count=1 seek=12 conv=notrunc
28581         #define OBD_FAIL_OST_RESTART_IO 0x251
28582         do_facet ost1 "$LCTL set_param fail_loc=0x251"
28583         $LFS setstripe -c 1 -i 0 $file.0 || error "lfs setstripe failed"
28584         cp $file $file.0
28585         cancel_lru_locks
28586         sync_all_data
28587         echo 3 > /proc/sys/vm/drop_caches
28588         diff  $file $file.0 || error "data diff"
28589 }
28590 run_test 431 "Restart transaction for IO"
28591
28592 cleanup_test_432() {
28593         do_facet mgs $LCTL nodemap_activate 0
28594         wait_nm_sync active
28595 }
28596
28597 test_432() {
28598         local tmpdir=$TMP/dir432
28599
28600         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
28601                 skip "Need MDS version at least 2.14.52"
28602
28603         stack_trap cleanup_test_432 EXIT
28604         mkdir $DIR/$tdir
28605         mkdir $tmpdir
28606
28607         do_facet mgs $LCTL nodemap_activate 1
28608         wait_nm_sync active
28609         do_facet mgs $LCTL nodemap_modify --name default \
28610                 --property admin --value 1
28611         do_facet mgs $LCTL nodemap_modify --name default \
28612                 --property trusted --value 1
28613         cancel_lru_locks mdc
28614         wait_nm_sync default admin_nodemap
28615         wait_nm_sync default trusted_nodemap
28616
28617         if [ $(mv $tmpdir $DIR/$tdir/ 2>&1 |
28618                grep -ci "Operation not permitted") -ne 0 ]; then
28619                 error "mv $tmpdir $DIR/$tdir/ hits 'Operation not permitted'"
28620         fi
28621 }
28622 run_test 432 "mv dir from outside Lustre"
28623
28624 test_433() {
28625         [ $PARALLEL == "yes" ] && skip "skip parallel run"
28626
28627         [[ -n "$($LCTL list_param llite.*.inode_cache 2>/dev/null)" ]] ||
28628                 skip "inode cache not supported"
28629
28630         $LCTL set_param llite.*.inode_cache=0
28631         stack_trap "$LCTL set_param llite.*.inode_cache=1"
28632
28633         local count=256
28634         local before
28635         local after
28636
28637         cancel_lru_locks mdc
28638         test_mkdir $DIR/$tdir || error "mkdir $tdir"
28639         createmany -m $DIR/$tdir/f $count
28640         createmany -d $DIR/$tdir/d $count
28641         ls -l $DIR/$tdir > /dev/null
28642         stack_trap "rm -rf $DIR/$tdir"
28643
28644         before=$(num_objects)
28645         cancel_lru_locks mdc
28646         after=$(num_objects)
28647
28648         # sometimes even @before is less than 2 * count
28649         while (( before - after < count )); do
28650                 sleep 1
28651                 after=$(num_objects)
28652                 wait=$((wait + 1))
28653                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
28654                 if (( wait > 60 )); then
28655                         error "inode slab grew from $before to $after"
28656                 fi
28657         done
28658
28659         echo "lustre_inode_cache $before objs before lock cancel, $after after"
28660 }
28661 run_test 433 "ldlm lock cancel releases dentries and inodes"
28662
28663 test_434() {
28664         local file
28665         local getxattr_count
28666         local mdc_stat_param="mdc.$FSNAME-MDT0000*.md_stats"
28667         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
28668
28669         [[ $(getenforce) == "Disabled" ]] ||
28670                 skip "lsm selinux module have to be disabled for this test"
28671
28672         test_mkdir -i 0 -c1 $DIR/$tdir/ ||
28673                 error "fail to create $DIR/$tdir/ on MDT0000"
28674
28675         touch $DIR/$tdir/$tfile-{001..100}
28676
28677         # disable the xattr cache
28678         save_lustre_params client "llite.*.xattr_cache" > $p
28679         lctl set_param llite.*.xattr_cache=0
28680         stack_trap "restore_lustre_params < $p; rm -f $p" EXIT
28681
28682         # clear clients mdc stats
28683         clear_stats $mdc_stat_param ||
28684                 error "fail to clear stats on mdc MDT0000"
28685
28686         for file in $DIR/$tdir/$tfile-{001..100}; do
28687                 getfattr -n security.selinux $file |&
28688                         grep -q "Operation not supported" ||
28689                         error "getxattr on security.selinux should return EOPNOTSUPP"
28690         done
28691
28692         getxattr_count=$(calc_stats $mdc_stat_param "getxattr")
28693         (( getxattr_count < 100 )) ||
28694                 error "client sent $getxattr_count getxattr RPCs to the MDS"
28695 }
28696 run_test 434 "Client should not send RPCs for security.selinux with SElinux disabled"
28697
28698 test_440() {
28699         if [[ -f $LUSTRE/scripts/bash-completion/lustre ]]; then
28700                 source $LUSTRE/scripts/bash-completion/lustre
28701         elif [[ -f /usr/share/bash-completion/completions/lustre ]]; then
28702                 source /usr/share/bash-completion/completions/lustre
28703         else
28704                 skip "bash completion scripts not found"
28705         fi
28706
28707         local lctl_completions
28708         local lfs_completions
28709
28710         lctl_completions=$(_lustre_cmds lctl)
28711         if [[ ! $lctl_completions =~ "get_param" ]]; then
28712                 error "lctl bash completion failed"
28713         fi
28714
28715         lfs_completions=$(_lustre_cmds lfs)
28716         if [[ ! $lfs_completions =~ "setstripe" ]]; then
28717                 error "lfs bash completion failed"
28718         fi
28719 }
28720 run_test 440 "bash completion for lfs, lctl"
28721
28722 prep_801() {
28723         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
28724         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
28725                 skip "Need server version at least 2.9.55"
28726
28727         start_full_debug_logging
28728 }
28729
28730 post_801() {
28731         stop_full_debug_logging
28732 }
28733
28734 barrier_stat() {
28735         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
28736                 local st=$(do_facet mgs $LCTL barrier_stat $FSNAME |
28737                            awk '/The barrier for/ { print $7 }')
28738                 echo $st
28739         else
28740                 local st=$(do_facet mgs $LCTL barrier_stat -s $FSNAME)
28741                 echo \'$st\'
28742         fi
28743 }
28744
28745 barrier_expired() {
28746         local expired
28747
28748         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
28749                 expired=$(do_facet mgs $LCTL barrier_stat $FSNAME |
28750                           awk '/will be expired/ { print $7 }')
28751         else
28752                 expired=$(do_facet mgs $LCTL barrier_stat -t $FSNAME)
28753         fi
28754
28755         echo $expired
28756 }
28757
28758 test_801a() {
28759         prep_801
28760
28761         echo "Start barrier_freeze at: $(date)"
28762         #define OBD_FAIL_BARRIER_DELAY          0x2202
28763         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
28764         # Do not reduce barrier time - See LU-11873
28765         do_facet mgs $LCTL barrier_freeze $FSNAME 20 &
28766
28767         sleep 2
28768         local b_status=$(barrier_stat)
28769         echo "Got barrier status at: $(date)"
28770         [ "$b_status" = "'freezing_p1'" ] ||
28771                 error "(1) unexpected barrier status $b_status"
28772
28773         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
28774         wait
28775         b_status=$(barrier_stat)
28776         [ "$b_status" = "'frozen'" ] ||
28777                 error "(2) unexpected barrier status $b_status"
28778
28779         local expired=$(barrier_expired)
28780         echo "sleep $((expired + 3)) seconds, then the barrier will be expired"
28781         sleep $((expired + 3))
28782
28783         b_status=$(barrier_stat)
28784         [ "$b_status" = "'expired'" ] ||
28785                 error "(3) unexpected barrier status $b_status"
28786
28787         # Do not reduce barrier time - See LU-11873
28788         do_facet mgs $LCTL barrier_freeze $FSNAME 20 ||
28789                 error "(4) fail to freeze barrier"
28790
28791         b_status=$(barrier_stat)
28792         [ "$b_status" = "'frozen'" ] ||
28793                 error "(5) unexpected barrier status $b_status"
28794
28795         echo "Start barrier_thaw at: $(date)"
28796         #define OBD_FAIL_BARRIER_DELAY          0x2202
28797         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
28798         do_facet mgs $LCTL barrier_thaw $FSNAME &
28799
28800         sleep 2
28801         b_status=$(barrier_stat)
28802         echo "Got barrier status at: $(date)"
28803         [ "$b_status" = "'thawing'" ] ||
28804                 error "(6) unexpected barrier status $b_status"
28805
28806         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
28807         wait
28808         b_status=$(barrier_stat)
28809         [ "$b_status" = "'thawed'" ] ||
28810                 error "(7) unexpected barrier status $b_status"
28811
28812         #define OBD_FAIL_BARRIER_FAILURE        0x2203
28813         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2203
28814         do_facet mgs $LCTL barrier_freeze $FSNAME
28815
28816         b_status=$(barrier_stat)
28817         [ "$b_status" = "'failed'" ] ||
28818                 error "(8) unexpected barrier status $b_status"
28819
28820         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
28821         do_facet mgs $LCTL barrier_thaw $FSNAME
28822
28823         post_801
28824 }
28825 run_test 801a "write barrier user interfaces and stat machine"
28826
28827 test_801b() {
28828         prep_801
28829
28830         mkdir $DIR/$tdir || error "(1) fail to mkdir"
28831         createmany -d $DIR/$tdir/d 6 || error "(2) fail to mkdir"
28832         touch $DIR/$tdir/d2/f10 || error "(3) fail to touch"
28833         touch $DIR/$tdir/d3/f11 || error "(4) fail to touch"
28834         touch $DIR/$tdir/d4/f12 || error "(5) fail to touch"
28835
28836         cancel_lru_locks mdc
28837
28838         # 180 seconds should be long enough
28839         do_facet mgs $LCTL barrier_freeze $FSNAME 180
28840
28841         local b_status=$(barrier_stat)
28842         [ "$b_status" = "'frozen'" ] ||
28843                 error "(6) unexpected barrier status $b_status"
28844
28845         mkdir $DIR/$tdir/d0/d10 &
28846         mkdir_pid=$!
28847
28848         touch $DIR/$tdir/d1/f13 &
28849         touch_pid=$!
28850
28851         ln $DIR/$tdir/d2/f10 $DIR/$tdir/d2/f14 &
28852         ln_pid=$!
28853
28854         mv $DIR/$tdir/d3/f11 $DIR/$tdir/d3/f15 &
28855         mv_pid=$!
28856
28857         rm -f $DIR/$tdir/d4/f12 &
28858         rm_pid=$!
28859
28860         stat $DIR/$tdir/d5 || error "(7) stat should succeed"
28861
28862         # To guarantee taht the 'stat' is not blocked
28863         b_status=$(barrier_stat)
28864         [ "$b_status" = "'frozen'" ] ||
28865                 error "(8) unexpected barrier status $b_status"
28866
28867         # let above commands to run at background
28868         sleep 5
28869
28870         ps -p $mkdir_pid || error "(9) mkdir should be blocked"
28871         ps -p $touch_pid || error "(10) touch should be blocked"
28872         ps -p $ln_pid || error "(11) link should be blocked"
28873         ps -p $mv_pid || error "(12) rename should be blocked"
28874         ps -p $rm_pid || error "(13) unlink should be blocked"
28875
28876         b_status=$(barrier_stat)
28877         [ "$b_status" = "'frozen'" ] ||
28878                 error "(14) unexpected barrier status $b_status"
28879
28880         do_facet mgs $LCTL barrier_thaw $FSNAME
28881         b_status=$(barrier_stat)
28882         [ "$b_status" = "'thawed'" ] ||
28883                 error "(15) unexpected barrier status $b_status"
28884
28885         wait $mkdir_pid || error "(16) mkdir should succeed"
28886         wait $touch_pid || error "(17) touch should succeed"
28887         wait $ln_pid || error "(18) link should succeed"
28888         wait $mv_pid || error "(19) rename should succeed"
28889         wait $rm_pid || error "(20) unlink should succeed"
28890
28891         post_801
28892 }
28893 run_test 801b "modification will be blocked by write barrier"
28894
28895 test_801c() {
28896         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
28897
28898         prep_801
28899
28900         stop mds2 || error "(1) Fail to stop mds2"
28901
28902         do_facet mgs $LCTL barrier_freeze $FSNAME 30
28903
28904         local b_status=$(barrier_stat)
28905         [ "$b_status" = "'expired'" ] || [ "$b_status" = "'failed'" ] || {
28906                 do_facet mgs $LCTL barrier_thaw $FSNAME
28907                 error "(2) unexpected barrier status $b_status"
28908         }
28909
28910         do_facet mgs $LCTL barrier_rescan $FSNAME ||
28911                 error "(3) Fail to rescan barrier bitmap"
28912
28913         # Do not reduce barrier time - See LU-11873
28914         do_facet mgs $LCTL barrier_freeze $FSNAME 20
28915
28916         b_status=$(barrier_stat)
28917         [ "$b_status" = "'frozen'" ] ||
28918                 error "(4) unexpected barrier status $b_status"
28919
28920         do_facet mgs $LCTL barrier_thaw $FSNAME
28921         b_status=$(barrier_stat)
28922         [ "$b_status" = "'thawed'" ] ||
28923                 error "(5) unexpected barrier status $b_status"
28924
28925         local devname=$(mdsdevname 2)
28926
28927         start mds2 $devname $MDS_MOUNT_OPTS || error "(6) Fail to start mds2"
28928
28929         do_facet mgs $LCTL barrier_rescan $FSNAME ||
28930                 error "(7) Fail to rescan barrier bitmap"
28931
28932         post_801
28933 }
28934 run_test 801c "rescan barrier bitmap"
28935
28936 test_802b() {
28937         [ $PARALLEL == "yes" ] && skip "skip parallel run"
28938         remote_mds_nodsh && skip "remote MDS with nodsh"
28939
28940         do_facet $SINGLEMDS $LCTL get_param mdt.*.readonly ||
28941                 skip "readonly option not available"
28942
28943         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "(1) fail to mkdir"
28944
28945         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
28946                 error "(2) Fail to copy"
28947
28948         # write back all cached data before setting MDT to readonly
28949         cancel_lru_locks
28950         sync_all_data
28951
28952         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=1
28953         stack_trap "do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0" EXIT
28954
28955         echo "Modify should be refused"
28956         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
28957
28958         echo "Read should be allowed"
28959         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
28960                 error "(7) Read should succeed under ro mode"
28961
28962         # disable readonly
28963         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0
28964 }
28965 run_test 802b "be able to set MDTs to readonly"
28966
28967 test_803a() {
28968         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
28969         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
28970                 skip "MDS needs to be newer than 2.10.54"
28971
28972         mkdir_on_mdt0 $DIR/$tdir
28973         # Create some objects on all MDTs to trigger related logs objects
28974         for idx in $(seq $MDSCOUNT); do
28975                 $LFS mkdir -c $MDSCOUNT -i $((idx % $MDSCOUNT)) \
28976                         $DIR/$tdir/dir${idx} ||
28977                         error "Fail to create $DIR/$tdir/dir${idx}"
28978         done
28979
28980         wait_delete_completed # ensure old test cleanups are finished
28981         sleep 3
28982         echo "before create:"
28983         $LFS df -i $MOUNT
28984         local before_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
28985
28986         for i in {1..10}; do
28987                 $LFS mkdir -c 1 -i 1 $DIR/$tdir/foo$i ||
28988                         error "Fail to create $DIR/$tdir/foo$i"
28989         done
28990
28991         # sync ZFS-on-MDS to refresh statfs data
28992         wait_zfs_commit mds1
28993         sleep 3
28994         echo "after create:"
28995         $LFS df -i $MOUNT
28996         local after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
28997
28998         # allow for an llog to be cleaned up during the test
28999         [ $after_used -ge $((before_used + 10 - 1)) ] ||
29000                 error "before ($before_used) + 10 > after ($after_used)"
29001
29002         for i in {1..10}; do
29003                 rm -rf $DIR/$tdir/foo$i ||
29004                         error "Fail to remove $DIR/$tdir/foo$i"
29005         done
29006
29007         # sync ZFS-on-MDS to refresh statfs data
29008         wait_zfs_commit mds1
29009         wait_delete_completed
29010         sleep 3 # avoid MDT return cached statfs
29011         echo "after unlink:"
29012         $LFS df -i $MOUNT
29013         after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
29014
29015         # allow for an llog to be created during the test
29016         [ $after_used -le $((before_used + 1)) ] ||
29017                 error "after ($after_used) > before ($before_used) + 1"
29018 }
29019 run_test 803a "verify agent object for remote object"
29020
29021 test_803b() {
29022         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
29023         [ $MDS1_VERSION -lt $(version_code 2.13.56) ] &&
29024                 skip "MDS needs to be newer than 2.13.56"
29025         [ $PARALLEL == "yes" ] && skip "skip parallel run"
29026
29027         for i in $(seq 0 $((MDSCOUNT - 1))); do
29028                 $LFS mkdir -i $i $DIR/$tdir.$i || error "mkdir $tdir.$i"
29029         done
29030
29031         local before=0
29032         local after=0
29033
29034         local tmp
29035
29036         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
29037         for i in $(seq 0 $((MDSCOUNT - 1))); do
29038                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
29039                         awk '/getattr/ { print $2 }')
29040                 before=$((before + tmp))
29041         done
29042         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
29043         for i in $(seq 0 $((MDSCOUNT - 1))); do
29044                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
29045                         awk '/getattr/ { print $2 }')
29046                 after=$((after + tmp))
29047         done
29048
29049         [ $before -eq $after ] || error "getattr count $before != $after"
29050 }
29051 run_test 803b "remote object can getattr from cache"
29052
29053 test_804() {
29054         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
29055         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
29056                 skip "MDS needs to be newer than 2.10.54"
29057         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
29058
29059         mkdir -p $DIR/$tdir
29060         $LFS mkdir -c 1 -i 1 $DIR/$tdir/dir0 ||
29061                 error "Fail to create $DIR/$tdir/dir0"
29062
29063         local fid=$($LFS path2fid $DIR/$tdir/dir0)
29064         local dev=$(mdsdevname 2)
29065
29066         do_facet mds2 "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
29067                 grep ${fid} || error "NOT found agent entry for dir0"
29068
29069         $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir/dir1 ||
29070                 error "Fail to create $DIR/$tdir/dir1"
29071
29072         touch $DIR/$tdir/dir1/foo0 ||
29073                 error "Fail to create $DIR/$tdir/dir1/foo0"
29074         fid=$($LFS path2fid $DIR/$tdir/dir1/foo0)
29075         local rc=0
29076
29077         for idx in $(seq $MDSCOUNT); do
29078                 dev=$(mdsdevname $idx)
29079                 do_facet mds${idx} \
29080                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
29081                         grep ${fid} && rc=$idx
29082         done
29083
29084         mv $DIR/$tdir/dir1/foo0 $DIR/$tdir/dir1/foo1 ||
29085                 error "Fail to rename foo0 to foo1"
29086         if [ $rc -eq 0 ]; then
29087                 for idx in $(seq $MDSCOUNT); do
29088                         dev=$(mdsdevname $idx)
29089                         do_facet mds${idx} \
29090                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
29091                         grep ${fid} && rc=$idx
29092                 done
29093         fi
29094
29095         mv $DIR/$tdir/dir1/foo1 $DIR/$tdir/dir1/foo2 ||
29096                 error "Fail to rename foo1 to foo2"
29097         if [ $rc -eq 0 ]; then
29098                 for idx in $(seq $MDSCOUNT); do
29099                         dev=$(mdsdevname $idx)
29100                         do_facet mds${idx} \
29101                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
29102                         grep ${fid} && rc=$idx
29103                 done
29104         fi
29105
29106         [ $rc -ne 0 ] || error "NOT found agent entry for foo"
29107
29108         ln $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir0/guard ||
29109                 error "Fail to link to $DIR/$tdir/dir1/foo2"
29110         mv $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir1/foo0 ||
29111                 error "Fail to rename foo2 to foo0"
29112         unlink $DIR/$tdir/dir1/foo0 ||
29113                 error "Fail to unlink $DIR/$tdir/dir1/foo0"
29114         rm -rf $DIR/$tdir/dir0 ||
29115                 error "Fail to rm $DIR/$tdir/dir0"
29116
29117         for idx in $(seq $MDSCOUNT); do
29118                 rc=0
29119
29120                 stop mds${idx}
29121                 dev=$(mdsdevname $idx)
29122                 run_e2fsck $(facet_active_host mds$idx) $dev -n ||
29123                         rc=$?
29124                 start mds${idx} $dev $MDS_MOUNT_OPTS ||
29125                         error "mount mds$idx failed"
29126                 df $MOUNT > /dev/null 2>&1
29127
29128                 # e2fsck should not return error
29129                 [ $rc -eq 0 ] ||
29130                         error "e2fsck detected error on MDT${idx}: rc=$rc"
29131         done
29132 }
29133 run_test 804 "verify agent entry for remote entry"
29134
29135 cleanup_805() {
29136         do_facet $SINGLEMDS zfs set quota=$old $fsset
29137         unlinkmany $DIR/$tdir/f- 1000000
29138         trap 0
29139 }
29140
29141 test_805() {
29142         local zfs_version=$(do_facet mds1 cat /sys/module/zfs/version)
29143         [ "$mds1_FSTYPE" != "zfs" ] && skip "ZFS specific test"
29144         [ $(version_code $zfs_version) -lt $(version_code 0.7.2) ] &&
29145                 skip "netfree not implemented before 0.7"
29146         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
29147                 skip "Need MDS version at least 2.10.57"
29148
29149         local fsset
29150         local freekb
29151         local usedkb
29152         local old
29153         local quota
29154         local pref="osd-zfs.$FSNAME-MDT0000."
29155
29156         # limit available space on MDS dataset to meet nospace issue
29157         # quickly. then ZFS 0.7.2 can use reserved space if asked
29158         # properly (using netfree flag in osd_declare_destroy()
29159         fsset=$(do_facet $SINGLEMDS lctl get_param -n $pref.mntdev)
29160         old=$(do_facet $SINGLEMDS zfs get -H quota $fsset | \
29161                 gawk '{print $3}')
29162         freekb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytesfree)
29163         usedkb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytestotal)
29164         let "usedkb=usedkb-freekb"
29165         let "freekb=freekb/2"
29166         if let "freekb > 5000"; then
29167                 let "freekb=5000"
29168         fi
29169         do_facet $SINGLEMDS zfs set quota=$(((usedkb+freekb)*1024)) $fsset
29170         trap cleanup_805 EXIT
29171         mkdir_on_mdt0 $DIR/$tdir
29172         $LFS setstripe -E 1M -c2 -E 4M -c2 -E -1 -c2 $DIR/$tdir ||
29173                 error "Can't set PFL layout"
29174         createmany -m $DIR/$tdir/f- 1000000 && error "ENOSPC wasn't met"
29175         rm -rf $DIR/$tdir || error "not able to remove"
29176         do_facet $SINGLEMDS zfs set quota=$old $fsset
29177         trap 0
29178 }
29179 run_test 805 "ZFS can remove from full fs"
29180
29181 # Size-on-MDS test
29182 check_lsom_data()
29183 {
29184         local file=$1
29185         local expect=$(stat -c %s $file)
29186
29187         check_lsom_size $1 $expect
29188
29189         local blocks=$($LFS getsom -b $file)
29190         expect=$(stat -c %b $file)
29191         [[ $blocks == $expect ]] ||
29192                 error "$file expected blocks: $expect, got: $blocks"
29193 }
29194
29195 check_lsom_size()
29196 {
29197         local size
29198         local expect=$2
29199
29200         cancel_lru_locks mdc
29201
29202         size=$($LFS getsom -s $1)
29203         [[ $size == $expect ]] ||
29204                 error "$file expected size: $expect, got: $size"
29205 }
29206
29207 test_806() {
29208         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
29209                 skip "Need MDS version at least 2.11.52"
29210
29211         local bs=1048576
29212
29213         $LFS setstripe -c-1 $DIR/$tfile || error "setstripe $tfile failed"
29214
29215         disable_opencache
29216         stack_trap "restore_opencache"
29217
29218         # single-threaded write
29219         echo "Test SOM for single-threaded write"
29220         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 ||
29221                 error "write $tfile failed"
29222         check_lsom_size $DIR/$tfile $bs
29223
29224         local num=32
29225         local size=$(($num * $bs))
29226         local offset=0
29227         local i
29228
29229         echo "Test SOM for single client multi-threaded($num) write"
29230         $TRUNCATE $DIR/$tfile 0
29231         for ((i = 0; i < $num; i++)); do
29232                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
29233                 local pids[$i]=$!
29234                 offset=$((offset + $bs))
29235         done
29236         for (( i=0; i < $num; i++ )); do
29237                 wait ${pids[$i]}
29238         done
29239         check_lsom_size $DIR/$tfile $size
29240
29241         $TRUNCATE $DIR/$tfile 0
29242         for ((i = 0; i < $num; i++)); do
29243                 offset=$((offset - $bs))
29244                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
29245                 local pids[$i]=$!
29246         done
29247         for (( i=0; i < $num; i++ )); do
29248                 wait ${pids[$i]}
29249         done
29250         check_lsom_size $DIR/$tfile $size
29251
29252         # multi-client writes
29253         num=$(get_node_count ${CLIENTS//,/ })
29254         size=$(($num * $bs))
29255         offset=0
29256         i=0
29257
29258         echo "Test SOM for multi-client ($num) writes"
29259         $TRUNCATE $DIR/$tfile 0
29260         for client in ${CLIENTS//,/ }; do
29261                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
29262                 local pids[$i]=$!
29263                 i=$((i + 1))
29264                 offset=$((offset + $bs))
29265         done
29266         for (( i=0; i < $num; i++ )); do
29267                 wait ${pids[$i]}
29268         done
29269         check_lsom_size $DIR/$tfile $offset
29270
29271         i=0
29272         $TRUNCATE $DIR/$tfile 0
29273         for client in ${CLIENTS//,/ }; do
29274                 offset=$((offset - $bs))
29275                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
29276                 local pids[$i]=$!
29277                 i=$((i + 1))
29278         done
29279         for (( i=0; i < $num; i++ )); do
29280                 wait ${pids[$i]}
29281         done
29282         check_lsom_size $DIR/$tfile $size
29283
29284         # verify SOM blocks count
29285         echo "Verify SOM block count"
29286         $TRUNCATE $DIR/$tfile 0
29287         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w$((bs))YSc ||
29288                 error "failed to write file $tfile with fdatasync and fstat"
29289         check_lsom_data $DIR/$tfile
29290
29291         $TRUNCATE $DIR/$tfile 0
29292         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w$((bs * 2))Yc ||
29293                 error "failed to write file $tfile with fdatasync"
29294         check_lsom_data $DIR/$tfile
29295
29296         $TRUNCATE $DIR/$tfile 0
29297         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:O_SYNC:w$((bs * 3))c ||
29298                 error "failed to write file $tfile with sync IO"
29299         check_lsom_data $DIR/$tfile
29300
29301         # verify truncate
29302         echo "Test SOM for truncate"
29303         # use ftruncate to sync blocks on close request
29304         $MULTIOP $DIR/$tfile oO_WRONLY:T16384c
29305         check_lsom_size $DIR/$tfile 16384
29306         check_lsom_data $DIR/$tfile
29307
29308         $TRUNCATE $DIR/$tfile 1234
29309         check_lsom_size $DIR/$tfile 1234
29310         # sync blocks on the MDT
29311         $MULTIOP $DIR/$tfile oc
29312         check_lsom_data $DIR/$tfile
29313 }
29314 run_test 806 "Verify Lazy Size on MDS"
29315
29316 test_807() {
29317         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
29318         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
29319                 skip "Need MDS version at least 2.11.52"
29320
29321         # Registration step
29322         changelog_register || error "changelog_register failed"
29323         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
29324         changelog_users $SINGLEMDS | grep -q $cl_user ||
29325                 error "User $cl_user not found in changelog_users"
29326
29327         rm -rf $DIR/$tdir || error "rm $tdir failed"
29328         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
29329         touch $DIR/$tdir/trunc || error "touch $tdir/trunc failed"
29330         $TRUNCATE $DIR/$tdir/trunc 1024 || error "truncate $tdir/trunc failed"
29331         $TRUNCATE $DIR/$tdir/trunc 1048576 ||
29332                 error "truncate $tdir/trunc failed"
29333
29334         local bs=1048576
29335         echo "Test SOM for single-threaded write with fsync"
29336         dd if=/dev/zero of=$DIR/$tdir/single_dd bs=$bs count=1 ||
29337                 error "write $tfile failed"
29338         sync;sync;sync
29339
29340         # multi-client wirtes
29341         local num=$(get_node_count ${CLIENTS//,/ })
29342         local offset=0
29343         local i=0
29344
29345         echo "Test SOM for multi-client ($num) writes"
29346         touch $DIR/$tfile || error "touch $tfile failed"
29347         $TRUNCATE $DIR/$tfile 0
29348         for client in ${CLIENTS//,/ }; do
29349                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
29350                 local pids[$i]=$!
29351                 i=$((i + 1))
29352                 offset=$((offset + $bs))
29353         done
29354         for (( i=0; i < $num; i++ )); do
29355                 wait ${pids[$i]}
29356         done
29357
29358         do_rpc_nodes "$CLIENTS" cancel_lru_locks osc
29359         do_nodes "$CLIENTS" "sync ; sleep 5 ; sync"
29360         $LSOM_SYNC -u $cl_user -m $FSNAME-MDT0000 $MOUNT
29361         check_lsom_data $DIR/$tdir/trunc
29362         check_lsom_data $DIR/$tdir/single_dd
29363         check_lsom_data $DIR/$tfile
29364
29365         rm -rf $DIR/$tdir
29366         # Deregistration step
29367         changelog_deregister || error "changelog_deregister failed"
29368 }
29369 run_test 807 "verify LSOM syncing tool"
29370
29371 check_som_nologged()
29372 {
29373         local lines=$($LFS changelog $FSNAME-MDT0000 |
29374                 grep 'x=trusted.som' | wc -l)
29375         [ $lines -ne 0 ] && error "trusted.som xattr is logged in Changelogs"
29376 }
29377
29378 test_808() {
29379         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
29380                 skip "Need MDS version at least 2.11.55"
29381
29382         # Registration step
29383         changelog_register || error "changelog_register failed"
29384
29385         touch $DIR/$tfile || error "touch $tfile failed"
29386         check_som_nologged
29387
29388         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=1 ||
29389                 error "write $tfile failed"
29390         check_som_nologged
29391
29392         $TRUNCATE $DIR/$tfile 1234
29393         check_som_nologged
29394
29395         $TRUNCATE $DIR/$tfile 1048576
29396         check_som_nologged
29397
29398         # Deregistration step
29399         changelog_deregister || error "changelog_deregister failed"
29400 }
29401 run_test 808 "Check trusted.som xattr not logged in Changelogs"
29402
29403 check_som_nodata()
29404 {
29405         $LFS getsom $1
29406         [[ $? -eq 61 ]] || error "DoM-only file $1 has SOM xattr"
29407 }
29408
29409 test_809() {
29410         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
29411                 skip "Need MDS version at least 2.11.56"
29412
29413         $LFS setstripe -E 1M -L mdt $DIR/$tfile ||
29414                 error "failed to create DoM-only file $DIR/$tfile"
29415         touch $DIR/$tfile || error "touch $tfile failed"
29416         check_som_nodata $DIR/$tfile
29417
29418         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 ||
29419                 error "write $tfile failed"
29420         check_som_nodata $DIR/$tfile
29421
29422         $TRUNCATE $DIR/$tfile 1234
29423         check_som_nodata $DIR/$tfile
29424
29425         $TRUNCATE $DIR/$tfile 4097
29426         check_som_nodata $DIR/$file
29427 }
29428 run_test 809 "Verify no SOM xattr store for DoM-only files"
29429
29430 test_810() {
29431         [ $PARALLEL == "yes" ] && skip "skip parallel run"
29432         $GSS && skip_env "could not run with gss"
29433         [[ $OST1_VERSION -gt $(version_code 2.12.58) ]] ||
29434                 skip "OST < 2.12.58 doesn't align checksum"
29435
29436         set_checksums 1
29437         stack_trap "set_checksums $ORIG_CSUM" EXIT
29438         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
29439
29440         local csum
29441         local before
29442         local after
29443         for csum in $CKSUM_TYPES; do
29444                 #define OBD_FAIL_OSC_NO_GRANT   0x411
29445                 $LCTL set_param osc.*.checksum_type=$csum fail_loc=0x411
29446                 for i in "10240 0" "10000 0" "4000 1" "500 1"; do
29447                         eval set -- $i
29448                         dd if=/dev/urandom of=$DIR/$tfile bs=$1 count=2 seek=$2
29449                         before=$(md5sum $DIR/$tfile)
29450                         $LCTL set_param ldlm.namespaces.*osc*.lru_size=clear
29451                         after=$(md5sum $DIR/$tfile)
29452                         [ "$before" == "$after" ] ||
29453                                 error "$csum: $before != $after bs=$1 seek=$2"
29454                 done
29455         done
29456 }
29457 run_test 810 "partial page writes on ZFS (LU-11663)"
29458
29459 test_812a() {
29460         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
29461                 skip "OST < 2.12.51 doesn't support this fail_loc"
29462
29463         $LFS setstripe -c 1 -i 0 $DIR/$tfile
29464         # ensure ost1 is connected
29465         stat $DIR/$tfile >/dev/null || error "can't stat"
29466         wait_osc_import_state client ost1 FULL
29467         # no locks, no reqs to let the connection idle
29468         cancel_lru_locks osc
29469
29470         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
29471 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
29472         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
29473         wait_osc_import_state client ost1 CONNECTING
29474         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
29475
29476         stat $DIR/$tfile >/dev/null || error "can't stat file"
29477 }
29478 run_test 812a "do not drop reqs generated when imp is going to idle (LU-11951)"
29479
29480 test_812b() { # LU-12378
29481         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
29482                 skip "OST < 2.12.51 doesn't support this fail_loc"
29483
29484         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "setstripe failed"
29485         # ensure ost1 is connected
29486         stat $DIR/$tfile >/dev/null || error "can't stat"
29487         wait_osc_import_state client ost1 FULL
29488         # no locks, no reqs to let the connection idle
29489         cancel_lru_locks osc
29490
29491         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
29492 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
29493         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
29494         wait_osc_import_state client ost1 CONNECTING
29495         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
29496
29497         $LFS quota -u 0 $DIR/ || error "lfs quota should succeed"
29498         wait_osc_import_state client ost1 IDLE
29499 }
29500 run_test 812b "do not drop no resend request for idle connect"
29501
29502 test_812c() {
29503         local old
29504
29505         old=$($LCTL get_param -n osc.*.idle_timeout | head -n 1)
29506
29507         $LFS setstripe -c 1 -o 0 $DIR/$tfile
29508         $LFS getstripe $DIR/$tfile
29509         $LCTL set_param osc.*.idle_timeout=10
29510         stack_trap "$LCTL set_param osc.*.idle_timeout=$old" EXIT
29511         # ensure ost1 is connected
29512         stat $DIR/$tfile >/dev/null || error "can't stat"
29513         wait_osc_import_state client ost1 FULL
29514         # no locks, no reqs to let the connection idle
29515         cancel_lru_locks osc
29516
29517 #define OBD_FAIL_PTLRPC_IDLE_RACE        0x533
29518         $LCTL set_param fail_loc=0x80000533
29519         sleep 15
29520         dd if=/dev/zero of=$DIR/$tfile count=1 conv=sync || error "dd failed"
29521 }
29522 run_test 812c "idle import vs lock enqueue race"
29523
29524 test_813() {
29525         local file_heat_sav=$($LCTL get_param -n llite.*.file_heat 2>/dev/null)
29526         [ -z "$file_heat_sav" ] && skip "no file heat support"
29527
29528         local readsample
29529         local writesample
29530         local readbyte
29531         local writebyte
29532         local readsample1
29533         local writesample1
29534         local readbyte1
29535         local writebyte1
29536
29537         local period_second=$($LCTL get_param -n llite.*.heat_period_second)
29538         local decay_pct=$($LCTL get_param -n llite.*.heat_decay_percentage)
29539
29540         $LCTL set_param -n llite.*.file_heat=1
29541         echo "Turn on file heat"
29542         echo "Period second: $period_second, Decay percentage: $decay_pct"
29543
29544         echo "QQQQ" > $DIR/$tfile
29545         echo "QQQQ" > $DIR/$tfile
29546         echo "QQQQ" > $DIR/$tfile
29547         cat $DIR/$tfile > /dev/null
29548         cat $DIR/$tfile > /dev/null
29549         cat $DIR/$tfile > /dev/null
29550         cat $DIR/$tfile > /dev/null
29551
29552         local out=$($LFS heat_get $DIR/$tfile)
29553
29554         $LFS heat_get $DIR/$tfile
29555         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
29556         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
29557         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
29558         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
29559
29560         [ $readsample -le 4 ] || error "read sample ($readsample) is wrong"
29561         [ $writesample -le 3 ] || error "write sample ($writesample) is wrong"
29562         [ $readbyte -le 20 ] || error "read bytes ($readbyte) is wrong"
29563         [ $writebyte -le 15 ] || error "write bytes ($writebyte) is wrong"
29564
29565         sleep $((period_second + 3))
29566         echo "Sleep $((period_second + 3)) seconds..."
29567         # The recursion formula to calculate the heat of the file f is as
29568         # follow:
29569         # Hi+1(f) = (1-P)*Hi(f)+ P*Ci
29570         # Where Hi is the heat value in the period between time points i*I and
29571         # (i+1)*I; Ci is the access count in the period; the symbol P refers
29572         # to the weight of Ci.
29573         out=$($LFS heat_get $DIR/$tfile)
29574         $LFS heat_get $DIR/$tfile
29575         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
29576         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
29577         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
29578         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
29579
29580         [ $(bc <<< "$readsample <= 4 * $decay_pct / 100") -eq 1 ] ||
29581                 error "read sample ($readsample) is wrong"
29582         [ $(bc <<< "$writesample <= 3 * $decay_pct / 100") -eq 1 ] ||
29583                 error "write sample ($writesample) is wrong"
29584         [ $(bc <<< "$readbyte <= 20 * $decay_pct / 100") -eq 1 ] ||
29585                 error "read bytes ($readbyte) is wrong"
29586         [ $(bc <<< "$writebyte <= 15 * $decay_pct / 100") -eq 1 ] ||
29587                 error "write bytes ($writebyte) is wrong"
29588
29589         echo "QQQQ" > $DIR/$tfile
29590         echo "QQQQ" > $DIR/$tfile
29591         echo "QQQQ" > $DIR/$tfile
29592         cat $DIR/$tfile > /dev/null
29593         cat $DIR/$tfile > /dev/null
29594         cat $DIR/$tfile > /dev/null
29595         cat $DIR/$tfile > /dev/null
29596
29597         sleep $((period_second + 3))
29598         echo "Sleep $((period_second + 3)) seconds..."
29599
29600         out=$($LFS heat_get $DIR/$tfile)
29601         $LFS heat_get $DIR/$tfile
29602         readsample1=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
29603         writesample1=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
29604         readbyte1=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
29605         writebyte1=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
29606
29607         [ $(bc <<< "$readsample1 <= ($readsample * (100 - $decay_pct) + \
29608                 4 * $decay_pct) / 100") -eq 1 ] ||
29609                 error "read sample ($readsample1) is wrong"
29610         [ $(bc <<< "$writesample1 <= ($writesample * (100 - $decay_pct) + \
29611                 3 * $decay_pct) / 100") -eq 1 ] ||
29612                 error "write sample ($writesample1) is wrong"
29613         [ $(bc <<< "$readbyte1 <= ($readbyte * (100 - $decay_pct) + \
29614                 20 * $decay_pct) / 100") -eq 1 ] ||
29615                 error "read bytes ($readbyte1) is wrong"
29616         [ $(bc <<< "$writebyte1 <= ($writebyte * (100 - $decay_pct) + \
29617                 15 * $decay_pct) / 100") -eq 1 ] ||
29618                 error "write bytes ($writebyte1) is wrong"
29619
29620         echo "Turn off file heat for the file $DIR/$tfile"
29621         $LFS heat_set -o $DIR/$tfile
29622
29623         echo "QQQQ" > $DIR/$tfile
29624         echo "QQQQ" > $DIR/$tfile
29625         echo "QQQQ" > $DIR/$tfile
29626         cat $DIR/$tfile > /dev/null
29627         cat $DIR/$tfile > /dev/null
29628         cat $DIR/$tfile > /dev/null
29629         cat $DIR/$tfile > /dev/null
29630
29631         out=$($LFS heat_get $DIR/$tfile)
29632         $LFS heat_get $DIR/$tfile
29633         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
29634         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
29635         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
29636         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
29637
29638         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
29639         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
29640         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
29641         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
29642
29643         echo "Trun on file heat for the file $DIR/$tfile"
29644         $LFS heat_set -O $DIR/$tfile
29645
29646         echo "QQQQ" > $DIR/$tfile
29647         echo "QQQQ" > $DIR/$tfile
29648         echo "QQQQ" > $DIR/$tfile
29649         cat $DIR/$tfile > /dev/null
29650         cat $DIR/$tfile > /dev/null
29651         cat $DIR/$tfile > /dev/null
29652         cat $DIR/$tfile > /dev/null
29653
29654         out=$($LFS heat_get $DIR/$tfile)
29655         $LFS heat_get $DIR/$tfile
29656         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
29657         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
29658         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
29659         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
29660
29661         [ $readsample -gt 0 ] || error "read sample ($readsample) is wrong"
29662         [ $writesample -gt 0 ] || error "write sample ($writesample) is wrong"
29663         [ $readbyte -gt 0 ] || error "read bytes ($readbyte) is wrong"
29664         [ $writebyte -gt 0 ] || error "write bytes ($writebyte) is wrong"
29665
29666         $LFS heat_set -c $DIR/$tfile
29667         $LCTL set_param -n llite.*.file_heat=0
29668         echo "Turn off file heat support for the Lustre filesystem"
29669
29670         echo "QQQQ" > $DIR/$tfile
29671         echo "QQQQ" > $DIR/$tfile
29672         echo "QQQQ" > $DIR/$tfile
29673         cat $DIR/$tfile > /dev/null
29674         cat $DIR/$tfile > /dev/null
29675         cat $DIR/$tfile > /dev/null
29676         cat $DIR/$tfile > /dev/null
29677
29678         out=$($LFS heat_get $DIR/$tfile)
29679         $LFS heat_get $DIR/$tfile
29680         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
29681         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
29682         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
29683         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
29684
29685         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
29686         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
29687         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
29688         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
29689
29690         $LCTL set_param -n llite.*.file_heat=$file_heat_sav
29691         rm -f $DIR/$tfile
29692 }
29693 run_test 813 "File heat verfication"
29694
29695 test_814()
29696 {
29697         dd of=$DIR/$tfile seek=128 bs=1k < /dev/null
29698         echo -n y >> $DIR/$tfile
29699         cp --sparse=always $DIR/$tfile $DIR/${tfile}.cp || error "copy failed"
29700         diff $DIR/$tfile $DIR/${tfile}.cp || error "files should be same"
29701 }
29702 run_test 814 "sparse cp works as expected (LU-12361)"
29703
29704 test_815()
29705 {
29706         writeme -b 100 $DIR/$tfile || error "write 100 bytes failed"
29707         writeme -b 0 $DIR/$tfile || error "write 0 byte failed"
29708 }
29709 run_test 815 "zero byte tiny write doesn't hang (LU-12382)"
29710
29711 test_816() {
29712         local ost1_imp=$(get_osc_import_name client ost1)
29713         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
29714                          cut -d'.' -f2)
29715
29716         $LFS setstripe -c 1 -i 0 $DIR/$tfile
29717         # ensure ost1 is connected
29718
29719         stat $DIR/$tfile >/dev/null || error "can't stat"
29720         wait_osc_import_state client ost1 FULL
29721         # no locks, no reqs to let the connection idle
29722         cancel_lru_locks osc
29723         lru_resize_disable osc
29724         local before
29725         local now
29726         before=$($LCTL get_param -n \
29727                  ldlm.namespaces.$imp_name.lru_size)
29728
29729         wait_osc_import_state client ost1 IDLE
29730         dd if=/dev/null of=$DIR/$tfile bs=1k count=1 conv=sync
29731         now=$($LCTL get_param -n \
29732               ldlm.namespaces.$imp_name.lru_size)
29733         [ $before == $now ] || error "lru_size changed $before != $now"
29734 }
29735 run_test 816 "do not reset lru_resize on idle reconnect"
29736
29737 cleanup_817() {
29738         umount $tmpdir
29739         exportfs -u localhost:$DIR/nfsexp
29740         rm -rf $DIR/nfsexp
29741 }
29742
29743 test_817() {
29744         systemctl restart nfs-server.service || skip "failed to restart nfsd"
29745
29746         mkdir -p $DIR/nfsexp
29747         exportfs -orw,no_root_squash localhost:$DIR/nfsexp ||
29748                 error "failed to export nfs"
29749
29750         tmpdir=$(mktemp -d /tmp/nfs-XXXXXX)
29751         stack_trap cleanup_817 EXIT
29752
29753         mount -t nfs -orw localhost:$DIR/nfsexp $tmpdir ||
29754                 error "failed to mount nfs to $tmpdir"
29755
29756         cp /bin/true $tmpdir
29757         $DIR/nfsexp/true || error "failed to execute 'true' command"
29758 }
29759 run_test 817 "nfsd won't cache write lock for exec file"
29760
29761 test_818() {
29762         test_mkdir -i0 -c1 $DIR/$tdir
29763         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
29764         $LFS setstripe -c1 -i1 $DIR/$tdir/$tfile
29765         stop $SINGLEMDS
29766
29767         # restore osp-syn threads
29768         stack_trap "fail $SINGLEMDS"
29769
29770         #define OBD_FAIL_OSP_CANT_PROCESS_LLOG          0x2105
29771         do_facet $SINGLEMDS lctl set_param fail_loc=0x80002105
29772         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
29773                 error "start $SINGLEMDS failed"
29774         rm -rf $DIR/$tdir
29775
29776         local testid=$(echo $TESTNAME | tr '_' ' ')
29777
29778         do_facet mds1 dmesg | tac | sed "/$testid/,$ d" |
29779                 grep "run LFSCK" || error "run LFSCK is not suggested"
29780 }
29781 run_test 818 "unlink with failed llog"
29782
29783 test_819a() {
29784         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
29785         cancel_lru_locks osc
29786         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
29787         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
29788         dd if=$DIR/$tfile of=/dev/null bs=1M count=1
29789         rm -f $TDIR/$tfile
29790 }
29791 run_test 819a "too big niobuf in read"
29792
29793 test_819b() {
29794         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
29795         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
29796         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
29797         cancel_lru_locks osc
29798         sleep 1
29799         rm -f $TDIR/$tfile
29800 }
29801 run_test 819b "too big niobuf in write"
29802
29803
29804 function test_820_start_ost() {
29805         sleep 5
29806
29807         for num in $(seq $OSTCOUNT); do
29808                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS
29809         done
29810 }
29811
29812 test_820() {
29813         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
29814
29815         mkdir $DIR/$tdir
29816         umount_client $MOUNT || error "umount failed"
29817         for num in $(seq $OSTCOUNT); do
29818                 stop ost$num
29819         done
29820
29821         # mount client with no active OSTs
29822         # so that the client can't initialize max LOV EA size
29823         # from OSC notifications
29824         mount_client $MOUNT || error "mount failed"
29825         # delay OST starting to keep this 0 max EA size for a while
29826         test_820_start_ost &
29827
29828         # create a directory on MDS2
29829         test_mkdir -i 1 -c1 $DIR/$tdir/mds2 ||
29830                 error "Failed to create directory"
29831         # open intent should update default EA size
29832         # see mdc_update_max_ea_from_body()
29833         # notice this is the very first RPC to MDS2
29834         out=$(cp /etc/services $DIR/$tdir/mds2 2>&1)
29835         ret=$?
29836         echo $out
29837         # With SSK, this situation can lead to -EPERM being returned.
29838         # In that case, simply retry.
29839         if [ $ret -ne 0 ] && $SHARED_KEY; then
29840                 if echo "$out" | grep -q "not permitted"; then
29841                         cp /etc/services $DIR/$tdir/mds2
29842                         ret=$?
29843                 fi
29844         fi
29845         [ $ret -eq 0 ] || error "Failed to copy files to mds$n"
29846 }
29847 run_test 820 "update max EA from open intent"
29848
29849 test_823() {
29850         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
29851         local OST_MAX_PRECREATE=20000
29852
29853         (( $MDS1_VERSION >= $(version_code 2.14.56) )) ||
29854                 skip "Need MDS version at least 2.14.56"
29855
29856         save_lustre_params mds1 \
29857                 "osp.$FSNAME-OST*-osc-MDT0000.max_create_count" > $p
29858         do_facet $SINGLEMDS "$LCTL set_param -n \
29859                 osp.$FSNAME-OST*MDT0000.max_create_count=0"
29860         do_facet $SINGLEMDS "$LCTL set_param -n \
29861                 osp.$FSNAME-OST0000*MDT0000.max_create_count=$OST_MAX_PRECREATE"
29862
29863         stack_trap "restore_lustre_params < $p; rm $p"
29864
29865         do_facet $SINGLEMDS "$LCTL set_param -n \
29866                 osp.$FSNAME-OST*-osc-MDT*.create_count=100200"
29867
29868         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
29869                       osp.$FSNAME-OST0000*MDT0000.create_count")
29870         local max=$(do_facet $SINGLEMDS "$LCTL get_param -n \
29871                     osp.$FSNAME-OST0000*MDT0000.max_create_count")
29872         local expect_count=$(((($max/2)/256) * 256))
29873
29874         log "setting create_count to 100200:"
29875         log " -result- count: $count with max: $max, expecting: $expect_count"
29876
29877         [[ $count -eq expect_count ]] ||
29878                 error "Create count not set to max precreate."
29879 }
29880 run_test 823 "Setting create_count > OST_MAX_PRECREATE is lowered to maximum"
29881
29882 test_831() {
29883         [[ $MDS1_VERSION -lt $(version_code 2.14.56) ]] &&
29884                 skip "Need MDS version 2.14.56"
29885
29886         local sync_changes=$(do_facet $SINGLEMDS \
29887                 $LCTL get_param -n osp.$FSNAME-OST0000-osc-MDT0000.sync_changes)
29888
29889         [ "$sync_changes" -gt 100 ] &&
29890                 skip "Sync changes $sync_changes > 100 already"
29891
29892         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
29893
29894         $LFS mkdir -i 0 $DIR/$tdir
29895         $LFS setstripe -c 1 -i 0 $DIR/$tdir
29896
29897         save_lustre_params mds1 \
29898                 "osp.$FSNAME-OST*-osc-MDT0000.max_sync_changes" > $p
29899         save_lustre_params mds1 \
29900                 "osp.$FSNAME-OST*-osc-MDT0000.max_rpcs_in_progress" >> $p
29901
29902         do_facet mds1 "$LCTL set_param -n \
29903                 osp.$FSNAME-OST*-osc-MDT0000.max_sync_changes=100 \
29904                 osp.$FSNAME-OST*-osc-MDT0000.max_rpcs_in_progress=128"
29905         stack_trap "restore_lustre_params < $p" EXIT
29906
29907         createmany -o $DIR/$tdir/f- 1000
29908         unlinkmany $DIR/$tdir/f- 1000 &
29909         local UNLINK_PID=$!
29910
29911         while sleep 1; do
29912                 sync_changes=$(do_facet mds1 \
29913                 $LCTL get_param -n osp.$FSNAME-OST0000-osc-MDT0000.sync_changes)
29914                 # the check in the code is racy, fail the test
29915                 # if the value above the limit by 10.
29916                 [ $sync_changes -gt 110 ] && {
29917                         kill -2 $UNLINK_PID
29918                         wait
29919                         error "osp changes throttling failed, $sync_changes>110"
29920                 }
29921                 kill -0 $UNLINK_PID 2> /dev/null || break
29922         done
29923         wait
29924 }
29925 run_test 831 "throttling unlink/setattr queuing on OSP"
29926
29927 test_832() {
29928         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
29929         (( $MDS1_VERSION >= $(version_code 2.15.52) )) ||
29930                 skip "Need MDS version 2.15.52+"
29931         is_rmentry_supported || skip "rm_entry not supported"
29932
29933         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
29934         mkdir $DIR/$tdir/local_dir || error "mkdir local_dir failed"
29935         mkdir_on_mdt -i 1 $DIR/$tdir/remote_dir ||
29936                 error "mkdir remote_dir failed"
29937         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/striped_dir ||
29938                 error "mkdir striped_dir failed"
29939         touch $DIR/$tdir/file || error "touch file failed"
29940         $LFS rm_entry $DIR/$tdir/* || error "lfs rm_entry $tdir/* failed"
29941         [ -z "$(ls -A $DIR/$tdir)" ] || error "$tdir not empty"
29942 }
29943 run_test 832 "lfs rm_entry"
29944
29945 #
29946 # tests that do cleanup/setup should be run at the end
29947 #
29948
29949 test_900() {
29950         [ $PARALLEL == "yes" ] && skip "skip parallel run"
29951         local ls
29952
29953         #define OBD_FAIL_MGC_PAUSE_PROCESS_LOG   0x903
29954         $LCTL set_param fail_loc=0x903
29955
29956         cancel_lru_locks MGC
29957
29958         FAIL_ON_ERROR=true cleanup
29959         FAIL_ON_ERROR=true setup
29960 }
29961 run_test 900 "umount should not race with any mgc requeue thread"
29962
29963 # LUS-6253/LU-11185
29964 test_901() {
29965         local old
29966         local count
29967         local oldc
29968         local newc
29969         local olds
29970         local news
29971         [ $PARALLEL == "yes" ] && skip "skip parallel run"
29972
29973         # some get_param have a bug to handle dot in param name
29974         cancel_lru_locks MGC
29975         old=$(mount -t lustre | wc -l)
29976         # 1 config+sptlrpc
29977         # 2 params
29978         # 3 nodemap
29979         # 4 IR
29980         old=$((old * 4))
29981         oldc=0
29982         count=0
29983         while [ $old -ne $oldc ]; do
29984                 oldc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
29985                 sleep 1
29986                 ((count++))
29987                 if [ $count -ge $TIMEOUT ]; then
29988                         error "too large timeout"
29989                 fi
29990         done
29991         umount_client $MOUNT || error "umount failed"
29992         mount_client $MOUNT || error "mount failed"
29993         cancel_lru_locks MGC
29994         newc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
29995
29996         [ $oldc -lt $newc ] && error "mgc lock leak ($oldc != $newc)"
29997
29998         return 0
29999 }
30000 run_test 901 "don't leak a mgc lock on client umount"
30001
30002 # LU-13377
30003 test_902() {
30004         [ $CLIENT_VERSION -lt $(version_code 2.13.52) ] &&
30005                 skip "client does not have LU-13377 fix"
30006         #define OBD_FAIL_LLITE_SHORT_COMMIT 0x1415
30007         $LCTL set_param fail_loc=0x1415
30008         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
30009         cancel_lru_locks osc
30010         rm -f $DIR/$tfile
30011 }
30012 run_test 902 "test short write doesn't hang lustre"
30013
30014 # LU-14711
30015 test_903() {
30016         $LFS setstripe -i 0 -c 1 $DIR/$tfile $DIR/${tfile}-2
30017         echo "blah" > $DIR/${tfile}-2
30018         dd if=/dev/zero of=$DIR/$tfile bs=1M count=6 conv=fsync
30019         #define OBD_FAIL_OSC_SLOW_PAGE_EVICT 0x417
30020         $LCTL set_param fail_loc=0x417 fail_val=20
30021
30022         mv $DIR/${tfile}-2 $DIR/$tfile # Destroys the big object
30023         sleep 1 # To start the destroy
30024         wait_destroy_complete 150 || error "Destroy taking too long"
30025         cat $DIR/$tfile > /dev/null || error "Evicted"
30026 }
30027 run_test 903 "Test long page discard does not cause evictions"
30028
30029 test_904() {
30030         [ "$mds1_FSTYPE" == "ldiskfs" ] || skip "ldiskfs only test"
30031         do_facet mds1 $DEBUGFS -R features $(mdsdevname 1) |
30032                 grep -q project || skip "skip project quota not supported"
30033
30034         local testfile="$DIR/$tdir/$tfile"
30035         local xattr="trusted.projid"
30036         local projid
30037         local mdts=$(comma_list $(mdts_nodes))
30038         local saved=$(do_facet mds1 $LCTL get_param -n \
30039                 osd-ldiskfs.*MDT0000.enable_projid_xattr)
30040
30041         do_nodes $mdts $LCTL set_param osd-ldiskfs.*MDT*.enable_projid_xattr=0
30042         stack_trap "do_nodes $mdts $LCTL set_param \
30043                 osd-ldiskfs.*MDT*.enable_projid_xattr=$saved"
30044
30045         mkdir -p $DIR/$tdir
30046         touch $testfile
30047         #hide projid xattr on server
30048         $LFS project -p 1 $testfile ||
30049                 error "set $testfile project id failed"
30050         getfattr -m - $testfile | grep $xattr &&
30051                 error "do not show trusted.projid when disabled on server"
30052         do_nodes $mdts $LCTL set_param osd-ldiskfs.*MDT*.enable_projid_xattr=1
30053         #should be hidden when projid is 0
30054         $LFS project -p 0 $testfile ||
30055                 error "set $testfile project id failed"
30056         getfattr -m - $testfile | grep $xattr &&
30057                 error "do not show trusted.projid with project ID 0"
30058
30059         #still can getxattr explicitly
30060         projid=$(getfattr -n $xattr $testfile |
30061                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
30062         [ $projid == "0" ] ||
30063                 error "projid expected 0 not $projid"
30064
30065         #set the projid via setxattr
30066         setfattr -n $xattr -v "1000" $testfile ||
30067                 error "setattr failed with $?"
30068         projid=($($LFS project $testfile))
30069         [ ${projid[0]} == "1000" ] ||
30070                 error "projid expected 1000 not $projid"
30071
30072         #check the new projid via getxattr
30073         $LFS project -p 1001 $testfile ||
30074                 error "set $testfile project id failed"
30075         getfattr -m - $testfile | grep $xattr ||
30076                 error "should show trusted.projid when project ID != 0"
30077         projid=$(getfattr -n $xattr $testfile |
30078                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
30079         [ $projid == "1001" ] ||
30080                 error "projid expected 1001 not $projid"
30081
30082         #try to set invalid projid
30083         setfattr -n $xattr -v "4294967295" $testfile &&
30084                 error "set invalid projid should fail"
30085
30086         #remove the xattr means setting projid to 0
30087         setfattr -x $xattr $testfile ||
30088                 error "setfattr failed with $?"
30089         projid=($($LFS project $testfile))
30090         [ ${projid[0]} == "0" ] ||
30091                 error "projid expected 0 not $projid"
30092
30093         #should be hidden when parent has inherit flag and same projid
30094         $LFS project -srp 1002 $DIR/$tdir ||
30095                 error "set $tdir project id failed"
30096         getfattr -m - $testfile | grep $xattr &&
30097                 error "do not show trusted.projid with inherit flag"
30098
30099         #still can getxattr explicitly
30100         projid=$(getfattr -n $xattr $testfile |
30101                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
30102         [ $projid == "1002" ] ||
30103                 error "projid expected 1002 not $projid"
30104 }
30105 run_test 904 "virtual project ID xattr"
30106
30107 # LU-8582
30108 test_905() {
30109         (( $OST1_VERSION >= $(version_code 2.8.54) )) ||
30110                 skip "lustre < 2.8.54 does not support ladvise"
30111
30112         remote_ost_nodsh && skip "remote OST with nodsh"
30113         $LFS setstripe -c -1 -i 0 $DIR/$tfile || error "setstripe failed"
30114
30115         $LFS ladvise -a willread $DIR/$tfile || error "ladvise does not work"
30116
30117         #define OBD_FAIL_OST_OPCODE 0x253
30118         # OST_LADVISE = 21
30119         do_facet ost1 "$LCTL set_param fail_val=21 fail_loc=0x0253"
30120         $LFS ladvise -a willread $DIR/$tfile &&
30121                 error "unexpected success of ladvise with fault injection"
30122         $LFS ladvise -a willread $DIR/$tfile |&
30123                 grep -q "Operation not supported"
30124         (( $? == 0 )) || error "unexpected stderr of ladvise with fault injection"
30125 }
30126 run_test 905 "bad or new opcode should not stuck client"
30127
30128 test_906() {
30129         grep -q io_uring_setup /proc/kallsyms ||
30130                 skip "Client OS does not support io_uring I/O engine"
30131         io_uring_probe || skip "kernel does not support io_uring fully"
30132         which fio || skip_env "no fio installed"
30133         fio --enghelp | grep -q io_uring ||
30134                 skip_env "fio does not support io_uring I/O engine"
30135
30136         local file=$DIR/$tfile
30137         local ioengine="io_uring"
30138         local numjobs=2
30139         local size=50M
30140
30141         fio --name=seqwrite --ioengine=$ioengine        \
30142                 --bs=$PAGE_SIZE --direct=1 --numjobs=$numjobs   \
30143                 --iodepth=64 --size=$size --filename=$file --rw=write ||
30144                 error "fio seqwrite $file failed"
30145
30146         fio --name=seqread --ioengine=$ioengine \
30147                 --bs=$PAGE_SIZE --direct=1 --numjobs=$numjobs   \
30148                 --iodepth=64 --size=$size --filename=$file --rw=read ||
30149                 error "fio seqread $file failed"
30150
30151         rm -f $file || error "rm -f $file failed"
30152 }
30153 run_test 906 "Simple test for io_uring I/O engine via fio"
30154
30155 complete $SECONDS
30156 [ -f $EXT2_DEV ] && rm $EXT2_DEV || true
30157 check_and_cleanup_lustre
30158 if [ "$I_MOUNTED" != "yes" ]; then
30159         lctl set_param debug="$OLDDEBUG" 2> /dev/null || true
30160 fi
30161 exit_status