Whamcloud - gitweb
LU-16842 fsx: tolerate delete last non-stale mirror error
[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_56rd() {
7188         local dir=$DIR/$tdir
7189
7190         test_mkdir $dir
7191         rm -f $dir/*
7192
7193         mkfifo $dir/fifo || error "failed to create fifo file"
7194         $LFS find $dir -t p --printf "%p %y %LP\n" ||
7195                 error "should not fail even cannot get projid from pipe file"
7196         found=$($LFS find $dir -t p --printf "%y")
7197         [[ "p" == $found ]] || error "found $found, expect p"
7198
7199         mknod $dir/chardev c 1 5 ||
7200                 error "failed to create character device file"
7201         $LFS find $dir -t c --printf "%p %y %LP\n" ||
7202                 error "should not fail even cannot get projid from chardev file"
7203         found=$($LFS find $dir -t c --printf "%y")
7204         [[ "c" == $found ]] || error "found $found, expect c"
7205
7206         found=$($LFS find $dir ! -type d --printf "%p %y %LP\n" | wc -l)
7207         (( found == 2 )) || error "unable to list all files"
7208 }
7209 run_test 56rd "check lfs find --printf special files"
7210
7211 test_56s() { # LU-611 #LU-9369
7212         [[ $OSTCOUNT -lt 2 ]] && skip_env "need at least 2 OSTs"
7213
7214         local dir=$DIR/$tdir
7215         local onestripe=$(((NUMDIRS + 1) * NUMFILES))
7216
7217         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
7218         for i in $(seq $NUMDIRS); do
7219                 $LFS setstripe -c $((OSTCOUNT + 1)) $dir/dir$i/$tfile
7220         done
7221
7222         local expected=$NUMDIRS
7223         local cmd="$LFS find -c $OSTCOUNT $dir"
7224         local nums=$($cmd | wc -l)
7225
7226         [ $nums -eq $expected ] || {
7227                 $LFS getstripe -R $dir
7228                 error "'$cmd' wrong: found $nums, expected $expected"
7229         }
7230
7231         expected=$((NUMDIRS + onestripe))
7232         cmd="$LFS find -stripe-count +0 -type f $dir"
7233         nums=$($cmd | wc -l)
7234         [ $nums -eq $expected ] || {
7235                 $LFS getstripe -R $dir
7236                 error "'$cmd' wrong: found $nums, expected $expected"
7237         }
7238
7239         expected=$onestripe
7240         cmd="$LFS find -stripe-count 1 -type f $dir"
7241         nums=$($cmd | wc -l)
7242         [ $nums -eq $expected ] || {
7243                 $LFS getstripe -R $dir
7244                 error "'$cmd' wrong: found $nums, expected $expected"
7245         }
7246
7247         cmd="$LFS find -stripe-count -2 -type f $dir"
7248         nums=$($cmd | wc -l)
7249         [ $nums -eq $expected ] || {
7250                 $LFS getstripe -R $dir
7251                 error "'$cmd' wrong: found $nums, expected $expected"
7252         }
7253
7254         expected=0
7255         cmd="$LFS find -stripe-count $((OSTCOUNT + 1)) -type f $dir"
7256         nums=$($cmd | wc -l)
7257         [ $nums -eq $expected ] || {
7258                 $LFS getstripe -R $dir
7259                 error "'$cmd' wrong: found $nums, expected $expected"
7260         }
7261 }
7262 run_test 56s "check lfs find -stripe-count works"
7263
7264 test_56t() { # LU-611 #LU-9369
7265         local dir=$DIR/$tdir
7266
7267         setup_56 $dir 0 $NUMDIRS
7268         for i in $(seq $NUMDIRS); do
7269                 $LFS setstripe -S 8M $dir/dir$i/$tfile
7270         done
7271
7272         local expected=$NUMDIRS
7273         local cmd="$LFS find -S 8M $dir"
7274         local nums=$($cmd | wc -l)
7275
7276         [ $nums -eq $expected ] || {
7277                 $LFS getstripe -R $dir
7278                 error "'$cmd' wrong: found $nums, expected $expected"
7279         }
7280         rm -rf $dir
7281
7282         setup_56 $dir $NUMFILES $NUMDIRS "--stripe-size 512k"
7283
7284         $LFS setstripe -S 256k $dir/$tfile.{0,1,2,3}
7285
7286         expected=$(((NUMDIRS + 1) * NUMFILES))
7287         cmd="$LFS find -stripe-size 512k -type f $dir"
7288         nums=$($cmd | wc -l)
7289         [ $nums -eq $expected ] ||
7290                 error "'$cmd' wrong: found $nums, expected $expected"
7291
7292         cmd="$LFS find -stripe-size +320k -type f $dir"
7293         nums=$($cmd | wc -l)
7294         [ $nums -eq $expected ] ||
7295                 error "'$cmd' wrong: found $nums, expected $expected"
7296
7297         expected=$(((NUMDIRS + 1) * NUMFILES + 4))
7298         cmd="$LFS find -stripe-size +200k -type f $dir"
7299         nums=$($cmd | wc -l)
7300         [ $nums -eq $expected ] ||
7301                 error "'$cmd' wrong: found $nums, expected $expected"
7302
7303         cmd="$LFS find -stripe-size -640k -type f $dir"
7304         nums=$($cmd | wc -l)
7305         [ $nums -eq $expected ] ||
7306                 error "'$cmd' wrong: found $nums, expected $expected"
7307
7308         expected=4
7309         cmd="$LFS find -stripe-size 256k -type f $dir"
7310         nums=$($cmd | wc -l)
7311         [ $nums -eq $expected ] ||
7312                 error "'$cmd' wrong: found $nums, expected $expected"
7313
7314         cmd="$LFS find -stripe-size -320k -type f $dir"
7315         nums=$($cmd | wc -l)
7316         [ $nums -eq $expected ] ||
7317                 error "'$cmd' wrong: found $nums, expected $expected"
7318
7319         expected=0
7320         cmd="$LFS find -stripe-size 1024k -type f $dir"
7321         nums=$($cmd | wc -l)
7322         [ $nums -eq $expected ] ||
7323                 error "'$cmd' wrong: found $nums, expected $expected"
7324 }
7325 run_test 56t "check lfs find -stripe-size works"
7326
7327 test_56u() { # LU-611
7328         local dir=$DIR/$tdir
7329
7330         setup_56 $dir $NUMFILES $NUMDIRS "-i 0 -c 1"
7331
7332         if [[ $OSTCOUNT -gt 1 ]]; then
7333                 $LFS setstripe -i 1 -c 1 $dir/$tfile.{0,1,2,3}
7334                 onestripe=4
7335         else
7336                 onestripe=0
7337         fi
7338
7339         local expected=$(((NUMDIRS + 1) * NUMFILES))
7340         local cmd="$LFS find -stripe-index 0 -type f $dir"
7341         local nums=$($cmd | wc -l)
7342
7343         [ $nums -eq $expected ] ||
7344                 error "'$cmd' wrong: found $nums, expected $expected"
7345
7346         expected=$onestripe
7347         cmd="$LFS find -stripe-index 1 -type f $dir"
7348         nums=$($cmd | wc -l)
7349         [ $nums -eq $expected ] ||
7350                 error "'$cmd' wrong: found $nums, expected $expected"
7351
7352         cmd="$LFS find ! -stripe-index 0 -type f $dir"
7353         nums=$($cmd | wc -l)
7354         [ $nums -eq $expected ] ||
7355                 error "'$cmd' wrong: found $nums, expected $expected"
7356
7357         expected=0
7358         # This should produce an error and not return any files
7359         cmd="$LFS find -stripe-index $OSTCOUNT -type f $dir"
7360         nums=$($cmd 2>/dev/null | wc -l)
7361         [ $nums -eq $expected ] ||
7362                 error "'$cmd' wrong: found $nums, expected $expected"
7363
7364         if [[ $OSTCOUNT -gt 1 ]]; then
7365                 expected=$(((NUMDIRS + 1) * NUMFILES + onestripe))
7366                 cmd="$LFS find -stripe-index 0,1 -type f $dir"
7367                 nums=$($cmd | wc -l)
7368                 [ $nums -eq $expected ] ||
7369                         error "'$cmd' wrong: found $nums, expected $expected"
7370         fi
7371 }
7372 run_test 56u "check lfs find -stripe-index works"
7373
7374 test_56v() {
7375         local mdt_idx=0
7376         local dir=$DIR/$tdir
7377
7378         setup_56 $dir $NUMFILES $NUMDIRS
7379
7380         UUID=$(mdtuuid_from_index $mdt_idx $dir)
7381         [ -z "$UUID" ] && error "mdtuuid_from_index cannot find MDT $mdt_idx"
7382
7383         for file in $($LFS find -m $UUID $dir); do
7384                 file_midx=$($LFS getstripe -m $file)
7385                 [ $file_midx -eq $mdt_idx ] ||
7386                         error "lfs find -m $UUID != getstripe -m $file_midx"
7387         done
7388 }
7389 run_test 56v "check 'lfs find -m match with lfs getstripe -m'"
7390
7391 test_56wa() {
7392         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
7393         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7394
7395         local dir=$DIR/$tdir
7396
7397         setup_56 $dir $NUMFILES $NUMDIRS "-c $OSTCOUNT" "-c1"
7398         stack_trap "rm -rf $dir"
7399
7400         local stripe_size=$($LFS getstripe -S -d $dir) ||
7401                 error "$LFS getstripe -S -d $dir failed"
7402         stripe_size=${stripe_size%% *}
7403
7404         local file_size=$((stripe_size * OSTCOUNT))
7405         local file_num=$((NUMDIRS * NUMFILES + NUMFILES))
7406         local required_space=$((file_num * file_size))
7407         local free_space=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
7408                            head -n1)
7409         (( free_space >= required_space / 1024 )) ||
7410                 skip_env "need $required_space, have $free_space kbytes"
7411
7412         local dd_bs=65536
7413         local dd_count=$((file_size / dd_bs))
7414
7415         # write data into the files
7416         local i
7417         local j
7418         local file
7419
7420         for ((i = 1; i <= NUMFILES; i++ )); do
7421                 file=$dir/file$i
7422                 yes | dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
7423                         error "write data into $file failed"
7424         done
7425         for ((i = 1; i <= NUMDIRS; i++ )); do
7426                 for ((j = 1; j <= NUMFILES; j++ )); do
7427                         file=$dir/dir$i/file$j
7428                         yes|dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
7429                                 error "write data into $file failed"
7430                 done
7431         done
7432
7433         # $LFS_MIGRATE will fail if hard link migration is unsupported
7434         if (( MDS1_VERSION > $(version_code 2.5.55) )); then
7435                 createmany -l$dir/dir1/file1 $dir/dir1/link 200 ||
7436                         error "creating links to $dir/dir1/file1 failed"
7437         fi
7438
7439         local expected=-1
7440
7441         (( OSTCOUNT <= 1 )) || expected=$((OSTCOUNT - 1))
7442
7443         # lfs_migrate file
7444         local cmd="$LFS_MIGRATE -y -c $expected $dir/file1"
7445
7446         echo "$cmd"
7447         eval $cmd || error "$cmd failed"
7448
7449         check_stripe_count $dir/file1 $expected
7450
7451         if (( $MDS1_VERSION >= $(version_code 2.6.90) )); then
7452                 # lfs_migrate file onto OST 0 if it is on OST 1, or onto
7453                 # OST 1 if it is on OST 0. This file is small enough to
7454                 # be on only one stripe.
7455                 file=$dir/migr_1_ost
7456                 dd bs=$dd_bs count=1 if=/dev/urandom of=$file >/dev/null 2>&1 ||
7457                         error "write data into $file failed"
7458                 local obdidx=$($LFS getstripe -i $file)
7459                 local oldmd5=$(md5sum $file)
7460                 local newobdidx=0
7461
7462                 (( obdidx != 0 )) || newobdidx=1
7463                 cmd="$LFS migrate -i $newobdidx $file"
7464                 echo $cmd
7465                 eval $cmd || error "$cmd failed"
7466
7467                 local realobdix=$($LFS getstripe -i $file)
7468                 local newmd5=$(md5sum $file)
7469
7470                 (( $newobdidx == $realobdix )) ||
7471                         error "new OST is different (was=$obdidx, wanted=$newobdidx, got=$realobdix)"
7472                 [[ "$oldmd5" == "$newmd5" ]] ||
7473                         error "md5sum differ: $oldmd5, $newmd5"
7474         fi
7475
7476         # lfs_migrate dir
7477         cmd="$LFS_MIGRATE -y -c $expected $dir/dir1"
7478         echo "$cmd"
7479         eval $cmd || error "$cmd failed"
7480
7481         for (( j = 1; j <= NUMFILES; j++ )); do
7482                 check_stripe_count $dir/dir1/file$j $expected
7483         done
7484
7485         # lfs_migrate works with lfs find
7486         cmd="$LFS find -stripe_count $OSTCOUNT -type f $dir |
7487              $LFS_MIGRATE -y -c $expected"
7488         echo "$cmd"
7489         eval $cmd || error "$cmd failed"
7490
7491         for (( i = 2; i <= NUMFILES; i++ )); do
7492                 check_stripe_count $dir/file$i $expected
7493         done
7494         for (( i = 2; i <= NUMDIRS; i++ )); do
7495                 for (( j = 1; j <= NUMFILES; j++ )); do
7496                         check_stripe_count $dir/dir$i/file$j $expected
7497                 done
7498         done
7499 }
7500 run_test 56wa "check lfs_migrate -c stripe_count works"
7501
7502 test_56wb() {
7503         local file1=$DIR/$tdir/file1
7504         local create_pool=false
7505         local initial_pool=$($LFS getstripe -p $DIR)
7506         local pool_list=()
7507         local pool=""
7508
7509         echo -n "Creating test dir..."
7510         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
7511         echo "done."
7512
7513         echo -n "Creating test file..."
7514         touch $file1 || error "cannot create file"
7515         echo "done."
7516
7517         echo -n "Detecting existing pools..."
7518         pool_list=($($LFS pool_list $FSNAME | grep "$FSNAME\." | cut -d. -f2))
7519
7520         if [ ${#pool_list[@]} -gt 0 ]; then
7521                 echo "${pool_list[@]}"
7522                 for thispool in "${pool_list[@]}"; do
7523                         if [[ -z "$initial_pool" ||
7524                               "$initial_pool" != "$thispool" ]]; then
7525                                 pool="$thispool"
7526                                 echo "Using existing pool '$pool'"
7527                                 break
7528                         fi
7529                 done
7530         else
7531                 echo "none detected."
7532         fi
7533         if [ -z "$pool" ]; then
7534                 pool=${POOL:-testpool}
7535                 [ "$initial_pool" = "$pool" ] && pool="testpool2"
7536                 echo -n "Creating pool '$pool'..."
7537                 create_pool=true
7538                 pool_add $pool &> /dev/null ||
7539                         error "pool_add failed"
7540                 echo "done."
7541
7542                 echo -n "Adding target to pool..."
7543                 pool_add_targets $pool 0 0 1 &> /dev/null ||
7544                         error "pool_add_targets failed"
7545                 echo "done."
7546         fi
7547
7548         echo -n "Setting pool using -p option..."
7549         $LFS_MIGRATE -y -q --no-rsync -p $pool $file1 &> /dev/null ||
7550                 error "migrate failed rc = $?"
7551         echo "done."
7552
7553         echo -n "Verifying test file is in pool after migrating..."
7554         [ "$($LFS getstripe -p $file1)" = $pool ] ||
7555                 error "file was not migrated to pool $pool"
7556         echo "done."
7557
7558         echo -n "Removing test file from pool '$pool'..."
7559         # "lfs migrate $file" won't remove the file from the pool
7560         # until some striping information is changed.
7561         $LFS migrate -c 1 $file1 &> /dev/null ||
7562                 error "cannot remove from pool"
7563         [ "$($LFS getstripe -p $file1)" ] &&
7564                 error "pool still set"
7565         echo "done."
7566
7567         echo -n "Setting pool using --pool option..."
7568         $LFS_MIGRATE -y -q --no-rsync --pool $pool $file1 &> /dev/null ||
7569                 error "migrate failed rc = $?"
7570         echo "done."
7571
7572         # Clean up
7573         rm -f $file1
7574         if $create_pool; then
7575                 destroy_test_pools 2> /dev/null ||
7576                         error "destroy test pools failed"
7577         fi
7578 }
7579 run_test 56wb "check lfs_migrate pool support"
7580
7581 test_56wc() {
7582         local file1="$DIR/$tdir/$tfile"
7583         local md5
7584         local parent_ssize
7585         local parent_scount
7586         local cur_ssize
7587         local cur_scount
7588         local orig_ssize
7589         local new_scount
7590         local cur_comp
7591
7592         echo -n "Creating test dir..."
7593         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
7594         $LFS setstripe -S 1M -c 1 "$DIR/$tdir" &> /dev/null ||
7595                 error "cannot set stripe by '-S 1M -c 1'"
7596         echo "done"
7597
7598         echo -n "Setting initial stripe for test file..."
7599         $LFS setstripe -S 512K -c 1 "$file1" &> /dev/null ||
7600                 error "cannot set stripe"
7601         cur_ssize=$($LFS getstripe -S "$file1")
7602         (( cur_ssize == 524288 )) || error "setstripe -S $cur_ssize != 524288"
7603         echo "done."
7604
7605         dd if=/dev/urandom of=$file1 bs=1M count=12 || error "dd $file1 failed"
7606         stack_trap "rm -f $file1"
7607         md5="$(md5sum $file1)"
7608
7609         # File currently set to -S 512K -c 1
7610
7611         # Ensure -c and -S options are rejected when -R is set
7612         echo -n "Verifying incompatible options are detected..."
7613         $LFS_MIGRATE -R -c 1 "$file1" &&
7614                 error "incompatible -R and -c options not detected"
7615         $LFS_MIGRATE -R -S 1M "$file1" &&
7616                 error "incompatible -R and -S options not detected"
7617         $LFS_MIGRATE -R -p pool "$file1" &&
7618                 error "incompatible -R and -p options not detected"
7619         $LFS_MIGRATE -R -E eof -c 1 "$file1" &&
7620                 error "incompatible -R and -E options not detected"
7621         $LFS_MIGRATE -R -A "$file1" &&
7622                 error "incompatible -R and -A options not detected"
7623         $LFS_MIGRATE -A -c 1 "$file1" &&
7624                 error "incompatible -A and -c options not detected"
7625         $LFS_MIGRATE -A -S 1M "$file1" &&
7626                 error "incompatible -A and -S options not detected"
7627         $LFS_MIGRATE -A -p pool "$file1" &&
7628                 error "incompatible -A and -p options not detected"
7629         $LFS_MIGRATE -A -E eof -c 1 "$file1" &&
7630                 error "incompatible -A and -E options not detected"
7631         echo "done."
7632
7633         # Ensure unrecognized options are passed through to 'lfs migrate'
7634         echo -n "Verifying -S option is passed through to lfs migrate..."
7635         $LFS_MIGRATE -y -S 1M "$file1" || error "migration failed"
7636         cur_ssize=$($LFS getstripe -S "$file1")
7637         (( cur_ssize == 1048576 )) || error "migrate -S $cur_ssize != 1048576"
7638         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (1)"
7639         echo "done."
7640
7641         # File currently set to -S 1M -c 1
7642
7643         # Ensure long options are supported
7644         echo -n "Verifying long options supported..."
7645         $LFS_MIGRATE --non-block "$file1" ||
7646                 error "long option without argument not supported"
7647         $LFS_MIGRATE --stripe-size 512K "$file1" ||
7648                 error "long option with argument not supported"
7649         cur_ssize=$($LFS getstripe -S "$file1")
7650         (( cur_ssize == 524288 )) ||
7651                 error "migrate --stripe-size $cur_ssize != 524288"
7652         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (2)"
7653         echo "done."
7654
7655         # File currently set to -S 512K -c 1
7656
7657         if (( OSTCOUNT > 1 )); then
7658                 echo -n "Verifying explicit stripe count can be set..."
7659                 $LFS_MIGRATE -c 2 "$file1" || error "migrate failed"
7660                 cur_scount=$($LFS getstripe -c "$file1")
7661                 (( cur_scount == 2 )) || error "migrate -c $cur_scount != 2"
7662                 [[ "$(md5sum $file1)" == "$md5" ]] ||
7663                         error "file data has changed (3)"
7664                 echo "done."
7665         fi
7666
7667         # File currently set to -S 512K -c 1 or -S 512K -c 2
7668
7669         # Ensure parent striping is used if -R is set, and no stripe
7670         # count or size is specified
7671         echo -n "Setting stripe for parent directory..."
7672         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
7673                 error "cannot set stripe '-S 2M -c 1'"
7674         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (4)"
7675         echo "done."
7676
7677         echo -n "Verifying restripe option uses parent stripe settings..."
7678         parent_ssize=$($LFS getstripe -S $DIR/$tdir 2>/dev/null)
7679         parent_scount=$($LFS getstripe -c $DIR/$tdir 2>/dev/null)
7680         $LFS_MIGRATE -R "$file1" || error "migrate failed"
7681         cur_ssize=$($LFS getstripe -S "$file1")
7682         (( cur_ssize == parent_ssize )) ||
7683                 error "migrate -R stripe_size $cur_ssize != $parent_ssize"
7684         cur_scount=$($LFS getstripe -c "$file1")
7685         (( cur_scount == parent_scount )) ||
7686                 error "migrate -R stripe_count $cur_scount != $parent_scount"
7687         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (5)"
7688         echo "done."
7689
7690         # File currently set to -S 1M -c 1
7691
7692         # Ensure striping is preserved if -R is not set, and no stripe
7693         # count or size is specified
7694         echo -n "Verifying striping size preserved when not specified..."
7695         orig_ssize=$($LFS getstripe -S "$file1" 2>/dev/null)
7696         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
7697                 error "cannot set stripe on parent directory"
7698         $LFS_MIGRATE "$file1" || error "migrate failed"
7699         cur_ssize=$($LFS getstripe -S "$file1")
7700         (( cur_ssize == orig_ssize )) ||
7701                 error "migrate by default $cur_ssize != $orig_ssize"
7702         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (6)"
7703         echo "done."
7704
7705         # Ensure file name properly detected when final option has no argument
7706         echo -n "Verifying file name properly detected..."
7707         $LFS_MIGRATE "$file1" ||
7708                 error "file name interpreted as option argument"
7709         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (7)"
7710         echo "done."
7711
7712         # Ensure PFL arguments are passed through properly
7713         echo -n "Verifying PFL options passed through..."
7714         new_scount=$(((OSTCOUNT + 1) / 2))
7715         $LFS_MIGRATE -E 1M -c 1 -E 16M -c $new_scount -E eof -c -1 "$file1" ||
7716                 error "migrate PFL arguments failed"
7717         cur_comp=$($LFS getstripe --comp-count $file1)
7718         (( cur_comp == 3 )) || error "component count '$cur_comp' != 3"
7719         cur_scount=$($LFS getstripe --stripe-count $file1)
7720         (( cur_scount == new_scount)) ||
7721                 error "PFL stripe count $cur_scount != $new_scount"
7722         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (8)"
7723         echo "done."
7724 }
7725 run_test 56wc "check unrecognized options for lfs_migrate are passed through"
7726
7727 test_56wd() {
7728         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
7729
7730         local file1=$DIR/$tdir/$tfile
7731
7732         echo -n "Creating test dir..."
7733         test_mkdir $DIR/$tdir || error "cannot create dir"
7734         echo "done."
7735
7736         echo -n "Creating test file..."
7737         echo "$tfile" > $file1
7738         echo "done."
7739
7740         # Ensure 'lfs migrate' will fail by using a non-existent option,
7741         # and make sure rsync is not called to recover
7742         echo -n "Make sure --no-rsync option works..."
7743         $LFS_MIGRATE -y --no-rsync --invalid-opt $file1 2>&1 |
7744                 grep -q 'refusing to fall back to rsync' ||
7745                 error "rsync was called with --no-rsync set"
7746         echo "done."
7747
7748         # Ensure rsync is called without trying 'lfs migrate' first
7749         echo -n "Make sure --rsync option works..."
7750         $LFS_MIGRATE -y --rsync --invalid-opt $file1 2>&1 |
7751                 grep -q 'falling back to rsync' &&
7752                 error "lfs migrate was called with --rsync set"
7753         echo "done."
7754 }
7755 run_test 56wd "check lfs_migrate --rsync and --no-rsync work"
7756
7757 test_56we() {
7758         local td=$DIR/$tdir
7759         local tf=$td/$tfile
7760
7761         test_mkdir $td || error "cannot create $td"
7762         touch $tf || error "cannot touch $tf"
7763
7764         echo -n "Make sure --non-direct|-D works..."
7765         $LFS_MIGRATE -y --non-direct -v $tf 2>&1 |
7766                 grep -q "lfs migrate --non-direct" ||
7767                 error "--non-direct option cannot work correctly"
7768         $LFS_MIGRATE -y -D -v $tf 2>&1 |
7769                 grep -q "lfs migrate -D" ||
7770                 error "-D option cannot work correctly"
7771         echo "done."
7772 }
7773 run_test 56we "check lfs_migrate --non-direct|-D support"
7774
7775 test_56x() {
7776         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7777         check_swap_layouts_support
7778
7779         local dir=$DIR/$tdir
7780         local ref1=/etc/passwd
7781         local file1=$dir/file1
7782
7783         test_mkdir $dir || error "creating dir $dir"
7784         $LFS setstripe -c 2 $file1
7785         cp $ref1 $file1
7786         $LFS migrate -c 1 $file1 || error "migrate failed rc = $?"
7787         stripe=$($LFS getstripe -c $file1)
7788         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
7789         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
7790
7791         # clean up
7792         rm -f $file1
7793 }
7794 run_test 56x "lfs migration support"
7795
7796 test_56xa() {
7797         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7798         check_swap_layouts_support
7799
7800         local dir=$DIR/$tdir/$testnum
7801
7802         test_mkdir -p $dir
7803
7804         local ref1=/etc/passwd
7805         local file1=$dir/file1
7806
7807         $LFS setstripe -c 2 $file1
7808         cp $ref1 $file1
7809         $LFS migrate --block -c 1 $file1 || error "migrate failed rc = $?"
7810
7811         local stripe=$($LFS getstripe -c $file1)
7812
7813         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
7814         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
7815
7816         # clean up
7817         rm -f $file1
7818 }
7819 run_test 56xa "lfs migration --block support"
7820
7821 check_migrate_links() {
7822         [[ "$1" == "--rsync" ]] && local opts="--rsync -y" && shift
7823         local dir="$1"
7824         local file1="$dir/file1"
7825         local begin="$2"
7826         local count="$3"
7827         local runas="$4"
7828         local total_count=$(($begin + $count - 1))
7829         local symlink_count=10
7830         local uniq_count=10
7831
7832         if [ ! -f "$file1" ]; then
7833                 echo -n "creating initial file..."
7834                 $LFS setstripe -c 1 -S "512k" "$file1" ||
7835                         error "cannot setstripe initial file"
7836                 echo "done"
7837
7838                 echo -n "creating symlinks..."
7839                 for s in $(seq 1 $symlink_count); do
7840                         ln -s "$file1" "$dir/slink$s" ||
7841                                 error "cannot create symlinks"
7842                 done
7843                 echo "done"
7844
7845                 echo -n "creating nonlinked files..."
7846                 createmany -o "$dir/uniq" 1 10 &> /dev/null ||
7847                         error "cannot create nonlinked files"
7848                 echo "done"
7849         fi
7850
7851         # create hard links
7852         if [ ! -f "$dir/file$total_count" ]; then
7853                 echo -n "creating hard links $begin:$total_count..."
7854                 createmany -l"$file1" "$dir/file" "$begin" "$count" &>  \
7855                         /dev/null || error "cannot create hard links"
7856                 echo "done"
7857         fi
7858
7859         echo -n "checking number of hard links listed in xattrs..."
7860         local fid=$($LFS getstripe -F "$file1")
7861         local paths=($($LFS fid2path "$MOUNT" "$fid" 2> /dev/null))
7862
7863         echo "${#paths[*]}"
7864         if [ ${#paths[*]} -lt $total_count -a "$begin" -eq 2  ]; then
7865                         skip "hard link list has unexpected size, skipping test"
7866         fi
7867         if [ ${#paths[*]} -ge $total_count -a "$begin" -ne 2  ]; then
7868                         error "link names should exceed xattrs size"
7869         fi
7870
7871         echo -n "migrating files..."
7872         local migrate_out=$($runas $LFS_MIGRATE $opts -S '1m' $dir)
7873         local rc=$?
7874         [ $rc -eq 0 ] || error "migrate failed rc = $rc"
7875         echo "done"
7876
7877         # make sure all links have been properly migrated
7878         echo -n "verifying files..."
7879         fid=$($LFS getstripe -F "$file1") ||
7880                 error "cannot get fid for file $file1"
7881         for i in $(seq 2 $total_count); do
7882                 local fid2=$($LFS getstripe -F $dir/file$i)
7883
7884                 [ "$fid2" == "$fid" ] ||
7885                         error "migrated hard link has mismatched FID"
7886         done
7887
7888         # make sure hard links were properly detected, and migration was
7889         # performed only once for the entire link set; nonlinked files should
7890         # also be migrated
7891         local actual=$(grep -c 'done' <<< "$migrate_out")
7892         local expected=$(($uniq_count + 1))
7893
7894         [ "$actual" -eq  "$expected" ] ||
7895                 error "hard links individually migrated ($actual != $expected)"
7896
7897         # make sure the correct number of hard links are present
7898         local hardlinks=$(stat -c '%h' "$file1")
7899
7900         [ $hardlinks -eq $total_count ] ||
7901                 error "num hard links $hardlinks != $total_count"
7902         echo "done"
7903
7904         return 0
7905 }
7906
7907 test_56xb() {
7908         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
7909                 skip "Need MDS version at least 2.10.55"
7910
7911         local dir="$DIR/$tdir"
7912
7913         test_mkdir "$dir" || error "cannot create dir $dir"
7914
7915         echo "testing lfs migrate mode when all links fit within xattrs"
7916         check_migrate_links "$dir" 2 99
7917
7918         echo "testing rsync mode when all links fit within xattrs"
7919         check_migrate_links --rsync "$dir" 2 99
7920
7921         echo "testing lfs migrate mode when all links do not fit within xattrs"
7922         check_migrate_links "$dir" 101 100
7923
7924         echo "testing rsync mode when all links do not fit within xattrs"
7925         check_migrate_links --rsync "$dir" 101 100
7926
7927         chown -R $RUNAS_ID $dir
7928         echo "testing non-root lfs migrate mode when not all links are in xattr"
7929         check_migrate_links "$dir" 101 100 "$RUNAS"
7930
7931         # clean up
7932         rm -rf $dir
7933 }
7934 run_test 56xb "lfs migration hard link support"
7935
7936 test_56xc() {
7937         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7938
7939         local dir="$DIR/$tdir"
7940
7941         test_mkdir "$dir" || error "cannot create dir $dir"
7942
7943         # Test 1: ensure file < 1 GB is always migrated with 1 stripe
7944         echo -n "Setting initial stripe for 20MB test file..."
7945         $LFS setstripe -c 2 -i 0 "$dir/20mb" ||
7946                 error "cannot setstripe 20MB file"
7947         echo "done"
7948         echo -n "Sizing 20MB test file..."
7949         $TRUNCATE "$dir/20mb" 20971520 || error "cannot create 20MB test file"
7950         echo "done"
7951         echo -n "Verifying small file autostripe count is 1..."
7952         $LFS_MIGRATE -y -A -C 1 "$dir/20mb" ||
7953                 error "cannot migrate 20MB file"
7954         local stripe_count=$($LFS getstripe -c "$dir/20mb") ||
7955                 error "cannot get stripe for $dir/20mb"
7956         [ $stripe_count -eq 1 ] ||
7957                 error "unexpected stripe count $stripe_count for 20MB file"
7958         rm -f "$dir/20mb"
7959         echo "done"
7960
7961         # Test 2: File is small enough to fit within the available space on
7962         # sqrt(size_in_gb) + 1 OSTs but is larger than 1GB.  The file must
7963         # have at least an additional 1KB for each desired stripe for test 3
7964         echo -n "Setting stripe for 1GB test file..."
7965         $LFS setstripe -c 1 -i 0 "$dir/1gb" || error "cannot setstripe 1GB file"
7966         echo "done"
7967         echo -n "Sizing 1GB test file..."
7968         # File size is 1GB + 3KB
7969         $TRUNCATE "$dir/1gb" 1073744896 || error "cannot create 1GB test file"
7970         echo "done"
7971
7972         # need at least 512MB per OST for 1GB file to fit in 2 stripes
7973         local avail=$($LCTL get_param -n llite.$FSNAME*.kbytesavail)
7974         if (( avail > 524288 * OSTCOUNT )); then
7975                 echo -n "Migrating 1GB file..."
7976                 $LFS_MIGRATE -y -A -C 1 "$dir/1gb" ||
7977                         error "cannot migrate 1GB file"
7978                 echo "done"
7979                 echo -n "Verifying autostripe count is sqrt(n) + 1..."
7980                 stripe_count=$($LFS getstripe -c "$dir/1gb") ||
7981                         error "cannot getstripe for 1GB file"
7982                 [ $stripe_count -eq 2 ] ||
7983                         error "unexpected stripe count $stripe_count != 2"
7984                 echo "done"
7985         fi
7986
7987         # Test 3: File is too large to fit within the available space on
7988         # sqrt(n) + 1 OSTs.  Simulate limited available space with -X
7989         if [ $OSTCOUNT -ge 3 ]; then
7990                 # The required available space is calculated as
7991                 # file size (1GB + 3KB) / OST count (3).
7992                 local kb_per_ost=349526
7993
7994                 echo -n "Migrating 1GB file with limit..."
7995                 $LFS_MIGRATE -y -A -C 1 -X $kb_per_ost "$dir/1gb" ||
7996                         error "cannot migrate 1GB file with limit"
7997                 echo "done"
7998
7999                 stripe_count=$($LFS getstripe -c "$dir/1gb")
8000                 echo -n "Verifying 1GB autostripe count with limited space..."
8001                 [ "$stripe_count" -a $stripe_count -ge 3 ] ||
8002                         error "unexpected stripe count $stripe_count (min 3)"
8003                 echo "done"
8004         fi
8005
8006         # clean up
8007         rm -rf $dir
8008 }
8009 run_test 56xc "lfs migration autostripe"
8010
8011 test_56xd() {
8012         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8013
8014         local dir=$DIR/$tdir
8015         local f_mgrt=$dir/$tfile.mgrt
8016         local f_yaml=$dir/$tfile.yaml
8017         local f_copy=$dir/$tfile.copy
8018         local layout_yaml="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
8019         local layout_copy="-c 2 -S 2M -i 1"
8020         local yamlfile=$dir/yamlfile
8021         local layout_before;
8022         local layout_after;
8023
8024         test_mkdir "$dir" || error "cannot create dir $dir"
8025         stack_trap "rm -rf $dir"
8026         $LFS setstripe $layout_yaml $f_yaml ||
8027                 error "cannot setstripe $f_yaml with layout $layout_yaml"
8028         $LFS getstripe --yaml $f_yaml > $yamlfile
8029         $LFS setstripe $layout_copy $f_copy ||
8030                 error "cannot setstripe $f_copy with layout $layout_copy"
8031         touch $f_mgrt
8032         dd if=/dev/zero of=$f_mgrt bs=1M count=4
8033
8034         # 1. test option --yaml
8035         $LFS_MIGRATE -y --yaml $yamlfile $f_mgrt ||
8036                 error "cannot migrate $f_mgrt with --yaml $yamlfile"
8037         layout_before=$(get_layout_param $f_yaml)
8038         layout_after=$(get_layout_param $f_mgrt)
8039         [ "$layout_after" == "$layout_before" ] ||
8040                 error "lfs_migrate --yaml: $layout_after != $layout_before"
8041
8042         # 2. test option --copy
8043         $LFS_MIGRATE -y --copy $f_copy $f_mgrt ||
8044                 error "cannot migrate $f_mgrt with --copy $f_copy"
8045         layout_before=$(SKIP_INDEX=yes get_layout_param $f_copy)
8046         layout_after=$(SKIP_INDEX=yes get_layout_param $f_mgrt)
8047         [ "$layout_after" == "$layout_before" ] ||
8048                 error "lfs_migrate --copy: $layout_after != $layout_before"
8049 }
8050 run_test 56xd "check lfs_migrate --yaml and --copy support"
8051
8052 test_56xe() {
8053         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8054
8055         local dir=$DIR/$tdir
8056         local f_comp=$dir/$tfile
8057         local layout="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
8058         local layout_before=""
8059         local layout_after=""
8060
8061         test_mkdir "$dir" || error "cannot create dir $dir"
8062         stack_trap "rm -rf $dir"
8063         $LFS setstripe $layout $f_comp ||
8064                 error "cannot setstripe $f_comp with layout $layout"
8065         layout_before=$(SKIP_INDEX=yes get_layout_param $f_comp)
8066         dd if=/dev/zero of=$f_comp bs=1M count=4
8067
8068         # 1. migrate a comp layout file by lfs_migrate
8069         $LFS_MIGRATE -y $f_comp || error "cannot migrate $f_comp by lfs_migrate"
8070         layout_after=$(SKIP_INDEX=yes get_layout_param $f_comp)
8071         [ "$layout_before" == "$layout_after" ] ||
8072                 error "lfs_migrate: $layout_before != $layout_after"
8073
8074         # 2. migrate a comp layout file by lfs migrate
8075         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
8076         layout_after=$(SKIP_INDEX=yes get_layout_param $f_comp)
8077         [ "$layout_before" == "$layout_after" ] ||
8078                 error "lfs migrate: $layout_before != $layout_after"
8079 }
8080 run_test 56xe "migrate a composite layout file"
8081
8082 test_56xf() {
8083         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
8084
8085         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
8086                 skip "Need server version at least 2.13.53"
8087
8088         local dir=$DIR/$tdir
8089         local f_comp=$dir/$tfile
8090         local layout="-E 1M -c1 -E -1 -c2"
8091         local fid_before=""
8092         local fid_after=""
8093
8094         test_mkdir "$dir" || error "cannot create dir $dir"
8095         stack_trap "rm -rf $dir"
8096         $LFS setstripe $layout $f_comp ||
8097                 error "cannot setstripe $f_comp with layout $layout"
8098         fid_before=$($LFS getstripe --fid $f_comp)
8099         dd if=/dev/zero of=$f_comp bs=1M count=4
8100
8101         # 1. migrate a comp layout file to a comp layout
8102         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
8103         fid_after=$($LFS getstripe --fid $f_comp)
8104         [ "$fid_before" == "$fid_after" ] ||
8105                 error "comp-to-comp migrate: $fid_before != $fid_after"
8106
8107         # 2. migrate a comp layout file to a plain layout
8108         $LFS migrate -c2 $f_comp ||
8109                 error "cannot migrate $f_comp by lfs migrate"
8110         fid_after=$($LFS getstripe --fid $f_comp)
8111         [ "$fid_before" == "$fid_after" ] ||
8112                 error "comp-to-plain migrate: $fid_before != $fid_after"
8113
8114         # 3. migrate a plain layout file to a comp layout
8115         $LFS migrate $layout $f_comp ||
8116                 error "cannot migrate $f_comp by lfs migrate"
8117         fid_after=$($LFS getstripe --fid $f_comp)
8118         [ "$fid_before" == "$fid_after" ] ||
8119                 error "plain-to-comp migrate: $fid_before != $fid_after"
8120 }
8121 run_test 56xf "FID is not lost during migration of a composite layout file"
8122
8123 check_file_ost_range() {
8124         local file="$1"
8125         shift
8126         local range="$*"
8127         local -a file_range
8128         local idx
8129
8130         file_range=($($LFS getstripe -y "$file" |
8131                 awk '/l_ost_idx:/ { print $NF }'))
8132
8133         if [[ "${#file_range[@]}" = 0 ]]; then
8134                 echo "No osts found for $file"
8135                 return 1
8136         fi
8137
8138         for idx in "${file_range[@]}"; do
8139                 [[ " $range " =~ " $idx " ]] ||
8140                         return 1
8141         done
8142
8143         return 0
8144 }
8145
8146 sub_test_56xg() {
8147         local stripe_opt="$1"
8148         local pool="$2"
8149         shift 2
8150         local pool_ostidx="$(seq $* | tr '\n' ' ')"
8151
8152         $LFS migrate $stripe_opt -p $pool $DIR/$tfile ||
8153                 error "Fail to migrate $tfile on $pool"
8154         [[ "$($LFS getstripe -p $DIR/$tfile)" = "$pool" ]] ||
8155                 error "$tfile is not in pool $pool"
8156         check_file_ost_range "$DIR/$tfile" $pool_ostidx ||
8157                 error "$tfile osts mismatch with pool $pool (osts $pool_ostidx)"
8158 }
8159
8160 test_56xg() {
8161         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
8162         [[ $OSTCOUNT -ge 2 ]] || skip "needs >= 2 OSTs"
8163         [[ $MDS1_VERSION -gt $(version_code 2.14.52) ]] ||
8164                 skip "Need MDS version newer than 2.14.52"
8165
8166         local -a pool_names=("${TESTNAME}_0" "${TESTNAME}_1" "${TESTNAME}_2")
8167         local -a pool_ranges=("0 0" "1 1" "0 1")
8168
8169         # init pools
8170         for i in "${!pool_names[@]}"; do
8171                 pool_add ${pool_names[$i]} ||
8172                         error "pool_add failed (pool: ${pool_names[$i]})"
8173                 pool_add_targets ${pool_names[$i]} ${pool_ranges[$i]} ||
8174                         error "pool_add_targets failed (pool: ${pool_names[$i]})"
8175         done
8176
8177         # init the file to migrate
8178         $LFS setstripe -c1 -i1 $DIR/$tfile ||
8179                 error "Unable to create $tfile on OST1"
8180         stack_trap "rm -f $DIR/$tfile"
8181         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=4 status=none ||
8182                 error "Unable to write on $tfile"
8183
8184         echo "1. migrate $tfile on pool ${pool_names[0]}"
8185         sub_test_56xg "-c-1" "${pool_names[0]}" ${pool_ranges[0]}
8186
8187         echo "2. migrate $tfile on pool ${pool_names[2]}"
8188         sub_test_56xg "-c-1 -S2M" "${pool_names[2]}" ${pool_ranges[2]}
8189
8190         echo "3. migrate $tfile on pool ${pool_names[1]}"
8191         sub_test_56xg "-n -c-1" "${pool_names[1]}" ${pool_ranges[1]}
8192
8193         echo "4. migrate $tfile on pool ${pool_names[2]} with default stripe parameters"
8194         sub_test_56xg "" "${pool_names[2]}" ${pool_ranges[2]}
8195         echo
8196
8197         # Clean pools
8198         destroy_test_pools ||
8199                 error "pool_destroy failed"
8200 }
8201 run_test 56xg "lfs migrate pool support"
8202
8203 test_56xh() {
8204         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
8205
8206         local size_mb=25
8207         local file1=$DIR/$tfile
8208         local tmp1=$TMP/$tfile.tmp
8209
8210         $LFS setstripe -c 2 $file1
8211
8212         stack_trap "rm -f $file1 $tmp1"
8213         dd if=/dev/urandom of=$tmp1 bs=1M count=$size_mb ||
8214                         error "error creating $tmp1"
8215         ls -lsh $tmp1
8216         cp $tmp1 $file1
8217
8218         local start=$SECONDS
8219
8220         $LFS migrate --stats --stats-interval=1 -W 1M -c 1 $file1 ||
8221                 error "migrate failed rc = $?"
8222
8223         local elapsed=$((SECONDS - start))
8224
8225         # with 1MB/s, elapsed should equal size_mb
8226         (( elapsed >= size_mb * 95 / 100 )) ||
8227                 error "'lfs migrate -W' too fast ($elapsed < 0.95 * $size_mb)?"
8228
8229         (( elapsed <= size_mb * 120 / 100 )) ||
8230                 error_not_in_vm "'lfs migrate -W' slow ($elapsed > 1.2 * $size_mb)"
8231
8232         (( elapsed <= size_mb * 350 / 100 )) ||
8233                 error "'lfs migrate -W' too slow in VM ($elapsed > 3.5 * $size_mb)"
8234
8235         stripe=$($LFS getstripe -c $file1)
8236         (( $stripe == 1 )) || error "stripe of $file1 is $stripe != 1"
8237         cmp $file1 $tmp1 || error "content mismatch $file1 differs from $tmp1"
8238
8239         # Clean up file (since it is multiple MB)
8240         rm -f $file1 $tmp1
8241 }
8242 run_test 56xh "lfs migrate bandwidth limitation support"
8243
8244 test_56xi() {
8245         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
8246         verify_yaml_available || skip_env "YAML verification not installed"
8247
8248         local size_mb=5
8249         local file1=$DIR/$tfile.1
8250         local file2=$DIR/$tfile.2
8251         local file3=$DIR/$tfile.3
8252         local output_file=$DIR/$tfile.out
8253         local tmp1=$TMP/$tfile.tmp
8254
8255         $LFS setstripe -c 2 $file1
8256         $LFS setstripe -c 2 $file2
8257         $LFS setstripe -c 2 $file3
8258
8259         stack_trap "rm -f $file1 $file2 $file3 $tmp1 $output_file"
8260         dd if=/dev/urandom of=$tmp1 bs=1M count=$size_mb ||
8261                         error "error creating $tmp1"
8262         ls -lsh $tmp1
8263         cp $tmp1 $file1
8264         cp $tmp1 $file2
8265         cp $tmp1 $file3
8266
8267         $LFS migrate --stats --stats-interval=1 \
8268                 -c 1 $file1 $file2 $file3 1> $output_file ||
8269                 error "migrate failed rc = $?"
8270
8271         cat $output_file
8272         cat $output_file | verify_yaml || error "rename_stats is not valid YAML"
8273
8274         # Clean up file (since it is multiple MB)
8275         rm -f $file1 $file2 $file3 $tmp1 $output_file
8276 }
8277 run_test 56xi "lfs migrate stats support"
8278
8279 test_56xj() { # LU-16571 "lfs migrate -b" can cause thread starvation on OSS
8280         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
8281
8282         local file=$DIR/$tfile
8283         local linkdir=$DIR/$tdir
8284
8285         test_mkdir $linkdir || error "fail to create $linkdir"
8286         $LFS setstripe -i 0 -c 1 -S1M $file
8287         stack_trap "rm -rf $file $linkdir"
8288         dd if=/dev/urandom of=$file bs=1M count=10 ||
8289                 error "fail to create $file"
8290
8291         # Create file links
8292         local cpts
8293         local threads_max
8294         local nlinks
8295
8296         thread_max=$(do_facet ost1 "$LCTL get_param -n ost.OSS.ost.threads_max")
8297         cpts=$(do_facet ost1 "$LCTL get_param -n cpu_partition_table | wc -l")
8298         (( nlinks = thread_max * 3 / 2 / cpts))
8299
8300         echo "create $nlinks hard links of $file"
8301         createmany -l $file $linkdir/link $nlinks
8302
8303         # Parallel migrates (should not block)
8304         local i
8305         for ((i = 0; i < nlinks; i++)); do
8306                 echo $linkdir/link$i
8307         done | xargs -n1 -P $nlinks $LFS migrate -c2
8308
8309         local stripe_count
8310         stripe_count=$($LFS getstripe -c $file) ||
8311                 error "fail to get stripe count on $file"
8312
8313         ((stripe_count == 2)) ||
8314                 error "fail to migrate $file (stripe_count = $stripe_count)"
8315 }
8316 run_test 56xj "lfs migrate -b should not cause starvation of threads on OSS"
8317
8318 test_56y() {
8319         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
8320                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
8321
8322         local res=""
8323         local dir=$DIR/$tdir
8324         local f1=$dir/file1
8325         local f2=$dir/file2
8326
8327         test_mkdir -p $dir || error "creating dir $dir"
8328         touch $f1 || error "creating std file $f1"
8329         $MULTIOP $f2 H2c || error "creating released file $f2"
8330
8331         # a directory can be raid0, so ask only for files
8332         res=$($LFS find $dir -L raid0 -type f | wc -l)
8333         [[ $res == 2 ]] || error "search raid0: found $res files != 2"
8334
8335         res=$($LFS find $dir \! -L raid0 -type f | wc -l)
8336         [[ $res == 0 ]] || error "search !raid0: found $res files != 0"
8337
8338         # only files can be released, so no need to force file search
8339         res=$($LFS find $dir -L released)
8340         [[ $res == $f2 ]] || error "search released: found $res != $f2"
8341
8342         res=$($LFS find $dir -type f \! -L released)
8343         [[ $res == $f1 ]] || error "search !released: found $res != $f1"
8344 }
8345 run_test 56y "lfs find -L raid0|released"
8346
8347 test_56z() { # LU-4824
8348         # This checks to make sure 'lfs find' continues after errors
8349         # There are two classes of errors that should be caught:
8350         # - If multiple paths are provided, all should be searched even if one
8351         #   errors out
8352         # - If errors are encountered during the search, it should not terminate
8353         #   early
8354         local dir=$DIR/$tdir
8355         local i
8356
8357         test_mkdir $dir
8358         for i in d{0..9}; do
8359                 test_mkdir $dir/$i
8360                 touch $dir/$i/$tfile
8361         done
8362         $LFS find $DIR/non_existent_dir $dir &&
8363                 error "$LFS find did not return an error"
8364         # Make a directory unsearchable. This should NOT be the last entry in
8365         # directory order.  Arbitrarily pick the 6th entry
8366         chmod 700 $($LFS find $dir -type d | sed '6!d')
8367
8368         $RUNAS $LFS find $DIR/non_existent $dir
8369         local count=$($RUNAS $LFS find $DIR/non_existent $dir | wc -l)
8370
8371         # The user should be able to see 10 directories and 9 files
8372         (( count == 19 )) ||
8373                 error "$LFS find found $count != 19 entries after error"
8374 }
8375 run_test 56z "lfs find should continue after an error"
8376
8377 test_56aa() { # LU-5937
8378         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
8379
8380         local dir=$DIR/$tdir
8381
8382         mkdir $dir
8383         $LFS setdirstripe -c$MDSCOUNT $dir/striped_dir
8384
8385         createmany -o $dir/striped_dir/${tfile}- 1024
8386         local dirs=$($LFS find --size +8k $dir/)
8387
8388         [ -n "$dirs" ] || error "lfs find --size wrong under striped dir"
8389 }
8390 run_test 56aa "lfs find --size under striped dir"
8391
8392 test_56ab() { # LU-10705
8393         test_mkdir $DIR/$tdir
8394         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=8k count=1 seek=2k
8395         dd if=/dev/zero of=$DIR/$tdir/$tfile.2 bs=4k count=1 seek=4k
8396         dd if=/dev/zero of=$DIR/$tdir/$tfile.3 bs=1M count=2 seek=16
8397         # Flush writes to ensure valid blocks.  Need to be more thorough for
8398         # ZFS, since blocks are not allocated/returned to client immediately.
8399         sync_all_data
8400         wait_zfs_commit ost1 2
8401         cancel_lru_locks osc
8402         ls -ls $DIR/$tdir
8403
8404         local files=$($LFS find --size +16M $DIR/$tdir | wc -l)
8405
8406         [[ $files == 3 ]] || error ">16M size files $files isn't 3 as expected"
8407
8408         files=$($LFS find --blocks +1M $DIR/$tdir | wc -l)
8409         [[ $files == 1 ]] || error ">1M blocks files $files isn't 1 as expected"
8410
8411         rm -f $DIR/$tdir/$tfile.[123]
8412 }
8413 run_test 56ab "lfs find --blocks"
8414
8415 # LU-11188
8416 test_56aca() {
8417         local dir="$DIR/$tdir"
8418         local perms=(001 002 003 004 005 006 007
8419                      010 020 030 040 050 060 070
8420                      100 200 300 400 500 600 700
8421                      111 222 333 444 555 666 777)
8422         local perm_minus=(8 8 4 8 4 4 2
8423                           8 8 4 8 4 4 2
8424                           8 8 4 8 4 4 2
8425                           4 4 2 4 2 2 1)
8426         local perm_slash=(8  8 12  8 12 12 14
8427                           8  8 12  8 12 12 14
8428                           8  8 12  8 12 12 14
8429                          16 16 24 16 24 24 28)
8430
8431         test_mkdir "$dir"
8432         for perm in ${perms[*]}; do
8433                 touch "$dir/$tfile.$perm"
8434                 chmod $perm "$dir/$tfile.$perm"
8435         done
8436
8437         for ((i = 0; i < ${#perms[*]}; i++)); do
8438                 local num=$($LFS find $dir -perm ${perms[i]} | wc -l)
8439                 (( $num == 1 )) ||
8440                         error "lfs find -perm ${perms[i]}:"\
8441                               "$num != 1"
8442
8443                 num=$($LFS find $dir -perm -${perms[i]} -type f| wc -l)
8444                 (( $num == ${perm_minus[i]} )) ||
8445                         error "lfs find -perm -${perms[i]}:"\
8446                               "$num != ${perm_minus[i]}"
8447
8448                 num=$($LFS find $dir -perm /${perms[i]} -type f| wc -l)
8449                 (( $num == ${perm_slash[i]} )) ||
8450                         error "lfs find -perm /${perms[i]}:"\
8451                               "$num != ${perm_slash[i]}"
8452         done
8453 }
8454 run_test 56aca "check lfs find -perm with octal representation"
8455
8456 test_56acb() {
8457         local dir=$DIR/$tdir
8458         # p is the permission of write and execute for user, group and other
8459         # without the umask. It is used to test +wx.
8460         local p=$(printf "%o" "$((0333 & ~$(umask)))")
8461         local perms=(1000 000 2000 4000 $p 644 111 110 100 004)
8462         local symbolic=(+t  a+t u+t g+t o+t
8463                         g+s u+s o+s +s o+sr
8464                         o=r,ug+o,u+w
8465                         u+ g+ o+ a+ ugo+
8466                         u- g- o- a- ugo-
8467                         u= g= o= a= ugo=
8468                         o=r,ug+o,u+w u=r,a+u,u+w
8469                         g=r,ugo=g,u+w u+x,+X +X
8470                         u+x,u+X u+X u+x,g+X o+r,+X
8471                         u+x,go+X +wx +rwx)
8472
8473         test_mkdir $dir
8474         for perm in ${perms[*]}; do
8475                 touch "$dir/$tfile.$perm"
8476                 chmod $perm "$dir/$tfile.$perm"
8477         done
8478
8479         for (( i = 0; i < ${#symbolic[*]}; i++ )); do
8480                 local num=$($LFS find $dir -perm ${symbolic[i]} | wc -l)
8481
8482                 (( $num == 1 )) ||
8483                         error "lfs find $dir -perm ${symbolic[i]}: $num != 1"
8484         done
8485 }
8486 run_test 56acb "check lfs find -perm with symbolic representation"
8487
8488 test_56acc() {
8489         local dir=$DIR/$tdir
8490         local tests="17777 787 789 abcd
8491                 ug=uu ug=a ug=gu uo=ou urw
8492                 u+xg+x a=r,u+x,"
8493
8494         test_mkdir $dir
8495         for err in $tests; do
8496                 if $LFS find $dir -perm $err 2>/dev/null; then
8497                         error "lfs find -perm $err: parsing should have failed"
8498                 fi
8499         done
8500 }
8501 run_test 56acc "check parsing error for lfs find -perm"
8502
8503 test_56ba() {
8504         [ $MDS1_VERSION -lt $(version_code 2.10.50) ] &&
8505                 skip "Need MDS version at least 2.10.50"
8506
8507         # Create composite files with one component
8508         local dir=$DIR/$tdir
8509
8510         setup_56 $dir/1Mfiles 5 1 "-S 1M --component-end 1M"
8511         # Create composite files with three components
8512         setup_56 $dir/2Mfiles 5 2 "-E 2M -S 1M -E 4M -E 6M"
8513         # Create non-composite files
8514         createmany -o $dir/${tfile}- 10
8515
8516         local nfiles=$($LFS find --component-end 1M --type f $dir | wc -l)
8517
8518         [[ $nfiles == 10 ]] ||
8519                 error "lfs find -E 1M found $nfiles != 10 files"
8520
8521         nfiles=$($LFS find ! -E 1M --type f $dir | wc -l)
8522         [[ $nfiles == 25 ]] ||
8523                 error "lfs find ! -E 1M found $nfiles != 25 files"
8524
8525         # All files have a component that starts at 0
8526         nfiles=$($LFS find --component-start 0 --type f $dir | wc -l)
8527         [[ $nfiles == 35 ]] ||
8528                 error "lfs find --component-start 0 - $nfiles != 35 files"
8529
8530         nfiles=$($LFS find --component-start 2M --type f $dir | wc -l)
8531         [[ $nfiles == 15 ]] ||
8532                 error "lfs find --component-start 2M - $nfiles != 15 files"
8533
8534         # All files created here have a componenet that does not starts at 2M
8535         nfiles=$($LFS find ! --component-start 2M --type f $dir | wc -l)
8536         [[ $nfiles == 35 ]] ||
8537                 error "lfs find ! --component-start 2M - $nfiles != 35 files"
8538
8539         # Find files with a specified number of components
8540         local nfiles=$($LFS find --component-count 3 --type f $dir | wc -l)
8541         [[ $nfiles == 15 ]] ||
8542                 error "lfs find --component-count 3 - $nfiles != 15 files"
8543
8544         # Remember non-composite files have a component count of zero
8545         local nfiles=$($LFS find --component-count 0 --type f $dir | wc -l)
8546         [[ $nfiles == 10 ]] ||
8547                 error "lfs find --component-count 0 - $nfiles != 10 files"
8548
8549         nfiles=$($LFS find ! --component-count 3 --type f $dir | wc -l)
8550         [[ $nfiles == 20 ]] ||
8551                 error "lfs find ! --component-count 3 - $nfiles != 20 files"
8552
8553         # All files have a flag called "init"
8554         local nfiles=$($LFS find --component-flags init --type f $dir | wc -l)
8555         [[ $nfiles == 35 ]] ||
8556                 error "lfs find --component-flags init - $nfiles != 35 files"
8557
8558         # Multi-component files will have a component not initialized
8559         local nfiles=$($LFS find ! --component-flags init --type f $dir | wc -l)
8560         [[ $nfiles == 15 ]] ||
8561                 error "lfs find !--component-flags init - $nfiles != 15 files"
8562
8563         rm -rf $dir
8564
8565 }
8566 run_test 56ba "test lfs find --component-end, -start, -count, and -flags"
8567
8568 test_56ca() {
8569         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
8570                 skip "Need MDS version at least 2.10.57"
8571
8572         local td=$DIR/$tdir
8573         local tf=$td/$tfile
8574         local dir
8575         local nfiles
8576         local cmd
8577         local i
8578         local j
8579
8580         # create mirrored directories and mirrored files
8581         mkdir $td || error "mkdir $td failed"
8582         $LFS mirror create -N3 $td || error "create mirrored dir $td failed"
8583         createmany -o $tf- 10 || error "create $tf- failed"
8584
8585         for i in $(seq 2); do
8586                 dir=$td/dir$i
8587                 mkdir $dir || error "mkdir $dir failed"
8588                 $LFS mirror create -N$((3 + i)) $dir ||
8589                         error "create mirrored dir $dir failed"
8590                 createmany -o $dir/$tfile- 10 ||
8591                         error "create $dir/$tfile- failed"
8592         done
8593
8594         # change the states of some mirrored files
8595         echo foo > $tf-6
8596         for i in $(seq 2); do
8597                 dir=$td/dir$i
8598                 for j in $(seq 4 9); do
8599                         echo foo > $dir/$tfile-$j
8600                 done
8601         done
8602
8603         # find mirrored files with specific mirror count
8604         cmd="$LFS find --mirror-count 3 --type f $td"
8605         nfiles=$($cmd | wc -l)
8606         [[ $nfiles = 10 ]] || error "$cmd: $nfiles != 10 files"
8607
8608         cmd="$LFS find ! --mirror-count 3 --type f $td"
8609         nfiles=$($cmd | wc -l)
8610         [[ $nfiles = 20 ]] || error "$cmd: $nfiles != 20 files"
8611
8612         cmd="$LFS find --mirror-count +2 --type f $td"
8613         nfiles=$($cmd | wc -l)
8614         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8615
8616         cmd="$LFS find --mirror-count -6 --type f $td"
8617         nfiles=$($cmd | wc -l)
8618         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8619
8620         # find mirrored files with specific file state
8621         cmd="$LFS find --maxdepth 1 --mirror-state=^ro --type f $td"
8622         [[ $($cmd) = $tf-6 ]] || error "$cmd: didn't return $tf-6"
8623
8624         cmd="$LFS find --mirror-state=ro --type f $td"
8625         nfiles=$($cmd | wc -l)
8626         [[ $nfiles = 17 ]] || error "$cmd: $nfiles != 17 files"
8627
8628         cmd="$LFS find ! --mirror-state=ro --type f $td"
8629         nfiles=$($cmd | wc -l)
8630         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
8631
8632         cmd="$LFS find --mirror-state=wp --type f $td"
8633         nfiles=$($cmd | wc -l)
8634         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
8635
8636         cmd="$LFS find ! --mirror-state=sp --type f $td"
8637         nfiles=$($cmd | wc -l)
8638         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8639 }
8640 run_test 56ca "check lfs find --mirror-count|-N and --mirror-state"
8641
8642 test_56da() { # LU-14179
8643         local path=$DIR/$tdir
8644
8645         test_mkdir $path
8646         cd $path
8647
8648         local longdir=$(str_repeat 'a' 255)
8649
8650         for i in {1..15}; do
8651                 path=$path/$longdir
8652                 test_mkdir $longdir
8653                 cd $longdir
8654         done
8655
8656         local len=${#path}
8657         local lastdir=$(str_repeat 'a' $((4096 - 1 - $len - 1)))
8658
8659         test_mkdir $lastdir
8660         cd $lastdir
8661         # PATH_MAX-1
8662         (( ${#PWD} == 4095 )) || error "bad PWD length ${#PWD}, expect 4095"
8663
8664         # NAME_MAX
8665         touch $(str_repeat 'f' 255)
8666
8667         $LFS find $DIR/$tdir --type d |& grep "lfs find: error" &&
8668                 error "lfs find reported an error"
8669
8670         rm -rf $DIR/$tdir
8671 }
8672 run_test 56da "test lfs find with long paths"
8673
8674 test_56ea() { #LU-10378
8675         local path=$DIR/$tdir
8676         local pool=$TESTNAME
8677
8678         # Create ost pool
8679         pool_add $pool || error "pool_add $pool failed"
8680         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
8681                 error "adding targets to $pool failed"
8682
8683         # Set default pool on directory before creating file
8684         mkdir $path || error "mkdir $path failed"
8685         $LFS setstripe -p $pool $path ||
8686                 error "set OST pool on $pool failed"
8687         touch $path/$tfile || error "touch $path/$tfile failed"
8688
8689         # Compare basic file attributes from -printf and stat
8690         local attr_printf=$($LFS find $path/$tfile -printf "%A@ %T@ %C@ %U %G %n")
8691         local attr_stat=$(stat -c "%X %Y %Z %u %g %h" $path/$tfile)
8692
8693         [[ "${attr_printf}" == "${attr_stat}" ]] ||
8694                 error "Attrs from lfs find and stat don't match"
8695
8696         # Compare Lustre attributes from lfs find and lfs getstripe
8697         local lattr_printf=$($LFS find $path/$tfile -printf "%Lc %LS %Li %Lp")
8698         local str_cnt=$($LFS getstripe --stripe-count $path/$tfile)
8699         local str_size=$($LFS getstripe --stripe-size $path/$tfile)
8700         local str_idx=$($LFS getstripe --stripe-index $path/$tfile)
8701         local fpool=$($LFS getstripe --pool $path/$tfile)
8702         local lattr_getstr="${str_cnt} ${str_size} ${str_idx} ${fpool}"
8703
8704         [[ "${lattr_printf}" == "${lattr_getstr}" ]] ||
8705                 error "Attrs from lfs find and lfs getstripe don't match"
8706
8707         # Verify behavior for unknown escape/format sequences
8708         local esc_printf=$($LFS find $path/$tfile -printf '\\ %% \Q %Q')
8709
8710         [[ "${esc_printf}" == '\ % \Q %Q' ]] ||
8711                 error "Escape/format codes don't match"
8712 }
8713 run_test 56ea "test lfs find -printf option"
8714
8715 test_56eb() {
8716         local dir=$DIR/$tdir
8717         local subdir_1=$dir/subdir_1
8718
8719         test_mkdir -p $subdir_1
8720         ln -s subdir_1 $dir/link_1
8721
8722         $LFS getstripe $dir | grep "^$dir/link_1$" -A1 ||
8723                 error "symlink is not followed"
8724
8725         $LFS getstripe --no-follow $dir |
8726                 grep "^$dir/link_1 has no stripe info$" ||
8727                 error "symlink should not have stripe info"
8728
8729         touch $dir/testfile
8730         ln -s testfile $dir/file_link_2
8731
8732         $LFS getstripe $dir | grep "^$dir/file_link_2$" -A1 ||
8733                 error "symlink is not followed"
8734
8735         $LFS getstripe --no-follow $dir |
8736                 grep "^$dir/file_link_2 has no stripe info$" ||
8737                 error "symlink should not have stripe info"
8738 }
8739 run_test 56eb "check lfs getstripe on symlink"
8740
8741 test_56ec() {
8742         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8743         local dir=$DIR/$tdir
8744         local srcfile=$dir/srcfile
8745         local srcyaml=$dir/srcyaml
8746         local destfile=$dir/destfile
8747
8748         test_mkdir -p $dir
8749
8750         $LFS setstripe -i 1 $srcfile
8751         $LFS getstripe --hex-idx --yaml $srcfile > $srcyaml
8752         # if the setstripe yaml parsing fails for any reason, the command can
8753         # randomly assign the correct OST index, leading to an erroneous
8754         # success. but the chance of false success is low enough that a
8755         # regression should still be quickly caught.
8756         $LFS setstripe --yaml=$srcyaml $destfile
8757
8758         local srcindex=$($LFS getstripe -i $srcfile)
8759         local destindex=$($LFS getstripe -i $destfile)
8760
8761         if [[ ! $srcindex -eq $destindex ]]; then
8762                 error "setstripe did not set OST index correctly"
8763         fi
8764 }
8765 run_test 56ec "check lfs getstripe,setstripe --hex --yaml"
8766
8767 test_56eda() {
8768         local dir=$DIR/$tdir
8769         local subdir=$dir/subdir
8770         local file1=$dir/$tfile
8771         local file2=$dir/$tfile\2
8772         local link=$dir/$tfile-link
8773         local nfiles
8774
8775         test_mkdir -p $dir
8776         $LFS setdirstripe -c1 $subdir
8777         touch $file1
8778         touch $file2
8779         ln $file2 $link
8780
8781         nfiles=$($LFS find --links 1 $dir | wc -l)
8782         (( $nfiles == 1 )) ||
8783                 error "lfs find --links expected 1 file, got $nfiles"
8784
8785         nfiles=$($LFS find --type f --links 2 $dir | wc -l)
8786         (( $nfiles == 2 )) ||
8787                 error "lfs find --links expected 2 files, got $nfiles"
8788
8789         nfiles=$($LFS find --type d --links 2 $dir | wc -l)
8790         (( $nfiles == 1 )) ||
8791                 error "lfs find --links expected 1 directory, got $nfiles"
8792 }
8793 run_test 56eda "check lfs find --links"
8794
8795 test_56edb() {
8796         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
8797
8798         local dir=$DIR/$tdir
8799         local stripedir=$dir/stripedir
8800         local nfiles
8801
8802         test_mkdir -p $dir
8803
8804         $LFS setdirstripe -c2 $stripedir
8805
8806         $LFS getdirstripe $stripedir
8807
8808         nfiles=$($LFS find --type d --links 2 $stripedir | wc -l)
8809         (( $nfiles == 1 )) ||
8810                 error "lfs find --links expected 1 directory, got $nfiles"
8811 }
8812 run_test 56edb "check lfs find --links for directory striped on multiple MDTs"
8813
8814 test_57a() {
8815         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8816         # note test will not do anything if MDS is not local
8817         if [ "$mds1_FSTYPE" != ldiskfs ]; then
8818                 skip_env "ldiskfs only test"
8819         fi
8820         remote_mds_nodsh && skip "remote MDS with nodsh"
8821
8822         local MNTDEV="osd*.*MDT*.mntdev"
8823         DEV=$(do_facet $SINGLEMDS lctl get_param -n $MNTDEV)
8824         [ -z "$DEV" ] && error "can't access $MNTDEV"
8825         for DEV in $(do_facet $SINGLEMDS lctl get_param -n $MNTDEV); do
8826                 do_facet $SINGLEMDS $DUMPE2FS -h $DEV > $TMP/t57a.dump ||
8827                         error "can't access $DEV"
8828                 DEVISIZE=$(awk '/Inode size:/ { print $3 }' $TMP/t57a.dump)
8829                 [[ $DEVISIZE -gt 128 ]] || error "inode size $DEVISIZE"
8830                 rm $TMP/t57a.dump
8831         done
8832 }
8833 run_test 57a "verify MDS filesystem created with large inodes =="
8834
8835 test_57b() {
8836         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8837         if [ "$mds1_FSTYPE" != ldiskfs ]; then
8838                 skip_env "ldiskfs only test"
8839         fi
8840         remote_mds_nodsh && skip "remote MDS with nodsh"
8841
8842         local dir=$DIR/$tdir
8843         local filecount=100
8844         local file1=$dir/f1
8845         local fileN=$dir/f$filecount
8846
8847         rm -rf $dir || error "removing $dir"
8848         test_mkdir -c1 $dir
8849         local mdtidx=$($LFS getstripe -m $dir)
8850         local mdtname=MDT$(printf %04x $mdtidx)
8851         local facet=mds$((mdtidx + 1))
8852
8853         echo "mcreating $filecount files"
8854         createmany -m $dir/f 1 $filecount || error "creating files in $dir"
8855
8856         # verify that files do not have EAs yet
8857         $LFS getstripe $file1 2>&1 | grep -q "no stripe" ||
8858                 error "$file1 has an EA"
8859         $LFS getstripe $fileN 2>&1 | grep -q "no stripe" ||
8860                 error "$fileN has an EA"
8861
8862         sync
8863         sleep 1
8864         df $dir  #make sure we get new statfs data
8865         local mdsfree=$(do_facet $facet \
8866                         lctl get_param -n osd*.*$mdtname.kbytesfree)
8867         local mdcfree=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
8868         local file
8869
8870         echo "opening files to create objects/EAs"
8871         for file in $(seq -f $dir/f%g 1 $filecount); do
8872                 $OPENFILE -f O_RDWR $file > /dev/null 2>&1 ||
8873                         error "opening $file"
8874         done
8875
8876         # verify that files have EAs now
8877         $LFS getstripe $file1 | grep -q "obdidx" || error "$file1 missing EA"
8878         $LFS getstripe $fileN | grep -q "obdidx" || error "$fileN missing EA"
8879
8880         sleep 1  #make sure we get new statfs data
8881         df $dir
8882         local mdsfree2=$(do_facet $facet \
8883                          lctl get_param -n osd*.*$mdtname.kbytesfree)
8884         local mdcfree2=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
8885
8886         if [[ $mdcfree2 -lt $((mdcfree - 16)) ]]; then
8887                 if [ "$mdsfree" != "$mdsfree2" ]; then
8888                         error "MDC before $mdcfree != after $mdcfree2"
8889                 else
8890                         echo "MDC before $mdcfree != after $mdcfree2"
8891                         echo "unable to confirm if MDS has large inodes"
8892                 fi
8893         fi
8894         rm -rf $dir
8895 }
8896 run_test 57b "default LOV EAs are stored inside large inodes ==="
8897
8898 test_58() {
8899         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8900         [ -z "$(which wiretest 2>/dev/null)" ] &&
8901                         skip_env "could not find wiretest"
8902
8903         wiretest
8904 }
8905 run_test 58 "verify cross-platform wire constants =============="
8906
8907 test_59() {
8908         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8909
8910         echo "touch 130 files"
8911         createmany -o $DIR/f59- 130
8912         echo "rm 130 files"
8913         unlinkmany $DIR/f59- 130
8914         sync
8915         # wait for commitment of removal
8916         wait_delete_completed
8917 }
8918 run_test 59 "verify cancellation of llog records async ========="
8919
8920 TEST60_HEAD="test_60 run $RANDOM"
8921 test_60a() {
8922         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8923         remote_mgs_nodsh && skip "remote MGS with nodsh"
8924         do_facet mgs "! which run-llog.sh &> /dev/null" &&
8925                 do_facet mgs "! ls run-llog.sh &> /dev/null" &&
8926                         skip_env "missing subtest run-llog.sh"
8927
8928         log "$TEST60_HEAD - from kernel mode"
8929         do_facet mgs "$LCTL dk > /dev/null"
8930         do_facet mgs "bash run-llog.sh" || error "run-llog.sh failed"
8931         do_facet mgs $LCTL dk > $TMP/$tfile
8932
8933         # LU-6388: test llog_reader
8934         local llog_reader=$(do_facet mgs "which llog_reader 2> /dev/null")
8935         llog_reader=${llog_reader:-$LUSTRE/utils/llog_reader}
8936         [ -z $(do_facet mgs ls -d $llog_reader 2> /dev/null) ] &&
8937                         skip_env "missing llog_reader"
8938         local fstype=$(facet_fstype mgs)
8939         [ $fstype != ldiskfs -a $fstype != zfs ] &&
8940                 skip_env "Only for ldiskfs or zfs type mgs"
8941
8942         local mntpt=$(facet_mntpt mgs)
8943         local mgsdev=$(mgsdevname 1)
8944         local fid_list
8945         local fid
8946         local rec_list
8947         local rec
8948         local rec_type
8949         local obj_file
8950         local path
8951         local seq
8952         local oid
8953         local pass=true
8954
8955         #get fid and record list
8956         fid_list=($(awk '/9_sub.*record/ { print $NF }' $TMP/$tfile |
8957                 tail -n 4))
8958         rec_list=($(awk '/9_sub.*record/ { print $((NF-3)) }' $TMP/$tfile |
8959                 tail -n 4))
8960         #remount mgs as ldiskfs or zfs type
8961         stop mgs || error "stop mgs failed"
8962         mount_fstype mgs || error "remount mgs failed"
8963         for ((i = 0; i < ${#fid_list[@]}; i++)); do
8964                 fid=${fid_list[i]}
8965                 rec=${rec_list[i]}
8966                 seq=$(echo $fid | awk -F ':' '{ print $1 }' | sed -e "s/^0x//g")
8967                 oid=$(echo $fid | awk -F ':' '{ print $2 }' | sed -e "s/^0x//g")
8968                 oid=$((16#$oid))
8969
8970                 case $fstype in
8971                         ldiskfs )
8972                                 obj_file=$mntpt/O/$seq/d$((oid%32))/$oid ;;
8973                         zfs )
8974                                 obj_file=$mntpt/oi.$(($((16#$seq))&127))/$fid ;;
8975                 esac
8976                 echo "obj_file is $obj_file"
8977                 do_facet mgs $llog_reader $obj_file
8978
8979                 rec_type=$(do_facet mgs $llog_reader $obj_file | grep "type=" |
8980                         awk '{ print $3 }' | sed -e "s/^type=//g")
8981                 if [ $rec_type != $rec ]; then
8982                         echo "FAILED test_60a wrong record type $rec_type," \
8983                               "should be $rec"
8984                         pass=false
8985                         break
8986                 fi
8987
8988                 #check obj path if record type is LLOG_LOGID_MAGIC
8989                 if [ "$rec" == "1064553b" ]; then
8990                         path=$(do_facet mgs $llog_reader $obj_file |
8991                                 grep "path=" | awk '{ print $NF }' |
8992                                 sed -e "s/^path=//g")
8993                         if [ $obj_file != $mntpt/$path ]; then
8994                                 echo "FAILED test_60a wrong obj path" \
8995                                       "$montpt/$path, should be $obj_file"
8996                                 pass=false
8997                                 break
8998                         fi
8999                 fi
9000         done
9001         rm -f $TMP/$tfile
9002         #restart mgs before "error", otherwise it will block the next test
9003         stop mgs || error "stop mgs failed"
9004         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
9005         $pass || error "test failed, see FAILED test_60a messages for specifics"
9006 }
9007 run_test 60a "llog_test run from kernel module and test llog_reader"
9008
9009 test_60b() { # bug 6411
9010         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9011
9012         dmesg > $DIR/$tfile
9013         LLOG_COUNT=$(do_facet mgs dmesg |
9014                      awk "/$TEST60_HEAD/ { marker = 1; from_marker = 0; }
9015                           /llog_[a-z]*.c:[0-9]/ {
9016                                 if (marker)
9017                                         from_marker++
9018                                 from_begin++
9019                           }
9020                           END {
9021                                 if (marker)
9022                                         print from_marker
9023                                 else
9024                                         print from_begin
9025                           }")
9026
9027         [[ $LLOG_COUNT -gt 120 ]] &&
9028                 error "CDEBUG_LIMIT not limiting messages ($LLOG_COUNT)" || true
9029 }
9030 run_test 60b "limit repeated messages from CERROR/CWARN"
9031
9032 test_60c() {
9033         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9034
9035         echo "create 5000 files"
9036         createmany -o $DIR/f60c- 5000
9037 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED  0x137
9038         lctl set_param fail_loc=0x80000137
9039         unlinkmany $DIR/f60c- 5000
9040         lctl set_param fail_loc=0
9041 }
9042 run_test 60c "unlink file when mds full"
9043
9044 test_60d() {
9045         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9046
9047         SAVEPRINTK=$(lctl get_param -n printk)
9048         # verify "lctl mark" is even working"
9049         MESSAGE="test message ID $RANDOM $$"
9050         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
9051         dmesg | grep -q "$MESSAGE" || error "didn't find debug marker in log"
9052
9053         lctl set_param printk=0 || error "set lnet.printk failed"
9054         lctl get_param -n printk | grep emerg || error "lnet.printk dropped emerg"
9055         MESSAGE="new test message ID $RANDOM $$"
9056         # Assume here that libcfs_debug_mark_buffer() uses D_WARNING
9057         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
9058         dmesg | grep -q "$MESSAGE" && error "D_WARNING wasn't masked" || true
9059
9060         lctl set_param -n printk="$SAVEPRINTK"
9061 }
9062 run_test 60d "test printk console message masking"
9063
9064 test_60e() {
9065         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9066         remote_mds_nodsh && skip "remote MDS with nodsh"
9067
9068         touch $DIR/$tfile
9069 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED2  0x15b
9070         do_facet mds1 lctl set_param fail_loc=0x15b
9071         rm $DIR/$tfile
9072 }
9073 run_test 60e "no space while new llog is being created"
9074
9075 test_60f() {
9076         local old_path=$($LCTL get_param -n debug_path)
9077
9078         stack_trap "$LCTL set_param debug_path=$old_path"
9079         stack_trap "rm -f $TMP/$tfile*"
9080         rm -f $TMP/$tfile* 2> /dev/null
9081         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
9082         $LCTL set_param debug_path=$TMP/$tfile fail_loc=0x8000050e
9083         test_mkdir $DIR/$tdir
9084         # retry in case the open is cached and not released
9085         for (( i = 0; i < 100 && $(ls $TMP/$tfile* | wc -l) == 0; i++ )); do
9086                 echo $i > $DIR/$tdir/$tfile.$i && cat $DIR/$tdir/$tfile.$i
9087                 sleep 0.1
9088         done
9089         ls $TMP/$tfile*
9090         (( $(ls $TMP/$tfile* | wc -l) > 0 )) || error "$TMP/$tfile not dumped"
9091 }
9092 run_test 60f "change debug_path works"
9093
9094 test_60g() {
9095         local pid
9096         local i
9097
9098         test_mkdir -c $MDSCOUNT $DIR/$tdir
9099
9100         (
9101                 local index=0
9102                 while true; do
9103                         $LFS setdirstripe -i $(($index % $MDSCOUNT)) \
9104                                 -c $MDSCOUNT $DIR/$tdir/subdir$index \
9105                                 2>/dev/null
9106                         mkdir $DIR/$tdir/subdir$index 2>/dev/null
9107                         rmdir $DIR/$tdir/subdir$index 2>/dev/null
9108                         index=$((index + 1))
9109                 done
9110         ) &
9111
9112         pid=$!
9113
9114         for i in {0..100}; do
9115                 # define OBD_FAIL_OSD_TXN_START    0x19a
9116                 local index=$((i % MDSCOUNT + 1))
9117
9118                 do_facet mds$index $LCTL set_param fail_loc=0x8000019a \
9119                         > /dev/null
9120                 sleep 0.01
9121         done
9122
9123         kill -9 $pid
9124
9125         for i in $(seq $MDSCOUNT); do
9126                 do_facet mds$i $LCTL set_param fail_loc=0 > /dev/null
9127         done
9128
9129         mkdir $DIR/$tdir/new || error "mkdir failed"
9130         rmdir $DIR/$tdir/new || error "rmdir failed"
9131
9132         do_facet mds1 $LCTL lfsck_start -M $(facet_svc mds1) -A -C \
9133                 -t namespace
9134         for i in $(seq $MDSCOUNT); do
9135                 wait_update_facet mds$i "$LCTL get_param -n \
9136                         mdd.$(facet_svc mds$i).lfsck_namespace |
9137                         awk '/^status/ { print \\\$2 }'" "completed"
9138         done
9139
9140         ls -R $DIR/$tdir
9141         rm -rf $DIR/$tdir || error "rmdir failed"
9142 }
9143 run_test 60g "transaction abort won't cause MDT hung"
9144
9145 test_60h() {
9146         [ $MDS1_VERSION -le $(version_code 2.12.52) ] &&
9147                 skip "Need MDS version at least 2.12.52"
9148         [ $MDSCOUNT -lt 2 ] && skip "Need at least 2 MDTs"
9149
9150         local f
9151
9152         #define OBD_FAIL_MDS_STRIPE_CREATE       0x188
9153         #define OBD_FAIL_MDS_STRIPE_FID          0x189
9154         for fail_loc in 0x80000188 0x80000189; do
9155                 do_facet mds1 "$LCTL set_param fail_loc=$fail_loc"
9156                 $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir-$fail_loc ||
9157                         error "mkdir $dir-$fail_loc failed"
9158                 for i in {0..10}; do
9159                         # create may fail on missing stripe
9160                         echo $i > $DIR/$tdir-$fail_loc/$i
9161                 done
9162                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
9163                         error "getdirstripe $tdir-$fail_loc failed"
9164                 $LFS migrate -m 1 $DIR/$tdir-$fail_loc ||
9165                         error "migrate $tdir-$fail_loc failed"
9166                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
9167                         error "getdirstripe $tdir-$fail_loc failed"
9168                 pushd $DIR/$tdir-$fail_loc
9169                 for f in *; do
9170                         echo $f | cmp $f - || error "$f data mismatch"
9171                 done
9172                 popd
9173                 rm -rf $DIR/$tdir-$fail_loc
9174         done
9175 }
9176 run_test 60h "striped directory with missing stripes can be accessed"
9177
9178 function t60i_load() {
9179         mkdir $DIR/$tdir
9180         #define OBD_FAIL_LLOG_PAUSE_AFTER_PAD               0x131c
9181         $LCTL set_param fail_loc=0x131c fail_val=1
9182         for ((i=0; i<5000; i++)); do
9183                 touch $DIR/$tdir/f$i
9184         done
9185 }
9186
9187 test_60i() {
9188         changelog_register || error "changelog_register failed"
9189         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
9190         changelog_users $SINGLEMDS | grep -q $cl_user ||
9191                 error "User $cl_user not found in changelog_users"
9192         changelog_chmask "ALL"
9193         t60i_load &
9194         local PID=$!
9195         for((i=0; i<100; i++)); do
9196                 changelog_dump >/dev/null ||
9197                         error "can't read changelog"
9198         done
9199         kill $PID
9200         wait $PID
9201         changelog_deregister || error "changelog_deregister failed"
9202         $LCTL set_param fail_loc=0
9203 }
9204 run_test 60i "llog: new record vs reader race"
9205
9206 test_60j() {
9207         (( $MDS1_VERSION >= $(version_code 2.15.50) )) ||
9208                 skip "need MDS version at least 2.15.50"
9209         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
9210         remote_mds_nodsh && skip "remote MDS with nodsh"
9211         [[ "$mds1_FSTYPE" == "ldiskfs" ]] || skip "ldiskfs only test"
9212
9213         changelog_users $SINGLEMDS | grep "^cl" &&
9214                 skip "active changelog user"
9215
9216         local llog_reader=$(do_facet $SINGLEMDS "which llog_reader 2> /dev/null")
9217
9218         [[ -z $(do_facet $SINGLEMDS ls -d $llog_reader 2> /dev/null) ]] &&
9219                 skip_env "missing llog_reader"
9220
9221         mkdir_on_mdt0 $DIR/$tdir
9222
9223         local f=$DIR/$tdir/$tfile
9224         local mdt_dev
9225         local tmpfile
9226         local plain
9227
9228         changelog_register || error "cannot register changelog user"
9229
9230         # set changelog_mask to ALL
9231         changelog_chmask "ALL"
9232         changelog_clear
9233
9234         createmany -o ${f}- 100 || error "createmany failed as $RUNAS_ID"
9235         unlinkmany ${f}- 100 || error "unlinkmany failed"
9236
9237         tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
9238         mdt_dev=$(facet_device $SINGLEMDS)
9239
9240         do_facet $SINGLEMDS sync
9241         plain=$(do_facet $SINGLEMDS "$DEBUGFS -c -R 'dump changelog_catalog \
9242                 $tmpfile' $mdt_dev; $llog_reader $tmpfile" |
9243                 awk '{match($0,"path=([^ ]+)",a)}END{print a[1]}')
9244
9245         stack_trap "do_facet $SINGLEMDS rm -f $tmpfile"
9246
9247         # if $tmpfile is not on EXT3 filesystem for some reason
9248         [[ ${plain:0:1} == 'O' ]] ||
9249                 skip "path $plain is not in 'O/1/d<n>/<n>' format"
9250
9251         size=$(do_facet $SINGLEMDS "$DEBUGFS -c -R 'dump $plain $tmpfile' \
9252                 $mdt_dev; stat -c %s $tmpfile")
9253         echo "Truncate llog from $size to $((size - size % 8192))"
9254         size=$((size - size % 8192))
9255         do_facet $SINGLEMDS $TRUNCATE $tmpfile $size
9256         errs=$(do_facet $SINGLEMDS "$llog_reader $tmpfile" |
9257                 grep -c 'in bitmap only')
9258         (( $errs > 0 )) || error "llog_reader didn't find lost records"
9259
9260         size=$((size - 9000))
9261         echo "Corrupt llog in the middle at $size"
9262         do_facet $SINGLEMDS dd if=/dev/urandom of=$tmpfile bs=1 seek=$size \
9263                 count=333 conv=notrunc
9264         errs=$(do_facet $SINGLEMDS "$llog_reader $tmpfile" |
9265                 grep -c 'next chunk')
9266         (( $errs > 0 )) || error "llog_reader didn't skip bad chunk"
9267 }
9268 run_test 60j "llog_reader reports corruptions"
9269
9270 test_61a() {
9271         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9272
9273         f="$DIR/f61"
9274         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1 || error "dd $f failed"
9275         cancel_lru_locks osc
9276         $MULTIOP $f OSMWUc || error "$MULTIOP $f failed"
9277         sync
9278 }
9279 run_test 61a "mmap() writes don't make sync hang ================"
9280
9281 test_61b() {
9282         mmap_mknod_test $DIR/$tfile || error "mmap_mknod_test failed"
9283 }
9284 run_test 61b "mmap() of unstriped file is successful"
9285
9286 # bug 2319 - oig_wait() interrupted causes crash because of invalid waitq.
9287 # Though this test is irrelevant anymore, it helped to reveal some
9288 # other grant bugs (LU-4482), let's keep it.
9289 test_63a() {   # was test_63
9290         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9291
9292         MAX_DIRTY_MB=$(lctl get_param -n osc.*.max_dirty_mb | head -n 1)
9293
9294         for i in `seq 10` ; do
9295                 dd if=/dev/zero of=$DIR/f63 bs=8k &
9296                 sleep 5
9297                 kill $!
9298                 sleep 1
9299         done
9300
9301         rm -f $DIR/f63 || true
9302 }
9303 run_test 63a "Verify oig_wait interruption does not crash ======="
9304
9305 # bug 2248 - async write errors didn't return to application on sync
9306 # bug 3677 - async write errors left page locked
9307 test_63b() {
9308         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9309
9310         debugsave
9311         lctl set_param debug=-1
9312
9313         # ensure we have a grant to do async writes
9314         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1
9315         rm $DIR/$tfile
9316
9317         sync    # sync lest earlier test intercept the fail_loc
9318
9319         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
9320         lctl set_param fail_loc=0x80000406
9321         $MULTIOP $DIR/$tfile Owy && \
9322                 error "sync didn't return ENOMEM"
9323         sync; sleep 2; sync     # do a real sync this time to flush page
9324         lctl get_param -n llite.*.dump_page_cache | grep locked && \
9325                 error "locked page left in cache after async error" || true
9326         debugrestore
9327 }
9328 run_test 63b "async write errors should be returned to fsync ==="
9329
9330 test_64a () {
9331         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9332
9333         lfs df $DIR
9334         lctl get_param osc.*[oO][sS][cC][_-]*.cur* | grep "=[1-9]"
9335 }
9336 run_test 64a "verify filter grant calculations (in kernel) ====="
9337
9338 test_64b () {
9339         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9340
9341         bash oos.sh $MOUNT || error "oos.sh failed: $?"
9342 }
9343 run_test 64b "check out-of-space detection on client"
9344
9345 test_64c() {
9346         $LCTL set_param osc.*OST0000-osc-[^mM]*.cur_grant_bytes=0
9347 }
9348 run_test 64c "verify grant shrink"
9349
9350 import_param() {
9351         local tgt=$1
9352         local param=$2
9353
9354         $LCTL get_param osc.$tgt.import | awk "/$param/ { print \$2 }"
9355 }
9356
9357 # this does exactly what osc_request.c:osc_announce_cached() does in
9358 # order to calculate max amount of grants to ask from server
9359 want_grant() {
9360         local tgt=$1
9361
9362         local nrpages=$($LCTL get_param -n osc.$tgt.max_pages_per_rpc)
9363         local rpc_in_flight=$($LCTL get_param -n osc.$tgt.max_rpcs_in_flight)
9364
9365         ((rpc_in_flight++));
9366         nrpages=$((nrpages * rpc_in_flight))
9367
9368         local dirty_max_pages=$($LCTL get_param -n osc.$tgt.max_dirty_mb)
9369
9370         dirty_max_pages=$((dirty_max_pages * 1024 * 1024 / PAGE_SIZE))
9371
9372         [[ $dirty_max_pages -gt $nrpages ]] && nrpages=$dirty_max_pages
9373         local undirty=$((nrpages * PAGE_SIZE))
9374
9375         local max_extent_pages
9376         max_extent_pages=$(import_param $tgt grant_max_extent_size)
9377         max_extent_pages=$((max_extent_pages / PAGE_SIZE))
9378         local nrextents=$(((nrpages + max_extent_pages - 1) / max_extent_pages))
9379         local grant_extent_tax
9380         grant_extent_tax=$(import_param $tgt grant_extent_tax)
9381
9382         undirty=$((undirty + nrextents * grant_extent_tax))
9383
9384         echo $undirty
9385 }
9386
9387 # this is size of unit for grant allocation. It should be equal to
9388 # what tgt_grant.c:tgt_grant_chunk() calculates
9389 grant_chunk() {
9390         local tgt=$1
9391         local max_brw_size
9392         local grant_extent_tax
9393
9394         max_brw_size=$(import_param $tgt max_brw_size)
9395
9396         grant_extent_tax=$(import_param $tgt grant_extent_tax)
9397
9398         echo $(((max_brw_size + grant_extent_tax) * 2))
9399 }
9400
9401 test_64d() {
9402         [ $OST1_VERSION -ge $(version_code 2.10.56) ] ||
9403                 skip "OST < 2.10.55 doesn't limit grants enough"
9404
9405         local tgt=$($LCTL dl | awk '/OST0000-osc-[^mM]/ { print $4 }')
9406
9407         [[ "$($LCTL get_param osc.${tgt}.import)" =~ "grant_param" ]] ||
9408                 skip "no grant_param connect flag"
9409
9410         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
9411
9412         $LCTL set_param -n -n debug="$OLDDEBUG" || true
9413         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
9414
9415
9416         local max_cur_granted=$(($(want_grant $tgt) + $(grant_chunk $tgt)))
9417         stack_trap "rm -f $DIR/$tfile && wait_delete_completed" EXIT
9418
9419         $LFS setstripe $DIR/$tfile -i 0 -c 1
9420         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1000 &
9421         ddpid=$!
9422
9423         while kill -0 $ddpid; do
9424                 local cur_grant=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
9425
9426                 if [[ $cur_grant -gt $max_cur_granted ]]; then
9427                         kill $ddpid
9428                         error "cur_grant $cur_grant > $max_cur_granted"
9429                 fi
9430
9431                 sleep 1
9432         done
9433 }
9434 run_test 64d "check grant limit exceed"
9435
9436 check_grants() {
9437         local tgt=$1
9438         local expected=$2
9439         local msg=$3
9440         local cur_grants=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
9441
9442         ((cur_grants == expected)) ||
9443                 error "$msg: grants mismatch: $cur_grants, expected $expected"
9444 }
9445
9446 round_up_p2() {
9447         echo $((($1 + $2 - 1) & ~($2 - 1)))
9448 }
9449
9450 test_64e() {
9451         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9452         [ $OST1_VERSION -ge $(version_code 2.11.56) ] ||
9453                 skip "Need OSS version at least 2.11.56"
9454
9455         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
9456         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
9457         $LCTL set_param debug=+cache
9458
9459         # Remount client to reset grant
9460         remount_client $MOUNT || error "failed to remount client"
9461         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9462
9463         local init_grants=$(import_param $osc_tgt initial_grant)
9464
9465         check_grants $osc_tgt $init_grants "init grants"
9466
9467         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
9468         local max_brw_size=$(import_param $osc_tgt max_brw_size)
9469         local gbs=$(import_param $osc_tgt grant_block_size)
9470
9471         # write random number of bytes from max_brw_size / 4 to max_brw_size
9472         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
9473         # align for direct io
9474         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
9475         # round to grant consumption unit
9476         local wb_round_up=$(round_up_p2 $write_bytes gbs)
9477
9478         local grants=$((wb_round_up + extent_tax))
9479
9480         $LFS setstripe -c 1 -i 0 $DIR/$tfile  || error "lfs setstripe failed"
9481         stack_trap "rm -f $DIR/$tfile"
9482
9483         # define OBD_FAIL_TGT_NO_GRANT 0x725
9484         # make the server not grant more back
9485         do_facet ost1 $LCTL set_param fail_loc=0x725
9486         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct
9487
9488         do_facet ost1 $LCTL set_param fail_loc=0
9489
9490         check_grants $osc_tgt $((init_grants - grants)) "dio w/o grant alloc"
9491
9492         rm -f $DIR/$tfile || error "rm failed"
9493
9494         # Remount client to reset grant
9495         remount_client $MOUNT || error "failed to remount client"
9496         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9497
9498         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
9499
9500         # define OBD_FAIL_TGT_NO_GRANT 0x725
9501         # make the server not grant more back
9502         do_facet ost1 $LCTL set_param fail_loc=0x725
9503         $MULTIOP $DIR/$tfile "oO_WRONLY:w${write_bytes}yc"
9504         do_facet ost1 $LCTL set_param fail_loc=0
9505
9506         check_grants $osc_tgt $((init_grants - grants)) "buf io w/o grant alloc"
9507 }
9508 run_test 64e "check grant consumption (no grant allocation)"
9509
9510 test_64f() {
9511         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9512
9513         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
9514         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
9515         $LCTL set_param debug=+cache
9516
9517         # Remount client to reset grant
9518         remount_client $MOUNT || error "failed to remount client"
9519         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9520
9521         local init_grants=$(import_param $osc_tgt initial_grant)
9522         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
9523         local max_brw_size=$(import_param $osc_tgt max_brw_size)
9524         local gbs=$(import_param $osc_tgt grant_block_size)
9525         local chunk=$(grant_chunk $osc_tgt)
9526
9527         # write random number of bytes from max_brw_size / 4 to max_brw_size
9528         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
9529         # align for direct io
9530         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
9531         # round to grant consumption unit
9532         local wb_round_up=$(round_up_p2 $write_bytes gbs)
9533
9534         local grants=$((wb_round_up + extent_tax))
9535
9536         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
9537         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct ||
9538                 error "error writing to $DIR/$tfile"
9539
9540         check_grants $osc_tgt $((init_grants - grants + chunk)) \
9541                 "direct io with grant allocation"
9542
9543         rm -f $DIR/$tfile || error "rm failed"
9544
9545         # Remount client to reset grant
9546         remount_client $MOUNT || error "failed to remount client"
9547         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9548
9549         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
9550
9551         local cmd="oO_WRONLY:w${write_bytes}_yc"
9552
9553         $MULTIOP $DIR/$tfile $cmd &
9554         MULTIPID=$!
9555         sleep 1
9556
9557         check_grants $osc_tgt $((init_grants - grants)) \
9558                 "buffered io, not write rpc"
9559
9560         kill -USR1 $MULTIPID
9561         wait
9562
9563         check_grants $osc_tgt $((init_grants - grants + chunk)) \
9564                 "buffered io, one RPC"
9565 }
9566 run_test 64f "check grant consumption (with grant allocation)"
9567
9568 test_64g() {
9569         (( $MDS1_VERSION >= $(version_code 2.14.56) )) ||
9570                 skip "Need MDS version at least 2.14.56"
9571
9572         local mdts=$(comma_list $(mdts_nodes))
9573
9574         local old=$($LCTL get_param mdc.$FSNAME-*.grant_shrink_interval |
9575                         tr '\n' ' ')
9576         stack_trap "$LCTL set_param $old"
9577
9578         # generate dirty pages and increase dirty granted on MDT
9579         stack_trap "rm -f $DIR/$tfile-*"
9580         for (( i = 0; i < 10; i++)); do
9581                 $LFS setstripe -E 1M -L mdt $DIR/$tfile-$i ||
9582                         error "can't set stripe"
9583                 dd if=/dev/zero of=$DIR/$tfile-$i bs=128k count=1 ||
9584                         error "can't dd"
9585                 $LFS getstripe $DIR/$tfile-$i | grep -q pattern.*mdt || {
9586                         $LFS getstripe $DIR/$tfile-$i
9587                         error "not DoM file"
9588                 }
9589         done
9590
9591         # flush dirty pages
9592         sync
9593
9594         # wait until grant shrink reset grant dirty on MDTs
9595         for ((i = 0; i < 120; i++)); do
9596                 grant_dirty=$(do_nodes $mdts $LCTL get_param -n  mdt.*.tot_dirty |
9597                         awk '{sum=sum+$1} END {print sum}')
9598                 vm_dirty=$(awk '/Dirty:/{print $2}' /proc/meminfo)
9599                 echo "$grant_dirty grants, $vm_dirty pages"
9600                 (( grant_dirty + vm_dirty == 0 )) && break
9601                 (( i == 3 )) && sync &&
9602                         $LCTL set_param mdc.$FSNAME-*.grant_shrink_interval=5
9603                 sleep 1
9604         done
9605
9606         grant_dirty=$(do_nodes $mdts $LCTL get_param -n  mdt.*.tot_dirty |
9607                 awk '{sum=sum+$1} END {print sum}')
9608         (( grant_dirty == 0 )) || error "$grant_dirty on MDT"
9609 }
9610 run_test 64g "grant shrink on MDT"
9611
9612 test_64h() {
9613         (( $OST1_VERSION >= $(version_code 2.14.56) )) ||
9614                 skip "need OST at least 2.14.56 to avoid grant shrink on read"
9615
9616         local instance=$($LFS getname -i $DIR)
9617         local osc_tgt="$FSNAME-OST0000-osc-$instance"
9618         local num_exps=$(do_facet ost1 \
9619             $LCTL get_param -n obdfilter.*OST0000*.num_exports)
9620         local max_brw_size=$(import_param $osc_tgt max_brw_size)
9621         local avail=$($LCTL get_param -n osc.*OST0000-osc-$instance.kbytesavail)
9622         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
9623
9624         # 10MiB is for file to be written, max_brw_size * 16 *
9625         # num_exps is space reserve so that tgt_grant_shrink() decided
9626         # to not shrink
9627         local expect=$((max_brw_size * 16 * num_exps + 10 * 1048576))
9628         (( avail * 1024 < expect )) &&
9629                 skip "need $expect bytes on ost1, have $(( avail * 1024 )) only"
9630
9631         save_lustre_params client "osc.*OST0000*.grant_shrink" > $p
9632         save_lustre_params client "osc.*OST0000*.grant_shrink_interval" >> $p
9633         stack_trap "restore_lustre_params < $p; rm -f $save" EXIT
9634         $LCTL set_param osc.*OST0000*.grant_shrink=1
9635         $LCTL set_param osc.*OST0000*.grant_shrink_interval=10
9636
9637         $LFS setstripe -c 1 -i 0 $DIR/$tfile
9638         stack_trap "rm -f $DIR/$tfile"
9639         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 oflag=sync
9640
9641         # drop cache so that coming read would do rpc
9642         cancel_lru_locks osc
9643
9644         # shrink interval is set to 10, pause for 7 seconds so that
9645         # grant thread did not wake up yet but coming read entered
9646         # shrink mode for rpc (osc_should_shrink_grant())
9647         sleep 7
9648
9649         declare -a cur_grant_bytes
9650         declare -a tot_granted
9651         cur_grant_bytes[0]=$($LCTL get_param -n osc.*OST0000*.cur_grant_bytes)
9652         tot_granted[0]=$(do_facet ost1 \
9653             $LCTL get_param -n obdfilter.*OST0000*.tot_granted)
9654
9655         dd if=$DIR/$tfile bs=4K count=1 of=/dev/null
9656
9657         cur_grant_bytes[1]=$($LCTL get_param -n osc.*OST0000*.cur_grant_bytes)
9658         tot_granted[1]=$(do_facet ost1 \
9659             $LCTL get_param -n obdfilter.*OST0000*.tot_granted)
9660
9661         # grant change should be equal on both sides
9662         (( cur_grant_bytes[0] - cur_grant_bytes[1] ==
9663                 tot_granted[0] - tot_granted[1])) ||
9664                 error "grant change mismatch, "                                \
9665                         "server: ${tot_granted[0]} to ${tot_granted[1]}, "     \
9666                         "client: ${cur_grant_bytes[0]} to ${cur_grant_bytes[1]}"
9667 }
9668 run_test 64h "grant shrink on read"
9669
9670 test_64i() {
9671         (( $OST1_VERSION >= $(version_code 2.14.56) )) ||
9672                 skip "need OST at least 2.14.56 to avoid grant shrink on replay"
9673
9674         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9675         remote_ost_nodsh && skip "remote OSTs with nodsh"
9676
9677         $LFS setstripe -c 1 -i 0 $DIR/$tfile
9678         stack_trap "rm -f $DIR/$tfile"
9679
9680         dd if=/dev/zero of=$DIR/$tfile bs=1M count=64
9681
9682         # lustre-ffff9fc75e850800 /mnt/lustre -> ffff9fc75e850800
9683         local instance=$($LFS getname -i $DIR)
9684
9685         local osc_tgt="$FSNAME-OST0000-osc-$instance"
9686         local cgb=$($LCTL get_param -n osc.$osc_tgt.cur_grant_bytes)
9687
9688         # shrink grants and simulate rpc loss
9689         #define OBD_FAIL_PTLRPC_DROP_REQ_OPC     0x513
9690         do_facet ost1 "$LCTL set_param fail_loc=0x80000513 fail_val=17"
9691         $LCTL set_param osc.$osc_tgt.cur_grant_bytes=$((cgb/2))B
9692
9693         fail ost1
9694
9695         dd if=/dev/zero of=$DIR/$tfile oflag=append bs=1M count=8 conv=notrunc
9696
9697         local testid=$(echo $TESTNAME | tr '_' ' ')
9698
9699         do_facet ost1 dmesg | tac | sed "/$testid/,$ d" |
9700                 grep "GRANT, real grant" &&
9701                 error "client has more grants then it owns" || true
9702 }
9703 run_test 64i "shrink on reconnect"
9704
9705 # bug 1414 - set/get directories' stripe info
9706 test_65a() {
9707         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9708
9709         test_mkdir $DIR/$tdir
9710         touch $DIR/$tdir/f1
9711         $LVERIFY $DIR/$tdir $DIR/$tdir/f1 || error "lverify failed"
9712 }
9713 run_test 65a "directory with no stripe info"
9714
9715 test_65b() {
9716         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9717
9718         test_mkdir $DIR/$tdir
9719         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9720
9721         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
9722                                                 error "setstripe"
9723         touch $DIR/$tdir/f2
9724         $LVERIFY $DIR/$tdir $DIR/$tdir/f2 || error "lverify failed"
9725 }
9726 run_test 65b "directory setstripe -S stripe_size*2 -i 0 -c 1"
9727
9728 test_65c() {
9729         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9730         [ $OSTCOUNT -lt 2 ] && skip_env "need at least 2 OSTs"
9731
9732         test_mkdir $DIR/$tdir
9733         local stripesize=$($LFS getstripe -S $DIR/$tdir)
9734
9735         $LFS setstripe -S $((stripesize * 4)) -i 1 \
9736                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
9737         touch $DIR/$tdir/f3
9738         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
9739 }
9740 run_test 65c "directory setstripe -S stripe_size*4 -i 1 -c $((OSTCOUNT-1))"
9741
9742 test_65d() {
9743         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9744
9745         test_mkdir $DIR/$tdir
9746         local STRIPECOUNT=$($LFS getstripe -c $DIR/$tdir)
9747         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9748
9749         if [[ $STRIPECOUNT -le 0 ]]; then
9750                 sc=1
9751         elif [[ $STRIPECOUNT -gt $LOV_MAX_STRIPE_COUNT ]]; then
9752                 [[ $OSTCOUNT -gt $LOV_MAX_STRIPE_COUNT ]] &&
9753                         sc=$LOV_MAX_STRIPE_COUNT || sc=$(($OSTCOUNT - 1))
9754         else
9755                 sc=$(($STRIPECOUNT - 1))
9756         fi
9757         $LFS setstripe -S $STRIPESIZE -c $sc $DIR/$tdir || error "setstripe"
9758         touch $DIR/$tdir/f4 $DIR/$tdir/f5
9759         $LVERIFY $DIR/$tdir $DIR/$tdir/f4 $DIR/$tdir/f5 ||
9760                 error "lverify failed"
9761 }
9762 run_test 65d "directory setstripe -S stripe_size -c stripe_count"
9763
9764 test_65e() {
9765         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9766
9767         test_mkdir $DIR/$tdir
9768
9769         $LFS setstripe $DIR/$tdir || error "setstripe"
9770         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
9771                                         error "no stripe info failed"
9772         touch $DIR/$tdir/f6
9773         $LVERIFY $DIR/$tdir $DIR/$tdir/f6 || error "lverify failed"
9774 }
9775 run_test 65e "directory setstripe defaults"
9776
9777 test_65f() {
9778         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9779
9780         test_mkdir $DIR/${tdir}f
9781         $RUNAS $LFS setstripe $DIR/${tdir}f &&
9782                 error "setstripe succeeded" || true
9783 }
9784 run_test 65f "dir setstripe permission (should return error) ==="
9785
9786 test_65g() {
9787         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9788
9789         test_mkdir $DIR/$tdir
9790         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9791
9792         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
9793                 error "setstripe -S failed"
9794         $LFS setstripe -d $DIR/$tdir || error "setstripe -d failed"
9795         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
9796                 error "delete default stripe failed"
9797 }
9798 run_test 65g "directory setstripe -d"
9799
9800 test_65h() {
9801         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9802
9803         test_mkdir $DIR/$tdir
9804         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9805
9806         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
9807                 error "setstripe -S failed"
9808         test_mkdir $DIR/$tdir/dd1
9809         [ $($LFS getstripe -c $DIR/$tdir) = $($LFS getstripe -c $DIR/$tdir/dd1) ] ||
9810                 error "stripe info inherit failed"
9811 }
9812 run_test 65h "directory stripe info inherit ===================="
9813
9814 test_65i() {
9815         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9816
9817         save_layout_restore_at_exit $MOUNT
9818
9819         # bug6367: set non-default striping on root directory
9820         $LFS setstripe -S 65536 -c -1 $MOUNT || error "error setting stripe"
9821
9822         # bug12836: getstripe on -1 default directory striping
9823         $LFS getstripe $MOUNT || error "getstripe $MOUNT failed"
9824
9825         # bug12836: getstripe -v on -1 default directory striping
9826         $LFS getstripe -v $MOUNT || error "getstripe -v $MOUNT failed"
9827
9828         # bug12836: new find on -1 default directory striping
9829         $LFS find -mtime -1 $MOUNT > /dev/null || error "find $MOUNT failed"
9830 }
9831 run_test 65i "various tests to set root directory striping"
9832
9833 test_65j() { # bug6367
9834         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9835
9836         sync; sleep 1
9837
9838         # if we aren't already remounting for each test, do so for this test
9839         if [ "$I_MOUNTED" = "yes" ]; then
9840                 cleanup || error "failed to unmount"
9841                 setup
9842         fi
9843
9844         save_layout_restore_at_exit $MOUNT
9845
9846         $LFS setstripe -d $MOUNT || error "setstripe failed"
9847 }
9848 run_test 65j "set default striping on root directory (bug 6367)="
9849
9850 cleanup_65k() {
9851         rm -rf $DIR/$tdir
9852         wait_delete_completed
9853         do_facet $SINGLEMDS "lctl set_param -n \
9854                 osp.$ost*MDT0000.max_create_count=$max_count"
9855         do_facet $SINGLEMDS "lctl set_param -n \
9856                 osp.$ost*MDT0000.create_count=$count"
9857         do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
9858         echo $INACTIVE_OSC "is Activate"
9859
9860         wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
9861 }
9862
9863 test_65k() { # bug11679
9864         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9865         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9866         remote_mds_nodsh && skip "remote MDS with nodsh"
9867
9868         local disable_precreate=true
9869         [ $MDS1_VERSION -le $(version_code 2.8.54) ] &&
9870                 disable_precreate=false
9871
9872         echo "Check OST status: "
9873         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
9874                 awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
9875
9876         for OSC in $MDS_OSCS; do
9877                 echo $OSC "is active"
9878                 do_facet $SINGLEMDS lctl --device %$OSC activate
9879         done
9880
9881         for INACTIVE_OSC in $MDS_OSCS; do
9882                 local ost=$(osc_to_ost $INACTIVE_OSC)
9883                 local ostnum=$(do_facet $SINGLEMDS lctl get_param -n \
9884                                lov.*md*.target_obd |
9885                                awk -F: /$ost/'{ print $1 }' | head -n 1)
9886
9887                 mkdir -p $DIR/$tdir
9888                 $LFS setstripe -i $ostnum -c 1 $DIR/$tdir
9889                 createmany -o $DIR/$tdir/$tfile.$ostnum. 1000
9890
9891                 echo "Deactivate: " $INACTIVE_OSC
9892                 do_facet $SINGLEMDS lctl --device %$INACTIVE_OSC deactivate
9893
9894                 local count=$(do_facet $SINGLEMDS "lctl get_param -n \
9895                               osp.$ost*MDT0000.create_count")
9896                 local max_count=$(do_facet $SINGLEMDS "lctl get_param -n \
9897                                   osp.$ost*MDT0000.max_create_count")
9898                 $disable_precreate &&
9899                         do_facet $SINGLEMDS "lctl set_param -n \
9900                                 osp.$ost*MDT0000.max_create_count=0"
9901
9902                 for idx in $(seq 0 $((OSTCOUNT - 1))); do
9903                         [ -f $DIR/$tdir/$idx ] && continue
9904                         echo "$LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx"
9905                         $LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx ||
9906                                 { cleanup_65k;
9907                                   error "setstripe $idx should succeed"; }
9908                         rm -f $DIR/$tdir/$idx || error "rm $idx failed"
9909                 done
9910                 unlinkmany $DIR/$tdir/$tfile.$ostnum. 1000
9911                 rmdir $DIR/$tdir
9912
9913                 do_facet $SINGLEMDS "lctl set_param -n \
9914                         osp.$ost*MDT0000.max_create_count=$max_count"
9915                 do_facet $SINGLEMDS "lctl set_param -n \
9916                         osp.$ost*MDT0000.create_count=$count"
9917                 do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
9918                 echo $INACTIVE_OSC "is Activate"
9919
9920                 wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
9921         done
9922 }
9923 run_test 65k "validate manual striping works properly with deactivated OSCs"
9924
9925 test_65l() { # bug 12836
9926         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9927
9928         test_mkdir -p $DIR/$tdir/test_dir
9929         $LFS setstripe -c -1 $DIR/$tdir/test_dir
9930         $LFS find -mtime -1 $DIR/$tdir >/dev/null
9931 }
9932 run_test 65l "lfs find on -1 stripe dir ========================"
9933
9934 test_65m() {
9935         local layout=$(save_layout $MOUNT)
9936         $RUNAS $LFS setstripe -c 2 $MOUNT && {
9937                 restore_layout $MOUNT $layout
9938                 error "setstripe should fail by non-root users"
9939         }
9940         true
9941 }
9942 run_test 65m "normal user can't set filesystem default stripe"
9943
9944 test_65n() {
9945         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
9946         [[ $MDS1_VERSION -ge $(version_code 2.12.50) ]] ||
9947                 skip "Need MDS version at least 2.12.50"
9948         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
9949
9950         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
9951         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
9952         which setfattr > /dev/null 2>&1 || skip_env "no setfattr command"
9953
9954         save_layout_restore_at_exit $MOUNT
9955
9956         # new subdirectory under root directory should not inherit
9957         # the default layout from root
9958         local dir1=$MOUNT/$tdir-1
9959         mkdir $dir1 || error "mkdir $dir1 failed"
9960         ! getfattr -n trusted.lov $dir1 &> /dev/null ||
9961                 error "$dir1 shouldn't have LOV EA"
9962
9963         # delete the default layout on root directory
9964         $LFS setstripe -d $MOUNT || error "delete root default layout failed"
9965
9966         local dir2=$MOUNT/$tdir-2
9967         mkdir $dir2 || error "mkdir $dir2 failed"
9968         ! getfattr -n trusted.lov $dir2 &> /dev/null ||
9969                 error "$dir2 shouldn't have LOV EA"
9970
9971         # set a new striping pattern on root directory
9972         local def_stripe_size=$($LFS getstripe -S $MOUNT)
9973         local new_def_stripe_size=$((def_stripe_size * 2))
9974         $LFS setstripe -S $new_def_stripe_size $MOUNT ||
9975                 error "set stripe size on $MOUNT failed"
9976
9977         # new file created in $dir2 should inherit the new stripe size from
9978         # the filesystem default
9979         local file2=$dir2/$tfile-2
9980         touch $file2 || error "touch $file2 failed"
9981
9982         local file2_stripe_size=$($LFS getstripe -S $file2)
9983         [[ $file2_stripe_size -eq $new_def_stripe_size ]] ||
9984         {
9985                 echo "file2_stripe_size: '$file2_stripe_size'"
9986                 echo "new_def_stripe_size: '$new_def_stripe_size'"
9987                 error "$file2 didn't inherit stripe size $new_def_stripe_size"
9988         }
9989
9990         local dir3=$MOUNT/$tdir-3
9991         mkdir $dir3 || error "mkdir $dir3 failed"
9992         # $dir3 shouldn't have LOV EA, but "lfs getstripe -d $dir3" should show
9993         # the root layout, which is the actual default layout that will be used
9994         # when new files are created in $dir3.
9995         local dir3_layout=$(get_layout_param $dir3)
9996         local root_dir_layout=$(get_layout_param $MOUNT)
9997         [[ "$dir3_layout" = "$root_dir_layout" ]] ||
9998         {
9999                 echo "dir3_layout: '$dir3_layout'"
10000                 echo "root_dir_layout: '$root_dir_layout'"
10001                 error "$dir3 should show the default layout from $MOUNT"
10002         }
10003
10004         # set OST pool on root directory
10005         local pool=$TESTNAME
10006         pool_add $pool || error "add $pool failed"
10007         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
10008                 error "add targets to $pool failed"
10009
10010         $LFS setstripe -p $pool $MOUNT ||
10011                 error "set OST pool on $MOUNT failed"
10012
10013         # new file created in $dir3 should inherit the pool from
10014         # the filesystem default
10015         local file3=$dir3/$tfile-3
10016         touch $file3 || error "touch $file3 failed"
10017
10018         local file3_pool=$($LFS getstripe -p $file3)
10019         [[ "$file3_pool" = "$pool" ]] ||
10020                 error "$file3 ('$file3_pool') didn't inherit OST pool '$pool'"
10021
10022         local dir4=$MOUNT/$tdir-4
10023         mkdir $dir4 || error "mkdir $dir4 failed"
10024         local dir4_layout=$(get_layout_param $dir4)
10025         root_dir_layout=$(get_layout_param $MOUNT)
10026         echo "$LFS getstripe -d $dir4"
10027         $LFS getstripe -d $dir4
10028         echo "$LFS getstripe -d $MOUNT"
10029         $LFS getstripe -d $MOUNT
10030         [[ "$dir4_layout" = "$root_dir_layout" ]] ||
10031         {
10032                 echo "dir4_layout: '$dir4_layout'"
10033                 echo "root_dir_layout: '$root_dir_layout'"
10034                 error "$dir4 should show the default layout from $MOUNT"
10035         }
10036
10037         # new file created in $dir4 should inherit the pool from
10038         # the filesystem default
10039         local file4=$dir4/$tfile-4
10040         touch $file4 || error "touch $file4 failed"
10041
10042         local file4_pool=$($LFS getstripe -p $file4)
10043         [[ "$file4_pool" = "$pool" ]] ||
10044                 error "$file4 ('$file4_pool') didn't inherit OST pool $pool"
10045
10046         # new subdirectory under non-root directory should inherit
10047         # the default layout from its parent directory
10048         $LFS setstripe -S $new_def_stripe_size -p $pool $dir4 ||
10049                 error "set directory layout on $dir4 failed"
10050
10051         local dir5=$dir4/$tdir-5
10052         mkdir $dir5 || error "mkdir $dir5 failed"
10053
10054         dir4_layout=$(get_layout_param $dir4)
10055         local dir5_layout=$(get_layout_param $dir5)
10056         [[ "$dir4_layout" = "$dir5_layout" ]] ||
10057         {
10058                 echo "dir4_layout: '$dir4_layout'"
10059                 echo "dir5_layout: '$dir5_layout'"
10060                 error "$dir5 should inherit the default layout from $dir4"
10061         }
10062
10063         # though subdir under ROOT doesn't inherit default layout, but
10064         # its sub dir/file should be created with default layout.
10065         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
10066         [[ $MDS1_VERSION -ge $(version_code 2.12.59) ]] ||
10067                 skip "Need MDS version at least 2.12.59"
10068
10069         local default_lmv_count=$($LFS getdirstripe -D -c $MOUNT)
10070         local default_lmv_index=$($LFS getdirstripe -D -i $MOUNT)
10071         local default_lmv_hash=$($LFS getdirstripe -D -H $MOUNT)
10072
10073         if [ $default_lmv_hash == "none" ]; then
10074                 stack_trap "$LFS setdirstripe -D -d $MOUNT" EXIT
10075         else
10076                 stack_trap "$LFS setdirstripe -D -i $default_lmv_index \
10077                         -c $default_lmv_count -H $default_lmv_hash $MOUNT" EXIT
10078         fi
10079
10080         $LFS setdirstripe -D -c 2 $MOUNT ||
10081                 error "setdirstripe -D -c 2 failed"
10082         mkdir $MOUNT/$tdir-6 || error "mkdir $tdir-6 failed"
10083         local lmv_count=$($LFS getdirstripe -c $MOUNT/$tdir-6)
10084         [ $lmv_count -eq 2 ] || error "$tdir-6 stripe count $lmv_count"
10085
10086         # $dir4 layout includes pool
10087         $LFS setstripe -S $((new_def_stripe_size * 2)) $dir4
10088         [[ "$pool" = $($LFS getstripe -p -d $dir4) ]] ||
10089                 error "pool lost on setstripe"
10090         $LFS setstripe -E -1 -S $new_def_stripe_size $dir4
10091         [[ "$pool" = $($LFS getstripe -p -d $dir4) ]] ||
10092                 error "pool lost on compound layout setstripe"
10093 }
10094 run_test 65n "don't inherit default layout from root for new subdirectories"
10095
10096 test_65o() {
10097         (( $MDS1_VERSION >= $(version_code 2.14.57) )) ||
10098                 skip "need MDS version at least 2.14.57"
10099
10100         # set OST pool on root directory
10101         local pool=$TESTNAME
10102
10103         pool_add $pool || error "add $pool failed"
10104         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
10105                 error "add targets to $pool failed"
10106
10107         local dir1=$MOUNT/$tdir
10108
10109         mkdir $dir1 || error "mkdir $dir1 failed"
10110
10111         # set a new striping pattern on root directory
10112         local def_stripe_size=$($LFS getstripe -S $MOUNT)
10113
10114         $LFS setstripe -p $pool $dir1 ||
10115                 error "set directory layout on $dir1 failed"
10116
10117         # $dir1 layout includes pool
10118         $LFS setstripe -S $((def_stripe_size * 2)) $dir1
10119         [[ "$pool" = $($LFS getstripe -p -d $dir1) ]] ||
10120                 error "pool lost on setstripe"
10121         $LFS setstripe -E 1M -L mdt -E -1 -c 1 $dir1
10122         $LFS getstripe $dir1
10123         [[ "$pool" = $($LFS getstripe -p -d $dir1) ]] ||
10124                 error "pool lost on compound layout setstripe"
10125
10126         $LFS setdirstripe -i 0 -c 2 $dir1/dir2 ||
10127                 error "setdirstripe failed on sub-dir with inherited pool"
10128         $LFS getstripe $dir1/dir2
10129         [[ "$pool" = $($LFS getstripe -p -d $dir1/dir2) ]] ||
10130                 error "pool lost on compound layout setdirstripe"
10131
10132         $LFS setstripe -E -1 -c 1 $dir1
10133         $LFS getstripe -d $dir1
10134         [[ "$pool" = $($LFS getstripe -p -d $dir1) ]] ||
10135                 error "pool lost on setstripe"
10136 }
10137 run_test 65o "pool inheritance for mdt component"
10138
10139 test_65p () { # LU-16152
10140         local src_dir=$DIR/$tdir/src_dir
10141         local dst_dir=$DIR/$tdir/dst_dir
10142         local yaml_file=$DIR/$tdir/layout.yaml
10143         local border
10144
10145         (( $CLIENT_VERSION >= $(version_code 2.15.51) )) ||
10146                 skip "Need at least version 2.15.51"
10147
10148         test_mkdir -p $src_dir
10149         $LFS setstripe -E 2048M -c 4 -E EOF -c 8 $src_dir ||
10150                 error "failed to setstripe"
10151         $LFS getstripe --yaml -d $src_dir > $yaml_file ||
10152                 error "failed to getstripe"
10153
10154         test_mkdir -p $dst_dir
10155         $LFS setstripe --yaml $yaml_file $dst_dir ||
10156                 error "failed to setstripe with yaml file"
10157         border=$($LFS getstripe -d $dst_dir |
10158                 awk '/lcme_extent.e_end:/ { print $2; exit; }') ||
10159                 error "failed to getstripe"
10160
10161         # 2048M is 0x80000000, or 2147483648
10162         (( $border == 2147483648 )) ||
10163                 error "failed to handle huge number in yaml layout"
10164 }
10165 run_test 65p "setstripe with yaml file and huge number"
10166
10167 # bug 2543 - update blocks count on client
10168 test_66() {
10169         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10170
10171         local COUNT=${COUNT:-8}
10172         dd if=/dev/zero of=$DIR/f66 bs=1k count=$COUNT
10173         sync; sync_all_data; sync; sync_all_data
10174         cancel_lru_locks osc
10175         local BLOCKS=$(ls -s --block-size=1k $DIR/f66 | awk '{ print $1 }')
10176         (( BLOCKS >= COUNT )) || error "$DIR/f66 blocks $BLOCKS < $COUNT"
10177 }
10178 run_test 66 "update inode blocks count on client ==============="
10179
10180 meminfo() {
10181         awk '($1 == "'$1':") { print $2 }' /proc/meminfo
10182 }
10183
10184 swap_used() {
10185         swapon -s | awk '($1 == "'$1'") { print $4 }'
10186 }
10187
10188 # bug5265, obdfilter oa2dentry return -ENOENT
10189 # #define OBD_FAIL_SRV_ENOENT 0x217
10190 test_69() {
10191         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10192         remote_ost_nodsh && skip "remote OST with nodsh"
10193
10194         f="$DIR/$tfile"
10195         $LFS setstripe -c 1 -i 0 $f
10196         stack_trap "rm -f $f ${f}.2"
10197
10198         $DIRECTIO write ${f}.2 0 1 || error "directio write error"
10199
10200         do_facet ost1 lctl set_param fail_loc=0x217
10201         $TRUNCATE $f 1 # vmtruncate() will ignore truncate() error.
10202         $DIRECTIO write $f 0 2 && error "write succeeded, expect -ENOENT"
10203
10204         do_facet ost1 lctl set_param fail_loc=0
10205         $DIRECTIO write $f 0 2 || error "write error"
10206
10207         cancel_lru_locks osc
10208         $DIRECTIO read $f 0 1 || error "read error"
10209
10210         do_facet ost1 lctl set_param fail_loc=0x217
10211         $DIRECTIO read $f 1 1 && error "read succeeded, expect -ENOENT"
10212
10213         do_facet ost1 lctl set_param fail_loc=0
10214 }
10215 run_test 69 "verify oa2dentry return -ENOENT doesn't LBUG ======"
10216
10217 test_71() {
10218         test_mkdir $DIR/$tdir
10219         $LFS setdirstripe -D -c$MDSCOUNT $DIR/$tdir
10220         bash rundbench -C -D $DIR/$tdir 2 || error "dbench failed!"
10221 }
10222 run_test 71 "Running dbench on lustre (don't segment fault) ===="
10223
10224 test_72a() { # bug 5695 - Test that on 2.6 remove_suid works properly
10225         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10226         [ "$RUNAS_ID" = "$UID" ] &&
10227                 skip_env "RUNAS_ID = UID = $UID -- skipping"
10228         # Check that testing environment is properly set up. Skip if not
10229         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_GID $RUNAS ||
10230                 skip_env "User $RUNAS_ID does not exist - skipping"
10231
10232         touch $DIR/$tfile
10233         chmod 777 $DIR/$tfile
10234         chmod ug+s $DIR/$tfile
10235         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=512 count=1 ||
10236                 error "$RUNAS dd $DIR/$tfile failed"
10237         # See if we are still setuid/sgid
10238         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
10239                 error "S/gid is not dropped on write"
10240         # Now test that MDS is updated too
10241         cancel_lru_locks mdc
10242         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
10243                 error "S/gid is not dropped on MDS"
10244         rm -f $DIR/$tfile
10245 }
10246 run_test 72a "Test that remove suid works properly (bug5695) ===="
10247
10248 test_72b() { # bug 24226 -- keep mode setting when size is not changing
10249         local perm
10250
10251         [ "$RUNAS_ID" = "$UID" ] &&
10252                 skip_env "RUNAS_ID = UID = $UID -- skipping"
10253         [ "$RUNAS_ID" -eq 0 ] &&
10254                 skip_env "RUNAS_ID = 0 -- skipping"
10255         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10256         # Check that testing environment is properly set up. Skip if not
10257         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_ID $RUNAS ||
10258                 skip_env "User $RUNAS_ID does not exist - skipping"
10259
10260         touch $DIR/${tfile}-f{g,u}
10261         test_mkdir $DIR/${tfile}-dg
10262         test_mkdir $DIR/${tfile}-du
10263         chmod 770 $DIR/${tfile}-{f,d}{g,u}
10264         chmod g+s $DIR/${tfile}-{f,d}g
10265         chmod u+s $DIR/${tfile}-{f,d}u
10266         for perm in 777 2777 4777; do
10267                 $RUNAS chmod $perm $DIR/${tfile}-fg && error "S/gid file allowed improper chmod to $perm"
10268                 $RUNAS chmod $perm $DIR/${tfile}-fu && error "S/uid file allowed improper chmod to $perm"
10269                 $RUNAS chmod $perm $DIR/${tfile}-dg && error "S/gid dir allowed improper chmod to $perm"
10270                 $RUNAS chmod $perm $DIR/${tfile}-du && error "S/uid dir allowed improper chmod to $perm"
10271         done
10272         true
10273 }
10274 run_test 72b "Test that we keep mode setting if without file data changed (bug 24226)"
10275
10276 # bug 3462 - multiple simultaneous MDC requests
10277 test_73() {
10278         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10279
10280         test_mkdir $DIR/d73-1
10281         test_mkdir $DIR/d73-2
10282         multiop_bg_pause $DIR/d73-1/f73-1 O_c || return 1
10283         pid1=$!
10284
10285         lctl set_param fail_loc=0x80000129
10286         $MULTIOP $DIR/d73-1/f73-2 Oc &
10287         sleep 1
10288         lctl set_param fail_loc=0
10289
10290         $MULTIOP $DIR/d73-2/f73-3 Oc &
10291         pid3=$!
10292
10293         kill -USR1 $pid1
10294         wait $pid1 || return 1
10295
10296         sleep 25
10297
10298         $CHECKSTAT -t file $DIR/d73-1/f73-1 || return 4
10299         $CHECKSTAT -t file $DIR/d73-1/f73-2 || return 5
10300         $CHECKSTAT -t file $DIR/d73-2/f73-3 || return 6
10301
10302         rm -rf $DIR/d73-*
10303 }
10304 run_test 73 "multiple MDC requests (should not deadlock)"
10305
10306 test_74a() { # bug 6149, 6184
10307         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10308
10309         touch $DIR/f74a
10310         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
10311         #
10312         # very important to OR with CFS_FAIL_ONCE (0x80000000) -- otherwise it
10313         # will spin in a tight reconnection loop
10314         $LCTL set_param fail_loc=0x8000030e
10315         # get any lock that won't be difficult - lookup works.
10316         ls $DIR/f74a
10317         $LCTL set_param fail_loc=0
10318         rm -f $DIR/f74a
10319         true
10320 }
10321 run_test 74a "ldlm_enqueue freed-export error path, ls (shouldn't LBUG)"
10322
10323 test_74b() { # bug 13310
10324         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10325
10326         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
10327         #
10328         # very important to OR with CFS_FAIL_ONCE (0x80000000) -- otherwise it
10329         # will spin in a tight reconnection loop
10330         $LCTL set_param fail_loc=0x8000030e
10331         # get a "difficult" lock
10332         touch $DIR/f74b
10333         $LCTL set_param fail_loc=0
10334         rm -f $DIR/f74b
10335         true
10336 }
10337 run_test 74b "ldlm_enqueue freed-export error path, touch (shouldn't LBUG)"
10338
10339 test_74c() {
10340         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10341
10342         #define OBD_FAIL_LDLM_NEW_LOCK
10343         $LCTL set_param fail_loc=0x319
10344         touch $DIR/$tfile && error "touch successful"
10345         $LCTL set_param fail_loc=0
10346         true
10347 }
10348 run_test 74c "ldlm_lock_create error path, (shouldn't LBUG)"
10349
10350 slab_lic=/sys/kernel/slab/lustre_inode_cache
10351 num_objects() {
10352         [ -f $slab_lic/shrink ] && echo 1 > $slab_lic/shrink
10353         [ -f $slab_lic/objects ] && awk '{ print $1 }' $slab_lic/objects ||
10354                 awk '/lustre_inode_cache/ { print $2; exit }' /proc/slabinfo
10355 }
10356
10357 test_76a() { # Now for b=20433, added originally in b=1443
10358         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10359
10360         cancel_lru_locks osc
10361         # there may be some slab objects cached per core
10362         local cpus=$(getconf _NPROCESSORS_ONLN 2>/dev/null)
10363         local before=$(num_objects)
10364         local count=$((512 * cpus))
10365         [ "$SLOW" = "no" ] && count=$((128 * cpus))
10366         local margin=$((count / 10))
10367         if [[ -f $slab_lic/aliases ]]; then
10368                 local aliases=$(cat $slab_lic/aliases)
10369                 (( aliases > 0 )) && margin=$((margin * aliases))
10370         fi
10371
10372         echo "before slab objects: $before"
10373         for i in $(seq $count); do
10374                 touch $DIR/$tfile
10375                 rm -f $DIR/$tfile
10376         done
10377         cancel_lru_locks osc
10378         local after=$(num_objects)
10379         echo "created: $count, after slab objects: $after"
10380         # shared slab counts are not very accurate, allow significant margin
10381         # the main goal is that the cache growth is not permanently > $count
10382         while (( after > before + margin )); do
10383                 sleep 1
10384                 after=$(num_objects)
10385                 wait=$((wait + 1))
10386                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
10387                 if (( wait > 60 )); then
10388                         error "inode slab grew from $before+$margin to $after"
10389                 fi
10390         done
10391 }
10392 run_test 76a "confirm clients recycle inodes properly ===="
10393
10394 test_76b() {
10395         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10396         [ $CLIENT_VERSION -ge $(version_code 2.13.55) ] || skip "not supported"
10397
10398         local count=512
10399         local before=$(num_objects)
10400
10401         for i in $(seq $count); do
10402                 mkdir $DIR/$tdir
10403                 rmdir $DIR/$tdir
10404         done
10405
10406         local after=$(num_objects)
10407         local wait=0
10408
10409         while (( after > before )); do
10410                 sleep 1
10411                 after=$(num_objects)
10412                 wait=$((wait + 1))
10413                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
10414                 if (( wait > 60 )); then
10415                         error "inode slab grew from $before to $after"
10416                 fi
10417         done
10418
10419         echo "slab objects before: $before, after: $after"
10420 }
10421 run_test 76b "confirm clients recycle directory inodes properly ===="
10422
10423 export ORIG_CSUM=""
10424 set_checksums()
10425 {
10426         # Note: in sptlrpc modes which enable its own bulk checksum, the
10427         # original crc32_le bulk checksum will be automatically disabled,
10428         # and the OBD_FAIL_OSC_CHECKSUM_SEND/OBD_FAIL_OSC_CHECKSUM_RECEIVE
10429         # will be checked by sptlrpc code against sptlrpc bulk checksum.
10430         # In this case set_checksums() will not be no-op, because sptlrpc
10431         # bulk checksum will be enabled all through the test.
10432
10433         [ "$ORIG_CSUM" ] || ORIG_CSUM=`lctl get_param -n osc.*.checksums | head -n1`
10434         lctl set_param -n osc.*.checksums $1
10435         return 0
10436 }
10437
10438 export ORIG_CSUM_TYPE="`lctl get_param -n osc.*osc-[^mM]*.checksum_type |
10439                         sed 's/.*\[\(.*\)\].*/\1/g' | head -n1`"
10440 CKSUM_TYPES=${CKSUM_TYPES:-$(lctl get_param -n osc.*osc-[^mM]*.checksum_type |
10441                              tr -d [] | head -n1)}
10442 set_checksum_type()
10443 {
10444         lctl set_param -n osc.*osc-[^mM]*.checksum_type $1
10445         rc=$?
10446         log "set checksum type to $1, rc = $rc"
10447         return $rc
10448 }
10449
10450 get_osc_checksum_type()
10451 {
10452         # arugment 1: OST name, like OST0000
10453         ost=$1
10454         checksum_type=$(lctl get_param -n osc.*${ost}-osc-[^mM]*.checksum_type |
10455                         sed 's/.*\[\(.*\)\].*/\1/g')
10456         rc=$?
10457         [ $rc -ne 0 ] && error "failed to get checksum type of $ost, rc = $rc, output = $checksum_type"
10458         echo $checksum_type
10459 }
10460
10461 F77_TMP=$TMP/f77-temp
10462 F77SZ=8
10463 setup_f77() {
10464         dd if=/dev/urandom of=$F77_TMP bs=1M count=$F77SZ || \
10465                 error "error writing to $F77_TMP"
10466 }
10467
10468 test_77a() { # bug 10889
10469         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10470         $GSS && skip_env "could not run with gss"
10471
10472         [ ! -f $F77_TMP ] && setup_f77
10473         set_checksums 1
10474         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ || error "dd error"
10475         set_checksums 0
10476         rm -f $DIR/$tfile
10477 }
10478 run_test 77a "normal checksum read/write operation"
10479
10480 test_77b() { # bug 10889
10481         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10482         $GSS && skip_env "could not run with gss"
10483
10484         [ ! -f $F77_TMP ] && setup_f77
10485         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
10486         $LCTL set_param fail_loc=0x80000409
10487         set_checksums 1
10488
10489         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
10490                 error "dd error: $?"
10491         $LCTL set_param fail_loc=0
10492
10493         for algo in $CKSUM_TYPES; do
10494                 cancel_lru_locks osc
10495                 set_checksum_type $algo
10496                 #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
10497                 $LCTL set_param fail_loc=0x80000408
10498                 cmp $F77_TMP $DIR/$tfile || error "file compare failed"
10499                 $LCTL set_param fail_loc=0
10500         done
10501         set_checksums 0
10502         set_checksum_type $ORIG_CSUM_TYPE
10503         rm -f $DIR/$tfile
10504 }
10505 run_test 77b "checksum error on client write, read"
10506
10507 cleanup_77c() {
10508         trap 0
10509         set_checksums 0
10510         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=0
10511         $check_ost &&
10512                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=0
10513         [ -n "$osc_file_prefix" ] && rm -f ${osc_file_prefix}*
10514         $check_ost && [ -n "$ost_file_prefix" ] &&
10515                 do_facet ost1 rm -f ${ost_file_prefix}\*
10516 }
10517
10518 test_77c() {
10519         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10520         $GSS && skip_env "could not run with gss"
10521         remote_ost_nodsh && skip "remote OST with nodsh"
10522
10523         local bad1
10524         local osc_file_prefix
10525         local osc_file
10526         local check_ost=false
10527         local ost_file_prefix
10528         local ost_file
10529         local orig_cksum
10530         local dump_cksum
10531         local fid
10532
10533         # ensure corruption will occur on first OSS/OST
10534         $LFS setstripe -i 0 $DIR/$tfile
10535
10536         [ ! -f $F77_TMP ] && setup_f77
10537         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
10538                 error "dd write error: $?"
10539         fid=$($LFS path2fid $DIR/$tfile)
10540
10541         if [ $OST1_VERSION -ge $(version_code 2.9.57) ]
10542         then
10543                 check_ost=true
10544                 ost_file_prefix=$(do_facet ost1 $LCTL get_param -n debug_path)
10545                 ost_file_prefix=${ost_file_prefix}-checksum_dump-ost-\\${fid}
10546         else
10547                 echo "OSS do not support bulk pages dump upon error"
10548         fi
10549
10550         osc_file_prefix=$($LCTL get_param -n debug_path)
10551         osc_file_prefix=${osc_file_prefix}-checksum_dump-osc-\\${fid}
10552
10553         trap cleanup_77c EXIT
10554
10555         set_checksums 1
10556         # enable bulk pages dump upon error on Client
10557         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=1
10558         # enable bulk pages dump upon error on OSS
10559         $check_ost &&
10560                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=1
10561
10562         # flush Client cache to allow next read to reach OSS
10563         cancel_lru_locks osc
10564
10565         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE       0x408
10566         $LCTL set_param fail_loc=0x80000408
10567         dd if=$DIR/$tfile of=/dev/null bs=1M || error "dd read error: $?"
10568         $LCTL set_param fail_loc=0
10569
10570         rm -f $DIR/$tfile
10571
10572         # check cksum dump on Client
10573         osc_file=$(ls ${osc_file_prefix}*)
10574         [ -n "$osc_file" ] || error "no checksum dump file on Client"
10575         # OBD_FAIL_OSC_CHECKSUM_RECEIVE corrupts with "bad1" at start of file
10576         bad1=$(dd if=$osc_file bs=1 count=4 2>/dev/null) || error "dd error: $?"
10577         [ $bad1 == "bad1" ] || error "unexpected corrupt pattern"
10578         orig_cksum=$(dd if=$F77_TMP bs=1 skip=4 count=1048572 2>/dev/null |
10579                      cksum)
10580         dump_cksum=$(dd if=$osc_file bs=1 skip=4 2>/dev/null | cksum)
10581         [[ "$orig_cksum" == "$dump_cksum" ]] ||
10582                 error "dump content does not match on Client"
10583
10584         $check_ost || skip "No need to check cksum dump on OSS"
10585
10586         # check cksum dump on OSS
10587         ost_file=$(do_facet ost1 ls ${ost_file_prefix}\*)
10588         [ -n "$ost_file" ] || error "no checksum dump file on OSS"
10589         orig_cksum=$(dd if=$F77_TMP bs=1048576 count=1 2>/dev/null | cksum)
10590         dump_cksum=$(do_facet ost1 dd if=$ost_file 2>/dev/null \| cksum)
10591         [[ "$orig_cksum" == "$dump_cksum" ]] ||
10592                 error "dump content does not match on OSS"
10593
10594         cleanup_77c
10595 }
10596 run_test 77c "checksum error on client read with debug"
10597
10598 test_77d() { # bug 10889
10599         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10600         $GSS && skip_env "could not run with gss"
10601
10602         stack_trap "rm -f $DIR/$tfile"
10603         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
10604         $LCTL set_param fail_loc=0x80000409
10605         set_checksums 1
10606         $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
10607                 error "direct write: rc=$?"
10608         $LCTL set_param fail_loc=0
10609         set_checksums 0
10610
10611         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
10612         $LCTL set_param fail_loc=0x80000408
10613         set_checksums 1
10614         cancel_lru_locks osc
10615         $DIRECTIO read $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
10616                 error "direct read: rc=$?"
10617         $LCTL set_param fail_loc=0
10618         set_checksums 0
10619 }
10620 run_test 77d "checksum error on OST direct write, read"
10621
10622 test_77f() { # bug 10889
10623         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10624         $GSS && skip_env "could not run with gss"
10625
10626         set_checksums 1
10627         stack_trap "rm -f $DIR/$tfile"
10628         for algo in $CKSUM_TYPES; do
10629                 cancel_lru_locks osc
10630                 set_checksum_type $algo
10631                 #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
10632                 $LCTL set_param fail_loc=0x409
10633                 $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) &&
10634                         error "direct write succeeded"
10635                 $LCTL set_param fail_loc=0
10636         done
10637         set_checksum_type $ORIG_CSUM_TYPE
10638         set_checksums 0
10639 }
10640 run_test 77f "repeat checksum error on write (expect error)"
10641
10642 test_77g() { # bug 10889
10643         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10644         $GSS && skip_env "could not run with gss"
10645         remote_ost_nodsh && skip "remote OST with nodsh"
10646
10647         [ ! -f $F77_TMP ] && setup_f77
10648
10649         local file=$DIR/$tfile
10650         stack_trap "rm -f $file" EXIT
10651
10652         $LFS setstripe -c 1 -i 0 $file
10653         #define OBD_FAIL_OST_CHECKSUM_RECEIVE       0x21a
10654         do_facet ost1 lctl set_param fail_loc=0x8000021a
10655         set_checksums 1
10656         dd if=$F77_TMP of=$file bs=1M count=$F77SZ ||
10657                 error "write error: rc=$?"
10658         do_facet ost1 lctl set_param fail_loc=0
10659         set_checksums 0
10660
10661         cancel_lru_locks osc
10662         #define OBD_FAIL_OST_CHECKSUM_SEND          0x21b
10663         do_facet ost1 lctl set_param fail_loc=0x8000021b
10664         set_checksums 1
10665         cmp $F77_TMP $file || error "file compare failed"
10666         do_facet ost1 lctl set_param fail_loc=0
10667         set_checksums 0
10668 }
10669 run_test 77g "checksum error on OST write, read"
10670
10671 test_77k() { # LU-10906
10672         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10673         $GSS && skip_env "could not run with gss"
10674
10675         local cksum_param="osc.$FSNAME*.checksums"
10676         local get_checksum="$LCTL get_param -n $cksum_param | head -n1"
10677         local checksum
10678         local i
10679
10680         [ "$ORIG_CSUM" ] || ORIG_CSUM=$(eval $get_checksum)
10681         stack_trap "wait_update $HOSTNAME '$get_checksum' $ORIG_CSUM || true"
10682         stack_trap "do_facet mgs $LCTL set_param -P $cksum_param=$ORIG_CSUM"
10683
10684         for i in 0 1; do
10685                 do_facet mgs $LCTL set_param -P $cksum_param=$i ||
10686                         error "failed to set checksum=$i on MGS"
10687                 wait_update $HOSTNAME "$get_checksum" $i
10688                 #remount
10689                 echo "remount client, checksum should be $i"
10690                 remount_client $MOUNT || error "failed to remount client"
10691                 checksum=$(eval $get_checksum)
10692                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
10693         done
10694         # remove persistent param to avoid races with checksum mountopt below
10695         do_facet mgs $LCTL set_param -P -d $cksum_param ||
10696                 error "failed to delete checksum on MGS"
10697
10698         for opt in "checksum" "nochecksum"; do
10699                 #remount with mount option
10700                 echo "remount client with option $opt, checksum should be $i"
10701                 umount_client $MOUNT || error "failed to umount client"
10702                 mount_client $MOUNT "$MOUNT_OPTS,$opt" ||
10703                         error "failed to mount client with option '$opt'"
10704                 checksum=$(eval $get_checksum)
10705                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
10706                 i=$((i - 1))
10707         done
10708
10709         remount_client $MOUNT || error "failed to remount client"
10710 }
10711 run_test 77k "enable/disable checksum correctly"
10712
10713 test_77l() {
10714         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10715         $GSS && skip_env "could not run with gss"
10716
10717         set_checksums 1
10718         stack_trap "set_checksums $ORIG_CSUM" EXIT
10719         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
10720
10721         set_checksum_type invalid && error "unexpected success of invalid checksum type"
10722
10723         $LFS setstripe -c 1 -i 0 $DIR/$tfile
10724         for algo in $CKSUM_TYPES; do
10725                 set_checksum_type $algo || error "fail to set checksum type $algo"
10726                 osc_algo=$(get_osc_checksum_type OST0000)
10727                 [ "$osc_algo" != "$algo" ] && error "checksum type is $osc_algo after setting it to $algo"
10728
10729                 # no locks, no reqs to let the connection idle
10730                 cancel_lru_locks osc
10731                 lru_resize_disable osc
10732                 wait_osc_import_state client ost1 IDLE
10733
10734                 # ensure ost1 is connected
10735                 stat $DIR/$tfile >/dev/null || error "can't stat"
10736                 wait_osc_import_state client ost1 FULL
10737
10738                 osc_algo=$(get_osc_checksum_type OST0000)
10739                 [ "$osc_algo" != "$algo" ] && error "checksum type changed from $algo to $osc_algo after reconnection"
10740         done
10741         return 0
10742 }
10743 run_test 77l "preferred checksum type is remembered after reconnected"
10744
10745 [ "$ORIG_CSUM" ] && set_checksums $ORIG_CSUM || true
10746 rm -f $F77_TMP
10747 unset F77_TMP
10748
10749 test_77m() {
10750         (( $CLIENT_VERSION >= $(version_code 2.14.52) )) ||
10751                 skip "Need at least version 2.14.52"
10752         local param=checksum_speed
10753
10754         $LCTL get_param $param || error "reading $param failed"
10755
10756         csum_speeds=$($LCTL get_param -n $param)
10757
10758         [[ "$csum_speeds" =~ "adler32" && "$csum_speeds" =~ "crc32" ]] ||
10759                 error "known checksum types are missing"
10760 }
10761 run_test 77m "Verify checksum_speed is correctly read"
10762
10763 check_filefrag_77n() {
10764         local nr_ext=0
10765         local starts=()
10766         local ends=()
10767
10768         while read extidx a b start end rest; do
10769                 if [[ "${extidx}" =~ ^[0-9]+: ]]; then
10770                         nr_ext=$(( $nr_ext + 1 ))
10771                         starts+=( ${start%..} )
10772                         ends+=( ${end%:} )
10773                 fi
10774         done < <( filefrag -sv $1 )
10775
10776         [[ $nr_ext -eq 2 ]] && [[ "${starts[-1]}" == $(( ${ends[0]} + 1 )) ]] && return 0
10777         return 1
10778 }
10779
10780 test_77n() {
10781         [[ "$CKSUM_TYPES" =~ t10 ]] || skip "no T10 checksum support on osc"
10782
10783         touch $DIR/$tfile
10784         $TRUNCATE $DIR/$tfile 0
10785         dd if=/dev/urandom of=$DIR/$tfile bs=4k conv=notrunc count=1 seek=0
10786         dd if=/dev/urandom of=$DIR/$tfile bs=4k conv=notrunc count=1 seek=2
10787         check_filefrag_77n $DIR/$tfile ||
10788                 skip "$tfile blocks not contiguous around hole"
10789
10790         set_checksums 1
10791         stack_trap "set_checksums $ORIG_CSUM" EXIT
10792         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
10793         stack_trap "rm -f $DIR/$tfile"
10794
10795         for algo in $CKSUM_TYPES; do
10796                 if [[ "$algo" =~ ^t10 ]]; then
10797                         set_checksum_type $algo ||
10798                                 error "fail to set checksum type $algo"
10799                         dd if=$DIR/$tfile of=/dev/null bs=12k count=1 iflag=direct ||
10800                                 error "fail to read $tfile with $algo"
10801                 fi
10802         done
10803         rm -f $DIR/$tfile
10804         return 0
10805 }
10806 run_test 77n "Verify read from a hole inside contiguous blocks with T10PI"
10807
10808 test_77o() {
10809         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
10810                 skip "Need MDS version at least 2.14.55"
10811         (( $OST1_VERSION >= $(version_code 2.14.55) )) ||
10812                 skip "Need OST version at least 2.14.55"
10813         local ofd=obdfilter
10814         local mdt=mdt
10815
10816         # print OST checksum_type
10817         echo "$ofd.$FSNAME-*.checksum_type:"
10818         do_nodes $(comma_list $(osts_nodes)) \
10819                 $LCTL get_param -n $ofd.$FSNAME-*.checksum_type
10820
10821         # print MDT checksum_type
10822         echo "$mdt.$FSNAME-*.checksum_type:"
10823         do_nodes $(comma_list $(mdts_nodes)) \
10824                 $LCTL get_param -n $mdt.$FSNAME-*.checksum_type
10825
10826         local o_count=$(do_nodes $(comma_list $(osts_nodes)) \
10827                    $LCTL get_param -n $ofd.$FSNAME-*.checksum_type | wc -l)
10828
10829         (( $o_count == $OSTCOUNT )) ||
10830                 error "found $o_count checksums, not \$MDSCOUNT=$OSTCOUNT"
10831
10832         local m_count=$(do_nodes $(comma_list $(mdts_nodes)) \
10833                    $LCTL get_param -n $mdt.$FSNAME-*.checksum_type | wc -l)
10834
10835         (( $m_count == $MDSCOUNT )) ||
10836                 error "found $m_count checksums, not \$MDSCOUNT=$MDSCOUNT"
10837 }
10838 run_test 77o "Verify checksum_type for server (mdt and ofd(obdfilter))"
10839
10840 cleanup_test_78() {
10841         trap 0
10842         rm -f $DIR/$tfile
10843 }
10844
10845 test_78() { # bug 10901
10846         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10847         remote_ost || skip_env "local OST"
10848
10849         NSEQ=5
10850         F78SIZE=$(($(awk '/MemFree:/ { print $2 }' /proc/meminfo) / 1024))
10851         echo "MemFree: $F78SIZE, Max file size: $MAXFREE"
10852         MEMTOTAL=$(($(awk '/MemTotal:/ { print $2 }' /proc/meminfo) / 1024))
10853         echo "MemTotal: $MEMTOTAL"
10854
10855         # reserve 256MB of memory for the kernel and other running processes,
10856         # and then take 1/2 of the remaining memory for the read/write buffers.
10857         if [ $MEMTOTAL -gt 512 ] ;then
10858                 MEMTOTAL=$(((MEMTOTAL - 256 ) / 2))
10859         else
10860                 # for those poor memory-starved high-end clusters...
10861                 MEMTOTAL=$((MEMTOTAL / 2))
10862         fi
10863         echo "Mem to use for directio: $MEMTOTAL"
10864
10865         [[ $F78SIZE -gt $MEMTOTAL ]] && F78SIZE=$MEMTOTAL
10866         [[ $F78SIZE -gt 512 ]] && F78SIZE=512
10867         [[ $F78SIZE -gt $((MAXFREE / 1024)) ]] && F78SIZE=$((MAXFREE / 1024))
10868         SMALLESTOST=$($LFS df $DIR | grep OST | awk '{ print $4 }' | sort -n |
10869                 head -n1)
10870         echo "Smallest OST: $SMALLESTOST"
10871         [[ $SMALLESTOST -lt 10240 ]] &&
10872                 skip "too small OSTSIZE, useless to run large O_DIRECT test"
10873
10874         trap cleanup_test_78 EXIT
10875
10876         [[ $F78SIZE -gt $((SMALLESTOST * $OSTCOUNT / 1024 - 80)) ]] &&
10877                 F78SIZE=$((SMALLESTOST * $OSTCOUNT / 1024 - 80))
10878
10879         [ "$SLOW" = "no" ] && NSEQ=1 && [ $F78SIZE -gt 32 ] && F78SIZE=32
10880         echo "File size: $F78SIZE"
10881         $LFS setstripe -c $OSTCOUNT $DIR/$tfile || error "setstripe failed"
10882         for i in $(seq 1 $NSEQ); do
10883                 FSIZE=$(($F78SIZE / ($NSEQ - $i + 1)))
10884                 echo directIO rdwr round $i of $NSEQ
10885                 $DIRECTIO rdwr $DIR/$tfile 0 $FSIZE 1048576||error "rdwr failed"
10886         done
10887
10888         cleanup_test_78
10889 }
10890 run_test 78 "handle large O_DIRECT writes correctly ============"
10891
10892 test_79() { # bug 12743
10893         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10894
10895         wait_delete_completed
10896
10897         BKTOTAL=$(calc_osc_kbytes kbytestotal)
10898         BKFREE=$(calc_osc_kbytes kbytesfree)
10899         BKAVAIL=$(calc_osc_kbytes kbytesavail)
10900
10901         STRING=`df -P $MOUNT | tail -n 1 | awk '{print $2","$3","$4}'`
10902         DFTOTAL=`echo $STRING | cut -d, -f1`
10903         DFUSED=`echo $STRING  | cut -d, -f2`
10904         DFAVAIL=`echo $STRING | cut -d, -f3`
10905         DFFREE=$(($DFTOTAL - $DFUSED))
10906
10907         ALLOWANCE=$((64 * $OSTCOUNT))
10908
10909         if [ $DFTOTAL -lt $(($BKTOTAL - $ALLOWANCE)) ] ||
10910            [ $DFTOTAL -gt $(($BKTOTAL + $ALLOWANCE)) ] ; then
10911                 error "df total($DFTOTAL) mismatch OST total($BKTOTAL)"
10912         fi
10913         if [ $DFFREE -lt $(($BKFREE - $ALLOWANCE)) ] ||
10914            [ $DFFREE -gt $(($BKFREE + $ALLOWANCE)) ] ; then
10915                 error "df free($DFFREE) mismatch OST free($BKFREE)"
10916         fi
10917         if [ $DFAVAIL -lt $(($BKAVAIL - $ALLOWANCE)) ] ||
10918            [ $DFAVAIL -gt $(($BKAVAIL + $ALLOWANCE)) ] ; then
10919                 error "df avail($DFAVAIL) mismatch OST avail($BKAVAIL)"
10920         fi
10921 }
10922 run_test 79 "df report consistency check ======================="
10923
10924 test_80() { # bug 10718
10925         remote_ost_nodsh && skip "remote OST with nodsh"
10926         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10927
10928         # relax strong synchronous semantics for slow backends like ZFS
10929         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
10930                 local soc="obdfilter.*.sync_lock_cancel"
10931                 local save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
10932
10933                 # "sync_on_lock_cancel" was broken by v2_11_55_0-26-g7059644e9a
10934                 if [ -z "$save" ]; then
10935                         soc="obdfilter.*.sync_on_lock_cancel"
10936                         save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
10937                 fi
10938
10939                 if [ "$save" != "never" ]; then
10940                         local hosts=$(comma_list $(osts_nodes))
10941
10942                         do_nodes $hosts $LCTL set_param $soc=never
10943                         stack_trap "do_nodes $hosts $LCTL set_param $soc=$save"
10944                 fi
10945         fi
10946
10947         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1M
10948         sync; sleep 1; sync
10949         local before=$(date +%s)
10950         cancel_lru_locks osc
10951         local after=$(date +%s)
10952         local diff=$((after - before))
10953         [ $diff -le 1 ] || error "elapsed for 1M@1T = $diff"
10954
10955         rm -f $DIR/$tfile
10956 }
10957 run_test 80 "Page eviction is equally fast at high offsets too"
10958
10959 test_81a() { # LU-456
10960         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10961         remote_ost_nodsh && skip "remote OST with nodsh"
10962
10963         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
10964         # MUST OR with the CFS_FAIL_ONCE (0x80000000)
10965         do_facet ost1 lctl set_param fail_loc=0x80000228
10966
10967         # write should trigger a retry and success
10968         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10969         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10970         RC=$?
10971         if [ $RC -ne 0 ] ; then
10972                 error "write should success, but failed for $RC"
10973         fi
10974 }
10975 run_test 81a "OST should retry write when get -ENOSPC ==============="
10976
10977 test_81b() { # LU-456
10978         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10979         remote_ost_nodsh && skip "remote OST with nodsh"
10980
10981         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
10982         # Don't OR with the CFS_FAIL_ONCE (0x80000000)
10983         do_facet ost1 lctl set_param fail_loc=0x228
10984
10985         # write should retry several times and return -ENOSPC finally
10986         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10987         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10988         RC=$?
10989         ENOSPC=28
10990         if [ $RC -ne $ENOSPC ] ; then
10991                 error "dd should fail for -ENOSPC, but succeed."
10992         fi
10993 }
10994 run_test 81b "OST should return -ENOSPC when retry still fails ======="
10995
10996 test_99() {
10997         [ -z "$(which cvs 2>/dev/null)" ] && skip_env "could not find cvs"
10998
10999         test_mkdir $DIR/$tdir.cvsroot
11000         chown $RUNAS_ID $DIR/$tdir.cvsroot
11001
11002         cd $TMP
11003         $RUNAS cvs -d $DIR/$tdir.cvsroot init || error "cvs init failed"
11004
11005         cd /etc/init.d
11006         # some versions of cvs import exit(1) when asked to import links or
11007         # files they can't read.  ignore those files.
11008         local toignore=$(find . -type l -printf '-I %f\n' -o \
11009                          ! -perm /4 -printf '-I %f\n')
11010         $RUNAS cvs -d $DIR/$tdir.cvsroot import -m "nomesg" $toignore \
11011                 $tdir.reposname vtag rtag
11012
11013         cd $DIR
11014         test_mkdir $DIR/$tdir.reposname
11015         chown $RUNAS_ID $DIR/$tdir.reposname
11016         $RUNAS cvs -d $DIR/$tdir.cvsroot co $tdir.reposname
11017
11018         cd $DIR/$tdir.reposname
11019         $RUNAS touch foo99
11020         $RUNAS cvs add -m 'addmsg' foo99
11021         $RUNAS cvs update
11022         $RUNAS cvs commit -m 'nomsg' foo99
11023         rm -fr $DIR/$tdir.cvsroot
11024 }
11025 run_test 99 "cvs strange file/directory operations"
11026
11027 test_100() {
11028         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11029         [[ "$NETTYPE" =~ tcp ]] ||
11030                 skip_env "TCP secure port test, not useful for NETTYPE=$NETTYPE"
11031         [[ -n "$(type -p ss)" ]] || skip_env "ss not available"
11032         remote_ost_nodsh && skip "remote OST with nodsh"
11033         remote_mds_nodsh && skip "remote MDS with nodsh"
11034         remote_servers || skip "useless for local single node setup"
11035
11036         ss -tna | ( rc=1; while read STATE SND RCV LOCAL REMOTE STAT; do
11037                 [[ "${REMOTE/*:/}" == "$ACCEPTOR_PORT" ]] || continue
11038
11039                 rc=0
11040                 if (( ${LOCAL/*:/} >= 1024 )); then
11041                         echo "bad: $PROT $SND $RCV $LOCAL $REMOTE $STAT"
11042                         ss -tna
11043                         error "local: ${LOCAL/*:/} > 1024 remote: ${REMOTE/*:/}"
11044                 fi
11045         done
11046         (( $rc == 0 )) || error "privileged port not found" )
11047 }
11048 run_test 100 "check local port using privileged port"
11049
11050 function get_named_value()
11051 {
11052     local tag=$1
11053
11054     grep -w "$tag" | sed "s/^$tag  *\([0-9]*\)  *.*/\1/"
11055 }
11056
11057 export CACHE_MAX=$($LCTL get_param -n llite.*.max_cached_mb |
11058                    awk '/^max_cached_mb/ { print $2 }')
11059
11060 cleanup_101a() {
11061         $LCTL set_param -n llite.*.max_cached_mb $CACHE_MAX
11062         trap 0
11063 }
11064
11065 test_101a() {
11066         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11067
11068         local s
11069         local discard
11070         local nreads=10000
11071         local cache_limit=32
11072
11073         $LCTL set_param -n osc.*-osc*.rpc_stats=0
11074         trap cleanup_101a EXIT
11075         $LCTL set_param -n llite.*.read_ahead_stats=0
11076         $LCTL set_param -n llite.*.max_cached_mb=$cache_limit
11077
11078         #
11079         # randomly read 10000 of 64K chunks from file 3x 32MB in size
11080         #
11081         echo "nreads: $nreads file size: $((cache_limit * 3))MB"
11082         $READS -f $DIR/$tfile -s$((cache_limit * 3192 * 1024)) -b65536 -C -n$nreads -t 180
11083
11084         discard=0
11085         for s in $($LCTL get_param -n llite.*.read_ahead_stats |
11086                    get_named_value 'read.but.discarded'); do
11087                         discard=$(($discard + $s))
11088         done
11089         cleanup_101a
11090
11091         $LCTL get_param osc.*-osc*.rpc_stats
11092         $LCTL get_param llite.*.read_ahead_stats
11093
11094         # Discard is generally zero, but sometimes a few random reads line up
11095         # and trigger larger readahead, which is wasted & leads to discards.
11096         if [[ $(($discard)) -gt $nreads ]]; then
11097                 error "too many ($discard) discarded pages"
11098         fi
11099         rm -f $DIR/$tfile || true
11100 }
11101 run_test 101a "check read-ahead for random reads"
11102
11103 setup_test101bc() {
11104         test_mkdir $DIR/$tdir
11105         local ssize=$1
11106         local FILE_LENGTH=$2
11107         STRIPE_OFFSET=0
11108
11109         local FILE_SIZE_MB=$((FILE_LENGTH / ssize))
11110
11111         local list=$(comma_list $(osts_nodes))
11112         set_osd_param $list '' read_cache_enable 0
11113         set_osd_param $list '' writethrough_cache_enable 0
11114
11115         trap cleanup_test101bc EXIT
11116         # prepare the read-ahead file
11117         $LFS setstripe -S $ssize -i $STRIPE_OFFSET -c $OSTCOUNT $DIR/$tfile
11118
11119         dd if=/dev/zero of=$DIR/$tfile bs=$ssize \
11120                                 count=$FILE_SIZE_MB 2> /dev/null
11121
11122 }
11123
11124 cleanup_test101bc() {
11125         trap 0
11126         rm -rf $DIR/$tdir
11127         rm -f $DIR/$tfile
11128
11129         local list=$(comma_list $(osts_nodes))
11130         set_osd_param $list '' read_cache_enable 1
11131         set_osd_param $list '' writethrough_cache_enable 1
11132 }
11133
11134 calc_total() {
11135         awk 'BEGIN{total=0}; {total+=$1}; END{print total}'
11136 }
11137
11138 ra_check_101() {
11139         local read_size=$1
11140         local stripe_size=$2
11141         local stride_length=$((stripe_size / read_size))
11142         local stride_width=$((stride_length * OSTCOUNT))
11143         local discard_limit=$(( ((stride_length - 1) * 3 / stride_width) *
11144                                 (stride_width - stride_length) ))
11145         local discard=$($LCTL get_param -n llite.*.read_ahead_stats |
11146                   get_named_value 'read.but.discarded' | calc_total)
11147
11148         if [[ $discard -gt $discard_limit ]]; then
11149                 $LCTL get_param llite.*.read_ahead_stats
11150                 error "($discard limit ${discard_limit}) discarded pages with size (${read_size})"
11151         else
11152                 echo "Read-ahead success for size ${read_size}"
11153         fi
11154 }
11155
11156 test_101b() {
11157         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11158         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11159
11160         local STRIPE_SIZE=1048576
11161         local STRIDE_SIZE=$((STRIPE_SIZE*OSTCOUNT))
11162
11163         if [ $SLOW == "yes" ]; then
11164                 local FILE_LENGTH=$((STRIDE_SIZE * 64))
11165         else
11166                 local FILE_LENGTH=$((STRIDE_SIZE * 8))
11167         fi
11168
11169         local ITERATION=$((FILE_LENGTH / STRIDE_SIZE))
11170
11171         # prepare the read-ahead file
11172         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
11173         cancel_lru_locks osc
11174         for BIDX in 2 4 8 16 32 64 128 256
11175         do
11176                 local BSIZE=$((BIDX*4096))
11177                 local READ_COUNT=$((STRIPE_SIZE/BSIZE))
11178                 local STRIDE_LENGTH=$((STRIDE_SIZE/BSIZE))
11179                 local OFFSET=$((STRIPE_SIZE/BSIZE*(OSTCOUNT - 1)))
11180                 $LCTL set_param -n llite.*.read_ahead_stats=0
11181                 $READS -f $DIR/$tfile  -l $STRIDE_LENGTH -o $OFFSET \
11182                               -s $FILE_LENGTH -b $STRIPE_SIZE -a $READ_COUNT -n $ITERATION
11183                 cancel_lru_locks osc
11184                 ra_check_101 $BSIZE $STRIPE_SIZE $FILE_LENGTH
11185         done
11186         cleanup_test101bc
11187         true
11188 }
11189 run_test 101b "check stride-io mode read-ahead ================="
11190
11191 test_101c() {
11192         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11193
11194         local STRIPE_SIZE=1048576
11195         local FILE_LENGTH=$((STRIPE_SIZE*100))
11196         local nreads=10000
11197         local rsize=65536
11198         local osc_rpc_stats
11199
11200         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
11201
11202         cancel_lru_locks osc
11203         $LCTL set_param osc.*.rpc_stats=0
11204         $READS -f $DIR/$tfile -s$FILE_LENGTH -b$rsize -n$nreads -t 180
11205         $LCTL get_param osc.*.rpc_stats
11206         for osc_rpc_stats in $($LCTL get_param -N osc.*.rpc_stats); do
11207                 local stats=$($LCTL get_param -n $osc_rpc_stats)
11208                 local lines=$(echo "$stats" | awk 'END {print NR;}')
11209                 local size
11210
11211                 if [ $lines -le 20 ]; then
11212                         echo "continue debug"
11213                         continue
11214                 fi
11215                 for size in 1 2 4 8; do
11216                         local rpc=$(echo "$stats" |
11217                                     awk '($1 == "'$size':") {print $2; exit; }')
11218                         [ $rpc != 0 ] && ((size * PAGE_SIZE < rsize)) &&
11219                                 error "Small $((size*PAGE_SIZE)) read IO $rpc!"
11220                 done
11221                 echo "$osc_rpc_stats check passed!"
11222         done
11223         cleanup_test101bc
11224         true
11225 }
11226 run_test 101c "check stripe_size aligned read-ahead"
11227
11228 test_101d() {
11229         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11230
11231         local file=$DIR/$tfile
11232         local sz_MB=${FILESIZE_101d:-80}
11233         local ra_MB=${READAHEAD_MB:-40}
11234
11235         local free_MB=$(($(df -P $DIR | tail -n 1 | awk '{ print $4 }') / 1024))
11236         [ $free_MB -lt $sz_MB ] &&
11237                 skip "Need free space ${sz_MB}M, have ${free_MB}M"
11238
11239         echo "Create test file $file size ${sz_MB}M, ${free_MB}M free"
11240         $LFS setstripe -c -1 $file || error "setstripe failed"
11241
11242         dd if=/dev/zero of=$file bs=1M count=$sz_MB || error "dd failed"
11243         echo Cancel LRU locks on lustre client to flush the client cache
11244         cancel_lru_locks osc
11245
11246         echo Disable read-ahead
11247         local old_RA=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
11248         $LCTL set_param -n llite.*.max_read_ahead_mb=0
11249         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb=$old_RA" EXIT
11250         $LCTL get_param -n llite.*.max_read_ahead_mb
11251
11252         echo "Reading the test file $file with read-ahead disabled"
11253         local sz_KB=$((sz_MB * 1024 / 4))
11254         # 10485760 bytes transferred in 0.000938 secs (11179579337 bytes/sec)
11255         # 104857600 bytes (105 MB) copied, 0.00876352 s, 12.0 GB/s
11256         local raOFF=$(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 "Cancel LRU locks on lustre client to flush the client cache"
11260         cancel_lru_locks osc
11261         echo Enable read-ahead with ${ra_MB}MB
11262         $LCTL set_param -n llite.*.max_read_ahead_mb=$ra_MB
11263
11264         echo "Reading the test file $file with read-ahead enabled"
11265         local raON=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
11266                      sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
11267
11268         echo "read-ahead disabled time read $raOFF"
11269         echo "read-ahead enabled time read $raON"
11270
11271         rm -f $file
11272         wait_delete_completed
11273
11274         # use awk for this check instead of bash because it handles decimals
11275         awk "{ exit !($raOFF < 1.0 || $raOFF > $raON) }" <<<"ignore_me" ||
11276                 error "readahead ${raON}s > no-readahead ${raOFF}s ${sz_MB}M"
11277 }
11278 run_test 101d "file read with and without read-ahead enabled"
11279
11280 test_101e() {
11281         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11282
11283         local file=$DIR/$tfile
11284         local size_KB=500  #KB
11285         local count=100
11286         local bsize=1024
11287
11288         local free_KB=$(df -P $DIR | tail -n 1 | awk '{ print $4 }')
11289         local need_KB=$((count * size_KB))
11290         [[ $free_KB -le $need_KB ]] &&
11291                 skip_env "Need free space $need_KB, have $free_KB"
11292
11293         echo "Creating $count ${size_KB}K test files"
11294         for ((i = 0; i < $count; i++)); do
11295                 dd if=/dev/zero of=$file.$i bs=$bsize count=$size_KB 2>/dev/null
11296         done
11297
11298         echo "Cancel LRU locks on lustre client to flush the client cache"
11299         cancel_lru_locks $OSC
11300
11301         echo "Reset readahead stats"
11302         $LCTL set_param -n llite.*.read_ahead_stats=0
11303
11304         for ((i = 0; i < $count; i++)); do
11305                 dd if=$file.$i of=/dev/null bs=$bsize count=$size_KB 2>/dev/null
11306         done
11307
11308         $LCTL get_param llite.*.max_cached_mb
11309         $LCTL get_param llite.*.read_ahead_stats
11310         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11311                      get_named_value 'misses' | calc_total)
11312
11313         for ((i = 0; i < $count; i++)); do
11314                 rm -rf $file.$i 2>/dev/null
11315         done
11316
11317         #10000 means 20% reads are missing in readahead
11318         [[ $miss -lt 10000 ]] ||  error "misses too much for small reads"
11319 }
11320 run_test 101e "check read-ahead for small read(1k) for small files(500k)"
11321
11322 test_101f() {
11323         which iozone || skip_env "no iozone installed"
11324
11325         local old_debug=$($LCTL get_param debug)
11326         old_debug=${old_debug#*=}
11327         $LCTL set_param debug="reada mmap"
11328
11329         # create a test file
11330         iozone -i 0 -+n -r 1m -s 128m -w -f $DIR/$tfile > /dev/null 2>&1
11331
11332         echo Cancel LRU locks on lustre client to flush the client cache
11333         cancel_lru_locks osc
11334
11335         echo Reset readahead stats
11336         $LCTL set_param -n llite.*.read_ahead_stats=0
11337
11338         echo mmap read the file with small block size
11339         iozone -i 1 -u 1 -l 1 -+n -r 32k -s 128m -B -f $DIR/$tfile \
11340                 > /dev/null 2>&1
11341
11342         echo checking missing pages
11343         $LCTL get_param llite.*.read_ahead_stats
11344         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11345                         get_named_value 'misses' | calc_total)
11346
11347         $LCTL set_param debug="$old_debug"
11348         [ $miss -lt 3 ] || error "misses too much pages ('$miss')!"
11349         rm -f $DIR/$tfile
11350 }
11351 run_test 101f "check mmap read performance"
11352
11353 test_101g_brw_size_test() {
11354         local mb=$1
11355         local pages=$((mb * 1048576 / PAGE_SIZE))
11356         local file=$DIR/$tfile
11357
11358         $LCTL set_param osc.*.max_pages_per_rpc=${mb}M ||
11359                 { error "unable to set max_pages_per_rpc=${mb}M"; return 1; }
11360         for mp in $($LCTL get_param -n osc.*.max_pages_per_rpc); do
11361                 [ $mp -ne $pages ] && error "max_pages_per_rpc $mp != $pages" &&
11362                         return 2
11363         done
11364
11365         stack_trap "rm -f $file" EXIT
11366         $LCTL set_param -n osc.*.rpc_stats=0
11367
11368         # 10 RPCs should be enough for the test
11369         local count=10
11370         dd if=/dev/zero of=$file bs=${mb}M count=$count ||
11371                 { error "dd write ${mb} MB blocks failed"; return 3; }
11372         cancel_lru_locks osc
11373         dd of=/dev/null if=$file bs=${mb}M count=$count ||
11374                 { error "dd write ${mb} MB blocks failed"; return 4; }
11375
11376         # calculate number of full-sized read and write RPCs
11377         rpcs=($($LCTL get_param -n 'osc.*.rpc_stats' |
11378                 sed -n '/pages per rpc/,/^$/p' |
11379                 awk '/'$pages':/ { reads += $2; writes += $6 }; \
11380                 END { print reads,writes }'))
11381         # allow one extra full-sized read RPC for async readahead
11382         [[ ${rpcs[0]} == $count || ${rpcs[0]} == $((count + 1)) ]] ||
11383                 { error "${rpcs[0]} != $count read RPCs"; return 5; }
11384         [[ ${rpcs[1]} == $count ]] ||
11385                 { error "${rpcs[1]} != $count write RPCs"; return 6; }
11386 }
11387
11388 test_101g() {
11389         remote_ost_nodsh && skip "remote OST with nodsh"
11390
11391         local rpcs
11392         local osts=$(get_facets OST)
11393         local list=$(comma_list $(osts_nodes))
11394         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
11395         local brw_size="obdfilter.*.brw_size"
11396
11397         $LFS setstripe -i 0 -c 1 $DIR/$tfile
11398
11399         local orig_mb=$(do_facet ost1 $LCTL get_param -n $brw_size | head -n 1)
11400
11401         if { [ $OST1_VERSION -ge $(version_code 2.8.52) ] ||
11402                 { [ $OST1_VERSION -ge $(version_code 2.7.17) ] &&
11403                   [ $OST1_VERSION -lt $(version_code 2.7.50) ]; }; } &&
11404            { [ $CLIENT_VERSION -ge $(version_code 2.8.52) ] ||
11405                 { [ $CLIENT_VERSION -ge $(version_code 2.7.17) ] &&
11406                   [ $CLIENT_VERSION -lt $(version_code 2.7.50) ]; }; }; then
11407
11408                 [ $OST1_VERSION -ge $(version_code 2.9.52) ] &&
11409                         suffix="M"
11410
11411                 if [[ $orig_mb -lt 16 ]]; then
11412                         save_lustre_params $osts "$brw_size" > $p
11413                         do_nodes $list $LCTL set_param -n $brw_size=16$suffix ||
11414                                 error "set 16MB RPC size failed"
11415
11416                         echo "remount client to enable new RPC size"
11417                         remount_client $MOUNT || error "remount_client failed"
11418                 fi
11419
11420                 test_101g_brw_size_test 16 || error "16MB RPC test failed"
11421                 # should be able to set brw_size=12, but no rpc_stats for that
11422                 test_101g_brw_size_test 8 || error "8MB RPC test failed"
11423         fi
11424
11425         test_101g_brw_size_test 4 || error "4MB RPC test failed"
11426
11427         if [[ $orig_mb -lt 16 ]]; then
11428                 restore_lustre_params < $p
11429                 remount_client $MOUNT || error "remount_client restore failed"
11430         fi
11431
11432         rm -f $p $DIR/$tfile
11433 }
11434 run_test 101g "Big bulk(4/16 MiB) readahead"
11435
11436 test_101h() {
11437         $LFS setstripe -i 0 -c 1 $DIR/$tfile
11438
11439         dd if=/dev/zero of=$DIR/$tfile bs=1M count=70 ||
11440                 error "dd 70M file failed"
11441         echo Cancel LRU locks on lustre client to flush the client cache
11442         cancel_lru_locks osc
11443
11444         echo "Reset readahead stats"
11445         $LCTL set_param -n llite.*.read_ahead_stats 0
11446
11447         echo "Read 10M of data but cross 64M bundary"
11448         dd if=$DIR/$tfile of=/dev/null bs=10M skip=6 count=1
11449         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11450                      get_named_value 'misses' | calc_total)
11451         [ $miss -eq 1 ] || error "expected miss 1 but got $miss"
11452         rm -f $p $DIR/$tfile
11453 }
11454 run_test 101h "Readahead should cover current read window"
11455
11456 test_101i() {
11457         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 ||
11458                 error "dd 10M file failed"
11459
11460         local max_per_file_mb=$($LCTL get_param -n \
11461                 llite.*.max_read_ahead_per_file_mb 2>/dev/null)
11462         cancel_lru_locks osc
11463         stack_trap "$LCTL set_param llite.*.max_read_ahead_per_file_mb=$max_per_file_mb"
11464         $LCTL set_param llite.*.max_read_ahead_per_file_mb=1 ||
11465                 error "set max_read_ahead_per_file_mb to 1 failed"
11466
11467         echo "Reset readahead stats"
11468         $LCTL set_param llite.*.read_ahead_stats=0
11469
11470         dd if=$DIR/$tfile of=/dev/null bs=2M
11471
11472         $LCTL get_param llite.*.read_ahead_stats
11473         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11474                      awk '/misses/ { print $2 }')
11475         [ $miss -eq 5 ] || error "expected misses 5 but got $miss"
11476         rm -f $DIR/$tfile
11477 }
11478 run_test 101i "allow current readahead to exceed reservation"
11479
11480 test_101j() {
11481         $LFS setstripe -i 0 -c 1 $DIR/$tfile ||
11482                 error "setstripe $DIR/$tfile failed"
11483         local file_size=$((1048576 * 16))
11484         local old_ra=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
11485         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb $old_ra" EXIT
11486
11487         echo Disable read-ahead
11488         $LCTL set_param -n llite.*.max_read_ahead_mb=0
11489
11490         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$(($file_size / 1048576))
11491         for blk in $PAGE_SIZE 1048576 $file_size; do
11492                 cancel_lru_locks osc
11493                 echo "Reset readahead stats"
11494                 $LCTL set_param -n llite.*.read_ahead_stats=0
11495                 local count=$(($file_size / $blk))
11496                 dd if=$DIR/$tfile bs=$blk count=$count of=/dev/null
11497                 local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11498                              get_named_value 'failed.to.fast.read' | calc_total)
11499                 $LCTL get_param -n llite.*.read_ahead_stats
11500                 [ $miss -eq $count ] || error "expected $count got $miss"
11501         done
11502
11503         rm -f $p $DIR/$tfile
11504 }
11505 run_test 101j "A complete read block should be submitted when no RA"
11506
11507 test_readahead_base() {
11508         local file=$DIR/$tfile
11509         local size=$1
11510         local iosz
11511         local ramax
11512         local ranum
11513
11514         $LCTL set_param -n llite.*.read_ahead_stats=0
11515         # The first page is not accounted into readahead
11516         ramax=$(((size + PAGE_SIZE - 1) / PAGE_SIZE - 1))
11517         iosz=$(((size + 1048575) / 1048576 * 1048576))
11518         echo "Test readahead: size=$size ramax=$ramx iosz=$iosz"
11519
11520         $LCTL mark  "Test readahead: size=$size ramax=$ramx iosz=$iosz"
11521         fallocate -l $size $file || error "failed to fallocate $file"
11522         cancel_lru_locks osc
11523         $MULTIOP $file or${iosz}c || error "failed to read $file"
11524         $LCTL get_param -n llite.*.read_ahead_stats
11525         ranum=$($LCTL get_param -n llite.*.read_ahead_stats |
11526                 awk '/readahead.pages/ { print $7 }' | calc_total)
11527         (( $ranum <= $ramax )) ||
11528                 error "read-ahead pages is $ranum more than $ramax"
11529         rm -rf $file || error "failed to remove $file"
11530 }
11531
11532 test_101m()
11533 {
11534         local file=$DIR/$tfile
11535         local ramax
11536         local ranum
11537         local size
11538         local iosz
11539
11540         check_set_fallocate_or_skip
11541         stack_trap "rm -f $file" EXIT
11542
11543         test_readahead_base 4096
11544
11545         # file size: 16K = 16384
11546         test_readahead_base 16384
11547         test_readahead_base 16385
11548         test_readahead_base 16383
11549
11550         # file size: 1M + 1 = 1048576 + 1
11551         test_readahead_base 1048577
11552         # file size: 1M + 16K
11553         test_readahead_base $((1048576 + 16384))
11554
11555         # file size: stripe_size * (stripe_count - 1) + 16K
11556         $LFS setstripe -c -1 $file || error "failed to setstripe $file"
11557         test_readahead_base $((1048576 * (OSTCOUNT - 1) + 16384))
11558         # file size: stripe_size * stripe_count + 16K
11559         $LFS setstripe -c -1 $file || error "failed to setstripe $file"
11560         test_readahead_base $((1048576 * OSTCOUNT + 16384))
11561         # file size: 2 * stripe_size * stripe_count + 16K
11562         $LFS setstripe -c -1 $file || error "failed to setstripe $file"
11563         test_readahead_base $((2 * 1048576 * OSTCOUNT + 16384))
11564 }
11565 run_test 101m "read ahead for small file and last stripe of the file"
11566
11567 setup_test102() {
11568         test_mkdir $DIR/$tdir
11569         chown $RUNAS_ID $DIR/$tdir
11570         STRIPE_SIZE=65536
11571         STRIPE_OFFSET=1
11572         STRIPE_COUNT=$OSTCOUNT
11573         [[ $OSTCOUNT -gt 4 ]] && STRIPE_COUNT=4
11574
11575         trap cleanup_test102 EXIT
11576         cd $DIR
11577         $1 $LFS setstripe -S $STRIPE_SIZE -i $STRIPE_OFFSET -c $STRIPE_COUNT $tdir
11578         cd $DIR/$tdir
11579         for num in 1 2 3 4; do
11580                 for count in $(seq 1 $STRIPE_COUNT); do
11581                         for idx in $(seq 0 $[$STRIPE_COUNT - 1]); do
11582                                 local size=`expr $STRIPE_SIZE \* $num`
11583                                 local file=file"$num-$idx-$count"
11584                                 $1 $LFS setstripe -S $size -i $idx -c $count $file
11585                         done
11586                 done
11587         done
11588
11589         cd $DIR
11590         $1 tar cf $TMP/f102.tar $tdir --xattrs
11591 }
11592
11593 cleanup_test102() {
11594         trap 0
11595         rm -f $TMP/f102.tar
11596         rm -rf $DIR/d0.sanity/d102
11597 }
11598
11599 test_102a() {
11600         [ "$UID" != 0 ] && skip "must run as root"
11601         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep xattr)" ] &&
11602                 skip_env "must have user_xattr"
11603
11604         [ -z "$(which setfattr 2>/dev/null)" ] &&
11605                 skip_env "could not find setfattr"
11606
11607         local testfile=$DIR/$tfile
11608
11609         touch $testfile
11610         echo "set/get xattr..."
11611         setfattr -n trusted.name1 -v value1 $testfile ||
11612                 error "setfattr -n trusted.name1=value1 $testfile failed"
11613         getfattr -n trusted.name1 $testfile 2> /dev/null |
11614           grep "trusted.name1=.value1" ||
11615                 error "$testfile missing trusted.name1=value1"
11616
11617         setfattr -n user.author1 -v author1 $testfile ||
11618                 error "setfattr -n user.author1=author1 $testfile failed"
11619         getfattr -n user.author1 $testfile 2> /dev/null |
11620           grep "user.author1=.author1" ||
11621                 error "$testfile missing trusted.author1=author1"
11622
11623         echo "listxattr..."
11624         setfattr -n trusted.name2 -v value2 $testfile ||
11625                 error "$testfile unable to set trusted.name2"
11626         setfattr -n trusted.name3 -v value3 $testfile ||
11627                 error "$testfile unable to set trusted.name3"
11628         [ $(getfattr -d -m "^trusted" $testfile 2> /dev/null |
11629             grep "trusted.name" | wc -l) -eq 3 ] ||
11630                 error "$testfile missing 3 trusted.name xattrs"
11631
11632         setfattr -n user.author2 -v author2 $testfile ||
11633                 error "$testfile unable to set user.author2"
11634         setfattr -n user.author3 -v author3 $testfile ||
11635                 error "$testfile unable to set user.author3"
11636         [ $(getfattr -d -m "^user" $testfile 2> /dev/null |
11637             grep "user.author" | wc -l) -eq 3 ] ||
11638                 error "$testfile missing 3 user.author xattrs"
11639
11640         echo "remove xattr..."
11641         setfattr -x trusted.name1 $testfile ||
11642                 error "$testfile error deleting trusted.name1"
11643         getfattr -d -m trusted $testfile 2> /dev/null | grep "trusted.name1" &&
11644                 error "$testfile did not delete trusted.name1 xattr"
11645
11646         setfattr -x user.author1 $testfile ||
11647                 error "$testfile error deleting user.author1"
11648         echo "set lustre special xattr ..."
11649         $LFS setstripe -c1 $testfile
11650         local lovea=$(getfattr -n "trusted.lov" -e hex $testfile |
11651                 awk -F "=" '/trusted.lov/ { print $2 }' )
11652         setfattr -n "trusted.lov" -v $lovea $testfile ||
11653                 error "$testfile doesn't ignore setting trusted.lov again"
11654         setfattr -n "trusted.lov" -v "invalid_value" $testfile &&
11655                 error "$testfile allow setting invalid trusted.lov"
11656         rm -f $testfile
11657 }
11658 run_test 102a "user xattr test =================================="
11659
11660 check_102b_layout() {
11661         local layout="$*"
11662         local testfile=$DIR/$tfile
11663
11664         echo "test layout '$layout'"
11665         $LFS setstripe $layout $testfile || error "setstripe failed"
11666         $LFS getstripe -y $testfile
11667
11668         echo "get/set/list trusted.lov xattr ..." # b=10930
11669         local value=$(getfattr -n trusted.lov -e hex $testfile | grep trusted)
11670         [[ "$value" =~ "trusted.lov" ]] ||
11671                 error "can't get trusted.lov from $testfile"
11672         local stripe_count_orig=$($LFS getstripe -c $testfile) ||
11673                 error "getstripe failed"
11674
11675         $MCREATE $testfile.2 || error "mcreate $testfile.2 failed"
11676
11677         value=$(cut -d= -f2 <<<$value)
11678         # LU-13168: truncated xattr should fail if short lov_user_md header
11679         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
11680                 lens="${#value}" || lens="$(seq 4 2 ${#value})"
11681         for len in $lens; do
11682                 echo "setfattr $len $testfile.2"
11683                 setfattr -n trusted.lov -v ${value:0:$len} $testfile.2 &&
11684                         [ $len -lt 66 ] && error "short xattr len=$len worked"
11685         done
11686         local stripe_size=$($LFS getstripe -S $testfile.2)
11687         local stripe_count=$($LFS getstripe -c $testfile.2)
11688         [[ $stripe_size -eq 65536 ]] ||
11689                 error "stripe size $stripe_size != 65536"
11690         [[ $stripe_count -eq $stripe_count_orig ]] ||
11691                 error "stripe count $stripe_count != $stripe_count_orig"
11692         rm $testfile $testfile.2
11693 }
11694
11695 test_102b() {
11696         [ -z "$(which setfattr 2>/dev/null)" ] &&
11697                 skip_env "could not find setfattr"
11698         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11699
11700         # check plain layout
11701         check_102b_layout -S 65536 -i 1 -c $OSTCOUNT
11702
11703         # and also check composite layout
11704         check_102b_layout -E 1M -S 65536 -i 1 -c $OSTCOUNT -Eeof -S4M
11705
11706 }
11707 run_test 102b "getfattr/setfattr for trusted.lov EAs"
11708
11709 test_102c() {
11710         [ -z "$(which setfattr 2>/dev/null)" ] &&
11711                 skip_env "could not find setfattr"
11712         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11713
11714         # b10930: get/set/list lustre.lov xattr
11715         echo "get/set/list lustre.lov xattr ..."
11716         test_mkdir $DIR/$tdir
11717         chown $RUNAS_ID $DIR/$tdir
11718         local testfile=$DIR/$tdir/$tfile
11719         $RUNAS $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
11720                 error "setstripe failed"
11721         local STRIPECOUNT=$($RUNAS $LFS getstripe -c $testfile) ||
11722                 error "getstripe failed"
11723         $RUNAS getfattr -d -m "^lustre" $testfile 2> /dev/null | \
11724         grep "lustre.lov" || error "can't get lustre.lov from $testfile"
11725
11726         local testfile2=${testfile}2
11727         local value=`getfattr -n lustre.lov $testfile 2> /dev/null | \
11728                      grep "lustre.lov" |sed -e 's/[^=]\+=//'  `
11729
11730         $RUNAS $MCREATE $testfile2
11731         $RUNAS setfattr -n lustre.lov -v $value $testfile2
11732         local stripe_size=$($RUNAS $LFS getstripe -S $testfile2)
11733         local stripe_count=$($RUNAS $LFS getstripe -c $testfile2)
11734         [ $stripe_size -eq 65536 ] || error "stripe size $stripe_size != 65536"
11735         [ $stripe_count -eq $STRIPECOUNT ] ||
11736                 error "stripe count $stripe_count != $STRIPECOUNT"
11737 }
11738 run_test 102c "non-root getfattr/setfattr for lustre.lov EAs ==========="
11739
11740 compare_stripe_info1() {
11741         local stripe_index_all_zero=true
11742
11743         for num in 1 2 3 4; do
11744                 for count in $(seq 1 $STRIPE_COUNT); do
11745                         for offset in $(seq 0 $[$STRIPE_COUNT - 1]); do
11746                                 local size=$((STRIPE_SIZE * num))
11747                                 local file=file"$num-$offset-$count"
11748                                 stripe_size=$($LFS getstripe -S $PWD/$file)
11749                                 [[ $stripe_size -ne $size ]] &&
11750                                     error "$file: size $stripe_size != $size"
11751                                 stripe_count=$($LFS getstripe -c $PWD/$file)
11752                                 # allow fewer stripes to be created, ORI-601
11753                                 [[ $stripe_count -lt $(((3 * count + 3) / 4)) ]] &&
11754                                     error "$file: count $stripe_count != $count"
11755                                 stripe_index=$($LFS getstripe -i $PWD/$file)
11756                                 [[ $stripe_index -ne 0 ]] &&
11757                                         stripe_index_all_zero=false
11758                         done
11759                 done
11760         done
11761         $stripe_index_all_zero &&
11762                 error "all files are being extracted starting from OST index 0"
11763         return 0
11764 }
11765
11766 have_xattrs_include() {
11767         tar --help | grep -q xattrs-include &&
11768                 echo --xattrs-include="lustre.*"
11769 }
11770
11771 test_102d() {
11772         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11773         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11774
11775         XINC=$(have_xattrs_include)
11776         setup_test102
11777         tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
11778         cd $DIR/$tdir/$tdir
11779         compare_stripe_info1
11780 }
11781 run_test 102d "tar restore stripe info from tarfile,not keep osts"
11782
11783 test_102f() {
11784         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11785         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11786
11787         XINC=$(have_xattrs_include)
11788         setup_test102
11789         test_mkdir $DIR/$tdir.restore
11790         cd $DIR
11791         tar cf - --xattrs $tdir | tar xf - \
11792                 -C $DIR/$tdir.restore --xattrs $XINC
11793         cd $DIR/$tdir.restore/$tdir
11794         compare_stripe_info1
11795 }
11796 run_test 102f "tar copy files, not keep osts"
11797
11798 grow_xattr() {
11799         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep xattr)" ] &&
11800                 skip "must have user_xattr"
11801         [ -z "$(which setfattr 2>/dev/null)" ] &&
11802                 skip_env "could not find setfattr"
11803         [ -z "$(which getfattr 2>/dev/null)" ] &&
11804                 skip_env "could not find getfattr"
11805
11806         local xsize=${1:-1024}  # in bytes
11807         local file=$DIR/$tfile
11808         local value="$(generate_string $xsize)"
11809         local xbig=trusted.big
11810         local toobig=$2
11811
11812         touch $file
11813         log "save $xbig on $file"
11814         if [ -z "$toobig" ]
11815         then
11816                 setfattr -n $xbig -v $value $file ||
11817                         error "saving $xbig on $file failed"
11818         else
11819                 setfattr -n $xbig -v $value $file &&
11820                         error "saving $xbig on $file succeeded"
11821                 return 0
11822         fi
11823
11824         local orig=$(get_xattr_value $xbig $file)
11825         [[ "$orig" != "$value" ]] && error "$xbig different after saving $xbig"
11826
11827         local xsml=trusted.sml
11828         log "save $xsml on $file"
11829         setfattr -n $xsml -v val $file || error "saving $xsml on $file failed"
11830
11831         local new=$(get_xattr_value $xbig $file)
11832         [[ "$new" != "$orig" ]] && error "$xbig different after saving $xsml"
11833
11834         log "grow $xsml on $file"
11835         setfattr -n $xsml -v "$value" $file ||
11836                 error "growing $xsml on $file failed"
11837
11838         new=$(get_xattr_value $xbig $file)
11839         [[ "$new" != "$orig" ]] && error "$xbig different after growing $xsml"
11840         log "$xbig still valid after growing $xsml"
11841
11842         rm -f $file
11843 }
11844
11845 test_102h() { # bug 15777
11846         grow_xattr 1024
11847 }
11848 run_test 102h "grow xattr from inside inode to external block"
11849
11850 test_102ha() {
11851         large_xattr_enabled || skip_env "ea_inode feature disabled"
11852
11853         echo "setting xattr of max xattr size: $(max_xattr_size)"
11854         grow_xattr $(max_xattr_size)
11855
11856         echo "setting xattr of > max xattr size: $(max_xattr_size) + 10"
11857         echo "This should fail:"
11858         grow_xattr $(($(max_xattr_size) + 10)) 1
11859 }
11860 run_test 102ha "grow xattr from inside inode to external inode"
11861
11862 test_102i() { # bug 17038
11863         [ -z "$(which getfattr 2>/dev/null)" ] &&
11864                 skip "could not find getfattr"
11865
11866         touch $DIR/$tfile
11867         ln -s $DIR/$tfile $DIR/${tfile}link
11868         getfattr -n trusted.lov $DIR/$tfile ||
11869                 error "lgetxattr on $DIR/$tfile failed"
11870         getfattr -h -n trusted.lov $DIR/${tfile}link 2>&1 |
11871                 grep -i "no such attr" ||
11872                 error "error for lgetxattr on $DIR/${tfile}link is not ENODATA"
11873         rm -f $DIR/$tfile $DIR/${tfile}link
11874 }
11875 run_test 102i "lgetxattr test on symbolic link ============"
11876
11877 test_102j() {
11878         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11879         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11880
11881         XINC=$(have_xattrs_include)
11882         setup_test102 "$RUNAS"
11883         chown $RUNAS_ID $DIR/$tdir
11884         $RUNAS tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
11885         cd $DIR/$tdir/$tdir
11886         compare_stripe_info1 "$RUNAS"
11887 }
11888 run_test 102j "non-root tar restore stripe info from tarfile, not keep osts ==="
11889
11890 test_102k() {
11891         [ -z "$(which setfattr 2>/dev/null)" ] &&
11892                 skip "could not find setfattr"
11893
11894         touch $DIR/$tfile
11895         # b22187 just check that does not crash for regular file.
11896         setfattr -n trusted.lov $DIR/$tfile
11897         # b22187 'setfattr -n trusted.lov' should remove LOV EA for directories
11898         local test_kdir=$DIR/$tdir
11899         test_mkdir $test_kdir
11900         local default_size=$($LFS getstripe -S $test_kdir)
11901         local default_count=$($LFS getstripe -c $test_kdir)
11902         local default_offset=$($LFS getstripe -i $test_kdir)
11903         $LFS setstripe -S 65536 -i 0 -c $OSTCOUNT $test_kdir ||
11904                 error 'dir setstripe failed'
11905         setfattr -n trusted.lov $test_kdir
11906         local stripe_size=$($LFS getstripe -S $test_kdir)
11907         local stripe_count=$($LFS getstripe -c $test_kdir)
11908         local stripe_offset=$($LFS getstripe -i $test_kdir)
11909         [ $stripe_size -eq $default_size ] ||
11910                 error "stripe size $stripe_size != $default_size"
11911         [ $stripe_count -eq $default_count ] ||
11912                 error "stripe count $stripe_count != $default_count"
11913         [ $stripe_offset -eq $default_offset ] ||
11914                 error "stripe offset $stripe_offset != $default_offset"
11915         rm -rf $DIR/$tfile $test_kdir
11916 }
11917 run_test 102k "setfattr without parameter of value shouldn't cause a crash"
11918
11919 test_102l() {
11920         [ -z "$(which getfattr 2>/dev/null)" ] &&
11921                 skip "could not find getfattr"
11922
11923         # LU-532 trusted. xattr is invisible to non-root
11924         local testfile=$DIR/$tfile
11925
11926         touch $testfile
11927
11928         echo "listxattr as user..."
11929         chown $RUNAS_ID $testfile
11930         $RUNAS getfattr -d -m '.*' $testfile 2>&1 |
11931             grep -q "trusted" &&
11932                 error "$testfile trusted xattrs are user visible"
11933
11934         return 0;
11935 }
11936 run_test 102l "listxattr size test =================================="
11937
11938 test_102m() { # LU-3403 llite: error of listxattr when buffer is small
11939         local path=$DIR/$tfile
11940         touch $path
11941
11942         listxattr_size_check $path || error "listattr_size_check $path failed"
11943 }
11944 run_test 102m "Ensure listxattr fails on small bufffer ========"
11945
11946 cleanup_test102
11947
11948 getxattr() { # getxattr path name
11949         # Return the base64 encoding of the value of xattr name on path.
11950         local path=$1
11951         local name=$2
11952
11953         # # getfattr --absolute-names --encoding=base64 --name=trusted.lov $path
11954         # file: $path
11955         # trusted.lov=0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
11956         #
11957         # We print just 0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
11958
11959         getfattr --absolute-names --encoding=base64 --name=$name $path |
11960                 awk -F= -v name=$name '$1 == name {
11961                         print substr($0, index($0, "=") + 1);
11962         }'
11963 }
11964
11965 test_102n() { # LU-4101 mdt: protect internal xattrs
11966         [ -z "$(which setfattr 2>/dev/null)" ] &&
11967                 skip "could not find setfattr"
11968         if [ $MDS1_VERSION -lt $(version_code 2.5.50) ]
11969         then
11970                 skip "MDT < 2.5.50 allows setxattr on internal trusted xattrs"
11971         fi
11972
11973         local file0=$DIR/$tfile.0
11974         local file1=$DIR/$tfile.1
11975         local xattr0=$TMP/$tfile.0
11976         local xattr1=$TMP/$tfile.1
11977         local namelist="lov lma lmv link fid version som hsm"
11978         local name
11979         local value
11980
11981         rm -rf $file0 $file1 $xattr0 $xattr1
11982         touch $file0 $file1
11983
11984         # Get 'before' xattrs of $file1.
11985         getfattr --absolute-names --dump --match=- $file1 > $xattr0
11986
11987         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
11988                 namelist+=" lfsck_namespace"
11989         for name in $namelist; do
11990                 # Try to copy xattr from $file0 to $file1.
11991                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
11992
11993                 setfattr --name=trusted.$name --value="$value" $file1 ||
11994                         error "setxattr 'trusted.$name' failed"
11995
11996                 # Try to set a garbage xattr.
11997                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
11998
11999                 if [[ x$name == "xlov" ]]; then
12000                         setfattr --name=trusted.lov --value="$value" $file1 &&
12001                         error "setxattr invalid 'trusted.lov' success"
12002                 else
12003                         setfattr --name=trusted.$name --value="$value" $file1 ||
12004                                 error "setxattr invalid 'trusted.$name' failed"
12005                 fi
12006
12007                 # Try to remove the xattr from $file1. We don't care if this
12008                 # appears to succeed or fail, we just don't want there to be
12009                 # any changes or crashes.
12010                 setfattr --remove=$trusted.$name $file1 2> /dev/null
12011         done
12012
12013         if [ $MDS1_VERSION -gt $(version_code 2.6.50) ]
12014         then
12015                 name="lfsck_ns"
12016                 # Try to copy xattr from $file0 to $file1.
12017                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
12018
12019                 setfattr --name=trusted.$name --value="$value" $file1 ||
12020                         error "setxattr 'trusted.$name' failed"
12021
12022                 # Try to set a garbage xattr.
12023                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
12024
12025                 setfattr --name=trusted.$name --value="$value" $file1 ||
12026                         error "setxattr 'trusted.$name' failed"
12027
12028                 # Try to remove the xattr from $file1. We don't care if this
12029                 # appears to succeed or fail, we just don't want there to be
12030                 # any changes or crashes.
12031                 setfattr --remove=$trusted.$name $file1 2> /dev/null
12032         fi
12033
12034         # Get 'after' xattrs of file1.
12035         getfattr --absolute-names --dump --match=- $file1 > $xattr1
12036
12037         if ! diff $xattr0 $xattr1; then
12038                 error "before and after xattrs of '$file1' differ"
12039         fi
12040
12041         rm -rf $file0 $file1 $xattr0 $xattr1
12042
12043         return 0
12044 }
12045 run_test 102n "silently ignore setxattr on internal trusted xattrs"
12046
12047 test_102p() { # LU-4703 setxattr did not check ownership
12048         [ $MDS1_VERSION -lt $(version_code 2.5.56) ] &&
12049                 skip "MDS needs to be at least 2.5.56"
12050
12051         local testfile=$DIR/$tfile
12052
12053         touch $testfile
12054
12055         echo "setfacl as user..."
12056         $RUNAS setfacl -m "u:$RUNAS_ID:rwx" $testfile
12057         [ $? -ne 0 ] || error "setfacl by $RUNAS_ID was allowed on $testfile"
12058
12059         echo "setfattr as user..."
12060         setfacl -m "u:$RUNAS_ID:---" $testfile
12061         $RUNAS setfattr -x system.posix_acl_access $testfile
12062         [ $? -ne 0 ] || error "setfattr by $RUNAS_ID was allowed on $testfile"
12063 }
12064 run_test 102p "check setxattr(2) correctly fails without permission"
12065
12066 test_102q() {
12067         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] &&
12068                 skip "MDS needs to be at least 2.6.92"
12069
12070         orphan_linkea_check $DIR/$tfile || error "orphan_linkea_check"
12071 }
12072 run_test 102q "flistxattr should not return trusted.link EAs for orphans"
12073
12074 test_102r() {
12075         [ $MDS1_VERSION -lt $(version_code 2.6.93) ] &&
12076                 skip "MDS needs to be at least 2.6.93"
12077
12078         touch $DIR/$tfile || error "touch"
12079         setfattr -n user.$(basename $tfile) $DIR/$tfile || error "setfattr"
12080         getfattr -n user.$(basename $tfile) $DIR/$tfile || error "getfattr"
12081         rm $DIR/$tfile || error "rm"
12082
12083         #normal directory
12084         mkdir -p $DIR/$tdir || error "mkdir"
12085         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
12086         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
12087         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
12088                 error "$testfile error deleting user.author1"
12089         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
12090                 grep "user.$(basename $tdir)" &&
12091                 error "$tdir did not delete user.$(basename $tdir)"
12092         rmdir $DIR/$tdir || error "rmdir"
12093
12094         #striped directory
12095         test_mkdir $DIR/$tdir
12096         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
12097         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
12098         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
12099                 error "$testfile error deleting user.author1"
12100         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
12101                 grep "user.$(basename $tdir)" &&
12102                 error "$tdir did not delete user.$(basename $tdir)"
12103         rmdir $DIR/$tdir || error "rm striped dir"
12104 }
12105 run_test 102r "set EAs with empty values"
12106
12107 test_102s() {
12108         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
12109                 skip "MDS needs to be at least 2.11.52"
12110
12111         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
12112
12113         save_lustre_params client "llite.*.xattr_cache" > $save
12114
12115         for cache in 0 1; do
12116                 lctl set_param llite.*.xattr_cache=$cache
12117
12118                 rm -f $DIR/$tfile
12119                 touch $DIR/$tfile || error "touch"
12120                 for prefix in lustre security system trusted user; do
12121                         # Note getxattr() may fail with 'Operation not
12122                         # supported' or 'No such attribute' depending
12123                         # on prefix and cache.
12124                         getfattr -n $prefix.n102s $DIR/$tfile &&
12125                                 error "getxattr '$prefix.n102s' should fail (cache = $cache)"
12126                 done
12127         done
12128
12129         restore_lustre_params < $save
12130 }
12131 run_test 102s "getting nonexistent xattrs should fail"
12132
12133 test_102t() {
12134         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
12135                 skip "MDS needs to be at least 2.11.52"
12136
12137         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
12138
12139         save_lustre_params client "llite.*.xattr_cache" > $save
12140
12141         for cache in 0 1; do
12142                 lctl set_param llite.*.xattr_cache=$cache
12143
12144                 for buf_size in 0 256; do
12145                         rm -f $DIR/$tfile
12146                         touch $DIR/$tfile || error "touch"
12147                         setfattr -n user.multiop $DIR/$tfile
12148                         $MULTIOP $DIR/$tfile oa$buf_size ||
12149                                 error "cannot get zero length xattr value (buf_size = $buf_size)"
12150                 done
12151         done
12152
12153         restore_lustre_params < $save
12154 }
12155 run_test 102t "zero length xattr values handled correctly"
12156
12157 run_acl_subtest()
12158 {
12159         local test=$LUSTRE/tests/acl/$1.test
12160         local tmp=$(mktemp -t $1-XXXXXX).test
12161         local bin=$2
12162         local dmn=$3
12163         local grp=$4
12164         local nbd=$5
12165         export LANG=C
12166
12167
12168         local sedusers="-e s/bin/$bin/g -e s/daemon/$dmn/g"
12169         local sedgroups="-e s/:users/:$grp/g"
12170         [[ -z "$nbd" ]] || sedusers+=" -e s/nobody/$nbd/g"
12171
12172         sed $sedusers $sedgroups < $test > $tmp
12173         stack_trap "rm -f $tmp"
12174         [[ -s $tmp ]] || error "sed failed to create test script"
12175
12176         echo "performing $1 with bin='$bin' daemon='$dmn' users='$grp'..."
12177         $LUSTRE/tests/acl/run $tmp || error "run_acl_subtest '$1' failed"
12178 }
12179
12180 test_103a() {
12181         [ "$UID" != 0 ] && skip "must run as root"
12182         $GSS && skip_env "could not run under gss"
12183         [[ "$(lctl get_param -n mdc.*-mdc-*.connect_flags)" =~ "acl" ]] ||
12184                 skip_env "must have acl enabled"
12185         which setfacl || skip_env "could not find setfacl"
12186         remote_mds_nodsh && skip "remote MDS with nodsh"
12187
12188         ACLBIN=${ACLBIN:-"bin"}
12189         ACLDMN=${ACLDMN:-"daemon"}
12190         ACLGRP=${ACLGRP:-"users"}
12191         ACLNBD=${ACLNBD:-"nobody"}
12192
12193         if ! id $ACLBIN ||
12194            [[ "$(id -u $ACLBIN)" != "$(do_facet mds1 id -u $ACLBIN)" ]]; then
12195                 echo "bad 'bin' user '$ACLBIN', using '$USER0'"
12196                 ACLBIN=$USER0
12197                 if ! id $ACLBIN ; then
12198                         cat /etc/passwd
12199                         skip_env "can't find suitable ACL 'bin' $ACLBIN"
12200                 fi
12201         fi
12202         if ! id $ACLDMN || (( $(id -u $ACLDMN) < $(id -u $ACLBIN) )) ||
12203            [[ "$(id -u $ACLDMN)" != "$(do_facet mds1 id -u $ACLDMN)" ]]; then
12204                 echo "bad 'daemon' user '$ACLDMN', using '$USER1'"
12205                 ACLDMN=$USER1
12206                 if ! id $ACLDMN ; then
12207                         cat /etc/passwd
12208                         skip_env "can't find suitable ACL 'daemon' $ACLDMN"
12209                 fi
12210         fi
12211         if ! getent group $ACLGRP; then
12212                 echo "missing 'users' group '$ACLGRP', using '$TSTUSR'"
12213                 ACLGRP="$TSTUSR"
12214                 if ! getent group $ACLGRP; then
12215                         echo "cannot find group '$ACLGRP', adding it"
12216                         cat /etc/group
12217                         add_group 60000 $ACLGRP
12218                 fi
12219         fi
12220
12221         local bingid=$(getent group $ACLBIN | cut -d: -f 3)
12222         local dmngid=$(getent group $ACLDMN | cut -d: -f 3)
12223         local grpgid=$(getent group $ACLGRP | cut -d: -f 3)
12224
12225         if (( $bingid > $grpgid || $dmngid > $grpgid )); then
12226                 echo "group '$ACLGRP' has low gid=$grpgid, use '$TSTUSR'"
12227                 ACLGRP="$TSTUSR"
12228                 if ! getent group $ACLGRP; then
12229                         echo "cannot find group '$ACLGRP', adding it"
12230                         cat /etc/group
12231                         add_group 60000 $ACLGRP
12232                 fi
12233                 grpgid=$(getent group $ACLGRP | cut -d: -f 3)
12234                 if (( $bingid > $grpgid || $dmngid > $grpgid )); then
12235                         cat /etc/group
12236                         skip_env "$ACLGRP gid=$grpgid less than $bingid|$dmngid"
12237                 fi
12238         fi
12239
12240         gpasswd -a $ACLDMN $ACLBIN ||
12241                 error "setting client group failed"             # LU-5641
12242         do_facet mds1 gpasswd -a $ACLDMN $ACLBIN ||
12243                 error "setting MDS group failed"                # LU-5641
12244
12245         declare -a identity_old
12246
12247         for num in $(seq $MDSCOUNT); do
12248                 switch_identity $num true || identity_old[$num]=$?
12249         done
12250
12251         SAVE_UMASK=$(umask)
12252         umask 0022
12253         mkdir -p $DIR/$tdir
12254         cd $DIR/$tdir
12255
12256         run_acl_subtest cp $ACLBIN $ACLDMN $ACLGRP
12257         run_acl_subtest getfacl-noacl $ACLBIN $ACLDMN $ACLGRP
12258         run_acl_subtest misc $ACLBIN $ACLDMN $ACLGRP
12259         run_acl_subtest permissions $ACLBIN $ACLDMN $ACLGRP
12260         # LU-1482 mdd: Setting xattr are properly checked with and without ACLs
12261         # CentOS7- uses nobody=99, while newer distros use nobody=65534
12262         if ! id -u $ACLNBD ||
12263            (( $(id -u nobody) != $(do_facet mds1 id -u nobody) )); then
12264                 ACLNBD="nfsnobody"
12265                 if ! id -u $ACLNBD; then
12266                         ACLNBD=""
12267                 fi
12268         fi
12269         if [[ -n "$ACLNBD" ]] && ! getent group $ACLNBD; then
12270                 add_group $(id -u $ACLNBD) $ACLNBD
12271                 if ! getent group $ACLNBD; then
12272                         ACLNBD=""
12273                 fi
12274         fi
12275         if (( $MDS1_VERSION > $(version_code 2.8.55) )) &&
12276            [[ -n "$ACLNBD" ]] && which setfattr; then
12277                 run_acl_subtest permissions_xattr \
12278                         $ACLBIN $ACLDMN $ACLGRP $ACLNBD
12279         elif [[ -z "$ACLNBD" ]]; then
12280                 echo "skip 'permission_xattr' test - missing 'nobody' user/grp"
12281         else
12282                 echo "skip 'permission_xattr' test - missing setfattr command"
12283         fi
12284         run_acl_subtest setfacl $ACLBIN $ACLDMN $ACLGRP
12285
12286         # inheritance test got from HP
12287         cp $LUSTRE/tests/acl/make-tree . || error "cannot copy make-tree"
12288         chmod +x make-tree || error "chmod +x failed"
12289         run_acl_subtest inheritance $ACLBIN $ACLDMN $ACLGRP
12290         rm -f make-tree
12291
12292         echo "LU-974 ignore umask when acl is enabled..."
12293         run_acl_subtest 974 $ACLBIN $ACLDMN $ACLGRP
12294         if [ $MDSCOUNT -ge 2 ]; then
12295                 run_acl_subtest 974_remote $ACLBIN $ACLDMN $ACLGRP
12296         fi
12297
12298         echo "LU-2561 newly created file is same size as directory..."
12299         if [ "$mds1_FSTYPE" != "zfs" ]; then
12300                 run_acl_subtest 2561 $ACLBIN $ACLDMN $ACLGRP
12301         else
12302                 run_acl_subtest 2561_zfs $ACLBIN $ACLDMN $ACLGRP
12303         fi
12304
12305         run_acl_subtest 4924 $ACLBIN $ACLDMN $ACLGRP
12306
12307         cd $SAVE_PWD
12308         umask $SAVE_UMASK
12309
12310         for num in $(seq $MDSCOUNT); do
12311                 if [ "${identity_old[$num]}" = 1 ]; then
12312                         switch_identity $num false || identity_old[$num]=$?
12313                 fi
12314         done
12315 }
12316 run_test 103a "acl test"
12317
12318 test_103b() {
12319         declare -a pids
12320         local U
12321
12322         stack_trap "rm -f $DIR/$tfile.*"
12323         for U in {0..511}; do
12324                 {
12325                 local O=$(printf "%04o" $U)
12326
12327                 umask $(printf "%04o" $((511 ^ $O)))
12328                 $LFS setstripe -c 1 $DIR/$tfile.s$O
12329                 local S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.s$O))
12330
12331                 (( $S == ($O & 0666) )) ||
12332                         error "lfs setstripe $DIR/$tfile.s$O '$S' != '$O'"
12333
12334                 $LFS setstripe -E16M -c 1 -E1G -S4M $DIR/$tfile.p$O
12335                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.p$O))
12336                 (( $S == ($O & 0666) )) ||
12337                         error "lfs setstripe -E $DIR/$tfile.p$O '$S' != '$O'"
12338
12339                 $LFS setstripe -N2 -c 1 $DIR/$tfile.m$O
12340                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.m$O))
12341                 (( $S == ($O & 0666) )) ||
12342                         error "lfs setstripe -N2 $DIR/$tfile.m$O '$S' != '$O'"
12343                 rm -f $DIR/$tfile.[smp]$0
12344                 } &
12345                 local pid=$!
12346
12347                 # limit the concurrently running threads to 64. LU-11878
12348                 local idx=$((U % 64))
12349                 [ -z "${pids[idx]}" ] || wait ${pids[idx]}
12350                 pids[idx]=$pid
12351         done
12352         wait
12353 }
12354 run_test 103b "umask lfs setstripe"
12355
12356 test_103c() {
12357         mkdir -p $DIR/$tdir
12358         cp -rp $DIR/$tdir $DIR/$tdir.bak
12359
12360         [ -n "$(getfattr -d -m. $DIR/$tdir | grep posix_acl_default)" ] &&
12361                 error "$DIR/$tdir shouldn't contain default ACL"
12362         [ -n "$(getfattr -d -m. $DIR/$tdir.bak | grep posix_acl_default)" ] &&
12363                 error "$DIR/$tdir.bak shouldn't contain default ACL"
12364         true
12365 }
12366 run_test 103c "'cp -rp' won't set empty acl"
12367
12368 test_103e() {
12369         local numacl
12370         local fileacl
12371         local saved_debug=$($LCTL get_param -n debug)
12372
12373         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
12374                 skip "MDS needs to be at least 2.14.52"
12375
12376         large_xattr_enabled || skip_env "ea_inode feature disabled"
12377
12378         mkdir -p $DIR/$tdir
12379         # add big LOV EA to cause reply buffer overflow earlier
12380         $LFS setstripe -C 1000 $DIR/$tdir
12381         lctl set_param mdc.*-mdc*.stats=clear
12382
12383         $LCTL set_param debug=0
12384         stack_trap "$LCTL set_param debug=\"$saved_debug\"" EXIT
12385         stack_trap "$LCTL get_param mdc.*-mdc*.stats" EXIT
12386
12387         # add a large number of default ACLs (expect 8000+ for 2.13+)
12388         for U in {2..7000}; do
12389                 setfacl -d -m user:$U:rwx $DIR/$tdir ||
12390                         error "Able to add just $U default ACLs"
12391         done
12392         numacl=$(getfacl $DIR/$tdir |& grep -c "default:user")
12393         echo "$numacl default ACLs created"
12394
12395         stat $DIR/$tdir || error "Cannot stat directory"
12396         # check file creation
12397         touch $DIR/$tdir/$tfile ||
12398                 error "failed to create $tfile with $numacl default ACLs"
12399         stat $DIR/$tdir/$tfile  || error "Cannot stat file"
12400         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
12401         echo "$fileacl ACLs were inherited"
12402         (( $fileacl == $numacl )) ||
12403                 error "Not all default ACLs were inherited: $numacl != $fileacl"
12404         # check that new ACLs creation adds new ACLs to inherited ACLs
12405         setfacl -m user:19000:rwx $DIR/$tdir/$tfile ||
12406                 error "Cannot set new ACL"
12407         numacl=$((numacl + 1))
12408         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
12409         (( $fileacl == $numacl )) ||
12410                 error "failed to add new ACL: $fileacl != $numacl as expected"
12411         # adds more ACLs to a file to reach their maximum at 8000+
12412         numacl=0
12413         for U in {20000..25000}; do
12414                 setfacl -m user:$U:rwx $DIR/$tdir/$tfile || break
12415                 numacl=$((numacl + 1))
12416         done
12417         echo "Added $numacl more ACLs to the file"
12418         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
12419         echo "Total $fileacl ACLs in file"
12420         stat $DIR/$tdir/$tfile > /dev/null || error "Cannot stat file"
12421         rm -f $DIR/$tdir/$tfile || error "Cannot remove file"
12422         rmdir $DIR/$tdir || error "Cannot remove directory"
12423 }
12424 run_test 103e "inheritance of big amount of default ACLs"
12425
12426 test_103f() {
12427         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
12428                 skip "MDS needs to be at least 2.14.51"
12429
12430         large_xattr_enabled || skip_env "ea_inode feature disabled"
12431
12432         # enable changelog to consume more internal MDD buffers
12433         changelog_register
12434
12435         mkdir -p $DIR/$tdir
12436         # add big LOV EA
12437         $LFS setstripe -C 1000 $DIR/$tdir
12438         setfacl -d -m user:$U:rwx $DIR/$tdir || error "Cannot add default ACLs"
12439         mkdir $DIR/$tdir/inherited || error "failed to create subdirectory"
12440         rmdir $DIR/$tdir/inherited || error "Cannot remove subdirectory"
12441         rmdir $DIR/$tdir || error "Cannot remove directory"
12442 }
12443 run_test 103f "changelog doesn't interfere with default ACLs buffers"
12444
12445 test_104a() {
12446         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12447
12448         touch $DIR/$tfile
12449         lfs df || error "lfs df failed"
12450         lfs df -ih || error "lfs df -ih failed"
12451         lfs df -h $DIR || error "lfs df -h $DIR failed"
12452         lfs df -i $DIR || error "lfs df -i $DIR failed"
12453         lfs df $DIR/$tfile || error "lfs df $DIR/$tfile failed"
12454         lfs df -ih $DIR/$tfile || error "lfs df -ih $DIR/$tfile failed"
12455
12456         local OSC=$(lctl dl | grep OST0000-osc-[^M] | awk '{ print $4 }')
12457         lctl --device %$OSC deactivate
12458         lfs df || error "lfs df with deactivated OSC failed"
12459         lctl --device %$OSC activate
12460         # wait the osc back to normal
12461         wait_osc_import_ready client ost
12462
12463         lfs df || error "lfs df with reactivated OSC failed"
12464         rm -f $DIR/$tfile
12465 }
12466 run_test 104a "lfs df [-ih] [path] test ========================="
12467
12468 test_104b() {
12469         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12470         [ $RUNAS_ID -eq $UID ] &&
12471                 skip_env "RUNAS_ID = UID = $UID -- skipping"
12472
12473         denied_cnt=$(($($RUNAS $LFS check servers 2>&1 |
12474                         grep "Permission denied" | wc -l)))
12475         if [ $denied_cnt -ne 0 ]; then
12476                 error "lfs check servers test failed"
12477         fi
12478 }
12479 run_test 104b "$RUNAS lfs check servers test ===================="
12480
12481 #
12482 # Verify $1 is within range of $2.
12483 # Success when $1 is within range. That is, when $1 is >= 2% of $2 and
12484 # $1 is <= 2% of $2. Else Fail.
12485 #
12486 value_in_range() {
12487         # Strip all units (M, G, T)
12488         actual=$(echo $1 | tr -d A-Z)
12489         expect=$(echo $2 | tr -d A-Z)
12490
12491         expect_lo=$(($expect * 98 / 100)) # 2% below
12492         expect_hi=$(($expect * 102 / 100)) # 2% above
12493
12494         # permit 2% drift above and below
12495         (( $actual >= $expect_lo && $actual <= $expect_hi ))
12496 }
12497
12498 test_104c() {
12499         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12500         [ "$ost1_FSTYPE" == "zfs" ] || skip "zfs only test"
12501
12502         local ost_param="osd-zfs.$FSNAME-OST0000."
12503         local mdt_param="osd-zfs.$FSNAME-MDT0000."
12504         local ofacets=$(get_facets OST)
12505         local mfacets=$(get_facets MDS)
12506         local saved_ost_blocks=
12507         local saved_mdt_blocks=
12508
12509         echo "Before recordsize change"
12510         lfs_df=($($LFS df -h | grep "filesystem_summary:"))
12511         df=($(df -h | grep "$MOUNT"$))
12512
12513         # For checking.
12514         echo "lfs output : ${lfs_df[*]}"
12515         echo "df  output : ${df[*]}"
12516
12517         for facet in ${ofacets//,/ }; do
12518                 if [ -z $saved_ost_blocks ]; then
12519                         saved_ost_blocks=$(do_facet $facet \
12520                                 lctl get_param -n $ost_param.blocksize)
12521                         echo "OST Blocksize: $saved_ost_blocks"
12522                 fi
12523                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
12524                 do_facet $facet zfs set recordsize=32768 $ost
12525         done
12526
12527         # BS too small. Sufficient for functional testing.
12528         for facet in ${mfacets//,/ }; do
12529                 if [ -z $saved_mdt_blocks ]; then
12530                         saved_mdt_blocks=$(do_facet $facet \
12531                                 lctl get_param -n $mdt_param.blocksize)
12532                         echo "MDT Blocksize: $saved_mdt_blocks"
12533                 fi
12534                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
12535                 do_facet $facet zfs set recordsize=32768 $mdt
12536         done
12537
12538         # Give new values chance to reflect change
12539         sleep 2
12540
12541         echo "After recordsize change"
12542         lfs_df_after=($($LFS df -h | grep "filesystem_summary:"))
12543         df_after=($(df -h | grep "$MOUNT"$))
12544
12545         # For checking.
12546         echo "lfs output : ${lfs_df_after[*]}"
12547         echo "df  output : ${df_after[*]}"
12548
12549         # Verify lfs df
12550         value_in_range ${lfs_df_after[1]%.*} ${lfs_df[1]%.*} ||
12551                 error "lfs_df bytes: ${lfs_df_after[1]%.*} != ${lfs_df[1]%.*}"
12552         value_in_range ${lfs_df_after[2]%.*} ${lfs_df[2]%.*} ||
12553                 error "lfs_df used: ${lfs_df_after[2]%.*} != ${lfs_df[2]%.*}"
12554         value_in_range ${lfs_df_after[3]%.*} ${lfs_df[3]%.*} ||
12555                 error "lfs_df avail: ${lfs_df_after[3]%.*} != ${lfs_df[3]%.*}"
12556
12557         # Verify df
12558         value_in_range ${df_after[1]%.*} ${df[1]%.*} ||
12559                 error "df bytes: ${df_after[1]%.*} != ${df[1]%.*}"
12560         value_in_range ${df_after[2]%.*} ${df[2]%.*} ||
12561                 error "df used: ${df_after[2]%.*} != ${df[2]%.*}"
12562         value_in_range ${df_after[3]%.*} ${df[3]%.*} ||
12563                 error "df avail: ${df_after[3]%.*} != ${df[3]%.*}"
12564
12565         # Restore MDT recordize back to original
12566         for facet in ${mfacets//,/ }; do
12567                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
12568                 do_facet $facet zfs set recordsize=$saved_mdt_blocks $mdt
12569         done
12570
12571         # Restore OST recordize back to original
12572         for facet in ${ofacets//,/ }; do
12573                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
12574                 do_facet $facet zfs set recordsize=$saved_ost_blocks $ost
12575         done
12576
12577         return 0
12578 }
12579 run_test 104c "Verify df vs lfs_df stays same after recordsize change"
12580
12581 test_104d() {
12582         (( $RUNAS_ID != $UID )) ||
12583                 skip_env "RUNAS_ID = UID = $UID -- skipping"
12584
12585         (( $CLIENT_VERSION >= $(version_code 2.15.51) )) ||
12586                 skip "lustre version doesn't support lctl dl with non-root"
12587
12588         # debugfs only allows root users to access files, so the
12589         # previous move of the "devices" file to debugfs broke
12590         # "lctl dl" for non-root users. The LU-9680 Netlink
12591         # interface again allows non-root users to list devices.
12592         [ "$($RUNAS $LCTL dl | wc -l)" -ge 3 ] ||
12593                 error "lctl dl doesn't work for non root"
12594
12595         ost_count="$($RUNAS $LCTL dl | grep $FSNAME-OST* | wc -l)"
12596         [ "$ost_count" -eq $OSTCOUNT ]  ||
12597                 error "lctl dl reports wrong number of OST devices"
12598
12599         mdt_count="$($RUNAS $LCTL dl | grep $FSNAME-MDT* | wc -l)"
12600         [ "$mdt_count" -eq $MDSCOUNT ]  ||
12601                 error "lctl dl reports wrong number of MDT devices"
12602 }
12603 run_test 104d "$RUNAS lctl dl test"
12604
12605 test_105a() {
12606         # doesn't work on 2.4 kernels
12607         touch $DIR/$tfile
12608         if $(flock_is_enabled); then
12609                 flocks_test 1 on -f $DIR/$tfile || error "fail flock on"
12610         else
12611                 flocks_test 1 off -f $DIR/$tfile || error "fail flock off"
12612         fi
12613         rm -f $DIR/$tfile
12614 }
12615 run_test 105a "flock when mounted without -o flock test ========"
12616
12617 test_105b() {
12618         touch $DIR/$tfile
12619         if $(flock_is_enabled); then
12620                 flocks_test 1 on -c $DIR/$tfile || error "fail flock on"
12621         else
12622                 flocks_test 1 off -c $DIR/$tfile || error "fail flock off"
12623         fi
12624         rm -f $DIR/$tfile
12625 }
12626 run_test 105b "fcntl when mounted without -o flock test ========"
12627
12628 test_105c() {
12629         touch $DIR/$tfile
12630         if $(flock_is_enabled); then
12631                 flocks_test 1 on -l $DIR/$tfile || error "fail flock on"
12632         else
12633                 flocks_test 1 off -l $DIR/$tfile || error "fail flock off"
12634         fi
12635         rm -f $DIR/$tfile
12636 }
12637 run_test 105c "lockf when mounted without -o flock test"
12638
12639 test_105d() { # bug 15924
12640         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12641
12642         test_mkdir $DIR/$tdir
12643         flock_is_enabled || skip_env "mount w/o flock enabled"
12644         #define OBD_FAIL_LDLM_CP_CB_WAIT  0x315
12645         $LCTL set_param fail_loc=0x80000315
12646         flocks_test 2 $DIR/$tdir
12647 }
12648 run_test 105d "flock race (should not freeze) ========"
12649
12650 test_105e() { # bug 22660 && 22040
12651         flock_is_enabled || skip_env "mount w/o flock enabled"
12652
12653         touch $DIR/$tfile
12654         flocks_test 3 $DIR/$tfile
12655 }
12656 run_test 105e "Two conflicting flocks from same process"
12657
12658 test_106() { #bug 10921
12659         test_mkdir $DIR/$tdir
12660         $DIR/$tdir && error "exec $DIR/$tdir succeeded"
12661         chmod 777 $DIR/$tdir || error "chmod $DIR/$tdir failed"
12662 }
12663 run_test 106 "attempt exec of dir followed by chown of that dir"
12664
12665 test_107() {
12666         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12667
12668         CDIR=`pwd`
12669         local file=core
12670
12671         cd $DIR
12672         rm -f $file
12673
12674         local save_pattern=$(sysctl -n kernel.core_pattern)
12675         local save_uses_pid=$(sysctl -n kernel.core_uses_pid)
12676         sysctl -w kernel.core_pattern=$file
12677         sysctl -w kernel.core_uses_pid=0
12678
12679         ulimit -c unlimited
12680         sleep 60 &
12681         SLEEPPID=$!
12682
12683         sleep 1
12684
12685         kill -s 11 $SLEEPPID
12686         wait $SLEEPPID
12687         if [ -e $file ]; then
12688                 size=`stat -c%s $file`
12689                 [ $size -eq 0 ] && error "Fail to create core file $file"
12690         else
12691                 error "Fail to create core file $file"
12692         fi
12693         rm -f $file
12694         sysctl -w kernel.core_pattern=$save_pattern
12695         sysctl -w kernel.core_uses_pid=$save_uses_pid
12696         cd $CDIR
12697 }
12698 run_test 107 "Coredump on SIG"
12699
12700 test_110() {
12701         test_mkdir $DIR/$tdir
12702         test_mkdir $DIR/$tdir/$(str_repeat 'a' 255)
12703         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/$(str_repeat 'b' 256) &&
12704                 error "mkdir with 256 char should fail, but did not"
12705         touch $DIR/$tdir/$(str_repeat 'x' 255) ||
12706                 error "create with 255 char failed"
12707         touch $DIR/$tdir/$(str_repeat 'y' 256) &&
12708                 error "create with 256 char should fail, but did not"
12709
12710         ls -l $DIR/$tdir
12711         rm -rf $DIR/$tdir
12712 }
12713 run_test 110 "filename length checking"
12714
12715 test_116a() { # was previously test_116()
12716         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12717         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12718         remote_mds_nodsh && skip "remote MDS with nodsh"
12719
12720         echo -n "Free space priority "
12721         do_facet $SINGLEMDS lctl get_param -n lo[vd].*-mdtlov.qos_prio_free |
12722                 head -n1
12723         declare -a AVAIL
12724         free_min_max
12725
12726         [ $MINV -eq 0 ] && skip "no free space in OST$MINI, skip"
12727         [ $MINV -gt 10000000 ] && skip "too much free space in OST$MINI, skip"
12728         stack_trap simple_cleanup_common
12729
12730         # Check if we need to generate uneven OSTs
12731         test_mkdir -p $DIR/$tdir/OST${MINI}
12732         local FILL=$((MINV / 4))
12733         local DIFF=$((MAXV - MINV))
12734         local DIFF2=$((DIFF * 100 / MINV))
12735
12736         local threshold=$(do_facet $SINGLEMDS \
12737                 lctl get_param -n *.*MDT0000-mdtlov.qos_threshold_rr | head -n1)
12738         threshold=${threshold%%%}
12739         echo -n "Check for uneven OSTs: "
12740         echo -n "diff=${DIFF}KB (${DIFF2}%) must be > ${threshold}% ..."
12741
12742         if [[ $DIFF2 -gt $threshold ]]; then
12743                 echo "ok"
12744                 echo "Don't need to fill OST$MINI"
12745         else
12746                 # generate uneven OSTs. Write 2% over the QOS threshold value
12747                 echo "no"
12748                 DIFF=$((threshold - DIFF2 + 2))
12749                 DIFF2=$((MINV * DIFF / 100))
12750                 echo "Fill $DIFF% remaining space in OST$MINI with ${DIFF2}KB"
12751                 $LFS setstripe -i $MINI -c 1 $DIR/$tdir/OST${MINI} ||
12752                         error "setstripe failed"
12753                 DIFF=$((DIFF2 / 2048))
12754                 i=0
12755                 while [ $i -lt $DIFF ]; do
12756                         i=$((i + 1))
12757                         dd if=/dev/zero of=$DIR/$tdir/OST${MINI}/$tfile-$i \
12758                                 bs=2M count=1 2>/dev/null
12759                         echo -n .
12760                 done
12761                 echo .
12762                 sync
12763                 sleep_maxage
12764                 free_min_max
12765         fi
12766
12767         DIFF=$((MAXV - MINV))
12768         DIFF2=$((DIFF * 100 / MINV))
12769         echo -n "diff=$DIFF=$DIFF2% must be > $threshold% for QOS mode..."
12770         if [ $DIFF2 -gt $threshold ]; then
12771                 echo "ok"
12772         else
12773                 skip "QOS imbalance criteria not met"
12774         fi
12775
12776         MINI1=$MINI
12777         MINV1=$MINV
12778         MAXI1=$MAXI
12779         MAXV1=$MAXV
12780
12781         # now fill using QOS
12782         $LFS setstripe -c 1 $DIR/$tdir
12783         FILL=$((FILL / 200))
12784         if [ $FILL -gt 600 ]; then
12785                 FILL=600
12786         fi
12787         echo "writing $FILL files to QOS-assigned OSTs"
12788         i=0
12789         while [ $i -lt $FILL ]; do
12790                 i=$((i + 1))
12791                 dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=200k \
12792                         count=1 2>/dev/null
12793                 echo -n .
12794         done
12795         echo "wrote $i 200k files"
12796         sync
12797         sleep_maxage
12798
12799         echo "Note: free space may not be updated, so measurements might be off"
12800         free_min_max
12801         DIFF2=$((MAXV - MINV))
12802         echo "free space delta: orig $DIFF final $DIFF2"
12803         [ $DIFF2 -gt $DIFF ] && echo "delta got worse!"
12804         DIFF=$((MINV1 - ${AVAIL[$MINI1]}))
12805         echo "Wrote ${DIFF}KB to smaller OST $MINI1"
12806         DIFF2=$((MAXV1 - ${AVAIL[$MAXI1]}))
12807         echo "Wrote ${DIFF2}KB to larger OST $MAXI1"
12808         if [[ $DIFF -gt 0 ]]; then
12809                 FILL=$((DIFF2 * 100 / DIFF - 100))
12810                 echo "Wrote ${FILL}% more data to larger OST $MAXI1"
12811         fi
12812
12813         # Figure out which files were written where
12814         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
12815                awk '/'$MINI1': / {print $2; exit}')
12816         echo $UUID
12817         MINC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
12818         echo "$MINC files created on smaller OST $MINI1"
12819         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
12820                awk '/'$MAXI1': / {print $2; exit}')
12821         echo $UUID
12822         MAXC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
12823         echo "$MAXC files created on larger OST $MAXI1"
12824         if [[ $MINC -gt 0 ]]; then
12825                 FILL=$((MAXC * 100 / MINC - 100))
12826                 echo "Wrote ${FILL}% more files to larger OST $MAXI1"
12827         fi
12828         [[ $MAXC -gt $MINC ]] ||
12829                 error_ignore LU-9 "stripe QOS didn't balance free space"
12830 }
12831 run_test 116a "stripe QOS: free space balance ==================="
12832
12833 test_116b() { # LU-2093
12834         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12835         remote_mds_nodsh && skip "remote MDS with nodsh"
12836
12837 #define OBD_FAIL_MDS_OSC_CREATE_FAIL     0x147
12838         local old_rr=$(do_facet $SINGLEMDS lctl get_param -n \
12839                        lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr | head -1)
12840         [ -z "$old_rr" ] && skip "no QOS"
12841         do_facet $SINGLEMDS lctl set_param \
12842                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=0
12843         mkdir -p $DIR/$tdir
12844         do_facet $SINGLEMDS lctl set_param fail_loc=0x147
12845         createmany -o $DIR/$tdir/f- 20 || error "can't create"
12846         do_facet $SINGLEMDS lctl set_param fail_loc=0
12847         rm -rf $DIR/$tdir
12848         do_facet $SINGLEMDS lctl set_param \
12849                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=$old_rr
12850 }
12851 run_test 116b "QoS shouldn't LBUG if not enough OSTs found on the 2nd pass"
12852
12853 test_117() # bug 10891
12854 {
12855         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12856
12857         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
12858         #define OBD_FAIL_OST_SETATTR_CREDITS 0x21e
12859         lctl set_param fail_loc=0x21e
12860         > $DIR/$tfile || error "truncate failed"
12861         lctl set_param fail_loc=0
12862         echo "Truncate succeeded."
12863         rm -f $DIR/$tfile
12864 }
12865 run_test 117 "verify osd extend =========="
12866
12867 NO_SLOW_RESENDCOUNT=4
12868 export OLD_RESENDCOUNT=""
12869 set_resend_count () {
12870         local PROC_RESENDCOUNT="osc.${FSNAME}-OST*-osc-*.resend_count"
12871         OLD_RESENDCOUNT=$(lctl get_param -n $PROC_RESENDCOUNT | head -n1)
12872         lctl set_param -n $PROC_RESENDCOUNT $1
12873         echo resend_count is set to $(lctl get_param -n $PROC_RESENDCOUNT)
12874 }
12875
12876 # for reduce test_118* time (b=14842)
12877 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
12878
12879 # Reset async IO behavior after error case
12880 reset_async() {
12881         FILE=$DIR/reset_async
12882
12883         # Ensure all OSCs are cleared
12884         $LFS setstripe -c -1 $FILE
12885         dd if=/dev/zero of=$FILE bs=64k count=$OSTCOUNT
12886         sync
12887         rm $FILE
12888 }
12889
12890 test_118a() #bug 11710
12891 {
12892         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12893
12894         reset_async
12895
12896         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12897         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12898         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
12899
12900         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12901                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12902                 return 1;
12903         fi
12904         rm -f $DIR/$tfile
12905 }
12906 run_test 118a "verify O_SYNC works =========="
12907
12908 test_118b()
12909 {
12910         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12911         remote_ost_nodsh && skip "remote OST with nodsh"
12912
12913         reset_async
12914
12915         #define OBD_FAIL_SRV_ENOENT 0x217
12916         set_nodes_failloc "$(osts_nodes)" 0x217
12917         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12918         RC=$?
12919         set_nodes_failloc "$(osts_nodes)" 0
12920         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12921         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12922                     grep -c writeback)
12923
12924         if [[ $RC -eq 0 ]]; then
12925                 error "Must return error due to dropped pages, rc=$RC"
12926                 return 1;
12927         fi
12928
12929         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12930                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12931                 return 1;
12932         fi
12933
12934         echo "Dirty pages not leaked on ENOENT"
12935
12936         # Due to the above error the OSC will issue all RPCs syncronously
12937         # until a subsequent RPC completes successfully without error.
12938         $MULTIOP $DIR/$tfile Ow4096yc
12939         rm -f $DIR/$tfile
12940
12941         return 0
12942 }
12943 run_test 118b "Reclaim dirty pages on fatal error =========="
12944
12945 test_118c()
12946 {
12947         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12948
12949         # for 118c, restore the original resend count, LU-1940
12950         [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] &&
12951                                 set_resend_count $OLD_RESENDCOUNT
12952         remote_ost_nodsh && skip "remote OST with nodsh"
12953
12954         reset_async
12955
12956         #define OBD_FAIL_OST_EROFS               0x216
12957         set_nodes_failloc "$(osts_nodes)" 0x216
12958
12959         # multiop should block due to fsync until pages are written
12960         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
12961         MULTIPID=$!
12962         sleep 1
12963
12964         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
12965                 error "Multiop failed to block on fsync, pid=$MULTIPID"
12966         fi
12967
12968         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12969                     grep -c writeback)
12970         if [[ $WRITEBACK -eq 0 ]]; then
12971                 error "No page in writeback, writeback=$WRITEBACK"
12972         fi
12973
12974         set_nodes_failloc "$(osts_nodes)" 0
12975         wait $MULTIPID
12976         RC=$?
12977         if [[ $RC -ne 0 ]]; then
12978                 error "Multiop fsync failed, rc=$RC"
12979         fi
12980
12981         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12982         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12983                     grep -c writeback)
12984         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12985                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12986         fi
12987
12988         rm -f $DIR/$tfile
12989         echo "Dirty pages flushed via fsync on EROFS"
12990         return 0
12991 }
12992 run_test 118c "Fsync blocks on EROFS until dirty pages are flushed =========="
12993
12994 # continue to use small resend count to reduce test_118* time (b=14842)
12995 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
12996
12997 test_118d()
12998 {
12999         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13000         remote_ost_nodsh && skip "remote OST with nodsh"
13001
13002         reset_async
13003
13004         #define OBD_FAIL_OST_BRW_PAUSE_BULK
13005         set_nodes_failloc "$(osts_nodes)" 0x214
13006         # multiop should block due to fsync until pages are written
13007         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
13008         MULTIPID=$!
13009         sleep 1
13010
13011         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
13012                 error "Multiop failed to block on fsync, pid=$MULTIPID"
13013         fi
13014
13015         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13016                     grep -c writeback)
13017         if [[ $WRITEBACK -eq 0 ]]; then
13018                 error "No page in writeback, writeback=$WRITEBACK"
13019         fi
13020
13021         wait $MULTIPID || error "Multiop fsync failed, rc=$?"
13022         set_nodes_failloc "$(osts_nodes)" 0
13023
13024         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13025         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13026                     grep -c writeback)
13027         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13028                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13029         fi
13030
13031         rm -f $DIR/$tfile
13032         echo "Dirty pages gaurenteed flushed via fsync"
13033         return 0
13034 }
13035 run_test 118d "Fsync validation inject a delay of the bulk =========="
13036
13037 test_118f() {
13038         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13039
13040         reset_async
13041
13042         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
13043         lctl set_param fail_loc=0x8000040a
13044
13045         # Should simulate EINVAL error which is fatal
13046         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13047         RC=$?
13048         if [[ $RC -eq 0 ]]; then
13049                 error "Must return error due to dropped pages, rc=$RC"
13050         fi
13051
13052         lctl set_param fail_loc=0x0
13053
13054         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
13055         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13056         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13057                     grep -c writeback)
13058         if [[ $LOCKED -ne 0 ]]; then
13059                 error "Locked pages remain in cache, locked=$LOCKED"
13060         fi
13061
13062         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13063                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13064         fi
13065
13066         rm -f $DIR/$tfile
13067         echo "No pages locked after fsync"
13068
13069         reset_async
13070         return 0
13071 }
13072 run_test 118f "Simulate unrecoverable OSC side error =========="
13073
13074 test_118g() {
13075         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13076
13077         reset_async
13078
13079         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
13080         lctl set_param fail_loc=0x406
13081
13082         # simulate local -ENOMEM
13083         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13084         RC=$?
13085
13086         lctl set_param fail_loc=0
13087         if [[ $RC -eq 0 ]]; then
13088                 error "Must return error due to dropped pages, rc=$RC"
13089         fi
13090
13091         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
13092         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13093         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13094                         grep -c writeback)
13095         if [[ $LOCKED -ne 0 ]]; then
13096                 error "Locked pages remain in cache, locked=$LOCKED"
13097         fi
13098
13099         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13100                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13101         fi
13102
13103         rm -f $DIR/$tfile
13104         echo "No pages locked after fsync"
13105
13106         reset_async
13107         return 0
13108 }
13109 run_test 118g "Don't stay in wait if we got local -ENOMEM  =========="
13110
13111 test_118h() {
13112         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13113         remote_ost_nodsh && skip "remote OST with nodsh"
13114
13115         reset_async
13116
13117         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
13118         set_nodes_failloc "$(osts_nodes)" 0x20e
13119         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
13120         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13121         RC=$?
13122
13123         set_nodes_failloc "$(osts_nodes)" 0
13124         if [[ $RC -eq 0 ]]; then
13125                 error "Must return error due to dropped pages, rc=$RC"
13126         fi
13127
13128         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
13129         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13130         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13131                     grep -c writeback)
13132         if [[ $LOCKED -ne 0 ]]; then
13133                 error "Locked pages remain in cache, locked=$LOCKED"
13134         fi
13135
13136         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13137                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13138         fi
13139
13140         rm -f $DIR/$tfile
13141         echo "No pages locked after fsync"
13142
13143         return 0
13144 }
13145 run_test 118h "Verify timeout in handling recoverables errors  =========="
13146
13147 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
13148
13149 test_118i() {
13150         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13151         remote_ost_nodsh && skip "remote OST with nodsh"
13152
13153         reset_async
13154
13155         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
13156         set_nodes_failloc "$(osts_nodes)" 0x20e
13157
13158         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
13159         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
13160         PID=$!
13161         sleep 5
13162         set_nodes_failloc "$(osts_nodes)" 0
13163
13164         wait $PID
13165         RC=$?
13166         if [[ $RC -ne 0 ]]; then
13167                 error "got error, but should be not, rc=$RC"
13168         fi
13169
13170         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
13171         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13172         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
13173         if [[ $LOCKED -ne 0 ]]; then
13174                 error "Locked pages remain in cache, locked=$LOCKED"
13175         fi
13176
13177         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13178                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13179         fi
13180
13181         rm -f $DIR/$tfile
13182         echo "No pages locked after fsync"
13183
13184         return 0
13185 }
13186 run_test 118i "Fix error before timeout in recoverable error  =========="
13187
13188 [ "$SLOW" = "no" ] && set_resend_count 4
13189
13190 test_118j() {
13191         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13192         remote_ost_nodsh && skip "remote OST with nodsh"
13193
13194         reset_async
13195
13196         #define OBD_FAIL_OST_BRW_WRITE_BULK2     0x220
13197         set_nodes_failloc "$(osts_nodes)" 0x220
13198
13199         # return -EIO from OST
13200         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13201         RC=$?
13202         set_nodes_failloc "$(osts_nodes)" 0x0
13203         if [[ $RC -eq 0 ]]; then
13204                 error "Must return error due to dropped pages, rc=$RC"
13205         fi
13206
13207         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
13208         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13209         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
13210         if [[ $LOCKED -ne 0 ]]; then
13211                 error "Locked pages remain in cache, locked=$LOCKED"
13212         fi
13213
13214         # in recoverable error on OST we want resend and stay until it finished
13215         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13216                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13217         fi
13218
13219         rm -f $DIR/$tfile
13220         echo "No pages locked after fsync"
13221
13222         return 0
13223 }
13224 run_test 118j "Simulate unrecoverable OST side error =========="
13225
13226 test_118k()
13227 {
13228         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13229         remote_ost_nodsh && skip "remote OSTs with nodsh"
13230
13231         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
13232         set_nodes_failloc "$(osts_nodes)" 0x20e
13233         test_mkdir $DIR/$tdir
13234
13235         for ((i=0;i<10;i++)); do
13236                 (dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=1M count=10 || \
13237                         error "dd to $DIR/$tdir/$tfile-$i failed" )&
13238                 SLEEPPID=$!
13239                 sleep 0.500s
13240                 kill $SLEEPPID
13241                 wait $SLEEPPID
13242         done
13243
13244         set_nodes_failloc "$(osts_nodes)" 0
13245         rm -rf $DIR/$tdir
13246 }
13247 run_test 118k "bio alloc -ENOMEM and IO TERM handling ========="
13248
13249 test_118l() # LU-646
13250 {
13251         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13252
13253         test_mkdir $DIR/$tdir
13254         $MULTIOP $DIR/$tdir Dy || error "fsync dir failed"
13255         rm -rf $DIR/$tdir
13256 }
13257 run_test 118l "fsync dir"
13258
13259 test_118m() # LU-3066
13260 {
13261         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13262
13263         test_mkdir $DIR/$tdir
13264         $MULTIOP $DIR/$tdir DY || error "fdatasync dir failed"
13265         rm -rf $DIR/$tdir
13266 }
13267 run_test 118m "fdatasync dir ========="
13268
13269 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
13270
13271 test_118n()
13272 {
13273         local begin
13274         local end
13275
13276         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13277         remote_ost_nodsh && skip "remote OSTs with nodsh"
13278
13279         # Sleep to avoid a cached response.
13280         #define OBD_STATFS_CACHE_SECONDS 1
13281         sleep 2
13282
13283         # Inject a 10 second delay in the OST_STATFS handler.
13284         #define OBD_FAIL_OST_STATFS_DELAY 0x242
13285         set_nodes_failloc "$(osts_nodes)" 0x242
13286
13287         begin=$SECONDS
13288         stat --file-system $MOUNT > /dev/null
13289         end=$SECONDS
13290
13291         set_nodes_failloc "$(osts_nodes)" 0
13292
13293         if ((end - begin > 20)); then
13294             error "statfs took $((end - begin)) seconds, expected 10"
13295         fi
13296 }
13297 run_test 118n "statfs() sends OST_STATFS requests in parallel"
13298
13299 test_119a() # bug 11737
13300 {
13301         BSIZE=$((512 * 1024))
13302         directio write $DIR/$tfile 0 1 $BSIZE
13303         # We ask to read two blocks, which is more than a file size.
13304         # directio will indicate an error when requested and actual
13305         # sizes aren't equeal (a normal situation in this case) and
13306         # print actual read amount.
13307         NOB=`directio read $DIR/$tfile 0 2 $BSIZE | awk '/error/ {print $6}'`
13308         if [ "$NOB" != "$BSIZE" ]; then
13309                 error "read $NOB bytes instead of $BSIZE"
13310         fi
13311         rm -f $DIR/$tfile
13312 }
13313 run_test 119a "Short directIO read must return actual read amount"
13314
13315 test_119b() # bug 11737
13316 {
13317         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
13318
13319         $LFS setstripe -c 2 $DIR/$tfile || error "setstripe failed"
13320         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1 || error "dd failed"
13321         sync
13322         $MULTIOP $DIR/$tfile oO_RDONLY:O_DIRECT:r$((2048 * 1024)) ||
13323                 error "direct read failed"
13324         rm -f $DIR/$tfile
13325 }
13326 run_test 119b "Sparse directIO read must return actual read amount"
13327
13328 test_119c() # bug 13099
13329 {
13330         BSIZE=1048576
13331         directio write $DIR/$tfile 3 1 $BSIZE || error "direct write failed"
13332         directio readhole $DIR/$tfile 0 2 $BSIZE || error "reading hole failed"
13333         rm -f $DIR/$tfile
13334 }
13335 run_test 119c "Testing for direct read hitting hole"
13336
13337 test_120a() {
13338         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13339         remote_mds_nodsh && skip "remote MDS with nodsh"
13340         test_mkdir -i0 -c1 $DIR/$tdir
13341         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13342                 skip_env "no early lock cancel on server"
13343
13344         lru_resize_disable mdc
13345         lru_resize_disable osc
13346         cancel_lru_locks mdc
13347         # asynchronous object destroy at MDT could cause bl ast to client
13348         cancel_lru_locks osc
13349
13350         stat $DIR/$tdir > /dev/null
13351         can1=$(do_facet mds1 \
13352                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13353                awk '/ldlm_cancel/ {print $2}')
13354         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13355                awk '/ldlm_bl_callback/ {print $2}')
13356         test_mkdir -i0 -c1 $DIR/$tdir/d1
13357         can2=$(do_facet mds1 \
13358                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13359                awk '/ldlm_cancel/ {print $2}')
13360         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13361                awk '/ldlm_bl_callback/ {print $2}')
13362         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
13363         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
13364         lru_resize_enable mdc
13365         lru_resize_enable osc
13366 }
13367 run_test 120a "Early Lock Cancel: mkdir test"
13368
13369 test_120b() {
13370         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13371         remote_mds_nodsh && skip "remote MDS with nodsh"
13372         test_mkdir $DIR/$tdir
13373         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13374                 skip_env "no early lock cancel on server"
13375
13376         lru_resize_disable mdc
13377         lru_resize_disable osc
13378         cancel_lru_locks mdc
13379         stat $DIR/$tdir > /dev/null
13380         can1=$(do_facet $SINGLEMDS \
13381                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13382                awk '/ldlm_cancel/ {print $2}')
13383         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13384                awk '/ldlm_bl_callback/ {print $2}')
13385         touch $DIR/$tdir/f1
13386         can2=$(do_facet $SINGLEMDS \
13387                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13388                awk '/ldlm_cancel/ {print $2}')
13389         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13390                awk '/ldlm_bl_callback/ {print $2}')
13391         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
13392         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
13393         lru_resize_enable mdc
13394         lru_resize_enable osc
13395 }
13396 run_test 120b "Early Lock Cancel: create test"
13397
13398 test_120c() {
13399         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13400         remote_mds_nodsh && skip "remote MDS with nodsh"
13401         test_mkdir -i0 -c1 $DIR/$tdir
13402         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13403                 skip "no early lock cancel on server"
13404
13405         lru_resize_disable mdc
13406         lru_resize_disable osc
13407         test_mkdir -i0 -c1 $DIR/$tdir/d1
13408         test_mkdir -i0 -c1 $DIR/$tdir/d2
13409         touch $DIR/$tdir/d1/f1
13410         cancel_lru_locks mdc
13411         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 > /dev/null
13412         can1=$(do_facet mds1 \
13413                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13414                awk '/ldlm_cancel/ {print $2}')
13415         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13416                awk '/ldlm_bl_callback/ {print $2}')
13417         ln $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
13418         can2=$(do_facet mds1 \
13419                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13420                awk '/ldlm_cancel/ {print $2}')
13421         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13422                awk '/ldlm_bl_callback/ {print $2}')
13423         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
13424         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
13425         lru_resize_enable mdc
13426         lru_resize_enable osc
13427 }
13428 run_test 120c "Early Lock Cancel: link test"
13429
13430 test_120d() {
13431         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13432         remote_mds_nodsh && skip "remote MDS with nodsh"
13433         test_mkdir -i0 -c1 $DIR/$tdir
13434         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13435                 skip_env "no early lock cancel on server"
13436
13437         lru_resize_disable mdc
13438         lru_resize_disable osc
13439         touch $DIR/$tdir
13440         cancel_lru_locks mdc
13441         stat $DIR/$tdir > /dev/null
13442         can1=$(do_facet mds1 \
13443                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13444                awk '/ldlm_cancel/ {print $2}')
13445         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13446                awk '/ldlm_bl_callback/ {print $2}')
13447         chmod a+x $DIR/$tdir
13448         can2=$(do_facet mds1 \
13449                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13450                awk '/ldlm_cancel/ {print $2}')
13451         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13452                awk '/ldlm_bl_callback/ {print $2}')
13453         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
13454         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
13455         lru_resize_enable mdc
13456         lru_resize_enable osc
13457 }
13458 run_test 120d "Early Lock Cancel: setattr test"
13459
13460 test_120e() {
13461         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13462         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13463                 skip_env "no early lock cancel on server"
13464         remote_mds_nodsh && skip "remote MDS with nodsh"
13465
13466         local dlmtrace_set=false
13467
13468         test_mkdir -i0 -c1 $DIR/$tdir
13469         lru_resize_disable mdc
13470         lru_resize_disable osc
13471         ! $LCTL get_param debug | grep -q dlmtrace &&
13472                 $LCTL set_param debug=+dlmtrace && dlmtrace_set=true
13473         dd if=/dev/zero of=$DIR/$tdir/f1 count=1
13474         cancel_lru_locks mdc
13475         cancel_lru_locks osc
13476         dd if=$DIR/$tdir/f1 of=/dev/null
13477         stat $DIR/$tdir $DIR/$tdir/f1 > /dev/null
13478         # XXX client can not do early lock cancel of OST lock
13479         # during unlink (LU-4206), so cancel osc lock now.
13480         sleep 2
13481         cancel_lru_locks osc
13482         can1=$(do_facet mds1 \
13483                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13484                awk '/ldlm_cancel/ {print $2}')
13485         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13486                awk '/ldlm_bl_callback/ {print $2}')
13487         unlink $DIR/$tdir/f1
13488         sleep 5
13489         can2=$(do_facet mds1 \
13490                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13491                awk '/ldlm_cancel/ {print $2}')
13492         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13493                awk '/ldlm_bl_callback/ {print $2}')
13494         [ $can1 -ne $can2 ] && error "$((can2 - can1)) cancel RPC occured" &&
13495                 $LCTL dk $TMP/cancel.debug.txt
13496         [ $blk1 -ne $blk2 ] && error "$((blk2 - blk1)) blocking RPC occured" &&
13497                 $LCTL dk $TMP/blocking.debug.txt
13498         $dlmtrace_set && $LCTL set_param debug=-dlmtrace
13499         lru_resize_enable mdc
13500         lru_resize_enable osc
13501 }
13502 run_test 120e "Early Lock Cancel: unlink test"
13503
13504 test_120f() {
13505         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13506         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13507                 skip_env "no early lock cancel on server"
13508         remote_mds_nodsh && skip "remote MDS with nodsh"
13509
13510         test_mkdir -i0 -c1 $DIR/$tdir
13511         lru_resize_disable mdc
13512         lru_resize_disable osc
13513         test_mkdir -i0 -c1 $DIR/$tdir/d1
13514         test_mkdir -i0 -c1 $DIR/$tdir/d2
13515         dd if=/dev/zero of=$DIR/$tdir/d1/f1 count=1
13516         dd if=/dev/zero of=$DIR/$tdir/d2/f2 count=1
13517         cancel_lru_locks mdc
13518         cancel_lru_locks osc
13519         dd if=$DIR/$tdir/d1/f1 of=/dev/null
13520         dd if=$DIR/$tdir/d2/f2 of=/dev/null
13521         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2 > /dev/null
13522         # XXX client can not do early lock cancel of OST lock
13523         # during rename (LU-4206), so cancel osc lock now.
13524         sleep 2
13525         cancel_lru_locks osc
13526         can1=$(do_facet mds1 \
13527                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13528                awk '/ldlm_cancel/ {print $2}')
13529         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13530                awk '/ldlm_bl_callback/ {print $2}')
13531         mrename $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
13532         sleep 5
13533         can2=$(do_facet mds1 \
13534                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13535                awk '/ldlm_cancel/ {print $2}')
13536         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13537                awk '/ldlm_bl_callback/ {print $2}')
13538         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
13539         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
13540         lru_resize_enable mdc
13541         lru_resize_enable osc
13542 }
13543 run_test 120f "Early Lock Cancel: rename test"
13544
13545 test_120g() {
13546         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13547         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13548                 skip_env "no early lock cancel on server"
13549         remote_mds_nodsh && skip "remote MDS with nodsh"
13550
13551         lru_resize_disable mdc
13552         lru_resize_disable osc
13553         count=10000
13554         echo create $count files
13555         test_mkdir $DIR/$tdir
13556         cancel_lru_locks mdc
13557         cancel_lru_locks osc
13558         t0=$(date +%s)
13559
13560         can0=$(do_facet $SINGLEMDS \
13561                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13562                awk '/ldlm_cancel/ {print $2}')
13563         blk0=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13564                awk '/ldlm_bl_callback/ {print $2}')
13565         createmany -o $DIR/$tdir/f $count
13566         sync
13567         can1=$(do_facet $SINGLEMDS \
13568                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13569                awk '/ldlm_cancel/ {print $2}')
13570         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13571                awk '/ldlm_bl_callback/ {print $2}')
13572         t1=$(date +%s)
13573         echo total: $((can1-can0)) cancels, $((blk1-blk0)) blockings
13574         echo rm $count files
13575         rm -r $DIR/$tdir
13576         sync
13577         can2=$(do_facet $SINGLEMDS \
13578                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13579                awk '/ldlm_cancel/ {print $2}')
13580         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13581                awk '/ldlm_bl_callback/ {print $2}')
13582         t2=$(date +%s)
13583         echo total: $count removes in $((t2-t1))
13584         echo total: $((can2-can1)) cancels, $((blk2-blk1)) blockings
13585         sleep 2
13586         # wait for commitment of removal
13587         lru_resize_enable mdc
13588         lru_resize_enable osc
13589 }
13590 run_test 120g "Early Lock Cancel: performance test"
13591
13592 test_121() { #bug #10589
13593         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13594
13595         rm -rf $DIR/$tfile
13596         writes=$(LANG=C dd if=/dev/zero of=$DIR/$tfile count=1 2>&1 | awk -F '+' '/out$/ {print $1}')
13597 #define OBD_FAIL_LDLM_CANCEL_RACE        0x310
13598         lctl set_param fail_loc=0x310
13599         cancel_lru_locks osc > /dev/null
13600         reads=$(LANG=C dd if=$DIR/$tfile of=/dev/null 2>&1 | awk -F '+' '/in$/ {print $1}')
13601         lctl set_param fail_loc=0
13602         [[ $reads -eq $writes ]] ||
13603                 error "read $reads blocks, must be $writes blocks"
13604 }
13605 run_test 121 "read cancel race ========="
13606
13607 test_123a_base() { # was test 123, statahead(bug 11401)
13608         local lsx="$1"
13609
13610         ost_set_temp_seq_width_all $DATA_SEQ_MAX_WIDTH
13611
13612         SLOWOK=0
13613         if ! grep -q "processor.*: 1" /proc/cpuinfo; then
13614                 log "testing UP system. Performance may be lower than expected."
13615                 SLOWOK=1
13616         fi
13617         running_in_vm && SLOWOK=1
13618
13619         $LCTL set_param mdc.*.batch_stats=0
13620
13621         rm -rf $DIR/$tdir
13622         test_mkdir $DIR/$tdir
13623         NUMFREE=$(df -i -P $DIR | tail -n 1 | awk '{ print $4 }')
13624         [[ $NUMFREE -gt 100000 ]] && NUMFREE=100000 || NUMFREE=$((NUMFREE-1000))
13625         MULT=10
13626         for ((i=100, j=0; i<=$NUMFREE; j=$i, i=$((i * MULT)) )); do
13627                 createmany -o $DIR/$tdir/$tfile $j $((i - j))
13628
13629                 max=$(lctl get_param -n llite.*.statahead_max | head -n 1)
13630                 lctl set_param -n llite.*.statahead_max 0
13631                 lctl get_param llite.*.statahead_max
13632                 cancel_lru_locks mdc
13633                 cancel_lru_locks osc
13634                 stime=$(date +%s)
13635                 time $lsx $DIR/$tdir | wc -l
13636                 etime=$(date +%s)
13637                 delta=$((etime - stime))
13638                 log "$lsx $i files without statahead: $delta sec"
13639                 lctl set_param llite.*.statahead_max=$max
13640
13641                 swrong=$(lctl get_param -n llite.*.statahead_stats |
13642                          awk '/statahead.wrong:/ { print $NF }')
13643                 lctl get_param -n llite.*.statahead_max | grep '[0-9]'
13644                 cancel_lru_locks mdc
13645                 cancel_lru_locks osc
13646                 stime=$(date +%s)
13647                 time $lsx $DIR/$tdir | wc -l
13648                 etime=$(date +%s)
13649                 delta_sa=$((etime - stime))
13650                 log "$lsx $i files with statahead: $delta_sa sec"
13651                 lctl get_param -n llite.*.statahead_stats
13652                 ewrong=$(lctl get_param -n llite.*.statahead_stats |
13653                          awk '/statahead.wrong:/ { print $NF }')
13654
13655                 [[ $swrong -lt $ewrong ]] &&
13656                         log "statahead was stopped, maybe too many locks held!"
13657                 [[ $delta -eq 0 || $delta_sa -eq 0 ]] && continue
13658
13659                 if (( $delta_sa*100 > $delta*105 && $delta_sa > $delta+2)); then
13660                         max=$(lctl get_param -n llite.*.statahead_max |
13661                                 head -n 1)
13662                         lctl set_param -n llite.*.statahead_max 0
13663                         lctl get_param llite.*.statahead_max
13664                         cancel_lru_locks mdc
13665                         cancel_lru_locks osc
13666                         stime=$(date +%s)
13667                         time $lsx $DIR/$tdir | wc -l
13668                         etime=$(date +%s)
13669                         delta=$((etime - stime))
13670                         log "$lsx $i files again without statahead: $delta sec"
13671                         lctl set_param llite.*.statahead_max=$max
13672                         if (( $delta_sa*100 > delta*105 && delta_sa > delta+2 )); then
13673                                 if [ $SLOWOK -eq 0 ]; then
13674                                         error "$lsx $i files is slower with statahead!"
13675                                 else
13676                                         log "$lsx $i files is slower with statahead!"
13677                                 fi
13678                                 break
13679                         fi
13680                 fi
13681
13682                 [ $delta -gt 20 ] && break
13683                 [ $delta -gt 8 ] && MULT=$((50 / delta))
13684                 [ "$SLOW" = "no" -a $delta -gt 5 ] && break
13685         done
13686         log "$lsx done"
13687
13688         stime=$(date +%s)
13689         rm -r $DIR/$tdir
13690         sync
13691         etime=$(date +%s)
13692         delta=$((etime - stime))
13693         log "rm -r $DIR/$tdir/: $delta seconds"
13694         log "rm done"
13695         lctl get_param -n llite.*.statahead_stats
13696         $LCTL get_param mdc.*.batch_stats
13697 }
13698
13699 test_123aa() {
13700         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13701
13702         test_123a_base "ls -l"
13703 }
13704 run_test 123aa "verify statahead work"
13705
13706 test_123ab() {
13707         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13708
13709         statx_supported || skip_env "Test must be statx() syscall supported"
13710
13711         test_123a_base "$STATX -l"
13712 }
13713 run_test 123ab "verify statahead work by using statx"
13714
13715 test_123ac() {
13716         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13717
13718         statx_supported || skip_env "Test must be statx() syscall supported"
13719
13720         local rpcs_before
13721         local rpcs_after
13722         local agl_before
13723         local agl_after
13724
13725         cancel_lru_locks $OSC
13726         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
13727         agl_before=$($LCTL get_param -n llite.*.statahead_stats |
13728                      awk '/agl.total:/ { print $NF }')
13729         test_123a_base "$STATX -c \"%n %i %A %h %u %g %W %X %Z\" -D"
13730         test_123a_base "$STATX --cached=always -D"
13731         agl_after=$($LCTL get_param -n llite.*.statahead_stats |
13732                     awk '/agl.total:/ { print $NF }')
13733         [ $agl_before -eq $agl_after ] ||
13734                 error "Should not trigger AGL thread - $agl_before:$agl_after"
13735         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
13736         [ $rpcs_after -eq $rpcs_before ] ||
13737                 error "$STATX should not send glimpse RPCs to $OSC"
13738 }
13739 run_test 123ac "verify statahead work by using statx without glimpse RPCs"
13740
13741 test_batch_statahead() {
13742         local max=$1
13743         local batch_max=$2
13744         local num=10000
13745         local batch_rpcs
13746         local unbatch_rpcs
13747         local hit_total
13748
13749         echo -e "\nbatching: statahead_max=$max statahead_batch_max=$batch_max"
13750         $LCTL set_param mdc.*.batch_stats=0
13751         $LCTL set_param llite.*.statahead_max=$max
13752         $LCTL set_param llite.*.statahead_batch_max=$batch_max
13753         # Verify that batched statahead is faster than one without statahead
13754         test_123a_base "ls -l"
13755
13756         stack_trap "rm -rf $DIR/$tdir" EXIT
13757         mkdir $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
13758         createmany -o $DIR/$tdir/$tfile $num || error "failed to create files"
13759
13760         # unbatched statahead
13761         $LCTL set_param llite.*.statahead_batch_max=0
13762         $LCTL set_param llite.*.statahead_stats=clear
13763         $LCTL set_param mdc.*.stats=clear
13764         cancel_lru_locks mdc
13765         cancel_lru_locks osc
13766         time ls -l $DIR/$tdir | wc -l
13767         unbatch_rpcs=$(calc_stats mdc.*.stats ldlm_ibits_enqueue)
13768         sleep 2
13769         hit_total=$($LCTL get_param -n llite.*.statahead_stats |
13770                     awk '/hit.total:/ { print $NF }')
13771         # hit ratio should be larger than 75% (7500).
13772         (( $hit_total > 7500 )) ||
13773                 error "unbatched statahead hit count ($hit_total) is too low"
13774
13775         # batched statahead
13776         $LCTL set_param llite.*.statahead_batch_max=$batch_max
13777         $LCTL set_param llite.*.statahead_stats=clear
13778         $LCTL set_param mdc.*.batch_stats=clear
13779         $LCTL set_param mdc.*.stats=clear
13780         cancel_lru_locks mdc
13781         cancel_lru_locks osc
13782         time ls -l $DIR/$tdir | wc -l
13783         batch_rpcs=$(calc_stats mdc.*.stats mds_batch)
13784         # wait for statahead thread to quit and update statahead stats
13785         sleep 2
13786         hit_total=$($LCTL get_param -n llite.*.statahead_stats |
13787                     awk '/hit.total:/ { print $NF }')
13788         # hit ratio should be larger than 75% (7500).
13789         (( $hit_total > 7500 )) ||
13790                 error "batched statahead hit count ($hit_total) is too low"
13791
13792         echo "unbatched RPCs: $unbatch_rpcs, batched RPCs: $batch_rpcs"
13793         (( $unbatch_rpcs > $batch_rpcs )) ||
13794                 error "batched statahead does not reduce RPC count"
13795         $LCTL get_param mdc.*.batch_stats
13796 }
13797
13798 test_123ad() {
13799         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13800
13801         (( $MDS1_VERSION >= $(version_code 2.15.53) )) ||
13802                 skip "Need server version at least 2.15.53"
13803
13804         local max
13805         local batch_max
13806
13807         max=$($LCTL get_param -n llite.*.statahead_max | head -n 1)
13808         batch_max=$($LCTL get_param -n llite.*.statahead_batch_max | head -n 1)
13809
13810         stack_trap "$LCTL set_param llite.*.statahead_max=$max" EXIT
13811         stack_trap "$LCTL set_param llite.*.statahead_batch_max=$batch_max" EXIT
13812
13813         test_batch_statahead 32 32
13814         test_batch_statahead 2048 256
13815 }
13816 run_test 123ad "Verify batching statahead works correctly"
13817
13818 test_123b () { # statahead(bug 15027)
13819         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13820
13821         test_mkdir $DIR/$tdir
13822         createmany -o $DIR/$tdir/$tfile-%d 1000
13823
13824         cancel_lru_locks mdc
13825         cancel_lru_locks osc
13826
13827 #define OBD_FAIL_MDC_GETATTR_ENQUEUE     0x803
13828         lctl set_param fail_loc=0x80000803
13829         ls -lR $DIR/$tdir > /dev/null
13830         log "ls done"
13831         lctl set_param fail_loc=0x0
13832         lctl get_param -n llite.*.statahead_stats
13833         rm -r $DIR/$tdir
13834         sync
13835
13836 }
13837 run_test 123b "not panic with network error in statahead enqueue (bug 15027)"
13838
13839 test_123c() {
13840         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
13841
13842         test_mkdir -i 0 -c 1 $DIR/$tdir.0
13843         test_mkdir -i 1 -c 1 $DIR/$tdir.1
13844         touch $DIR/$tdir.1/{1..3}
13845         mv $DIR/$tdir.1/{1..3} $DIR/$tdir.0
13846
13847         remount_client $MOUNT
13848
13849         $MULTIOP $DIR/$tdir.0 Q
13850
13851         # let statahead to complete
13852         ls -l $DIR/$tdir.0 > /dev/null
13853
13854         testid=$(echo $TESTNAME | tr '_' ' ')
13855         dmesg | tac | sed "/$testid/,$ d" | grep "Can not initialize inode" &&
13856                 error "statahead warning" || true
13857 }
13858 run_test 123c "Can not initialize inode warning on DNE statahead"
13859
13860 test_123d() {
13861         local num=100
13862         local swrong
13863         local ewrong
13864
13865         test_mkdir -c -1 $DIR/$tdir || error "test_mkdir $DIR/$tdir failed"
13866         $LFS setdirstripe -D -c $MDSCOUNT $DIR/$tdir ||
13867                 error "setdirstripe $DIR/$tdir failed"
13868         createmany -d $DIR/$tdir/$tfile $num || error "createmany $num failed"
13869         remount_client $MOUNT
13870         $LCTL get_param llite.*.statahead_max
13871         $LCTL set_param llite.*.statahead_stats=0 ||
13872                 error "clear statahead_stats failed"
13873         swrong=$(lctl get_param -n llite.*.statahead_stats |
13874                  awk '/statahead.wrong:/ { print $NF }')
13875         ls -l $DIR/$tdir || error "ls -l $DIR/$tdir failed"
13876         # wait for statahead thread finished to update hit/miss stats.
13877         sleep 1
13878         $LCTL get_param -n llite.*.statahead_stats
13879         ewrong=$(lctl get_param -n llite.*.statahead_stats |
13880                  awk '/statahead.wrong:/ { print $NF }')
13881         (( $swrong == $ewrong )) ||
13882                 log "statahead was stopped, maybe too many locks held!"
13883 }
13884 run_test 123d "Statahead on striped directories works correctly"
13885
13886 test_123e() {
13887         local max
13888         local batch_max
13889         local dir=$DIR/$tdir
13890
13891         mkdir $dir || error "mkdir $dir failed"
13892         $LFS setstripe -C 32 $dir || error "setstripe $dir failed"
13893         stack_trap "rm -rf $dir"
13894
13895         touch $dir/$tfile.{0..1000} || error "touch 1000 files failed"
13896
13897         max=$($LCTL get_param -n llite.*.statahead_max | head -n 1)
13898         batch_max=$($LCTL get_param -n llite.*.statahead_batch_max | head -n 1)
13899         stack_trap "$LCTL set_param llite.*.statahead_max=$max" EXIT
13900         stack_trap "$LCTL set_param llite.*.statahead_batch_max=$batch_max" EXIT
13901
13902         $LCTL set_param llite.*.statahead_max=2048
13903         $LCTL set_param llite.*.statahead_batch_max=1024
13904
13905         ls -l $dir
13906         $LCTL get_param mdc.*.batch_stats
13907         $LCTL get_param llite.*.statahead_*
13908 }
13909 run_test 123e "statahead with large wide striping"
13910
13911 test_123f() {
13912         local max
13913         local batch_max
13914         local dir=$DIR/$tdir
13915
13916         mkdir $dir || error "mkdir $dir failed"
13917         $LFS setstripe -C 1000 $dir || error "setstripe $dir failed"
13918         stack_trap "rm -rf $dir"
13919
13920         touch $dir/$tfile.{0..200} || error "touch 200 files failed"
13921
13922         max=$($LCTL get_param -n llite.*.statahead_max | head -n 1)
13923         batch_max=$($LCTL get_param -n llite.*.statahead_batch_max | head -n 1)
13924
13925         $LCTL set_param llite.*.statahead_max=64
13926         $LCTL set_param llite.*.statahead_batch_max=64
13927
13928         ls -l $dir
13929         lctl get_param mdc.*.batch_stats
13930         lctl get_param llite.*.statahead_*
13931
13932         $LCTL set_param llite.*.statahead_max=$max
13933         $LCTL set_param llite.*.statahead_batch_max=$batch_max
13934 }
13935 run_test 123f "Retry mechanism with large wide striping files"
13936
13937 test_124a() {
13938         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13939         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13940                 skip_env "no lru resize on server"
13941
13942         local NR=2000
13943
13944         test_mkdir $DIR/$tdir
13945
13946         log "create $NR files at $DIR/$tdir"
13947         createmany -o $DIR/$tdir/f $NR ||
13948                 error "failed to create $NR files in $DIR/$tdir"
13949
13950         cancel_lru_locks mdc
13951         ls -l $DIR/$tdir > /dev/null
13952
13953         local NSDIR=""
13954         local LRU_SIZE=0
13955         for VALUE in $($LCTL get_param ldlm.namespaces.*mdc-*.lru_size); do
13956                 local PARAM=$(echo ${VALUE[0]} | cut -d "=" -f1)
13957                 LRU_SIZE=$($LCTL get_param -n $PARAM)
13958                 if [[ $LRU_SIZE -gt $(default_lru_size) ]]; then
13959                         NSDIR=$(echo $PARAM | cut -d "." -f1-3)
13960                         log "NSDIR=$NSDIR"
13961                         log "NS=$(basename $NSDIR)"
13962                         break
13963                 fi
13964         done
13965
13966         if [[ -z "$NSDIR" || $LRU_SIZE -lt $(default_lru_size) ]]; then
13967                 skip "Not enough cached locks created!"
13968         fi
13969         log "LRU=$LRU_SIZE"
13970
13971         local SLEEP=30
13972
13973         # We know that lru resize allows one client to hold $LIMIT locks
13974         # for 10h. After that locks begin to be killed by client.
13975         local MAX_HRS=10
13976         local LIMIT=$($LCTL get_param -n $NSDIR.pool.limit)
13977         log "LIMIT=$LIMIT"
13978         if [ $LIMIT -lt $LRU_SIZE ]; then
13979                 skip "Limit is too small $LIMIT"
13980         fi
13981
13982         # Make LVF so higher that sleeping for $SLEEP is enough to _start_
13983         # killing locks. Some time was spent for creating locks. This means
13984         # that up to the moment of sleep finish we must have killed some of
13985         # them (10-100 locks). This depends on how fast ther were created.
13986         # Many of them were touched in almost the same moment and thus will
13987         # be killed in groups.
13988         local LVF=$(($MAX_HRS * 60 * 60 / $SLEEP * $LIMIT / $LRU_SIZE * 100))
13989
13990         # Use $LRU_SIZE_B here to take into account real number of locks
13991         # created in the case of CMD, LRU_SIZE_B != $NR in most of cases
13992         local LRU_SIZE_B=$LRU_SIZE
13993         log "LVF=$LVF"
13994         local OLD_LVF=$($LCTL get_param -n $NSDIR.pool.lock_volume_factor)
13995         log "OLD_LVF=$OLD_LVF"
13996         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $LVF
13997
13998         # Let's make sure that we really have some margin. Client checks
13999         # cached locks every 10 sec.
14000         SLEEP=$((SLEEP+20))
14001         log "Sleep ${SLEEP} sec"
14002         local SEC=0
14003         while ((SEC<$SLEEP)); do
14004                 echo -n "..."
14005                 sleep 5
14006                 SEC=$((SEC+5))
14007                 LRU_SIZE=$($LCTL get_param -n $NSDIR/lru_size)
14008                 echo -n "$LRU_SIZE"
14009         done
14010         echo ""
14011         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $OLD_LVF
14012         local LRU_SIZE_A=$($LCTL get_param -n $NSDIR.lru_size)
14013
14014         [[ $LRU_SIZE_B -gt $LRU_SIZE_A ]] || {
14015                 error "No locks dropped in ${SLEEP}s. LRU size: $LRU_SIZE_A"
14016                 unlinkmany $DIR/$tdir/f $NR
14017                 return
14018         }
14019
14020         log "Dropped "$((LRU_SIZE_B-LRU_SIZE_A))" locks in ${SLEEP}s"
14021         log "unlink $NR files at $DIR/$tdir"
14022         unlinkmany $DIR/$tdir/f $NR
14023 }
14024 run_test 124a "lru resize ======================================="
14025
14026 get_max_pool_limit()
14027 {
14028         local limit=$($LCTL get_param \
14029                       -n ldlm.namespaces.*-MDT0000-mdc-*.pool.limit)
14030         local max=0
14031         for l in $limit; do
14032                 if [[ $l -gt $max ]]; then
14033                         max=$l
14034                 fi
14035         done
14036         echo $max
14037 }
14038
14039 test_124b() {
14040         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14041         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
14042                 skip_env "no lru resize on server"
14043
14044         LIMIT=$(get_max_pool_limit)
14045
14046         NR=$(($(default_lru_size)*20))
14047         if [[ $NR -gt $LIMIT ]]; then
14048                 log "Limit lock number by $LIMIT locks"
14049                 NR=$LIMIT
14050         fi
14051
14052         IFree=$(mdsrate_inodes_available)
14053         if [ $IFree -lt $NR ]; then
14054                 log "Limit lock number by $IFree inodes"
14055                 NR=$IFree
14056         fi
14057
14058         lru_resize_disable mdc
14059         test_mkdir -p $DIR/$tdir/disable_lru_resize
14060
14061         createmany -o $DIR/$tdir/disable_lru_resize/f $NR
14062         log "doing ls -la $DIR/$tdir/disable_lru_resize 3 times"
14063         cancel_lru_locks mdc
14064         stime=`date +%s`
14065         PID=""
14066         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
14067         PID="$PID $!"
14068         sleep 2
14069         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
14070         PID="$PID $!"
14071         sleep 2
14072         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
14073         PID="$PID $!"
14074         wait $PID
14075         etime=`date +%s`
14076         nolruresize_delta=$((etime-stime))
14077         log "ls -la time: $nolruresize_delta seconds"
14078         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
14079         unlinkmany $DIR/$tdir/disable_lru_resize/f $NR
14080
14081         lru_resize_enable mdc
14082         test_mkdir -p $DIR/$tdir/enable_lru_resize
14083
14084         createmany -o $DIR/$tdir/enable_lru_resize/f $NR
14085         log "doing ls -la $DIR/$tdir/enable_lru_resize 3 times"
14086         cancel_lru_locks mdc
14087         stime=`date +%s`
14088         PID=""
14089         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
14090         PID="$PID $!"
14091         sleep 2
14092         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
14093         PID="$PID $!"
14094         sleep 2
14095         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
14096         PID="$PID $!"
14097         wait $PID
14098         etime=`date +%s`
14099         lruresize_delta=$((etime-stime))
14100         log "ls -la time: $lruresize_delta seconds"
14101         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
14102
14103         if [ $lruresize_delta -gt $nolruresize_delta ]; then
14104                 log "ls -la is $(((lruresize_delta - $nolruresize_delta) * 100 / $nolruresize_delta))% slower with lru resize enabled"
14105         elif [ $nolruresize_delta -gt $lruresize_delta ]; then
14106                 log "ls -la is $(((nolruresize_delta - $lruresize_delta) * 100 / $nolruresize_delta))% faster with lru resize enabled"
14107         else
14108                 log "lru resize performs the same with no lru resize"
14109         fi
14110         unlinkmany $DIR/$tdir/enable_lru_resize/f $NR
14111 }
14112 run_test 124b "lru resize (performance test) ======================="
14113
14114 test_124c() {
14115         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14116         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
14117                 skip_env "no lru resize on server"
14118
14119         # cache ununsed locks on client
14120         local nr=100
14121         cancel_lru_locks mdc
14122         test_mkdir $DIR/$tdir
14123         createmany -o $DIR/$tdir/f $nr ||
14124                 error "failed to create $nr files in $DIR/$tdir"
14125         ls -l $DIR/$tdir > /dev/null
14126
14127         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
14128         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
14129         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
14130         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
14131         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
14132
14133         # set lru_max_age to 1 sec
14134         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
14135         echo "sleep $((recalc_p * 2)) seconds..."
14136         sleep $((recalc_p * 2))
14137
14138         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
14139         # restore lru_max_age
14140         $LCTL set_param -n $nsdir.lru_max_age $max_age
14141         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
14142         unlinkmany $DIR/$tdir/f $nr
14143 }
14144 run_test 124c "LRUR cancel very aged locks"
14145
14146 test_124d() {
14147         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14148         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
14149                 skip_env "no lru resize on server"
14150
14151         # cache ununsed locks on client
14152         local nr=100
14153
14154         lru_resize_disable mdc
14155         stack_trap "lru_resize_enable mdc" EXIT
14156
14157         cancel_lru_locks mdc
14158
14159         # asynchronous object destroy at MDT could cause bl ast to client
14160         test_mkdir $DIR/$tdir
14161         createmany -o $DIR/$tdir/f $nr ||
14162                 error "failed to create $nr files in $DIR/$tdir"
14163         stack_trap "unlinkmany $DIR/$tdir/f $nr" EXIT
14164
14165         ls -l $DIR/$tdir > /dev/null
14166
14167         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
14168         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
14169         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
14170         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
14171
14172         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
14173
14174         # set lru_max_age to 1 sec
14175         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
14176         stack_trap "$LCTL set_param -n $nsdir.lru_max_age $max_age" EXIT
14177
14178         echo "sleep $((recalc_p * 2)) seconds..."
14179         sleep $((recalc_p * 2))
14180
14181         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
14182
14183         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
14184 }
14185 run_test 124d "cancel very aged locks if lru-resize diasbaled"
14186
14187 test_125() { # 13358
14188         $LCTL get_param -n llite.*.client_type | grep -q local ||
14189                 skip "must run as local client"
14190         $LCTL get_param -n mdc.*-mdc-*.connect_flags | grep -q acl ||
14191                 skip_env "must have acl enabled"
14192         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
14193
14194         test_mkdir $DIR/$tdir
14195         $LFS setstripe -S 65536 -c -1 $DIR/$tdir || error "setstripe failed"
14196         setfacl -R -m u:$USER0:rwx $DIR/$tdir ||
14197                 error "setfacl $DIR/$tdir failed"
14198         ls -ld $DIR/$tdir || error "cannot access $DIR/$tdir"
14199 }
14200 run_test 125 "don't return EPROTO when a dir has a non-default striping and ACLs"
14201
14202 test_126() { # bug 12829/13455
14203         $GSS && skip_env "must run as gss disabled"
14204         $LCTL get_param -n llite.*.client_type | grep -q local ||
14205                 skip "must run as local client"
14206         [ "$UID" != 0 ] && skip "must run as root, not UID $UID"
14207
14208         $RUNAS -u 0 -g 1 touch $DIR/$tfile || error "touch failed"
14209         gid=`ls -n $DIR/$tfile | awk '{print $4}'`
14210         rm -f $DIR/$tfile
14211         [ $gid -eq "1" ] || error "gid is set to" $gid "instead of 1"
14212 }
14213 run_test 126 "check that the fsgid provided by the client is taken into account"
14214
14215 test_127a() { # bug 15521
14216         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14217         local name count samp unit min max sum sumsq
14218         local tmpfile=$TMP/$tfile.tmp
14219
14220         $LFS setstripe -i 0 -c 1 $DIR/$tfile || error "setstripe failed"
14221         echo "stats before reset"
14222         stack_trap "rm -f $tmpfile"
14223         local now=$(date +%s)
14224
14225         $LCTL get_param osc.*.stats | tee $tmpfile
14226
14227         local snapshot_time=$(awk '/snapshot_time/ { print $2; exit }' $tmpfile)
14228         local start_time=$(awk '/start_time/ { print $2; exit }' $tmpfile)
14229         local elapsed=$(awk '/elapsed_time/ { print $2; exit }' $tmpfile)
14230         local uptime=$(awk '{ print $1 }' /proc/uptime)
14231
14232         # snapshot_time should match POSIX epoch time, allow some delta for VMs
14233         (( ${snapshot_time%\.*} >= $now - 5 &&
14234            ${snapshot_time%\.*} <= $now + 5 )) ||
14235                 error "snapshot_time=$snapshot_time != now=$now"
14236         # elapsed _should_ be from mount, but at least less than uptime
14237         (( ${elapsed%\.*} < ${uptime%\.*} )) ||
14238                 error "elapsed=$elapsed > uptime=$uptime"
14239         (( ${snapshot_time%\.*} - ${start_time%\.*} >= ${elapsed%\.*} - 2 &&
14240            ${snapshot_time%\.*} - ${start_time%\.*} <= ${elapsed%\.*} + 2 )) ||
14241                 error "elapsed=$elapsed != $snapshot_time - $start_time"
14242
14243         $LCTL set_param osc.*.stats=0
14244         local reset=$(date +%s)
14245         local fsize=$((2048 * 1024))
14246
14247         dd if=/dev/zero of=$DIR/$tfile bs=$fsize count=1
14248         cancel_lru_locks osc
14249         dd if=$DIR/$tfile of=/dev/null bs=$fsize
14250
14251         now=$(date +%s)
14252         $LCTL get_param osc.*0000-osc-*.stats > $tmpfile
14253         while read name count samp unit min max sum sumsq; do
14254                 [[ "$samp" == "samples" ]] || continue
14255
14256                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
14257                 [ ! $min ] && error "Missing min value for $name proc entry"
14258                 eval $name=$count || error "Wrong proc format"
14259
14260                 case $name in
14261                 read_bytes|write_bytes)
14262                         [[ "$unit" =~ "bytes" ]] ||
14263                                 error "unit is not 'bytes': $unit"
14264                         (( $min >= 4096 )) || error "min is too small: $min"
14265                         (( $min <= $fsize )) || error "min is too big: $min"
14266                         (( $max >= 4096 )) || error "max is too small: $max"
14267                         (( $max <= $fsize )) || error "max is too big: $max"
14268                         (( $sum == $fsize )) || error "sum is wrong: $sum"
14269                         (( $sumsq >= ($fsize / 4096) * (4096 * 4096) )) ||
14270                                 error "sumsquare is too small: $sumsq"
14271                         (( $sumsq <= $fsize * $fsize )) ||
14272                                 error "sumsquare is too big: $sumsq"
14273                         ;;
14274                 ost_read|ost_write)
14275                         [[ "$unit" =~ "usec" ]] ||
14276                                 error "unit is not 'usec': $unit"
14277                         ;;
14278                 *)      ;;
14279                 esac
14280         done < $tmpfile
14281
14282         #check that we actually got some stats
14283         [ "$read_bytes" ] || error "Missing read_bytes stats"
14284         [ "$write_bytes" ] || error "Missing write_bytes stats"
14285         [ "$read_bytes" != 0 ] || error "no read done"
14286         [ "$write_bytes" != 0 ] || error "no write done"
14287
14288         snapshot_time=$(awk '/snapshot_time/ { print $2; exit }' $tmpfile)
14289         start_time=$(awk '/start_time/ { print $2; exit }' $tmpfile)
14290         elapsed=$(awk '/elapsed_time/ { print $2; exit }' $tmpfile)
14291
14292         # snapshot_time should match POSIX epoch time, allow some delta for VMs
14293         (( ${snapshot_time%\.*} >= $now - 5 &&
14294            ${snapshot_time%\.*} <= $now + 5 )) ||
14295                 error "reset snapshot_time=$snapshot_time != now=$now"
14296         # elapsed should be from time of stats reset
14297         (( ${elapsed%\.*} >= $now - $reset - 2 &&
14298            ${elapsed%\.*} <= $now - $reset + 2 )) ||
14299                 error "reset elapsed=$elapsed > $now - $reset"
14300         (( ${snapshot_time%\.*} - ${start_time%\.*} >= ${elapsed%\.*} - 2 &&
14301            ${snapshot_time%\.*} - ${start_time%\.*} <= ${elapsed%\.*} + 2 )) ||
14302                 error "reset elapsed=$elapsed != $snapshot_time - $start_time"
14303 }
14304 run_test 127a "verify the client stats are sane"
14305
14306 test_127b() { # bug LU-333
14307         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14308         local name count samp unit min max sum sumsq
14309
14310         echo "stats before reset"
14311         $LCTL get_param llite.*.stats
14312         $LCTL set_param llite.*.stats=0
14313
14314         # perform 2 reads and writes so MAX is different from SUM.
14315         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
14316         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
14317         cancel_lru_locks osc
14318         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
14319         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
14320
14321         $LCTL get_param llite.*.stats | grep samples > $TMP/$tfile.tmp
14322         stack_trap "rm -f $TMP/$tfile.tmp"
14323         while read name count samp unit min max sum sumsq; do
14324                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
14325                 eval $name=$count || error "Wrong proc format"
14326
14327                 case $name in
14328                 read_bytes|write_bytes)
14329                         [[ "$unit" =~ "bytes" ]] ||
14330                                 error "unit is not 'bytes': $unit"
14331                         (( $count == 2 )) || error "count is not 2: $count"
14332                         (( $min == $PAGE_SIZE )) ||
14333                                 error "min is not $PAGE_SIZE: $min"
14334                         (( $max == $PAGE_SIZE )) ||
14335                                 error "max is not $PAGE_SIZE: $max"
14336                         (( $sum == $PAGE_SIZE * 2 )) ||
14337                                 error "sum is not $((PAGE_SIZE * 2)): $sum"
14338                         ;;
14339                 read|write)
14340                         [[ "$unit" =~ "usec" ]] ||
14341                                 error "unit is not 'usec': $unit"
14342                         ;;
14343                 *)      ;;
14344                 esac
14345         done < $TMP/$tfile.tmp
14346
14347         #check that we actually got some stats
14348         [ "$read_bytes" ] || error "Missing read_bytes stats"
14349         [ "$write_bytes" ] || error "Missing write_bytes stats"
14350         [ "$read_bytes" != 0 ] || error "no read done"
14351         [ "$write_bytes" != 0 ] || error "no write done"
14352 }
14353 run_test 127b "verify the llite client stats are sane"
14354
14355 test_127c() { # LU-12394
14356         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
14357         local size
14358         local bsize
14359         local reads
14360         local writes
14361         local count
14362
14363         $LCTL set_param llite.*.extents_stats=1
14364         stack_trap "$LCTL set_param llite.*.extents_stats=0" EXIT
14365
14366         # Use two stripes so there is enough space in default config
14367         $LFS setstripe -c 2 $DIR/$tfile
14368
14369         # Extent stats start at 0-4K and go in power of two buckets
14370         # LL_HIST_START = 12 --> 2^12 = 4K
14371         # We do 3K*2^i, so 3K, 6K, 12K, 24K... hitting each bucket.
14372         # We do not do buckets larger than 64 MiB to avoid ENOSPC issues on
14373         # small configs
14374         for size in 3K 6K 12K 24K 48K 96K 192K 384K 768K 1536K 3M 6M 12M 24M 48M;
14375                 do
14376                 # Write and read, 2x each, second time at a non-zero offset
14377                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1
14378                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1 seek=10
14379                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1
14380                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1 seek=10
14381                 rm -f $DIR/$tfile
14382         done
14383
14384         $LCTL get_param llite.*.extents_stats
14385
14386         count=2
14387         for bsize in 4K 8K 16K 32K 64K 128K 256K 512K 1M 2M 4M 8M 16M 32M 64M;
14388                 do
14389                 local bucket=$($LCTL get_param -n llite.*.extents_stats |
14390                                 grep -m 1 $bsize)
14391                 reads=$(echo $bucket | awk '{print $5}')
14392                 writes=$(echo $bucket | awk '{print $9}')
14393                 [ "$reads" -eq $count ] ||
14394                         error "$reads reads in < $bsize bucket, expect $count"
14395                 [ "$writes" -eq $count ] ||
14396                         error "$writes writes in < $bsize bucket, expect $count"
14397         done
14398
14399         # Test mmap write and read
14400         $LCTL set_param llite.*.extents_stats=c
14401         size=512
14402         dd if=/dev/zero of=$DIR/$tfile bs=${size}K count=1
14403         $MULTIOP $DIR/$tfile OSMRUc || error "$MULTIOP $DIR/$tfile failed"
14404         $MULTIOP $DIR/$tfile OSMWUc || error "$MULTIOP $DIR/$tfile failed"
14405
14406         $LCTL get_param llite.*.extents_stats
14407
14408         count=$(((size*1024) / PAGE_SIZE))
14409
14410         bsize=$((2 * PAGE_SIZE / 1024))K
14411
14412         bucket=$($LCTL get_param -n llite.*.extents_stats |
14413                         grep -m 1 $bsize)
14414         reads=$(echo $bucket | awk '{print $5}')
14415         writes=$(echo $bucket | awk '{print $9}')
14416         # mmap writes fault in the page first, creating an additonal read
14417         [ "$reads" -eq $((2 * count)) ] ||
14418                 error "$reads reads in < $bsize bucket, expect $count"
14419         [ "$writes" -eq $count ] ||
14420                 error "$writes writes in < $bsize bucket, expect $count"
14421 }
14422 run_test 127c "test llite extent stats with regular & mmap i/o"
14423
14424 test_128() { # bug 15212
14425         touch $DIR/$tfile
14426         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
14427                 find $DIR/$tfile
14428                 find $DIR/$tfile
14429         EOF
14430
14431         result=$(grep error $TMP/$tfile.log)
14432         rm -f $DIR/$tfile $TMP/$tfile.log
14433         [ -z "$result" ] ||
14434                 error "consecutive find's under interactive lfs failed"
14435 }
14436 run_test 128 "interactive lfs for 2 consecutive find's"
14437
14438 set_dir_limits () {
14439         local mntdev
14440         local canondev
14441         local node
14442
14443         local ldproc=/proc/fs/ldiskfs
14444         local facets=$(get_facets MDS)
14445
14446         for facet in ${facets//,/ }; do
14447                 canondev=$(ldiskfs_canon \
14448                            *.$(convert_facet2label $facet).mntdev $facet)
14449                 do_facet $facet "test -e $ldproc/$canondev/max_dir_size" ||
14450                         ldproc=/sys/fs/ldiskfs
14451                 do_facet $facet "echo $1 >$ldproc/$canondev/max_dir_size"
14452                 do_facet $facet "echo $2 >$ldproc/$canondev/warning_dir_size"
14453         done
14454 }
14455
14456 check_mds_dmesg() {
14457         local facets=$(get_facets MDS)
14458         for facet in ${facets//,/ }; do
14459                 do_facet $facet "dmesg | tail -3 | grep $1" && return 0
14460         done
14461         return 1
14462 }
14463
14464 test_129() {
14465         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14466         [[ $MDS1_VERSION -ge $(version_code 2.5.56) ]] ||
14467                 skip "Need MDS version with at least 2.5.56"
14468         if [ "$mds1_FSTYPE" != ldiskfs ]; then
14469                 skip_env "ldiskfs only test"
14470         fi
14471         remote_mds_nodsh && skip "remote MDS with nodsh"
14472
14473         local ENOSPC=28
14474         local has_warning=false
14475
14476         rm -rf $DIR/$tdir
14477         mkdir -p $DIR/$tdir
14478
14479         # block size of mds1
14480         local maxsize=$(($($LCTL get_param -n mdc.*MDT0000*.blocksize) * 8))
14481         set_dir_limits $maxsize $((maxsize * 6 / 8))
14482         stack_trap "set_dir_limits 0 0"
14483         stack_trap "unlinkmany $DIR/$tdir/file_base_ 2000 || true"
14484         local dirsize=$(stat -c%s "$DIR/$tdir")
14485         local nfiles=0
14486         while (( $dirsize <= $maxsize )); do
14487                 $MCREATE $DIR/$tdir/file_base_$nfiles
14488                 rc=$?
14489                 # check two errors:
14490                 # ENOSPC for ext4 max_dir_size, which has been used since
14491                 # kernel v3.6-rc1-8-gdf981d03ee, lustre v2_4_50_0-79-gaed82035c0
14492                 if (( rc == ENOSPC )); then
14493                         set_dir_limits 0 0
14494                         echo "rc=$rc returned as expected after $nfiles files"
14495
14496                         createmany -o $DIR/$tdir/file_extra_$nfiles. 5 ||
14497                                 error "create failed w/o dir size limit"
14498
14499                         # messages may be rate limited if test is run repeatedly
14500                         check_mds_dmesg '"is approaching max"' ||
14501                                 echo "warning message should be output"
14502                         check_mds_dmesg '"has reached max"' ||
14503                                 echo "reached message should be output"
14504
14505                         dirsize=$(stat -c%s "$DIR/$tdir")
14506
14507                         [[ $dirsize -ge $maxsize ]] && return 0
14508                         error "dirsize $dirsize < $maxsize after $nfiles files"
14509                 elif (( rc != 0 )); then
14510                         break
14511                 fi
14512                 nfiles=$((nfiles + 1))
14513                 dirsize=$(stat -c%s "$DIR/$tdir")
14514         done
14515
14516         error "rc=$rc, size=$dirsize/$maxsize, mdt=$MDSCOUNT, nfiles=$nfiles"
14517 }
14518 run_test 129 "test directory size limit ========================"
14519
14520 OLDIFS="$IFS"
14521 cleanup_130() {
14522         trap 0
14523         IFS="$OLDIFS"
14524         rm -f $DIR/$tfile
14525 }
14526
14527 test_130a() {
14528         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
14529         [[ -z "$filefrag_op" ]] || skip_env "filefrag does not support FIEMAP"
14530
14531         trap cleanup_130 EXIT RETURN
14532
14533         local fm_file=$DIR/$tfile
14534         $LFS setstripe -S 65536 -c 1 $fm_file || error "setstripe on $fm_file"
14535         dd if=/dev/zero of=$fm_file bs=65536 count=1 ||
14536                 error "dd failed for $fm_file"
14537
14538         # LU-1795: test filefrag/FIEMAP once, even if unsupported on ZFS
14539         filefrag -ves $fm_file
14540         local rc=$?
14541         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14542                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14543         (( $rc == 0 )) || error "filefrag $fm_file failed"
14544
14545         filefrag_op=$(filefrag -ve -k $fm_file |
14546                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
14547         local lun=$($LFS getstripe -i $fm_file)
14548
14549         local start_blk=$(echo $filefrag_op | cut -d: -f2 | cut -d. -f1)
14550         IFS=$'\n'
14551         local tot_len=0
14552         for line in $filefrag_op; do
14553                 local frag_lun=$(echo $line | cut -d: -f5)
14554                 local ext_len=$(echo $line | cut -d: -f4)
14555
14556                 if (( $frag_lun != $lun )); then
14557                         error "FIEMAP on 1-stripe file($fm_file) failed"
14558                         return
14559                 fi
14560                 (( tot_len += ext_len ))
14561         done
14562
14563         if (( lun != frag_lun || start_blk != 0 || tot_len != 64 )); then
14564                 error "FIEMAP on 1-stripe file($fm_file) failed"
14565                 return
14566         fi
14567
14568         echo "FIEMAP on single striped file succeeded"
14569 }
14570 run_test 130a "FIEMAP (1-stripe file)"
14571
14572 test_130b() {
14573         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
14574
14575         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
14576         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
14577         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14578                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14579
14580         trap cleanup_130 EXIT RETURN
14581
14582         local fm_file=$DIR/$tfile
14583         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
14584                 error "setstripe on $fm_file"
14585
14586         dd if=/dev/zero of=$fm_file bs=1M count=$OSTCOUNT ||
14587                 error "dd failed on $fm_file"
14588
14589         filefrag -ves $fm_file || error "filefrag $fm_file failed"
14590         filefrag_op=$(filefrag -ve -k $fm_file |
14591                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
14592
14593         local last_lun=$(echo $filefrag_op | cut -d: -f5 |
14594                          sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14595
14596         IFS=$'\n'
14597         local tot_len=0
14598         local num_luns=1
14599
14600         for line in $filefrag_op; do
14601                 local frag_lun=$(echo $line | cut -d: -f5 |
14602                                  sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14603                 local ext_len=$(echo $line | cut -d: -f4)
14604                 if (( $frag_lun != $last_lun )); then
14605                         if (( tot_len != 1024 )); then
14606                                 error "FIEMAP on $fm_file failed; returned len $tot_len for OST $last_lun instead of 1024"
14607                                 return
14608                         else
14609                                 (( num_luns += 1 ))
14610                                 tot_len=0
14611                         fi
14612                 fi
14613                 (( tot_len += ext_len ))
14614                 last_lun=$frag_lun
14615         done
14616         if (( num_luns != $OSTCOUNT || tot_len != 1024 )); then
14617                 error "FIEMAP on $fm_file failed; returned wrong number of luns or wrong len for OST $last_lun"
14618                 return
14619         fi
14620
14621         echo "FIEMAP on $OSTCOUNT-stripe file succeeded"
14622 }
14623 run_test 130b "FIEMAP ($OSTCOUNT-stripe file)"
14624
14625 test_130c() {
14626         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
14627
14628         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
14629         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
14630         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14631                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14632
14633         trap cleanup_130 EXIT RETURN
14634
14635         local fm_file=$DIR/$tfile
14636         $LFS setstripe -S 65536 -c 2 $fm_file || error "setstripe on $fm_file"
14637
14638         dd if=/dev/zero of=$fm_file seek=1 bs=1M count=1 ||
14639                 error "dd failed on $fm_file"
14640
14641         filefrag -ves $fm_file || error "filefrag $fm_file failed"
14642         filefrag_op=$(filefrag -ve -k $fm_file |
14643                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
14644
14645         local last_lun=$(echo $filefrag_op | cut -d: -f5 |
14646                          sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14647
14648         IFS=$'\n'
14649         local tot_len=0
14650         local num_luns=1
14651         for line in $filefrag_op; do
14652                 local frag_lun=$(echo $line | cut -d: -f5 |
14653                                  sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14654                 local ext_len=$(echo $line | cut -d: -f4)
14655                 if (( $frag_lun != $last_lun )); then
14656                         local logical=$(echo $line | cut -d: -f2 | cut -d. -f1)
14657                         if (( logical != 512 )); then
14658                                 error "FIEMAP on $fm_file failed; returned logical start for lun $logical instead of 512"
14659                                 return
14660                         fi
14661                         if (( tot_len != 512 )); then
14662                                 error "FIEMAP on $fm_file failed; returned len $tot_len for OST $last_lun instead of 1024"
14663                                 return
14664                         else
14665                                 (( num_luns += 1 ))
14666                                 tot_len=0
14667                         fi
14668                 fi
14669                 (( tot_len += ext_len ))
14670                 last_lun=$frag_lun
14671         done
14672         if (( num_luns != 2 || tot_len != 512 )); then
14673                 error "FIEMAP on $fm_file failed; returned wrong number of luns or wrong len for OST $last_lun"
14674                 return
14675         fi
14676
14677         echo "FIEMAP on 2-stripe file with hole succeeded"
14678 }
14679 run_test 130c "FIEMAP (2-stripe file with hole)"
14680
14681 test_130d() {
14682         (( $OSTCOUNT >= 3 )) || skip "needs >= 3 OSTs"
14683
14684         filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
14685         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
14686         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14687                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14688
14689         trap cleanup_130 EXIT RETURN
14690
14691         local fm_file=$DIR/$tfile
14692         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
14693                         error "setstripe on $fm_file"
14694
14695         local actual_stripe_count=$($LFS getstripe -c $fm_file)
14696         dd if=/dev/zero of=$fm_file bs=1M count=$actual_stripe_count ||
14697                 error "dd failed on $fm_file"
14698
14699         filefrag -ves $fm_file || error "filefrag $fm_file failed"
14700         filefrag_op=$(filefrag -ve -k $fm_file |
14701                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
14702
14703         local last_lun=$(echo $filefrag_op | cut -d: -f5 |
14704                          sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14705
14706         IFS=$'\n'
14707         local tot_len=0
14708         local num_luns=1
14709         for line in $filefrag_op; do
14710                 local frag_lun=$(echo $line | cut -d: -f5 |
14711                                  sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14712                 local ext_len=$(echo $line | cut -d: -f4)
14713                 if (( $frag_lun != $last_lun )); then
14714                         if (( tot_len != 1024 )); then
14715                                 error "FIEMAP on $fm_file failed; returned len $tot_len for OST $last_lun instead of 1024"
14716                                 return
14717                         else
14718                                 (( num_luns += 1 ))
14719                                 local tot_len=0
14720                         fi
14721                 fi
14722                 (( tot_len += ext_len ))
14723                 last_lun=$frag_lun
14724         done
14725         if (( num_luns != actual_stripe_count || tot_len != 1024 )); then
14726                 error "FIEMAP on $fm_file failed; returned wrong number of luns or wrong len for OST $last_lun"
14727                 return
14728         fi
14729
14730         echo "FIEMAP on N-stripe file succeeded"
14731 }
14732 run_test 130d "FIEMAP (N-stripe file)"
14733
14734 test_130e() {
14735         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
14736
14737         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
14738         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
14739         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14740                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14741
14742         trap cleanup_130 EXIT RETURN
14743
14744         local fm_file=$DIR/$tfile
14745         $LFS setstripe -S 131072 -c 2 $fm_file || error "setstripe on $fm_file"
14746         stack_trap "rm -f $fm_file"
14747
14748         local num_blks=512
14749         local expected_len=$(( (num_blks / 2) * 64 ))
14750         for ((i = 0; i < $num_blks; i++)); do
14751                 dd if=/dev/zero of=$fm_file count=1 bs=64k seek=$((2*$i)) \
14752                         conv=notrunc > /dev/null 2>&1
14753         done
14754
14755         filefrag -ves $fm_file || error "filefrag $fm_file failed"
14756         filefrag_op=$(filefrag -ve -k $fm_file |
14757                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
14758
14759         local last_lun=$(echo $filefrag_op | cut -d: -f5)
14760
14761         IFS=$'\n'
14762         local tot_len=0
14763         local num_luns=1
14764         for line in $filefrag_op; do
14765                 local frag_lun=$(echo $line | cut -d: -f5)
14766                 local ext_len=$(echo $line | cut -d: -f4)
14767                 if (( $frag_lun != $last_lun )); then
14768                         if (( tot_len != $expected_len )); then
14769                                 error "OST$last_lun $tot_len != $expected_len"
14770                         else
14771                                 (( num_luns += 1 ))
14772                                 tot_len=0
14773                         fi
14774                 fi
14775                 (( tot_len += ext_len ))
14776                 last_lun=$frag_lun
14777         done
14778         if (( num_luns != 2 || tot_len != $expected_len )); then
14779                 error "OST$last_lun $num_luns != 2, $tot_len != $expected_len"
14780         fi
14781
14782         echo "FIEMAP with continuation calls succeeded"
14783 }
14784 run_test 130e "FIEMAP (test continuation FIEMAP calls)"
14785
14786 test_130f() {
14787         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
14788         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
14789         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14790                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14791
14792         local fm_file=$DIR/$tfile
14793         $MULTIOP $fm_file oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T33554432c ||
14794                 error "multiop create with lov_delay_create on $fm_file"
14795
14796         filefrag -ves $fm_file || error "filefrag $fm_file failed"
14797         filefrag_extents=$(filefrag -vek $fm_file |
14798                            awk '/extents? found/ { print $2 }')
14799         if (( $filefrag_extents != 0 )); then
14800                 error "$fm_file: filefrag_extents=$filefrag_extents != 0"
14801         fi
14802
14803         rm -f $fm_file
14804 }
14805 run_test 130f "FIEMAP (unstriped file)"
14806
14807 test_130g() {
14808         (( $MDS1_VERSION >= $(version_code 2.12.53) )) ||
14809                 skip "Need MDS version with at least 2.12.53 for overstriping"
14810         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
14811         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
14812         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14813                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14814
14815         local file=$DIR/$tfile
14816         local nr=$((OSTCOUNT * 100))
14817
14818         $LFS setstripe -C $nr $file || error "failed to setstripe -C $nr $file"
14819
14820         stack_trap "rm -f $file"
14821         dd if=/dev/zero of=$file count=$nr bs=1M
14822         sync
14823         nr=$($LFS getstripe -c $file)
14824
14825         local extents=$(filefrag -v $file |
14826                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}' | wc -l)
14827
14828         echo "filefrag list $extents extents in file with stripecount $nr"
14829         if (( extents < nr )); then
14830                 $LFS getstripe $file
14831                 filefrag -v $file
14832                 error "filefrag printed $extents < $nr extents"
14833         fi
14834 }
14835 run_test 130g "FIEMAP (overstripe file)"
14836
14837 # Test for writev/readv
14838 test_131a() {
14839         rwv -f $DIR/$tfile -w -n 3 524288 1048576 1572864 ||
14840                 error "writev test failed"
14841         rwv -f $DIR/$tfile -r -v -n 2 1572864 1048576 ||
14842                 error "readv failed"
14843         rm -f $DIR/$tfile
14844 }
14845 run_test 131a "test iov's crossing stripe boundary for writev/readv"
14846
14847 test_131b() {
14848         local fsize=$((524288 + 1048576 + 1572864))
14849         rwv -f $DIR/$tfile -w -a -n 3 524288 1048576 1572864 &&
14850                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
14851                         error "append writev test failed"
14852
14853         ((fsize += 1572864 + 1048576))
14854         rwv -f $DIR/$tfile -w -a -n 2 1572864 1048576 &&
14855                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
14856                         error "append writev test failed"
14857         rm -f $DIR/$tfile
14858 }
14859 run_test 131b "test append writev"
14860
14861 test_131c() {
14862         rwv -f $DIR/$tfile -w -d -n 1 1048576 || return 0
14863         error "NOT PASS"
14864 }
14865 run_test 131c "test read/write on file w/o objects"
14866
14867 test_131d() {
14868         rwv -f $DIR/$tfile -w -n 1 1572864
14869         NOB=`rwv -f $DIR/$tfile -r -n 3 524288 524288 1048576 | awk '/error/ {print $6}'`
14870         if [ "$NOB" != 1572864 ]; then
14871                 error "Short read filed: read $NOB bytes instead of 1572864"
14872         fi
14873         rm -f $DIR/$tfile
14874 }
14875 run_test 131d "test short read"
14876
14877 test_131e() {
14878         rwv -f $DIR/$tfile -w -s 1048576 -n 1 1048576
14879         rwv -f $DIR/$tfile -r -z -s 0 -n 1 524288 || \
14880         error "read hitting hole failed"
14881         rm -f $DIR/$tfile
14882 }
14883 run_test 131e "test read hitting hole"
14884
14885 check_stats() {
14886         local facet=$1
14887         local op=$2
14888         local want=${3:-0}
14889         local res
14890
14891         # open             11 samples [usecs] 468 4793 13658 35791898
14892         case $facet in
14893         mds*) res=($(do_facet $facet \
14894                    $LCTL get_param mdt.$FSNAME-MDT0000.md_stats | grep "$op"))
14895                  ;;
14896         ost*) res=($(do_facet $facet \
14897                   $LCTL get_param obdfilter.$FSNAME-OST0000.stats | grep "$op"))
14898                  ;;
14899         *) error "Wrong facet '$facet'" ;;
14900         esac
14901         [[ -n "$res" ]] || error "counter for $op on $facet not incremented"
14902         # if $want is zero, it means any stat increment is ok.
14903         if (( $want > 0 )); then
14904                 local count=${res[1]}
14905
14906                 if (( $count != $want )); then
14907                         if [[ $facet =~ "mds" ]]; then
14908                                 do_nodes $(comma_list $(mdts_nodes)) \
14909                                         $LCTL get_param mdt.*.md_stats
14910                         else
14911                                 do_nodes $(comma_list $(osts-nodes)) \
14912                                         $LCTL get_param obdfilter.*.stats
14913                         fi
14914                         error "The $op counter on $facet is $count, not $want"
14915                 fi
14916         fi
14917 }
14918
14919 test_133a() {
14920         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14921         remote_ost_nodsh && skip "remote OST with nodsh"
14922         remote_mds_nodsh && skip "remote MDS with nodsh"
14923         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
14924                 skip_env "MDS doesn't support rename stats"
14925
14926         local testdir=$DIR/${tdir}/stats_testdir
14927
14928         mkdir -p $DIR/${tdir}
14929
14930         # clear stats.
14931         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14932         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
14933
14934         # verify mdt stats first.
14935         mkdir_on_mdt0 ${testdir} || error "mkdir_on_mdt0 failed"
14936         check_stats $SINGLEMDS "mkdir" 1
14937
14938         # clear "open" from "lfs mkdir" above
14939         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14940         touch ${testdir}/${tfile} || error "touch failed"
14941         check_stats $SINGLEMDS "open" 1
14942         check_stats $SINGLEMDS "close" 1
14943         [ $MDS1_VERSION -ge $(version_code 2.8.54) ] && {
14944                 mknod ${testdir}/${tfile}-pipe p || error "mknod failed"
14945                 check_stats $SINGLEMDS "mknod" 2
14946         }
14947         rm -f ${testdir}/${tfile}-pipe || error "pipe remove failed"
14948         check_stats $SINGLEMDS "unlink" 1
14949         rm -f ${testdir}/${tfile} || error "file remove failed"
14950         check_stats $SINGLEMDS "unlink" 2
14951
14952         # remove working dir and check mdt stats again.
14953         rmdir ${testdir} || error "rmdir failed"
14954         check_stats $SINGLEMDS "rmdir" 1
14955
14956         local testdir1=$DIR/${tdir}/stats_testdir1
14957         mkdir_on_mdt0 -p ${testdir}
14958         mkdir_on_mdt0 -p ${testdir1}
14959         touch ${testdir1}/test1
14960         mv ${testdir1}/test1 ${testdir} || error "file crossdir rename"
14961         check_stats $SINGLEMDS "crossdir_rename" 1
14962
14963         mv ${testdir}/test1 ${testdir}/test0 || error "file samedir rename"
14964         check_stats $SINGLEMDS "samedir_rename" 1
14965
14966         rm -rf $DIR/${tdir}
14967 }
14968 run_test 133a "Verifying MDT stats ========================================"
14969
14970 test_133b() {
14971         local res
14972
14973         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14974         remote_ost_nodsh && skip "remote OST with nodsh"
14975         remote_mds_nodsh && skip "remote MDS with nodsh"
14976
14977         local testdir=$DIR/${tdir}/stats_testdir
14978
14979         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
14980         mkdir_on_mdt0 ${testdir} || error "mkdir_on_mdt0 failed"
14981         touch ${testdir}/${tfile} || error "touch failed"
14982         cancel_lru_locks mdc
14983
14984         # clear stats.
14985         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14986         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
14987
14988         # extra mdt stats verification.
14989         chmod 444 ${testdir}/${tfile} || error "chmod failed"
14990         check_stats $SINGLEMDS "setattr" 1
14991         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14992         if [ $MDS1_VERSION -ne $(version_code 2.2.0) ]
14993         then            # LU-1740
14994                 ls -l ${testdir}/${tfile} > /dev/null|| error "ls failed"
14995                 check_stats $SINGLEMDS "getattr" 1
14996         fi
14997         rm -rf $DIR/${tdir}
14998
14999         # when DNE is enabled, MDT uses STATFS RPC to ping other targets
15000         # so the check below is not reliable
15001         [ $MDSCOUNT -eq 1 ] || return 0
15002
15003         # Sleep to avoid a cached response.
15004         #define OBD_STATFS_CACHE_SECONDS 1
15005         sleep 2
15006         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15007         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
15008         $LFS df || error "lfs failed"
15009         check_stats $SINGLEMDS "statfs" 1
15010
15011         # check aggregated statfs (LU-10018)
15012         [ $MDS1_VERSION -lt $(version_code 2.11.54) ] &&
15013                 return 0
15014         [ $CLIENT_VERSION -lt $(version_code 2.11.54) ] &&
15015                 return 0
15016         sleep 2
15017         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15018         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
15019         df $DIR
15020         check_stats $SINGLEMDS "statfs" 1
15021
15022         # We want to check that the client didn't send OST_STATFS to
15023         # ost1 but the MDT also uses OST_STATFS for precreate. So some
15024         # extra care is needed here.
15025         if remote_mds; then
15026                 local nid=$($LCTL list_nids | head -1 | sed  "s/\./\\\./g")
15027                 local param="obdfilter.$FSNAME-OST0000.exports.'$nid'.stats"
15028
15029                 res=$(do_facet ost1 $LCTL get_param $param | grep statfs)
15030                 [ "$res" ] && error "OST got STATFS"
15031         fi
15032
15033         return 0
15034 }
15035 run_test 133b "Verifying extra MDT stats =================================="
15036
15037 test_133c() {
15038         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15039         remote_ost_nodsh && skip "remote OST with nodsh"
15040         remote_mds_nodsh && skip "remote MDS with nodsh"
15041
15042         local testdir=$DIR/$tdir/stats_testdir
15043
15044         test_mkdir -p $testdir
15045
15046         # verify obdfilter stats.
15047         $LFS setstripe -c 1 -i 0 $testdir/$tfile
15048         sync
15049         cancel_lru_locks osc
15050         wait_delete_completed
15051
15052         # clear stats.
15053         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15054         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
15055
15056         dd if=/dev/zero of=$testdir/$tfile conv=notrunc bs=512k count=1 ||
15057                 error "dd failed"
15058         sync
15059         cancel_lru_locks osc
15060         check_stats ost1 "write" 1
15061
15062         dd if=$testdir/$tfile of=/dev/null bs=1k count=1 || error "dd failed"
15063         check_stats ost1 "read" 1
15064
15065         > $testdir/$tfile || error "truncate failed"
15066         check_stats ost1 "punch" 1
15067
15068         rm -f $testdir/$tfile || error "file remove failed"
15069         wait_delete_completed
15070         check_stats ost1 "destroy" 1
15071
15072         rm -rf $DIR/$tdir
15073 }
15074 run_test 133c "Verifying OST stats ========================================"
15075
15076 order_2() {
15077         local value=$1
15078         local orig=$value
15079         local order=1
15080
15081         while [ $value -ge 2 ]; do
15082                 order=$((order*2))
15083                 value=$((value/2))
15084         done
15085
15086         if [ $orig -gt $order ]; then
15087                 order=$((order*2))
15088         fi
15089         echo $order
15090 }
15091
15092 size_in_KMGT() {
15093     local value=$1
15094     local size=('K' 'M' 'G' 'T');
15095     local i=0
15096     local size_string=$value
15097
15098     while [ $value -ge 1024 ]; do
15099         if [ $i -gt 3 ]; then
15100             #T is the biggest unit we get here, if that is bigger,
15101             #just return XXXT
15102             size_string=${value}T
15103             break
15104         fi
15105         value=$((value >> 10))
15106         if [ $value -lt 1024 ]; then
15107             size_string=${value}${size[$i]}
15108             break
15109         fi
15110         i=$((i + 1))
15111     done
15112
15113     echo $size_string
15114 }
15115
15116 get_rename_size() {
15117         local size=$1
15118         local context=${2:-.}
15119         local sample=$(do_facet $SINGLEMDS $LCTL \
15120                 get_param mdt.$FSNAME-MDT0000.rename_stats |
15121                 grep -A1 $context |
15122                 awk '/ '${size}'/ {print $4}' | sed -e "s/,//g")
15123         echo $sample
15124 }
15125
15126 test_133d() {
15127         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15128         remote_ost_nodsh && skip "remote OST with nodsh"
15129         remote_mds_nodsh && skip "remote MDS with nodsh"
15130         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
15131                 skip_env "MDS doesn't support rename stats"
15132
15133         local testdir1=$DIR/${tdir}/stats_testdir1
15134         local testdir2=$DIR/${tdir}/stats_testdir2
15135         mkdir -p $DIR/${tdir} || error "mkdir $tdir failed"
15136
15137         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
15138
15139         mkdir_on_mdt0 ${testdir1} || error "mkdir $testdir1 failed"
15140         mkdir_on_mdt0 ${testdir2} || error "mkdir $testdir2 failed"
15141
15142         createmany -o $testdir1/test 512 || error "createmany failed"
15143
15144         # check samedir rename size
15145         mv ${testdir1}/test0 ${testdir1}/test_0
15146
15147         local testdir1_size=$(ls -l $DIR/${tdir} |
15148                 awk '/stats_testdir1/ {print $5}')
15149         local testdir2_size=$(ls -l $DIR/${tdir} |
15150                 awk '/stats_testdir2/ {print $5}')
15151
15152         testdir1_size=$(order_2 $testdir1_size)
15153         testdir2_size=$(order_2 $testdir2_size)
15154
15155         testdir1_size=$(size_in_KMGT $testdir1_size)
15156         testdir2_size=$(size_in_KMGT $testdir2_size)
15157
15158         echo "source rename dir size: ${testdir1_size}"
15159         echo "target rename dir size: ${testdir2_size}"
15160
15161         local cmd="do_facet $SINGLEMDS $LCTL "
15162         cmd+="get_param mdt.$FSNAME-MDT0000.rename_stats"
15163
15164         eval $cmd || error "$cmd failed"
15165         local samedir=$($cmd | grep 'same_dir')
15166         local same_sample=$(get_rename_size $testdir1_size)
15167         [ -z "$samedir" ] && error "samedir_rename_size count error"
15168         [[ $same_sample -eq 1 ]] ||
15169                 error "samedir_rename_size error $same_sample"
15170         echo "Check same dir rename stats success"
15171
15172         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
15173
15174         # check crossdir rename size
15175         mv ${testdir1}/test_0 ${testdir2}/test_0
15176
15177         testdir1_size=$(ls -l $DIR/${tdir} |
15178                 awk '/stats_testdir1/ {print $5}')
15179         testdir2_size=$(ls -l $DIR/${tdir} |
15180                 awk '/stats_testdir2/ {print $5}')
15181
15182         testdir1_size=$(order_2 $testdir1_size)
15183         testdir2_size=$(order_2 $testdir2_size)
15184
15185         testdir1_size=$(size_in_KMGT $testdir1_size)
15186         testdir2_size=$(size_in_KMGT $testdir2_size)
15187
15188         echo "source rename dir size: ${testdir1_size}"
15189         echo "target rename dir size: ${testdir2_size}"
15190
15191         eval $cmd || error "$cmd failed"
15192         local crossdir=$($cmd | grep 'crossdir')
15193         local src_sample=$(get_rename_size $testdir1_size crossdir_src)
15194         local tgt_sample=$(get_rename_size $testdir2_size crossdir_tgt)
15195         [ -z "$crossdir" ] && error "crossdir_rename_size count error"
15196         [[ $src_sample -eq 1 ]] ||
15197                 error "crossdir_rename_size error $src_sample"
15198         [[ $tgt_sample -eq 1 ]] ||
15199                 error "crossdir_rename_size error $tgt_sample"
15200         echo "Check cross dir rename stats success"
15201         rm -rf $DIR/${tdir}
15202 }
15203 run_test 133d "Verifying rename_stats ========================================"
15204
15205 test_133e() {
15206         remote_mds_nodsh && skip "remote MDS with nodsh"
15207         remote_ost_nodsh && skip "remote OST with nodsh"
15208         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15209
15210         local testdir=$DIR/${tdir}/stats_testdir
15211         local ctr f0 f1 bs=32768 count=42 sum
15212
15213         mkdir -p ${testdir} || error "mkdir failed"
15214
15215         $LFS setstripe -c 1 -i 0 ${testdir}/${tfile}
15216
15217         for ctr in {write,read}_bytes; do
15218                 sync
15219                 cancel_lru_locks osc
15220
15221                 do_facet ost1 $LCTL set_param -n \
15222                         "obdfilter.*.exports.clear=clear"
15223
15224                 if [ $ctr = write_bytes ]; then
15225                         f0=/dev/zero
15226                         f1=${testdir}/${tfile}
15227                 else
15228                         f0=${testdir}/${tfile}
15229                         f1=/dev/null
15230                 fi
15231
15232                 dd if=$f0 of=$f1 conv=notrunc bs=$bs count=$count || \
15233                         error "dd failed"
15234                 sync
15235                 cancel_lru_locks osc
15236
15237                 sum=$(do_facet ost1 $LCTL get_param \
15238                         "obdfilter.*.exports.*.stats" |
15239                         awk -v ctr=$ctr 'BEGIN { sum = 0 }
15240                                 $1 == ctr { sum += $7 }
15241                                 END { printf("%0.0f", sum) }')
15242
15243                 if ((sum != bs * count)); then
15244                         error "Bad $ctr sum, expected $((bs * count)), got $sum"
15245                 fi
15246         done
15247
15248         rm -rf $DIR/${tdir}
15249 }
15250 run_test 133e "Verifying OST {read,write}_bytes nid stats ================="
15251
15252 test_133f() {
15253         [[ $(lustre_version_code $facet) -ge $(version_code 2.7.65) ]] ||
15254                 skip "too old lustre for get_param -R ($facet_ver)"
15255
15256         # verifying readability.
15257         $LCTL get_param -R '*' &> /dev/null
15258
15259         # Verifing writability with badarea_io.
15260         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
15261         local skipped_params='force_lbug|changelog_mask|daemon_file'
15262         $LCTL list_param -FR '*' | grep '=' | tr -d = |
15263                 egrep -v "$skipped_params" |
15264                 xargs -n 1 find $proc_dirs -name |
15265                 xargs -n 1 badarea_io ||
15266                 error "client badarea_io failed"
15267
15268         # remount the FS in case writes/reads /proc break the FS
15269         cleanup || error "failed to unmount"
15270         setup || error "failed to setup"
15271 }
15272 run_test 133f "Check reads/writes of client lustre proc files with bad area io"
15273
15274 test_133g() {
15275         remote_mds_nodsh && skip "remote MDS with nodsh"
15276         remote_ost_nodsh && skip "remote OST with nodsh"
15277
15278         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
15279         local proc_dirs_str=$(eval echo $proc_dirs)
15280         local skipped_params="'force_lbug|changelog_mask|daemon_file'"
15281         local facet
15282         for facet in mds1 ost1; do
15283                 local facet_ver=$(lustre_version_code $facet)
15284                 if [ $facet_ver -ge $(version_code 2.7.65) ]; then
15285                         do_facet $facet "$LCTL get_param -R '*'" &> /dev/null
15286                 else
15287                         log "$facet: too old lustre for get_param -R"
15288                 fi
15289                 if [ $facet_ver -ge $(version_code 2.5.54) ]; then
15290                         do_facet $facet "$LCTL list_param -FR '*' | grep '=' |
15291                                 tr -d = | egrep -v $skipped_params |
15292                                 xargs -n 1 find $proc_dirs_str -name |
15293                                 xargs -n 1 badarea_io" ||
15294                                         error "$facet badarea_io failed"
15295                 else
15296                         skip_noexit "$facet: too old lustre for get_param -R"
15297                 fi
15298         done
15299
15300         # remount the FS in case writes/reads /proc break the FS
15301         cleanup || error "failed to unmount"
15302         setup || error "failed to setup"
15303 }
15304 run_test 133g "Check reads/writes of server lustre proc files with bad area io"
15305
15306 test_133h() {
15307         remote_mds_nodsh && skip "remote MDS with nodsh"
15308         remote_ost_nodsh && skip "remote OST with nodsh"
15309         [[ $MDS1_VERSION -lt $(version_code 2.9.54) ]] &&
15310                 skip "Need MDS version at least 2.9.54"
15311
15312         local facet
15313         for facet in client mds1 ost1; do
15314                 # Get the list of files that are missing the terminating newline
15315                 local plist=$(do_facet $facet
15316                         $LCTL list_param -FR '*' | grep '=' | tr -d =)
15317                 local ent
15318                 for ent in $plist; do
15319                         local missing=$(do_facet $facet $LCTL get_param $ent \|\
15320                                 awk -v FS='\v' -v RS='\v\v' \
15321                                 "'END { if(NR>0 && \\\$NF !~ /.*\\\n\$/) \
15322                                         print FILENAME}'" 2>/dev/null)
15323                         [ -z $missing ] || {
15324                                 do_facet $facet $LCTL get_param $ent | od -An -tx1
15325                                 error "file does not end with newline: $facet-$ent"
15326                         }
15327                 done
15328         done
15329 }
15330 run_test 133h "Proc files should end with newlines"
15331
15332 test_134a() {
15333         remote_mds_nodsh && skip "remote MDS with nodsh"
15334         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
15335                 skip "Need MDS version at least 2.7.54"
15336
15337         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
15338         cancel_lru_locks mdc
15339
15340         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
15341         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
15342         [ $unused -eq 0 ] || error "$unused locks are not cleared"
15343
15344         local nr=1000
15345         createmany -o $DIR/$tdir/f $nr ||
15346                 error "failed to create $nr files in $DIR/$tdir"
15347         unused=$($LCTL get_param -n $nsdir.lock_unused_count)
15348
15349         #define OBD_FAIL_LDLM_WATERMARK_LOW     0x327
15350         do_facet mds1 $LCTL set_param fail_loc=0x327
15351         do_facet mds1 $LCTL set_param fail_val=500
15352         touch $DIR/$tdir/m
15353
15354         echo "sleep 10 seconds ..."
15355         sleep 10
15356         local lck_cnt=$($LCTL get_param -n $nsdir.lock_unused_count)
15357
15358         do_facet mds1 $LCTL set_param fail_loc=0
15359         do_facet mds1 $LCTL set_param fail_val=0
15360         [ $lck_cnt -lt $unused ] ||
15361                 error "No locks reclaimed, before:$unused, after:$lck_cnt"
15362
15363         rm $DIR/$tdir/m
15364         unlinkmany $DIR/$tdir/f $nr
15365 }
15366 run_test 134a "Server reclaims locks when reaching lock_reclaim_threshold"
15367
15368 test_134b() {
15369         remote_mds_nodsh && skip "remote MDS with nodsh"
15370         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
15371                 skip "Need MDS version at least 2.7.54"
15372
15373         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
15374         cancel_lru_locks mdc
15375
15376         local low_wm=$(do_facet mds1 $LCTL get_param -n \
15377                         ldlm.lock_reclaim_threshold_mb)
15378         # disable reclaim temporarily
15379         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=0
15380
15381         #define OBD_FAIL_LDLM_WATERMARK_HIGH     0x328
15382         do_facet mds1 $LCTL set_param fail_loc=0x328
15383         do_facet mds1 $LCTL set_param fail_val=500
15384
15385         $LCTL set_param debug=+trace
15386
15387         local nr=600
15388         createmany -o $DIR/$tdir/f $nr &
15389         local create_pid=$!
15390
15391         echo "Sleep $TIMEOUT seconds ..."
15392         sleep $TIMEOUT
15393         if ! ps -p $create_pid  > /dev/null 2>&1; then
15394                 do_facet mds1 $LCTL set_param fail_loc=0
15395                 do_facet mds1 $LCTL set_param fail_val=0
15396                 do_facet mds1 $LCTL set_param \
15397                         ldlm.lock_reclaim_threshold_mb=${low_wm}m
15398                 error "createmany finished incorrectly!"
15399         fi
15400         do_facet mds1 $LCTL set_param fail_loc=0
15401         do_facet mds1 $LCTL set_param fail_val=0
15402         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=${low_wm}m
15403         wait $create_pid || return 1
15404
15405         unlinkmany $DIR/$tdir/f $nr
15406 }
15407 run_test 134b "Server rejects lock request when reaching lock_limit_mb"
15408
15409 test_135() {
15410         remote_mds_nodsh && skip "remote MDS with nodsh"
15411         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
15412                 skip "Need MDS version at least 2.13.50"
15413         local fname
15414
15415         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
15416
15417 #define OBD_FAIL_PLAIN_RECORDS 0x1319
15418         #set only one record at plain llog
15419         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1319 fail_val=1
15420
15421         ost_set_temp_seq_width_all $DATA_SEQ_MAX_WIDTH
15422
15423         #fill already existed plain llog each 64767
15424         #wrapping whole catalog
15425         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
15426
15427         createmany -o $DIR/$tdir/$tfile_ 64700
15428         for (( i = 0; i < 64700; i = i + 2 ))
15429         do
15430                 rm $DIR/$tdir/$tfile_$i &
15431                 rm $DIR/$tdir/$tfile_$((i + 1)) &
15432                 local pid=$!
15433                 wait $pid
15434         done
15435
15436         #waiting osp synchronization
15437         wait_delete_completed
15438 }
15439 run_test 135 "Race catalog processing"
15440
15441 test_136() {
15442         remote_mds_nodsh && skip "remote MDS with nodsh"
15443         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
15444                 skip "Need MDS version at least 2.13.50"
15445         local fname
15446
15447         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
15448         $LFS setstripe -c 1 -i 0 $DIR/$tdir || error "failed to set striping"
15449         #set only one record at plain llog
15450 #define OBD_FAIL_CATALOG_FULL_CHECK                0x131a
15451         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x131a fail_val=1
15452
15453         ost_set_temp_seq_width_all $DATA_SEQ_MAX_WIDTH
15454
15455         #fill already existed 2 plain llogs each 64767
15456         #wrapping whole catalog
15457         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
15458         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 3 / 2))
15459         wait_delete_completed
15460
15461         createmany -o $DIR/$tdir/$tfile_ 10
15462         sleep 25
15463
15464         do_facet $SINGLEMDS $LCTL set_param fail_val=3
15465         for (( i = 0; i < 10; i = i + 3 ))
15466         do
15467                 rm $DIR/$tdir/$tfile_$i &
15468                 rm $DIR/$tdir/$tfile_$((i + 1)) &
15469                 local pid=$!
15470                 wait $pid
15471                 sleep 7
15472                 rm $DIR/$tdir/$tfile_$((i + 2)) &
15473         done
15474
15475         #waiting osp synchronization
15476         wait_delete_completed
15477 }
15478 run_test 136 "Race catalog processing 2"
15479
15480 test_140() { #bug-17379
15481         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15482
15483         test_mkdir $DIR/$tdir
15484         cd $DIR/$tdir || error "Changing to $DIR/$tdir"
15485         cp $(which stat) . || error "Copying stat to $DIR/$tdir"
15486
15487         # VFS limits max symlink depth to 5(4KSTACK) or 7(8KSTACK) or 8
15488         # For kernel > 3.5, bellow only tests consecutive symlink (MAX 40)
15489         local i=0
15490         while i=$((i + 1)); do
15491                 test_mkdir $i
15492                 cd $i || error "Changing to $i"
15493                 ln -s ../stat stat || error "Creating stat symlink"
15494                 # Read the symlink until ELOOP present,
15495                 # not LBUGing the system is considered success,
15496                 # we didn't overrun the stack.
15497                 $OPENFILE -f O_RDONLY stat >/dev/null 2>&1; ret=$?
15498                 if [ $ret -ne 0 ]; then
15499                         if [ $ret -eq 40 ]; then
15500                                 break  # -ELOOP
15501                         else
15502                                 error "Open stat symlink"
15503                                         return
15504                         fi
15505                 fi
15506         done
15507         i=$((i - 1))
15508         echo "The symlink depth = $i"
15509         [ $i -eq 5 ] || [ $i -eq 7 ] || [ $i -eq 8 ] || [ $i -eq 40 ] ||
15510                 error "Invalid symlink depth"
15511
15512         # Test recursive symlink
15513         ln -s symlink_self symlink_self
15514         $OPENFILE -f O_RDONLY symlink_self >/dev/null 2>&1; ret=$?
15515         echo "open symlink_self returns $ret"
15516         [ $ret -eq 40 ] || error "recursive symlink doesn't return -ELOOP"
15517 }
15518 run_test 140 "Check reasonable stack depth (shouldn't LBUG) ===="
15519
15520 test_150a() {
15521         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15522
15523         local TF="$TMP/$tfile"
15524
15525         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15526         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
15527         cp $TF $DIR/$tfile
15528         cancel_lru_locks $OSC
15529         cmp $TF $DIR/$tfile || error "$TMP/$tfile $DIR/$tfile differ"
15530         remount_client $MOUNT
15531         df -P $MOUNT
15532         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (remount)"
15533
15534         $TRUNCATE $TF 6000
15535         $TRUNCATE $DIR/$tfile 6000
15536         cancel_lru_locks $OSC
15537         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (truncate1)"
15538
15539         echo "12345" >>$TF
15540         echo "12345" >>$DIR/$tfile
15541         cancel_lru_locks $OSC
15542         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append1)"
15543
15544         echo "12345" >>$TF
15545         echo "12345" >>$DIR/$tfile
15546         cancel_lru_locks $OSC
15547         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append2)"
15548 }
15549 run_test 150a "truncate/append tests"
15550
15551 test_150b() {
15552         check_set_fallocate_or_skip
15553         local out
15554
15555         touch $DIR/$tfile
15556         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15557         out=$(check_fallocate $DIR/$tfile 2>&1) ||
15558                 skip_eopnotsupp "$out|check_fallocate failed"
15559 }
15560 run_test 150b "Verify fallocate (prealloc) functionality"
15561
15562 test_150bb() {
15563         check_set_fallocate_or_skip
15564
15565         touch $DIR/$tfile
15566         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15567         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=20 || error "dd failed"
15568         > $DIR/$tfile
15569         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
15570         # precomputed md5sum for 20MB of zeroes
15571         local expect="8f4e33f3dc3e414ff94e5fb6905cba8c"
15572         local sum=($(md5sum $DIR/$tfile))
15573
15574         [[ "${sum[0]}" == "$expect" ]] || error "fallocate unwritten is not zero"
15575
15576         check_set_fallocate 1
15577
15578         > $DIR/$tfile
15579         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
15580         sum=($(md5sum $DIR/$tfile))
15581
15582         [[ "${sum[0]}" == "$expect" ]] || error "fallocate zero is not zero"
15583 }
15584 run_test 150bb "Verify fallocate modes both zero space"
15585
15586 test_150c() {
15587         check_set_fallocate_or_skip
15588         local striping="-c2"
15589
15590         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15591         $LFS setstripe -c $OSTCOUNT -S1M $DIR/$tfile || error "setstripe failed"
15592         fallocate -l ${OSTCOUNT}m $DIR/$tfile || error "fallocate failed"
15593         local bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
15594         local want=$((OSTCOUNT * 1048576))
15595
15596         # Must allocate all requested space, not more than 5% extra
15597         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
15598                 error "bytes $bytes is not $want"
15599
15600         rm -f $DIR/$tfile
15601
15602         echo "verify fallocate on PFL file"
15603
15604         [[ "x$DOM" == "xyes" ]] && striping="-L mdt"
15605
15606         $LFS setstripe -E1M $striping -E16M -c3 -Eeof -c 4 $DIR/$tfile ||
15607                 error "Create $DIR/$tfile failed"
15608         fallocate -l $((1048576 * 512)) $DIR/$tfile || error "fallocate failed"
15609         bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
15610         want=$((512 * 1048576))
15611
15612         # Must allocate all requested space, not more than 5% extra
15613         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
15614                 error "bytes $bytes is not $want"
15615 }
15616 run_test 150c "Verify fallocate Size and Blocks"
15617
15618 test_150d() {
15619         check_set_fallocate_or_skip
15620         local striping="-c2"
15621
15622         [[ "x$DOM" == "xyes" ]] && striping="-L mdt"
15623
15624         stack_trap "rm -f $DIR/$tdir; wait_delete_completed"
15625         $LFS setstripe -E1M $striping -E eof -c $OSTCOUNT -S1M $DIR/$tdir ||
15626                 error "setstripe failed"
15627         fallocate -o 1G -l ${OSTCOUNT}m $DIR/$tdir || error "fallocate failed"
15628         local bytes=$(($(stat -c '%b * %B' $DIR/$tdir)))
15629         local want=$((OSTCOUNT * 1048576))
15630
15631         # Must allocate all requested space, not more than 5% extra
15632         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
15633                 error "bytes $bytes is not $want"
15634 }
15635 run_test 150d "Verify fallocate Size and Blocks - Non zero start"
15636
15637 test_150e() {
15638         check_set_fallocate_or_skip
15639
15640         echo "df before:"
15641         $LFS df
15642         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15643         $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
15644                 error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
15645
15646         # Find OST with Minimum Size
15647         min_size_ost=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
15648                        sort -un | head -1)
15649
15650         # Get 100MB per OST of the available space to reduce run time
15651         # else 60% of the available space if we are running SLOW tests
15652         if [ $SLOW == "no" ]; then
15653                 local space=$((1024 * 100 * OSTCOUNT))
15654         else
15655                 local space=$(((min_size_ost * 60)/100 * OSTCOUNT))
15656         fi
15657
15658         fallocate -l${space}k $DIR/$tfile ||
15659                 error "fallocate ${space}k $DIR/$tfile failed"
15660         echo "'fallocate -l ${space}k $DIR/$tfile' succeeded"
15661
15662         # get size immediately after fallocate. This should be correctly
15663         # updated
15664         local size=$(stat -c '%s' $DIR/$tfile)
15665         local used=$(( $(stat -c '%b * %B' $DIR/$tfile) / 1024))
15666
15667         # Sleep for a while for statfs to get updated. And not pull from cache.
15668         sleep 2
15669
15670         echo "df after fallocate:"
15671         $LFS df
15672
15673         (( size / 1024 == space )) || error "size $size != requested $space"
15674         [ "$ost1_FSTYPE" != ldiskfs ] || (( used >= space )) ||
15675                 error "used $used < space $space"
15676
15677         rm $DIR/$tfile || error "rm failed"
15678         sync
15679         wait_delete_completed
15680
15681         echo "df after unlink:"
15682         $LFS df
15683 }
15684 run_test 150e "Verify 60% of available OST space consumed by fallocate"
15685
15686 test_150f() {
15687         local size
15688         local blocks
15689         local want_size_before=20480 # in bytes
15690         local want_blocks_before=40 # 512 sized blocks
15691         local want_blocks_after=24  # 512 sized blocks
15692         local length=$(((want_blocks_before - want_blocks_after) * 512))
15693
15694         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
15695                 skip "need at least 2.14.0 for fallocate punch"
15696
15697         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
15698                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
15699         fi
15700
15701         check_set_fallocate_or_skip
15702         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15703
15704         [[ "x$DOM" == "xyes" ]] &&
15705                 $LFS setstripe -E1M -L mdt -E eof $DIR/$tfile
15706
15707         echo "Verify fallocate punch: Range within the file range"
15708         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
15709                 error "dd failed for bs 4096 and count 5"
15710
15711         # Call fallocate with punch range which is within the file range
15712         out=$(fallocate -p --offset 4096 -l $length $DIR/$tfile 2>&1) ||
15713                 skip_eopnotsupp "$out|fallocate: offset 4096 and length $length"
15714         # client must see changes immediately after fallocate
15715         size=$(stat -c '%s' $DIR/$tfile)
15716         blocks=$(stat -c '%b' $DIR/$tfile)
15717
15718         # Verify punch worked.
15719         (( blocks == want_blocks_after )) ||
15720                 error "punch failed: blocks $blocks != $want_blocks_after"
15721
15722         (( size == want_size_before )) ||
15723                 error "punch failed: size $size != $want_size_before"
15724
15725         # Verify there is hole in file
15726         local data_off=$(lseek_test -d 4096 $DIR/$tfile)
15727         # precomputed md5sum
15728         local expect="4a9a834a2db02452929c0a348273b4aa"
15729
15730         cksum=($(md5sum $DIR/$tfile))
15731         [[ "${cksum[0]}" == "$expect" ]] ||
15732                 error "unexpected MD5SUM after punch: ${cksum[0]}"
15733
15734         # Start second sub-case for fallocate punch.
15735         echo "Verify fallocate punch: Range overlapping and less than blocksize"
15736         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
15737                 error "dd failed for bs 4096 and count 5"
15738
15739         # Punch range less than block size will have no change in block count
15740         want_blocks_after=40  # 512 sized blocks
15741
15742         # Punch overlaps two blocks and less than blocksize
15743         out=$(fallocate -p --offset 4000 -l 3000 $DIR/$tfile 2>&1) ||
15744                 skip_eopnotsupp "$out|fallocate: offset 4000 length 3000"
15745         size=$(stat -c '%s' $DIR/$tfile)
15746         blocks=$(stat -c '%b' $DIR/$tfile)
15747
15748         # Verify punch worked.
15749         (( blocks == want_blocks_after )) ||
15750                 error "punch failed: blocks $blocks != $want_blocks_after"
15751
15752         (( size == want_size_before )) ||
15753                 error "punch failed: size $size != $want_size_before"
15754
15755         # Verify if range is really zero'ed out. We expect Zeros.
15756         # precomputed md5sum
15757         expect="c57ec5d769c3dbe3426edc3f7d7e11d3"
15758         cksum=($(md5sum $DIR/$tfile))
15759         [[ "${cksum[0]}" == "$expect" ]] ||
15760                 error "unexpected MD5SUM after punch: ${cksum[0]}"
15761 }
15762 run_test 150f "Verify fallocate punch functionality"
15763
15764 test_150g() {
15765         local space
15766         local size
15767         local blocks
15768         local blocks_after
15769         local size_after
15770         local BS=4096 # Block size in bytes
15771
15772         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
15773                 skip "need at least 2.14.0 for fallocate punch"
15774
15775         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
15776                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
15777         fi
15778
15779         check_set_fallocate_or_skip
15780         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15781
15782         if [[ "x$DOM" == "xyes" ]]; then
15783                 $LFS setstripe -E2M -L mdt -E eof -c${OSTCOUNT} $DIR/$tfile ||
15784                         error "$LFS setstripe DoM + ${OSTCOUNT} OST failed"
15785         else
15786                 $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
15787                         error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
15788         fi
15789
15790         # Get 100MB per OST of the available space to reduce run time
15791         # else 60% of the available space if we are running SLOW tests
15792         if [ $SLOW == "no" ]; then
15793                 space=$((1024 * 100 * OSTCOUNT))
15794         else
15795                 # Find OST with Minimum Size
15796                 space=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
15797                         sort -un | head -1)
15798                 echo "min size OST: $space"
15799                 space=$(((space * 60)/100 * OSTCOUNT))
15800         fi
15801         # space in 1k units, round to 4k blocks
15802         local blkcount=$((space * 1024 / $BS))
15803
15804         echo "Verify fallocate punch: Very large Range"
15805         fallocate -l${space}k $DIR/$tfile ||
15806                 error "fallocate ${space}k $DIR/$tfile failed"
15807         # write 1M at the end, start and in the middle
15808         yes 'A' | dd of=$DIR/$tfile bs=$BS count=256 ||
15809                 error "dd failed: bs $BS count 256"
15810         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount - 256)) count=256 ||
15811                 error "dd failed: bs $BS count 256 seek $((blkcount - 256))"
15812         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount / 2)) count=1024 ||
15813                 error "dd failed: bs $BS count 256 seek $((blkcount / 2))"
15814
15815         # Gather stats.
15816         size=$(stat -c '%s' $DIR/$tfile)
15817
15818         # gather punch length.
15819         local punch_size=$((size - (BS * 2)))
15820
15821         echo "punch_size = $punch_size"
15822         echo "size - punch_size: $((size - punch_size))"
15823         echo "size - punch_size in blocks: $(((size - punch_size)/BS))"
15824
15825         # Call fallocate to punch all except 2 blocks. We leave the
15826         # first and the last block
15827         echo "fallocate -p --offset $BS -l $punch_size $DIR/$tfile"
15828         out=$(fallocate -p --offset $BS -l $punch_size $DIR/$tfile 2>&1) ||
15829                 skip_eopnotsupp "$out|fallocate: offset $BS length $punch_size"
15830
15831         size_after=$(stat -c '%s' $DIR/$tfile)
15832         blocks_after=$(stat -c '%b' $DIR/$tfile)
15833
15834         # Verify punch worked.
15835         # Size should be kept
15836         (( size == size_after )) ||
15837                 error "punch failed: size $size != $size_after"
15838
15839         # two 4k data blocks to remain plus possible 1 extra extent block
15840         (( blocks_after <= ((BS / 512) * 3) )) ||
15841                 error "too many blocks remains: $blocks_after"
15842
15843         # Verify that file has hole between the first and the last blocks
15844         local hole_start=$(lseek_test -l 0 $DIR/$tfile)
15845         local hole_end=$(lseek_test -d $BS $DIR/$tfile)
15846
15847         echo "Hole at [$hole_start, $hole_end)"
15848         (( hole_start == BS )) ||
15849                 error "no hole at offset $BS after punch"
15850
15851         (( hole_end == BS + punch_size )) ||
15852                 error "data at offset $hole_end < $((BS + punch_size))"
15853 }
15854 run_test 150g "Verify fallocate punch on large range"
15855
15856 test_150h() {
15857         local file=$DIR/$tfile
15858         local size
15859
15860         check_set_fallocate_or_skip
15861         statx_supported || skip_env "Test must be statx() syscall supported"
15862
15863         # fallocate() does not update the size information on the MDT
15864         fallocate -l 16K $file || error "failed to fallocate $file"
15865         cancel_lru_locks $OSC
15866         # STATX with cached-always mode will not send glimpse RPCs to OST,
15867         # it uses the caching attrs on the client side as much as possible.
15868         size=$($STATX --cached=always -c %s $file)
15869         [ $size == 16384 ] ||
15870                 error "size after fallocate() is $size, expected 16384"
15871 }
15872 run_test 150h "Verify extend fallocate updates the file size"
15873
15874 #LU-2902 roc_hit was not able to read all values from lproc
15875 function roc_hit_init() {
15876         local list=$(comma_list $(osts_nodes))
15877         local dir=$DIR/$tdir-check
15878         local file=$dir/$tfile
15879         local BEFORE
15880         local AFTER
15881         local idx
15882
15883         test_mkdir $dir
15884         #use setstripe to do a write to every ost
15885         for i in $(seq 0 $((OSTCOUNT-1))); do
15886                 $LFS setstripe -c 1 -i $i $dir || error "$LFS setstripe $file failed"
15887                 dd if=/dev/urandom of=$file bs=4k count=4 2>&1 > /dev/null
15888                 idx=$(printf %04x $i)
15889                 BEFORE=$(get_osd_param $list *OST*$idx stats |
15890                         awk '$1 == "cache_access" {sum += $7}
15891                                 END { printf("%0.0f", sum) }')
15892
15893                 cancel_lru_locks osc
15894                 cat $file >/dev/null
15895
15896                 AFTER=$(get_osd_param $list *OST*$idx stats |
15897                         awk '$1 == "cache_access" {sum += $7}
15898                                 END { printf("%0.0f", sum) }')
15899
15900                 echo BEFORE:$BEFORE AFTER:$AFTER
15901                 if ! let "AFTER - BEFORE == 4"; then
15902                         rm -rf $dir
15903                         error "roc_hit is not safe to use"
15904                 fi
15905                 rm $file
15906         done
15907
15908         rm -rf $dir
15909 }
15910
15911 function roc_hit() {
15912         local list=$(comma_list $(osts_nodes))
15913         echo $(get_osd_param $list '' stats |
15914                 awk '$1 == "cache_hit" {sum += $7}
15915                         END { printf("%0.0f", sum) }')
15916 }
15917
15918 function set_cache() {
15919         local on=1
15920
15921         if [ "$2" == "off" ]; then
15922                 on=0;
15923         fi
15924         local list=$(comma_list $(osts_nodes))
15925         set_osd_param $list '' $1_cache_enable $on
15926
15927         cancel_lru_locks osc
15928 }
15929
15930 test_151() {
15931         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15932         remote_ost_nodsh && skip "remote OST with nodsh"
15933         (( CLIENT_VERSION == OST1_VERSION )) ||
15934                 skip "LU-13081: no interop testing for OSS cache"
15935
15936         local CPAGES=3
15937         local list=$(comma_list $(osts_nodes))
15938
15939         # check whether obdfilter is cache capable at all
15940         if ! get_osd_param $list '' read_cache_enable >/dev/null; then
15941                 skip "not cache-capable obdfilter"
15942         fi
15943
15944         # check cache is enabled on all obdfilters
15945         if get_osd_param $list '' read_cache_enable | grep 0; then
15946                 skip "oss cache is disabled"
15947         fi
15948
15949         set_osd_param $list '' writethrough_cache_enable 1
15950
15951         # check write cache is enabled on all obdfilters
15952         if get_osd_param $list '' writethrough_cache_enable | grep 0; then
15953                 skip "oss write cache is NOT enabled"
15954         fi
15955
15956         roc_hit_init
15957
15958         #define OBD_FAIL_OBD_NO_LRU  0x609
15959         do_nodes $list $LCTL set_param fail_loc=0x609
15960
15961         # pages should be in the case right after write
15962         dd if=/dev/urandom of=$DIR/$tfile bs=4k count=$CPAGES ||
15963                 error "dd failed"
15964
15965         local BEFORE=$(roc_hit)
15966         cancel_lru_locks osc
15967         cat $DIR/$tfile >/dev/null
15968         local AFTER=$(roc_hit)
15969
15970         do_nodes $list $LCTL set_param fail_loc=0
15971
15972         if ! let "AFTER - BEFORE == CPAGES"; then
15973                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
15974         fi
15975
15976         cancel_lru_locks osc
15977         # invalidates OST cache
15978         do_nodes $list "echo 1 > /proc/sys/vm/drop_caches"
15979         set_osd_param $list '' read_cache_enable 0
15980         cat $DIR/$tfile >/dev/null
15981
15982         # now data shouldn't be found in the cache
15983         BEFORE=$(roc_hit)
15984         cancel_lru_locks osc
15985         cat $DIR/$tfile >/dev/null
15986         AFTER=$(roc_hit)
15987         if let "AFTER - BEFORE != 0"; then
15988                 error "IN CACHE: before: $BEFORE, after: $AFTER"
15989         fi
15990
15991         set_osd_param $list '' read_cache_enable 1
15992         rm -f $DIR/$tfile
15993 }
15994 run_test 151 "test cache on oss and controls ==============================="
15995
15996 test_152() {
15997         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15998
15999         local TF="$TMP/$tfile"
16000
16001         # simulate ENOMEM during write
16002 #define OBD_FAIL_OST_NOMEM      0x226
16003         lctl set_param fail_loc=0x80000226
16004         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
16005         cp $TF $DIR/$tfile
16006         sync || error "sync failed"
16007         lctl set_param fail_loc=0
16008
16009         # discard client's cache
16010         cancel_lru_locks osc
16011
16012         # simulate ENOMEM during read
16013         lctl set_param fail_loc=0x80000226
16014         cmp $TF $DIR/$tfile || error "cmp failed"
16015         lctl set_param fail_loc=0
16016
16017         rm -f $TF
16018 }
16019 run_test 152 "test read/write with enomem ============================"
16020
16021 test_153() {
16022         $MULTIOP $DIR/$tfile Ow4096Ycu || error "multiop failed"
16023 }
16024 run_test 153 "test if fdatasync does not crash ======================="
16025
16026 dot_lustre_fid_permission_check() {
16027         local fid=$1
16028         local ffid=$MOUNT/.lustre/fid/$fid
16029         local test_dir=$2
16030
16031         echo "stat fid $fid"
16032         stat $ffid || error "stat $ffid failed."
16033         echo "touch fid $fid"
16034         touch $ffid || error "touch $ffid failed."
16035         echo "write to fid $fid"
16036         cat /etc/hosts > $ffid || error "write $ffid failed."
16037         echo "read fid $fid"
16038         diff /etc/hosts $ffid || error "read $ffid failed."
16039         echo "append write to fid $fid"
16040         cat /etc/hosts >> $ffid || error "append write $ffid failed."
16041         echo "rename fid $fid"
16042         mv $ffid $test_dir/$tfile.1 &&
16043                 error "rename $ffid to $tfile.1 should fail."
16044         touch $test_dir/$tfile.1
16045         mv $test_dir/$tfile.1 $ffid &&
16046                 error "rename $tfile.1 to $ffid should fail."
16047         rm -f $test_dir/$tfile.1
16048         echo "truncate fid $fid"
16049         $TRUNCATE $ffid 777 || error "truncate $ffid failed."
16050         echo "link fid $fid"
16051         ln -f $ffid $test_dir/tfile.lnk || error "link $ffid failed."
16052         if [[ $($LCTL get_param -n mdc.*-mdc-*.connect_flags) =~ acl ]]; then
16053                 echo "setfacl fid $fid"
16054                 setfacl -R -m u:$USER0:rwx $ffid ||
16055                         error "setfacl $ffid failed"
16056                 echo "getfacl fid $fid"
16057                 getfacl $ffid || error "getfacl $ffid failed."
16058         fi
16059         echo "unlink fid $fid"
16060         unlink $MOUNT/.lustre/fid/$fid && error "unlink $ffid should fail."
16061         echo "mknod fid $fid"
16062         mknod $ffid c 1 3 && error "mknod $ffid should fail."
16063
16064         fid=[0xf00000400:0x1:0x0]
16065         ffid=$MOUNT/.lustre/fid/$fid
16066
16067         echo "stat non-exist fid $fid"
16068         stat $ffid > /dev/null && error "stat non-exist $ffid should fail."
16069         echo "write to non-exist fid $fid"
16070         cat /etc/hosts > $ffid && error "write non-exist $ffid should fail."
16071         echo "link new fid $fid"
16072         ln $test_dir/$tfile $ffid && error "link $ffid should fail."
16073
16074         mkdir -p $test_dir/$tdir
16075         touch $test_dir/$tdir/$tfile
16076         fid=$($LFS path2fid $test_dir/$tdir)
16077         rc=$?
16078         [ $rc -ne 0 ] &&
16079                 error "error: could not get fid for $test_dir/$dir/$tfile."
16080
16081         ffid=$MOUNT/.lustre/fid/$fid
16082
16083         echo "ls $fid"
16084         ls $ffid || error "ls $ffid failed."
16085         echo "touch $fid/$tfile.1"
16086         touch $ffid/$tfile.1 || error "touch $ffid/$tfile.1 failed."
16087
16088         echo "touch $MOUNT/.lustre/fid/$tfile"
16089         touch $MOUNT/.lustre/fid/$tfile && \
16090                 error "touch $MOUNT/.lustre/fid/$tfile should fail."
16091
16092         echo "setxattr to $MOUNT/.lustre/fid"
16093         setfattr -n trusted.name1 -v value1 $MOUNT/.lustre/fid
16094
16095         echo "listxattr for $MOUNT/.lustre/fid"
16096         getfattr -d -m "^trusted" $MOUNT/.lustre/fid
16097
16098         echo "delxattr from $MOUNT/.lustre/fid"
16099         setfattr -x trusted.name1 $MOUNT/.lustre/fid
16100
16101         echo "touch invalid fid: $MOUNT/.lustre/fid/[0x200000400:0x2:0x3]"
16102         touch $MOUNT/.lustre/fid/[0x200000400:0x2:0x3] &&
16103                 error "touch invalid fid should fail."
16104
16105         echo "touch non-normal fid: $MOUNT/.lustre/fid/[0x1:0x2:0x0]"
16106         touch $MOUNT/.lustre/fid/[0x1:0x2:0x0] &&
16107                 error "touch non-normal fid should fail."
16108
16109         echo "rename $tdir to $MOUNT/.lustre/fid"
16110         mrename $test_dir/$tdir $MOUNT/.lustre/fid &&
16111                 error "rename to $MOUNT/.lustre/fid should fail."
16112
16113         if [ $MDS1_VERSION -ge $(version_code 2.3.51) ]
16114         then            # LU-3547
16115                 local old_obf_mode=$(stat --format="%a" $DIR/.lustre/fid)
16116                 local new_obf_mode=777
16117
16118                 echo "change mode of $DIR/.lustre/fid to $new_obf_mode"
16119                 chmod $new_obf_mode $DIR/.lustre/fid ||
16120                         error "chmod $new_obf_mode $DIR/.lustre/fid failed"
16121
16122                 local obf_mode=$(stat --format=%a $DIR/.lustre/fid)
16123                 [ $obf_mode -eq $new_obf_mode ] ||
16124                         error "stat $DIR/.lustre/fid returned wrong mode $obf_mode"
16125
16126                 echo "restore mode of $DIR/.lustre/fid to $old_obf_mode"
16127                 chmod $old_obf_mode $DIR/.lustre/fid ||
16128                         error "chmod $old_obf_mode $DIR/.lustre/fid failed"
16129         fi
16130
16131         $OPENFILE -f O_LOV_DELAY_CREATE:O_CREAT $test_dir/$tfile-2
16132         fid=$($LFS path2fid $test_dir/$tfile-2)
16133
16134         if [ $MDS1_VERSION -ge $(version_code 2.6.50) ]
16135         then # LU-5424
16136                 echo "cp /etc/passwd $MOUNT/.lustre/fid/$fid"
16137                 cp /etc/passwd $MOUNT/.lustre/fid/$fid ||
16138                         error "create lov data thru .lustre failed"
16139         fi
16140         echo "cp /etc/passwd $test_dir/$tfile-2"
16141         cp /etc/passwd $test_dir/$tfile-2 ||
16142                 error "copy to $test_dir/$tfile-2 failed."
16143         echo "diff /etc/passwd $MOUNT/.lustre/fid/$fid"
16144         diff /etc/passwd $MOUNT/.lustre/fid/$fid ||
16145                 error "diff /etc/passwd $MOUNT/.lustre/fid/$fid failed."
16146
16147         rm -rf $test_dir/tfile.lnk
16148         rm -rf $test_dir/$tfile-2
16149 }
16150
16151 test_154A() {
16152         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
16153                 skip "Need MDS version at least 2.4.1"
16154
16155         local tf=$DIR/$tfile
16156         touch $tf
16157
16158         local fid=$($LFS path2fid $tf)
16159         [ -z "$fid" ] && error "path2fid unable to get $tf FID"
16160
16161         # check that we get the same pathname back
16162         local rootpath
16163         local found
16164         for rootpath in "$MOUNT" "$MOUNT///" "$MOUNT/$tfile"; do
16165                 echo "$rootpath $fid"
16166                 found=$($LFS fid2path $rootpath "$fid")
16167                 [ -z "$found" ] && error "fid2path unable to get '$fid' path"
16168                 [ "$found" == "$tf" ] || error "fid2path $found != $tf"
16169         done
16170
16171         # check wrong root path format
16172         rootpath=$MOUNT"_wrong"
16173         found=$($LFS fid2path $rootpath "$fid")
16174         [ -z "$found" ] || error "should fail ($rootpath != $MOUNT)"
16175 }
16176 run_test 154A "lfs path2fid and fid2path basic checks"
16177
16178 test_154B() {
16179         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
16180                 skip "Need MDS version at least 2.4.1"
16181
16182         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
16183         touch $DIR/$tdir/$tfile || error "touch $DIR/$tdir/$tfile failed"
16184         local linkea=$($LL_DECODE_LINKEA $DIR/$tdir/$tfile | grep 'pfid')
16185         [ -z "$linkea" ] && error "decode linkea $DIR/$tdir/$tfile failed"
16186
16187         local name=$(echo $linkea | awk '/pfid/ {print $5}' | sed -e "s/'//g")
16188         local PFID=$(echo $linkea | awk '/pfid/ {print $3}' | sed -e "s/,//g")
16189
16190         # check that we get the same pathname
16191         echo "PFID: $PFID, name: $name"
16192         local FOUND=$($LFS fid2path $MOUNT "$PFID")
16193         [ -z "$FOUND" ] && error "fid2path unable to get $PFID path"
16194         [ "$FOUND/$name" != "$DIR/$tdir/$tfile" ] &&
16195                 error "ll_decode_linkea has $FOUND/$name != $DIR/$tdir/$tfile"
16196
16197         rm -rf $DIR/$tdir || error "Can not delete directory $DIR/$tdir"
16198 }
16199 run_test 154B "verify the ll_decode_linkea tool"
16200
16201 test_154a() {
16202         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16203         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
16204         (( $MDS1_VERSION >= $(version_code 2.2.51) )) ||
16205                 skip "Need MDS version at least 2.2.51"
16206         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
16207
16208         cp /etc/hosts $DIR/$tfile
16209
16210         fid=$($LFS path2fid $DIR/$tfile)
16211         rc=$?
16212         [ $rc -ne 0 ] && error "error: could not get fid for $DIR/$tfile."
16213
16214         dot_lustre_fid_permission_check "$fid" $DIR ||
16215                 error "dot lustre permission check $fid failed"
16216
16217         ls -a $MOUNT | grep "\.lustre" && error ".lustre should not be listed"
16218
16219         rm -rf $MOUNT/.lustre && error ".lustre is not allowed to be unlinked"
16220
16221         touch $MOUNT/.lustre/file &&
16222                 error "creation is not allowed under .lustre"
16223
16224         mkdir $MOUNT/.lustre/dir &&
16225                 error "mkdir is not allowed under .lustre"
16226
16227         rm -rf $DIR/$tfile
16228 }
16229 run_test 154a "Open-by-FID"
16230
16231 test_154b() {
16232         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16233         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
16234         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16235         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
16236                 skip "Need MDS version at least 2.2.51"
16237
16238         local remote_dir=$DIR/$tdir/remote_dir
16239         local MDTIDX=1
16240         local rc=0
16241
16242         mkdir -p $DIR/$tdir
16243         $LFS mkdir -i $MDTIDX $remote_dir ||
16244                 error "create remote directory failed"
16245
16246         cp /etc/hosts $remote_dir/$tfile
16247
16248         fid=$($LFS path2fid $remote_dir/$tfile)
16249         rc=$?
16250         [ $rc -ne 0 ] && error "error: could not get fid for $remote_dir/$tfile"
16251
16252         dot_lustre_fid_permission_check "$fid" $remote_dir ||
16253                 error "dot lustre permission check $fid failed"
16254         rm -rf $DIR/$tdir
16255 }
16256 run_test 154b "Open-by-FID for remote directory"
16257
16258 test_154c() {
16259         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
16260                 skip "Need MDS version at least 2.4.1"
16261
16262         touch $DIR/$tfile.1 $DIR/$tfile.2 $DIR/$tfile.3
16263         local FID1=$($LFS path2fid $DIR/$tfile.1)
16264         local FID2=$($LFS path2fid $DIR/$tfile.2)
16265         local FID3=$($LFS path2fid $DIR/$tfile.3)
16266
16267         local N=1
16268         $LFS path2fid $DIR/$tfile.[123] | while read PATHNAME FID; do
16269                 [ "$PATHNAME" = "$DIR/$tfile.$N:" ] ||
16270                         error "path2fid pathname $PATHNAME != $DIR/$tfile.$N:"
16271                 local want=FID$N
16272                 [ "$FID" = "${!want}" ] ||
16273                         error "path2fid $PATHNAME FID $FID != FID$N ${!want}"
16274                 N=$((N + 1))
16275         done
16276
16277         $LFS fid2path $MOUNT "$FID1" "$FID2" "$FID3" | while read PATHNAME;
16278         do
16279                 [ "$PATHNAME" = "$DIR/$tfile.$N" ] ||
16280                         error "fid2path pathname $PATHNAME != $DIR/$tfile.$N:"
16281                 N=$((N + 1))
16282         done
16283 }
16284 run_test 154c "lfs path2fid and fid2path multiple arguments"
16285
16286 test_154d() {
16287         remote_mds_nodsh && skip "remote MDS with nodsh"
16288         [[ $MDS1_VERSION -lt $(version_code 2.5.53) ]] &&
16289                 skip "Need MDS version at least 2.5.53"
16290
16291         if remote_mds; then
16292                 nid=$($LCTL list_nids | sed  "s/\./\\\./g")
16293         else
16294                 nid="0@lo"
16295         fi
16296         local proc_ofile="mdt.*.exports.'$nid'.open_files"
16297         local fd
16298         local cmd
16299
16300         rm -f $DIR/$tfile
16301         touch $DIR/$tfile
16302
16303         local fid=$($LFS path2fid $DIR/$tfile)
16304         # Open the file
16305         fd=$(free_fd)
16306         cmd="exec $fd<$DIR/$tfile"
16307         eval $cmd
16308         local fid_list=$(do_facet $SINGLEMDS $LCTL get_param $proc_ofile)
16309         echo "$fid_list" | grep "$fid"
16310         rc=$?
16311
16312         cmd="exec $fd>/dev/null"
16313         eval $cmd
16314         if [ $rc -ne 0 ]; then
16315                 error "FID $fid not found in open files list $fid_list"
16316         fi
16317 }
16318 run_test 154d "Verify open file fid"
16319
16320 test_154e()
16321 {
16322         [[ $MDS1_VERSION -lt $(version_code 2.6.50) ]] &&
16323                 skip "Need MDS version at least 2.6.50"
16324
16325         if ls -a $MOUNT | grep -q '^\.lustre$'; then
16326                 error ".lustre returned by readdir"
16327         fi
16328 }
16329 run_test 154e ".lustre is not returned by readdir"
16330
16331 test_154f() {
16332         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
16333
16334         # create parent directory on a single MDT to avoid cross-MDT hardlinks
16335         mkdir_on_mdt0 $DIR/$tdir
16336         # test dirs inherit from its stripe
16337         mkdir -p $DIR/$tdir/foo1 || error "mkdir error"
16338         mkdir -p $DIR/$tdir/foo2 || error "mkdir error"
16339         cp /etc/hosts $DIR/$tdir/foo1/$tfile
16340         ln $DIR/$tdir/foo1/$tfile $DIR/$tdir/foo2/link
16341         touch $DIR/f
16342
16343         # get fid of parents
16344         local FID0=$($LFS path2fid $DIR/$tdir)
16345         local FID1=$($LFS path2fid $DIR/$tdir/foo1)
16346         local FID2=$($LFS path2fid $DIR/$tdir/foo2)
16347         local FID3=$($LFS path2fid $DIR)
16348
16349         # check that path2fid --parents returns expected <parent_fid>/name
16350         # 1) test for a directory (single parent)
16351         local parent=$($LFS path2fid --parents $DIR/$tdir/foo1)
16352         [ "$parent" == "$FID0/foo1" ] ||
16353                 error "expected parent: $FID0/foo1, got: $parent"
16354
16355         # 2) test for a file with nlink > 1 (multiple parents)
16356         parent=$($LFS path2fid --parents $DIR/$tdir/foo1/$tfile)
16357         echo "$parent" | grep -F "$FID1/$tfile" ||
16358                 error "$FID1/$tfile not returned in parent list"
16359         echo "$parent" | grep -F "$FID2/link" ||
16360                 error "$FID2/link not returned in parent list"
16361
16362         # 3) get parent by fid
16363         local file_fid=$($LFS path2fid $DIR/$tdir/foo1/$tfile)
16364         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
16365         echo "$parent" | grep -F "$FID1/$tfile" ||
16366                 error "$FID1/$tfile not returned in parent list (by fid)"
16367         echo "$parent" | grep -F "$FID2/link" ||
16368                 error "$FID2/link not returned in parent list (by fid)"
16369
16370         # 4) test for entry in root directory
16371         parent=$($LFS path2fid --parents $DIR/f)
16372         echo "$parent" | grep -F "$FID3/f" ||
16373                 error "$FID3/f not returned in parent list"
16374
16375         # 5) test it on root directory
16376         [ -z "$($LFS path2fid --parents $MOUNT 2>/dev/null)" ] ||
16377                 error "$MOUNT should not have parents"
16378
16379         # enable xattr caching and check that linkea is correctly updated
16380         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
16381         save_lustre_params client "llite.*.xattr_cache" > $save
16382         lctl set_param llite.*.xattr_cache 1
16383
16384         # 6.1) linkea update on rename
16385         mv $DIR/$tdir/foo1/$tfile $DIR/$tdir/foo2/$tfile.moved
16386
16387         # get parents by fid
16388         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
16389         # foo1 should no longer be returned in parent list
16390         echo "$parent" | grep -F "$FID1" &&
16391                 error "$FID1 should no longer be in parent list"
16392         # the new path should appear
16393         echo "$parent" | grep -F "$FID2/$tfile.moved" ||
16394                 error "$FID2/$tfile.moved is not in parent list"
16395
16396         # 6.2) linkea update on unlink
16397         rm -f $DIR/$tdir/foo2/link
16398         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
16399         # foo2/link should no longer be returned in parent list
16400         echo "$parent" | grep -F "$FID2/link" &&
16401                 error "$FID2/link should no longer be in parent list"
16402         true
16403
16404         rm -f $DIR/f
16405         restore_lustre_params < $save
16406         rm -f $save
16407 }
16408 run_test 154f "get parent fids by reading link ea"
16409
16410 test_154g()
16411 {
16412         [[ $MDS1_VERSION -ge $(version_code 2.6.92) &&
16413            $CLIENT_VERSION -gt $(version_code 2.6.99) ]] ||
16414                 skip "Need MDS version at least 2.6.92"
16415
16416         mkdir_on_mdt0 $DIR/$tdir
16417         llapi_fid_test -d $DIR/$tdir
16418 }
16419 run_test 154g "various llapi FID tests"
16420
16421 test_154h()
16422 {
16423         (( $CLIENT_VERSION >= $(version_code 2.15.55.1) )) ||
16424                 skip "Need client at least version 2.15.55.1"
16425
16426         # Create an empty file
16427         touch $DIR/$tfile
16428
16429         # Get FID (interactive mode) and save under $TMP/$tfile.log
16430         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
16431                 path2fid $DIR/$tfile
16432         EOF
16433
16434         fid=$(cat $TMP/$tfile.log)
16435         # $fid should not be empty
16436         [[ ! -z $fid ]] || error "FID is empty"
16437         $LFS rmfid $DIR "$fid" || error "rmfid failed for $fid"
16438 }
16439 run_test 154h "Verify interactive path2fid"
16440
16441 test_155_small_load() {
16442     local temp=$TMP/$tfile
16443     local file=$DIR/$tfile
16444
16445     dd if=/dev/urandom of=$temp bs=6096 count=1 || \
16446         error "dd of=$temp bs=6096 count=1 failed"
16447     cp $temp $file
16448     cancel_lru_locks $OSC
16449     cmp $temp $file || error "$temp $file differ"
16450
16451     $TRUNCATE $temp 6000
16452     $TRUNCATE $file 6000
16453     cmp $temp $file || error "$temp $file differ (truncate1)"
16454
16455     echo "12345" >>$temp
16456     echo "12345" >>$file
16457     cmp $temp $file || error "$temp $file differ (append1)"
16458
16459     echo "12345" >>$temp
16460     echo "12345" >>$file
16461     cmp $temp $file || error "$temp $file differ (append2)"
16462
16463     rm -f $temp $file
16464     true
16465 }
16466
16467 test_155_big_load() {
16468         remote_ost_nodsh && skip "remote OST with nodsh"
16469
16470         local temp=$TMP/$tfile
16471         local file=$DIR/$tfile
16472
16473         free_min_max
16474         local cache_size=$(do_facet ost$((MAXI+1)) \
16475                 "awk '/cache/ {sum+=\\\$4} END {print sum}' /proc/cpuinfo")
16476
16477         # LU-16042: can not get the cache size on Arm64 VM here, fallback to a
16478         # pre-set value
16479         if [ -z "$cache_size" ]; then
16480                 cache_size=256
16481         fi
16482         local large_file_size=$((cache_size * 2))
16483
16484         echo "OSS cache size: $cache_size KB"
16485         echo "Large file size: $large_file_size KB"
16486
16487         [ $MAXV -le $large_file_size ] &&
16488                 skip_env "max available OST size needs > $large_file_size KB"
16489
16490         $LFS setstripe $file -c 1 -i $MAXI || error "$LFS setstripe $file failed"
16491
16492         dd if=/dev/urandom of=$temp bs=$large_file_size count=1k ||
16493                 error "dd of=$temp bs=$large_file_size count=1k failed"
16494         cp $temp $file
16495         ls -lh $temp $file
16496         cancel_lru_locks osc
16497         cmp $temp $file || error "$temp $file differ"
16498
16499         rm -f $temp $file
16500         true
16501 }
16502
16503 save_writethrough() {
16504         local facets=$(get_facets OST)
16505
16506         save_lustre_params $facets "osd-*.*.writethrough_cache_enable" > $1
16507 }
16508
16509 test_155a() {
16510         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16511
16512         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16513
16514         save_writethrough $p
16515
16516         set_cache read on
16517         set_cache writethrough on
16518         test_155_small_load
16519         restore_lustre_params < $p
16520         rm -f $p
16521 }
16522 run_test 155a "Verify small file correctness: read cache:on write_cache:on"
16523
16524 test_155b() {
16525         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16526
16527         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16528
16529         save_writethrough $p
16530
16531         set_cache read on
16532         set_cache writethrough off
16533         test_155_small_load
16534         restore_lustre_params < $p
16535         rm -f $p
16536 }
16537 run_test 155b "Verify small file correctness: read cache:on write_cache:off"
16538
16539 test_155c() {
16540         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16541
16542         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16543
16544         save_writethrough $p
16545
16546         set_cache read off
16547         set_cache writethrough on
16548         test_155_small_load
16549         restore_lustre_params < $p
16550         rm -f $p
16551 }
16552 run_test 155c "Verify small file correctness: read cache:off write_cache:on"
16553
16554 test_155d() {
16555         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16556
16557         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16558
16559         save_writethrough $p
16560
16561         set_cache read off
16562         set_cache writethrough off
16563         test_155_small_load
16564         restore_lustre_params < $p
16565         rm -f $p
16566 }
16567 run_test 155d "Verify small file correctness: read cache:off write_cache:off"
16568
16569 test_155e() {
16570         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16571
16572         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16573
16574         save_writethrough $p
16575
16576         set_cache read on
16577         set_cache writethrough on
16578         test_155_big_load
16579         restore_lustre_params < $p
16580         rm -f $p
16581 }
16582 run_test 155e "Verify big file correctness: read cache:on write_cache:on"
16583
16584 test_155f() {
16585         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16586
16587         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16588
16589         save_writethrough $p
16590
16591         set_cache read on
16592         set_cache writethrough off
16593         test_155_big_load
16594         restore_lustre_params < $p
16595         rm -f $p
16596 }
16597 run_test 155f "Verify big file correctness: read cache:on write_cache:off"
16598
16599 test_155g() {
16600         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16601
16602         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16603
16604         save_writethrough $p
16605
16606         set_cache read off
16607         set_cache writethrough on
16608         test_155_big_load
16609         restore_lustre_params < $p
16610         rm -f $p
16611 }
16612 run_test 155g "Verify big file correctness: read cache:off write_cache:on"
16613
16614 test_155h() {
16615         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16616
16617         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16618
16619         save_writethrough $p
16620
16621         set_cache read off
16622         set_cache writethrough off
16623         test_155_big_load
16624         restore_lustre_params < $p
16625         rm -f $p
16626 }
16627 run_test 155h "Verify big file correctness: read cache:off write_cache:off"
16628
16629 test_156() {
16630         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16631         remote_ost_nodsh && skip "remote OST with nodsh"
16632         [ $OST1_VERSION -lt $(version_code 2.6.93) ] &&
16633                 skip "stats not implemented on old servers"
16634         [ "$ost1_FSTYPE" = "zfs" ] &&
16635                 skip "LU-1956/LU-2261: stats not implemented on OSD ZFS"
16636         (( CLIENT_VERSION == OST1_VERSION )) ||
16637                 skip "LU-13081: no interop testing for OSS cache"
16638
16639         local CPAGES=3
16640         local BEFORE
16641         local AFTER
16642         local file="$DIR/$tfile"
16643         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16644
16645         save_writethrough $p
16646         roc_hit_init
16647
16648         log "Turn on read and write cache"
16649         set_cache read on
16650         set_cache writethrough on
16651
16652         log "Write data and read it back."
16653         log "Read should be satisfied from the cache."
16654         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
16655         BEFORE=$(roc_hit)
16656         cancel_lru_locks osc
16657         cat $file >/dev/null
16658         AFTER=$(roc_hit)
16659         if ! let "AFTER - BEFORE == CPAGES"; then
16660                 error "NOT IN CACHE (2): before: $BEFORE, after: $AFTER"
16661         else
16662                 log "cache hits: before: $BEFORE, after: $AFTER"
16663         fi
16664
16665         log "Read again; it should be satisfied from the cache."
16666         BEFORE=$AFTER
16667         cancel_lru_locks osc
16668         cat $file >/dev/null
16669         AFTER=$(roc_hit)
16670         if ! let "AFTER - BEFORE == CPAGES"; then
16671                 error "NOT IN CACHE (3): before: $BEFORE, after: $AFTER"
16672         else
16673                 log "cache hits:: before: $BEFORE, after: $AFTER"
16674         fi
16675
16676         log "Turn off the read cache and turn on the write cache"
16677         set_cache read off
16678         set_cache writethrough on
16679
16680         log "Read again; it should be satisfied from the cache."
16681         BEFORE=$(roc_hit)
16682         cancel_lru_locks osc
16683         cat $file >/dev/null
16684         AFTER=$(roc_hit)
16685         if ! let "AFTER - BEFORE == CPAGES"; then
16686                 error "NOT IN CACHE (4): before: $BEFORE, after: $AFTER"
16687         else
16688                 log "cache hits:: before: $BEFORE, after: $AFTER"
16689         fi
16690
16691         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
16692                 # > 2.12.56 uses pagecache if cached
16693                 log "Read again; it should not be satisfied from the cache."
16694                 BEFORE=$AFTER
16695                 cancel_lru_locks osc
16696                 cat $file >/dev/null
16697                 AFTER=$(roc_hit)
16698                 if ! let "AFTER - BEFORE == 0"; then
16699                         error "IN CACHE (5): before: $BEFORE, after: $AFTER"
16700                 else
16701                         log "cache hits:: before: $BEFORE, after: $AFTER"
16702                 fi
16703         fi
16704
16705         log "Write data and read it back."
16706         log "Read should be satisfied from the cache."
16707         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
16708         BEFORE=$(roc_hit)
16709         cancel_lru_locks osc
16710         cat $file >/dev/null
16711         AFTER=$(roc_hit)
16712         if ! let "AFTER - BEFORE == CPAGES"; then
16713                 error "NOT IN CACHE (6): before: $BEFORE, after: $AFTER"
16714         else
16715                 log "cache hits:: before: $BEFORE, after: $AFTER"
16716         fi
16717
16718         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
16719                 # > 2.12.56 uses pagecache if cached
16720                 log "Read again; it should not be satisfied from the cache."
16721                 BEFORE=$AFTER
16722                 cancel_lru_locks osc
16723                 cat $file >/dev/null
16724                 AFTER=$(roc_hit)
16725                 if ! let "AFTER - BEFORE == 0"; then
16726                         error "IN CACHE (7): before: $BEFORE, after: $AFTER"
16727                 else
16728                         log "cache hits:: before: $BEFORE, after: $AFTER"
16729                 fi
16730         fi
16731
16732         log "Turn off read and write cache"
16733         set_cache read off
16734         set_cache writethrough off
16735
16736         log "Write data and read it back"
16737         log "It should not be satisfied from the cache."
16738         rm -f $file
16739         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
16740         cancel_lru_locks osc
16741         BEFORE=$(roc_hit)
16742         cat $file >/dev/null
16743         AFTER=$(roc_hit)
16744         if ! let "AFTER - BEFORE == 0"; then
16745                 error_ignore bz20762 "IN CACHE (8):before:$BEFORE,after:$AFTER"
16746         else
16747                 log "cache hits:: before: $BEFORE, after: $AFTER"
16748         fi
16749
16750         log "Turn on the read cache and turn off the write cache"
16751         set_cache read on
16752         set_cache writethrough off
16753
16754         log "Write data and read it back"
16755         log "It should not be satisfied from the cache."
16756         rm -f $file
16757         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
16758         BEFORE=$(roc_hit)
16759         cancel_lru_locks osc
16760         cat $file >/dev/null
16761         AFTER=$(roc_hit)
16762         if ! let "AFTER - BEFORE == 0"; then
16763                 error_ignore bz20762 "IN CACHE (9):before:$BEFORE,after:$AFTER"
16764         else
16765                 log "cache hits:: before: $BEFORE, after: $AFTER"
16766         fi
16767
16768         log "Read again; it should be satisfied from the cache."
16769         BEFORE=$(roc_hit)
16770         cancel_lru_locks osc
16771         cat $file >/dev/null
16772         AFTER=$(roc_hit)
16773         if ! let "AFTER - BEFORE == CPAGES"; then
16774                 error "NOT IN CACHE (1): before: $BEFORE, after: $AFTER"
16775         else
16776                 log "cache hits:: before: $BEFORE, after: $AFTER"
16777         fi
16778
16779         restore_lustre_params < $p
16780         rm -f $p $file
16781 }
16782 run_test 156 "Verification of tunables"
16783
16784 test_160a() {
16785         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16786         remote_mds_nodsh && skip "remote MDS with nodsh"
16787         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
16788                 skip "Need MDS version at least 2.2.0"
16789
16790         changelog_register || error "changelog_register failed"
16791         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16792         changelog_users $SINGLEMDS | grep -q $cl_user ||
16793                 error "User $cl_user not found in changelog_users"
16794
16795         mkdir_on_mdt0 $DIR/$tdir
16796
16797         # change something
16798         test_mkdir -p $DIR/$tdir/pics/2008/zachy
16799         changelog_clear 0 || error "changelog_clear failed"
16800         touch $DIR/$tdir/pics/2008/zachy/$tfile                 # open 1
16801         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg       # open 2
16802         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
16803         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
16804         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
16805         rm $DIR/$tdir/pics/desktop.jpg
16806
16807         echo "verifying changelog mask"
16808         changelog_chmask "-MKDIR"
16809         changelog_chmask "-CLOSE"
16810
16811         test_mkdir -p $DIR/$tdir/pics/zach/sofia                # not logged
16812         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # not logged
16813
16814         changelog_chmask "+MKDIR"
16815         changelog_chmask "+CLOSE"
16816
16817         test_mkdir -p $DIR/$tdir/pics/2008/sofia                # mkdir 1
16818         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # open 3
16819
16820         MKDIRS=$(changelog_dump | grep -c "MKDIR")
16821         CLOSES=$(changelog_dump | grep -c "CLOSE")
16822         [ $MKDIRS -eq 1 ] || error "MKDIR changelog mask count $MKDIRS != 1"
16823         [ $CLOSES -eq 3 ] || error "CLOSE changelog mask count $CLOSES != 3"
16824
16825         # verify contents
16826         echo "verifying target fid"
16827         local fidc=$(changelog_extract_field "CREAT" "$tfile" "t=")
16828         local fidf=$($LFS path2fid $DIR/$tdir/pics/zach/$tfile)
16829         [ "$fidc" == "$fidf" ] ||
16830                 error "changelog '$tfile' fid $fidc != file fid $fidf"
16831         echo "verifying parent fid"
16832         # The FID returned from the Changelog may be the directory shard on
16833         # a different MDT, and not the FID returned by path2fid on the parent.
16834         # Instead of comparing FIDs, verify that fid2path(fidp) is correct,
16835         # since this is what will matter when recreating this file in the tree.
16836         local fidp=$(changelog_extract_field "CREAT" "$tfile" "p=")
16837         local pathp=$($LFS fid2path $MOUNT "$fidp")
16838         [ "${pathp%/}" == "$DIR/$tdir/pics/zach" ] ||
16839                 error "changelog fid2path($fidc) $pathp != $DIR/$tdir/pics/zach"
16840
16841         echo "getting records for $cl_user"
16842         changelog_users $SINGLEMDS
16843         local user_rec1=$(changelog_user_rec $SINGLEMDS $cl_user)
16844         local nclr=3
16845         __changelog_clear $SINGLEMDS $cl_user +$nclr ||
16846                 error "changelog_clear failed"
16847         local user_rec2=$(changelog_user_rec $SINGLEMDS $cl_user)
16848         echo "verifying user clear: $user_rec1 + $nclr == $user_rec2"
16849         [ $user_rec2 == $((user_rec1 + nclr)) ] ||
16850                 error "user index expect $user_rec1 + $nclr != $user_rec2"
16851
16852         local min0_rec=$(changelog_users $SINGLEMDS |
16853                 awk 'min == "" || $2 < min { min = $2 }; END { print min }')
16854         local first_rec=$($LFS changelog $(facet_svc $SINGLEMDS) |
16855                           awk '{ print $1; exit; }')
16856
16857         changelog_dump | tail -n 5
16858         echo "verifying user min purge: $min0_rec + 1 == $first_rec"
16859         [ $first_rec == $((min0_rec + 1)) ] ||
16860                 error "first index should be $min0_rec + 1 not $first_rec"
16861
16862         # LU-3446 changelog index reset on MDT restart
16863         local cur_rec1=$(changelog_users $SINGLEMDS |
16864                          awk '/^current.index:/ { print $NF }')
16865         changelog_clear 0 ||
16866                 error "clear all changelog records for $cl_user failed"
16867         stop $SINGLEMDS || error "Fail to stop $SINGLEMDS"
16868         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
16869                 error "Fail to start $SINGLEMDS"
16870         local cur_rec2=$(changelog_users $SINGLEMDS |
16871                          awk '/^current.index:/ { print $NF }')
16872         echo "verifying index survives MDT restart: $cur_rec1 == $cur_rec2"
16873         [ $cur_rec1 == $cur_rec2 ] ||
16874                 error "current index should be $cur_rec1 not $cur_rec2"
16875
16876         echo "verifying users from this test are deregistered"
16877         changelog_deregister || error "changelog_deregister failed"
16878         changelog_users $SINGLEMDS | grep -q $cl_user &&
16879                 error "User '$cl_user' still in changelog_users"
16880
16881         # lctl get_param -n mdd.*.changelog_users
16882         # current_index: 144
16883         # ID    index (idle seconds)
16884         # cl3   144   (2) mask=<list>
16885         if [ -z "$(changelog_users $SINGLEMDS | grep -v current.index)" ]; then
16886                 # this is the normal case where all users were deregistered
16887                 # make sure no new records are added when no users are present
16888                 local last_rec1=$(changelog_users $SINGLEMDS |
16889                                   awk '/^current.index:/ { print $NF }')
16890                 touch $DIR/$tdir/chloe
16891                 local last_rec2=$(changelog_users $SINGLEMDS |
16892                                   awk '/^current.index:/ { print $NF }')
16893                 echo "verify changelogs are off: $last_rec1 == $last_rec2"
16894                 [ $last_rec1 == $last_rec2 ] || error "changelogs not off"
16895         else
16896                 # any changelog users must be leftovers from a previous test
16897                 changelog_users $SINGLEMDS
16898                 echo "other changelog users; can't verify off"
16899         fi
16900 }
16901 run_test 160a "changelog sanity"
16902
16903 test_160b() { # LU-3587
16904         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16905         remote_mds_nodsh && skip "remote MDS with nodsh"
16906         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
16907                 skip "Need MDS version at least 2.2.0"
16908
16909         changelog_register || error "changelog_register failed"
16910         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16911         changelog_users $SINGLEMDS | grep -q $cl_user ||
16912                 error "User '$cl_user' not found in changelog_users"
16913
16914         local longname1=$(str_repeat a 255)
16915         local longname2=$(str_repeat b 255)
16916
16917         cd $DIR
16918         echo "creating very long named file"
16919         touch $longname1 || error "create of '$longname1' failed"
16920         echo "renaming very long named file"
16921         mv $longname1 $longname2
16922
16923         changelog_dump | grep RENME | tail -n 5
16924         rm -f $longname2
16925 }
16926 run_test 160b "Verify that very long rename doesn't crash in changelog"
16927
16928 test_160c() {
16929         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16930         remote_mds_nodsh && skip "remote MDS with nodsh"
16931
16932         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
16933                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
16934                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
16935                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
16936
16937         local rc=0
16938
16939         # Registration step
16940         changelog_register || error "changelog_register failed"
16941
16942         rm -rf $DIR/$tdir
16943         mkdir -p $DIR/$tdir
16944         $MCREATE $DIR/$tdir/foo_160c
16945         changelog_chmask "-TRUNC"
16946         $TRUNCATE $DIR/$tdir/foo_160c 200
16947         changelog_chmask "+TRUNC"
16948         $TRUNCATE $DIR/$tdir/foo_160c 199
16949         changelog_dump | tail -n 5
16950         local truncs=$(changelog_dump | tail -n 5 | grep -c TRUNC)
16951         [ $truncs -eq 1 ] || error "TRUNC changelog mask count $truncs != 1"
16952 }
16953 run_test 160c "verify that changelog log catch the truncate event"
16954
16955 test_160d() {
16956         remote_mds_nodsh && skip "remote MDS with nodsh"
16957         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16958         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16959         [[ $MDS1_VERSION -ge $(version_code 2.7.60) ]] ||
16960                 skip "Need MDS version at least 2.7.60"
16961
16962         # Registration step
16963         changelog_register || error "changelog_register failed"
16964
16965         mkdir -p $DIR/$tdir/migrate_dir
16966         changelog_clear 0 || error "changelog_clear failed"
16967
16968         $LFS migrate -m 1 $DIR/$tdir/migrate_dir || error "migrate fails"
16969         changelog_dump | tail -n 5
16970         local migrates=$(changelog_dump | grep -c "MIGRT")
16971         [ $migrates -eq 1 ] || error "MIGRATE changelog count $migrates != 1"
16972 }
16973 run_test 160d "verify that changelog log catch the migrate event"
16974
16975 test_160e() {
16976         remote_mds_nodsh && skip "remote MDS with nodsh"
16977
16978         # Create a user
16979         changelog_register || error "changelog_register failed"
16980
16981         local MDT0=$(facet_svc $SINGLEMDS)
16982         local rc
16983
16984         # No user (expect fail)
16985         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister
16986         rc=$?
16987         if [ $rc -eq 0 ]; then
16988                 error "Should fail without user"
16989         elif [ $rc -ne 4 ]; then
16990                 error "changelog_deregister failed with $rc, expect 4(CMD_HELP)"
16991         fi
16992
16993         # Delete a future user (expect fail)
16994         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister "cl77"
16995         rc=$?
16996         if [ $rc -eq 0 ]; then
16997                 error "Deleted non-existant user cl77"
16998         elif [ $rc -ne 2 ]; then
16999                 error "changelog_deregister failed with $rc, expect 2 (ENOENT)"
17000         fi
17001
17002         # Clear to a bad index (1 billion should be safe)
17003         $LFS changelog_clear $MDT0 "${CL_USERS[$SINGLEMDS]%% *}" 1000000000
17004         rc=$?
17005
17006         if [ $rc -eq 0 ]; then
17007                 error "Successfully cleared to invalid CL index"
17008         elif [ $rc -ne 22 ]; then
17009                 error "changelog_clear failed with $rc, expected 22 (EINVAL)"
17010         fi
17011 }
17012 run_test 160e "changelog negative testing (should return errors)"
17013
17014 test_160f() {
17015         remote_mds_nodsh && skip "remote MDS with nodsh" && return
17016         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
17017                 skip "Need MDS version at least 2.10.56"
17018
17019         local mdts=$(comma_list $(mdts_nodes))
17020
17021         # Create a user
17022         changelog_register || error "first changelog_register failed"
17023         changelog_register || error "second changelog_register failed"
17024         local cl_users
17025         declare -A cl_user1
17026         declare -A cl_user2
17027         local user_rec1
17028         local user_rec2
17029         local i
17030
17031         # generate some changelog records to accumulate on each MDT
17032         # use all_char because created files should be evenly distributed
17033         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
17034                 error "test_mkdir $tdir failed"
17035         log "$(date +%s): creating first files"
17036         for ((i = 0; i < MDSCOUNT * 2; i++)); do
17037                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT)) ||
17038                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT)) failed"
17039         done
17040
17041         # check changelogs have been generated
17042         local start=$SECONDS
17043         local idle_time=$((MDSCOUNT * 5 + 5))
17044         local nbcl=$(changelog_dump | wc -l)
17045         [[ $nbcl -eq 0 ]] && error "no changelogs found"
17046
17047         for param in "changelog_max_idle_time=$idle_time" \
17048                      "changelog_gc=1" \
17049                      "changelog_min_gc_interval=2" \
17050                      "changelog_min_free_cat_entries=3"; do
17051                 local MDT0=$(facet_svc $SINGLEMDS)
17052                 local var="${param%=*}"
17053                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
17054
17055                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
17056                 do_nodes $mdts $LCTL set_param mdd.*.$param
17057         done
17058
17059         # force cl_user2 to be idle (1st part), but also cancel the
17060         # cl_user1 records so that it is not evicted later in the test.
17061         local sleep1=$((idle_time / 2))
17062         echo "$(date +%s): sleep1 $sleep1/${idle_time}s"
17063         sleep $sleep1
17064
17065         # simulate changelog catalog almost full
17066         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
17067         do_nodes $mdts "$LCTL set_param fail_loc=0x1313 fail_val=3"
17068
17069         for i in $(seq $MDSCOUNT); do
17070                 cl_users=(${CL_USERS[mds$i]})
17071                 cl_user1[mds$i]="${cl_users[0]}"
17072                 cl_user2[mds$i]="${cl_users[1]}"
17073
17074                 [ -n "${cl_user1[mds$i]}" ] ||
17075                         error "mds$i: no user registered"
17076                 [ -n "${cl_user2[mds$i]}" ] ||
17077                         error "mds$i: only ${cl_user2[mds$i]} is registered"
17078
17079                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17080                 [ -n "$user_rec1" ] ||
17081                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17082                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
17083                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17084                 [ -n "$user_rec2" ] ||
17085                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17086                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
17087                      "$user_rec1 + 2 == $user_rec2"
17088                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
17089                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
17090                               "$user_rec1 + 2, but is $user_rec2"
17091                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
17092                 [ -n "$user_rec2" ] ||
17093                         error "mds$i: User ${cl_user2[mds$i]} not registered"
17094                 [ $user_rec1 == $user_rec2 ] ||
17095                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
17096                               "$user_rec1, but is $user_rec2"
17097         done
17098
17099         # force cl_user2 idle (2nd part) to just exceed changelog_max_idle_time
17100         local sleep2=$((idle_time - (SECONDS - start) + 1))
17101         echo "$(date +%s): sleep2 $sleep2/${idle_time}s"
17102         sleep $sleep2
17103
17104         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
17105         # cl_user1 should be OK because it recently processed records.
17106         echo "$(date +%s): creating $((MDSCOUNT * 2)) files"
17107         for ((i = 0; i < MDSCOUNT * 2; i++)); do
17108                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT+2))||
17109                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT+2)) failed"
17110         done
17111
17112         # ensure gc thread is done
17113         for i in $(mdts_nodes); do
17114                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
17115                         error "$i: GC-thread not done"
17116         done
17117
17118         local first_rec
17119         for (( i = 1; i <= MDSCOUNT; i++ )); do
17120                 # check cl_user1 still registered
17121                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
17122                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17123                 # check cl_user2 unregistered
17124                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
17125                         error "mds$i: User ${cl_user2[mds$i]} still registered"
17126
17127                 # check changelogs are present and starting at $user_rec1 + 1
17128                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17129                 [ -n "$user_rec1" ] ||
17130                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17131                 first_rec=$($LFS changelog $(facet_svc mds$i) |
17132                             awk '{ print $1; exit; }')
17133
17134                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
17135                 [ $((user_rec1 + 1)) == $first_rec ] ||
17136                         error "mds$i: rec $first_rec != $user_rec1 + 1"
17137         done
17138 }
17139 run_test 160f "changelog garbage collect (timestamped users)"
17140
17141 test_160g() {
17142         remote_mds_nodsh && skip "remote MDS with nodsh"
17143         [[ $MDS1_VERSION -ge $(version_code 2.14.55) ]] ||
17144                 skip "Need MDS version at least 2.14.55"
17145
17146         local mdts=$(comma_list $(mdts_nodes))
17147
17148         # Create a user
17149         changelog_register || error "first changelog_register failed"
17150         changelog_register || error "second changelog_register failed"
17151         local cl_users
17152         declare -A cl_user1
17153         declare -A cl_user2
17154         local user_rec1
17155         local user_rec2
17156         local i
17157
17158         # generate some changelog records to accumulate on each MDT
17159         # use all_char because created files should be evenly distributed
17160         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
17161                 error "test_mkdir $tdir failed"
17162         for ((i = 0; i < MDSCOUNT; i++)); do
17163                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
17164                         error "create $DIR/$tdir/d$i.1 failed"
17165         done
17166
17167         # check changelogs have been generated
17168         local nbcl=$(changelog_dump | wc -l)
17169         (( $nbcl > 0 )) || error "no changelogs found"
17170
17171         # reduce the max_idle_indexes value to make sure we exceed it
17172         for param in "changelog_max_idle_indexes=2" \
17173                      "changelog_gc=1" \
17174                      "changelog_min_gc_interval=2"; do
17175                 local MDT0=$(facet_svc $SINGLEMDS)
17176                 local var="${param%=*}"
17177                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
17178
17179                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
17180                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
17181                         error "unable to set mdd.*.$param"
17182         done
17183
17184         local start=$SECONDS
17185         for i in $(seq $MDSCOUNT); do
17186                 cl_users=(${CL_USERS[mds$i]})
17187                 cl_user1[mds$i]="${cl_users[0]}"
17188                 cl_user2[mds$i]="${cl_users[1]}"
17189
17190                 [ -n "${cl_user1[mds$i]}" ] ||
17191                         error "mds$i: user1 is not registered"
17192                 [ -n "${cl_user2[mds$i]}" ] ||
17193                         error "mds$i: only ${cl_user1[mds$i]} is registered"
17194
17195                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17196                 [ -n "$user_rec1" ] ||
17197                         error "mds$i: user1 ${cl_user1[mds$i]} not found"
17198                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
17199                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17200                 [ -n "$user_rec2" ] ||
17201                         error "mds$i: user1 ${cl_user1[mds$i]} not found (2)"
17202                 echo "mds$i: verifying user1 ${cl_user1[mds$i]} clear: " \
17203                      "$user_rec1 + 2 == $user_rec2"
17204                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
17205                         error "mds$i: user1 ${cl_user1[mds$i]} index " \
17206                               "expected $user_rec1 + 2, but is $user_rec2"
17207                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
17208                 [ -n "$user_rec2" ] ||
17209                         error "mds$i: user2 ${cl_user2[mds$i]} not found"
17210                 [ $user_rec1 == $user_rec2 ] ||
17211                         error "mds$i: user2 ${cl_user2[mds$i]} index " \
17212                               "expected $user_rec1, but is $user_rec2"
17213         done
17214
17215         # ensure we are past the previous changelog_min_gc_interval set above
17216         local sleep2=$((start + 2 - SECONDS))
17217         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
17218         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
17219         # cl_user1 should be OK because it recently processed records.
17220         for ((i = 0; i < MDSCOUNT; i++)); do
17221                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 ||
17222                         error "create $DIR/$tdir/d$i.3 failed"
17223         done
17224
17225         # ensure gc thread is done
17226         for i in $(mdts_nodes); do
17227                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
17228                         error "$i: GC-thread not done"
17229         done
17230
17231         local first_rec
17232         for (( i = 1; i <= MDSCOUNT; i++ )); do
17233                 # check cl_user1 still registered
17234                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
17235                         error "mds$i: user1 ${cl_user1[mds$i]} not found (3)"
17236                 # check cl_user2 unregistered
17237                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
17238                         error "mds$i: user2 ${cl_user2[mds$i]} is registered"
17239
17240                 # check changelogs are present and starting at $user_rec1 + 1
17241                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17242                 [ -n "$user_rec1" ] ||
17243                         error "mds$i: user1 ${cl_user1[mds$i]} not found (4)"
17244                 first_rec=$($LFS changelog $(facet_svc mds$i) |
17245                             awk '{ print $1; exit; }')
17246
17247                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
17248                 [ $((user_rec1 + 1)) == $first_rec ] ||
17249                         error "mds$i: rec $first_rec != $user_rec1 + 1"
17250         done
17251 }
17252 run_test 160g "changelog garbage collect on idle records"
17253
17254 test_160h() {
17255         remote_mds_nodsh && skip "remote MDS with nodsh" && return
17256         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
17257                 skip "Need MDS version at least 2.10.56"
17258
17259         local mdts=$(comma_list $(mdts_nodes))
17260
17261         # Create a user
17262         changelog_register || error "first changelog_register failed"
17263         changelog_register || error "second changelog_register failed"
17264         local cl_users
17265         declare -A cl_user1
17266         declare -A cl_user2
17267         local user_rec1
17268         local user_rec2
17269         local i
17270
17271         # generate some changelog records to accumulate on each MDT
17272         # use all_char because created files should be evenly distributed
17273         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
17274                 error "test_mkdir $tdir failed"
17275         for ((i = 0; i < MDSCOUNT; i++)); do
17276                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
17277                         error "create $DIR/$tdir/d$i.1 failed"
17278         done
17279
17280         # check changelogs have been generated
17281         local nbcl=$(changelog_dump | wc -l)
17282         [[ $nbcl -eq 0 ]] && error "no changelogs found"
17283
17284         for param in "changelog_max_idle_time=10" \
17285                      "changelog_gc=1" \
17286                      "changelog_min_gc_interval=2"; do
17287                 local MDT0=$(facet_svc $SINGLEMDS)
17288                 local var="${param%=*}"
17289                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
17290
17291                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
17292                 do_nodes $mdts $LCTL set_param mdd.*.$param
17293         done
17294
17295         # force cl_user2 to be idle (1st part)
17296         sleep 9
17297
17298         for i in $(seq $MDSCOUNT); do
17299                 cl_users=(${CL_USERS[mds$i]})
17300                 cl_user1[mds$i]="${cl_users[0]}"
17301                 cl_user2[mds$i]="${cl_users[1]}"
17302
17303                 [ -n "${cl_user1[mds$i]}" ] ||
17304                         error "mds$i: no user registered"
17305                 [ -n "${cl_user2[mds$i]}" ] ||
17306                         error "mds$i: only ${cl_user2[mds$i]} is registered"
17307
17308                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17309                 [ -n "$user_rec1" ] ||
17310                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17311                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
17312                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17313                 [ -n "$user_rec2" ] ||
17314                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17315                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
17316                      "$user_rec1 + 2 == $user_rec2"
17317                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
17318                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
17319                               "$user_rec1 + 2, but is $user_rec2"
17320                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
17321                 [ -n "$user_rec2" ] ||
17322                         error "mds$i: User ${cl_user2[mds$i]} not registered"
17323                 [ $user_rec1 == $user_rec2 ] ||
17324                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
17325                               "$user_rec1, but is $user_rec2"
17326         done
17327
17328         # force cl_user2 to be idle (2nd part) and to reach
17329         # changelog_max_idle_time
17330         sleep 2
17331
17332         # force each GC-thread start and block then
17333         # one per MDT/MDD, set fail_val accordingly
17334         #define OBD_FAIL_FORCE_GC_THREAD 0x1316
17335         do_nodes $mdts $LCTL set_param fail_loc=0x1316
17336
17337         # generate more changelogs to trigger fail_loc
17338         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
17339                 error "create $DIR/$tdir/${tfile}bis failed"
17340
17341         # stop MDT to stop GC-thread, should be done in back-ground as it will
17342         # block waiting for the thread to be released and exit
17343         declare -A stop_pids
17344         for i in $(seq $MDSCOUNT); do
17345                 stop mds$i &
17346                 stop_pids[mds$i]=$!
17347         done
17348
17349         for i in $(mdts_nodes); do
17350                 local facet
17351                 local nb=0
17352                 local facets=$(facets_up_on_host $i)
17353
17354                 for facet in ${facets//,/ }; do
17355                         if [[ $facet == mds* ]]; then
17356                                 nb=$((nb + 1))
17357                         fi
17358                 done
17359                 # ensure each MDS's gc threads are still present and all in "R"
17360                 # state (OBD_FAIL_FORCE_GC_THREAD effect!)
17361                 [[ $(do_node $i pgrep chlg_gc_thread | wc -l) -eq $nb ]] ||
17362                         error "$i: expected $nb GC-thread"
17363                 wait_update $i \
17364                         "ps -C chlg_gc_thread -o state --no-headers | uniq" \
17365                         "R" 20 ||
17366                         error "$i: GC-thread not found in R-state"
17367                 # check umounts of each MDT on MDS have reached kthread_stop()
17368                 [[ $(do_node $i pgrep umount | wc -l) -eq $nb ]] ||
17369                         error "$i: expected $nb umount"
17370                 wait_update $i \
17371                         "ps -C umount -o state --no-headers | uniq" "D" 20 ||
17372                         error "$i: umount not found in D-state"
17373         done
17374
17375         # release all GC-threads
17376         do_nodes $mdts $LCTL set_param fail_loc=0
17377
17378         # wait for MDT stop to complete
17379         for i in $(seq $MDSCOUNT); do
17380                 wait ${stop_pids[mds$i]} || error "mds$i: stop failed"
17381         done
17382
17383         # XXX
17384         # may try to check if any orphan changelog records are present
17385         # via ldiskfs/zfs and llog_reader...
17386
17387         # re-start/mount MDTs
17388         for i in $(seq $MDSCOUNT); do
17389                 start mds$i $(mdsdevname $i) $MDS_MOUNT_OPTS ||
17390                         error "Fail to start mds$i"
17391         done
17392
17393         local first_rec
17394         for i in $(seq $MDSCOUNT); do
17395                 # check cl_user1 still registered
17396                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
17397                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17398                 # check cl_user2 unregistered
17399                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
17400                         error "mds$i: User ${cl_user2[mds$i]} still registered"
17401
17402                 # check changelogs are present and starting at $user_rec1 + 1
17403                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17404                 [ -n "$user_rec1" ] ||
17405                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17406                 first_rec=$($LFS changelog $(facet_svc mds$i) |
17407                             awk '{ print $1; exit; }')
17408
17409                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
17410                 [ $((user_rec1 + 1)) == $first_rec ] ||
17411                         error "mds$i: first index should be $user_rec1 + 1, " \
17412                               "but is $first_rec"
17413         done
17414 }
17415 run_test 160h "changelog gc thread stop upon umount, orphan records delete " \
17416               "during mount"
17417
17418 test_160i() {
17419
17420         local mdts=$(comma_list $(mdts_nodes))
17421
17422         changelog_register || error "first changelog_register failed"
17423
17424         # generate some changelog records to accumulate on each MDT
17425         # use all_char because created files should be evenly distributed
17426         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
17427                 error "test_mkdir $tdir failed"
17428         for ((i = 0; i < MDSCOUNT; i++)); do
17429                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
17430                         error "create $DIR/$tdir/d$i.1 failed"
17431         done
17432
17433         # check changelogs have been generated
17434         local nbcl=$(changelog_dump | wc -l)
17435         [[ $nbcl -eq 0 ]] && error "no changelogs found"
17436
17437         # simulate race between register and unregister
17438         # XXX as fail_loc is set per-MDS, with DNE configs the race
17439         # simulation will only occur for one MDT per MDS and for the
17440         # others the normal race scenario will take place
17441         #define CFS_FAIL_CHLOG_USER_REG_UNREG_RACE          0x1315
17442         do_nodes $mdts $LCTL set_param fail_loc=0x10001315
17443         do_nodes $mdts $LCTL set_param fail_val=1
17444
17445         # unregister 1st user
17446         changelog_deregister &
17447         local pid1=$!
17448         # wait some time for deregister work to reach race rdv
17449         sleep 2
17450         # register 2nd user
17451         changelog_register || error "2nd user register failed"
17452
17453         wait $pid1 || error "1st user deregister failed"
17454
17455         local i
17456         local last_rec
17457         declare -A LAST_REC
17458         for i in $(seq $MDSCOUNT); do
17459                 if changelog_users mds$i | grep "^cl"; then
17460                         # make sure new records are added with one user present
17461                         LAST_REC[mds$i]=$(changelog_users $SINGLEMDS |
17462                                           awk '/^current.index:/ { print $NF }')
17463                 else
17464                         error "mds$i has no user registered"
17465                 fi
17466         done
17467
17468         # generate more changelog records to accumulate on each MDT
17469         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
17470                 error "create $DIR/$tdir/${tfile}bis failed"
17471
17472         for i in $(seq $MDSCOUNT); do
17473                 last_rec=$(changelog_users $SINGLEMDS |
17474                            awk '/^current.index:/ { print $NF }')
17475                 echo "verify changelogs are on: $last_rec != ${LAST_REC[mds$i]}"
17476                 [ $last_rec != ${LAST_REC[mds$i]} ] ||
17477                         error "changelogs are off on mds$i"
17478         done
17479 }
17480 run_test 160i "changelog user register/unregister race"
17481
17482 test_160j() {
17483         remote_mds_nodsh && skip "remote MDS with nodsh"
17484         [[ $MDS1_VERSION -lt $(version_code 2.12.56) ]] &&
17485                 skip "Need MDS version at least 2.12.56"
17486
17487         mount_client $MOUNT2 || error "mount_client on $MOUNT2 failed"
17488         stack_trap "umount $MOUNT2" EXIT
17489
17490         changelog_register || error "first changelog_register failed"
17491         stack_trap "changelog_deregister" EXIT
17492
17493         # generate some changelog
17494         # use all_char because created files should be evenly distributed
17495         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
17496                 error "mkdir $tdir failed"
17497         for ((i = 0; i < MDSCOUNT; i++)); do
17498                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
17499                         error "create $DIR/$tdir/d$i.1 failed"
17500         done
17501
17502         # open the changelog device
17503         exec 3>/dev/changelog-$FSNAME-MDT0000
17504         stack_trap "exec 3>&-" EXIT
17505         exec 4</dev/changelog-$FSNAME-MDT0000
17506         stack_trap "exec 4<&-" EXIT
17507
17508         # umount the first lustre mount
17509         umount $MOUNT
17510         stack_trap "mount_client $MOUNT" EXIT
17511
17512         # read changelog, which may or may not fail, but should not crash
17513         cat <&4 >/dev/null
17514
17515         # clear changelog
17516         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
17517         changelog_users $SINGLEMDS | grep -q $cl_user ||
17518                 error "User $cl_user not found in changelog_users"
17519
17520         printf 'clear:'$cl_user':0' >&3
17521 }
17522 run_test 160j "client can be umounted while its chanangelog is being used"
17523
17524 test_160k() {
17525         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17526         remote_mds_nodsh && skip "remote MDS with nodsh"
17527
17528         mkdir -p $DIR/$tdir/1/1
17529
17530         changelog_register || error "changelog_register failed"
17531         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
17532
17533         changelog_users $SINGLEMDS | grep -q $cl_user ||
17534                 error "User '$cl_user' not found in changelog_users"
17535 #define OBD_FAIL_MDS_CHANGELOG_REORDER 0x15d
17536         do_facet mds1 $LCTL set_param fail_loc=0x8000015d fail_val=3
17537         rmdir $DIR/$tdir/1/1 & sleep 1
17538         mkdir $DIR/$tdir/2
17539         touch $DIR/$tdir/2/2
17540         rm -rf $DIR/$tdir/2
17541
17542         wait
17543         sleep 4
17544
17545         changelog_dump | grep rmdir || error "rmdir not recorded"
17546 }
17547 run_test 160k "Verify that changelog records are not lost"
17548
17549 # Verifies that a file passed as a parameter has recently had an operation
17550 # performed on it that has generated an MTIME changelog which contains the
17551 # correct parent FID. As files might reside on a different MDT from the
17552 # parent directory in DNE configurations, the FIDs are translated to paths
17553 # before being compared, which should be identical
17554 compare_mtime_changelog() {
17555         local file="${1}"
17556         local mdtidx
17557         local mtime
17558         local cl_fid
17559         local pdir
17560         local dir
17561
17562         mdtidx=$($LFS getstripe --mdt-index $file)
17563         mdtidx=$(printf "%04x" $mdtidx)
17564
17565         # Obtain the parent FID from the MTIME changelog
17566         mtime=$($LFS changelog $FSNAME-MDT$mdtidx | tail -n 1 | grep MTIME)
17567         [ -z "$mtime" ] && error "MTIME changelog not recorded"
17568
17569         cl_fid=$(sed -e 's/.* p=//' -e 's/ .*//' <<<$mtime)
17570         [ -z "$cl_fid" ] && error "parent FID not present"
17571
17572         # Verify that the path for the parent FID is the same as the path for
17573         # the test directory
17574         pdir=$($LFS fid2path $MOUNT "$cl_fid")
17575
17576         dir=$(dirname $1)
17577
17578         [[ "${pdir%/}" == "$dir" ]] ||
17579                 error "MTIME changelog parent FID is wrong, expected $dir, got $pdir"
17580 }
17581
17582 test_160l() {
17583         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17584
17585         remote_mds_nodsh && skip "remote MDS with nodsh"
17586         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
17587                 skip "Need MDS version at least 2.13.55"
17588
17589         local cl_user
17590
17591         changelog_register || error "changelog_register failed"
17592         cl_user="${CL_USERS[$SINGLEMDS]%% *}"
17593
17594         changelog_users $SINGLEMDS | grep -q $cl_user ||
17595                 error "User '$cl_user' not found in changelog_users"
17596
17597         # Clear some types so that MTIME changelogs are generated
17598         changelog_chmask "-CREAT"
17599         changelog_chmask "-CLOSE"
17600
17601         test_mkdir $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
17602
17603         # Test CL_MTIME during setattr
17604         touch $DIR/$tdir/$tfile
17605         compare_mtime_changelog $DIR/$tdir/$tfile
17606
17607         # Test CL_MTIME during close
17608         $MULTIOP $DIR/$tdir/${tfile}_2 O_2w4096c || error "multiop failed"
17609         compare_mtime_changelog $DIR/$tdir/${tfile}_2
17610 }
17611 run_test 160l "Verify that MTIME changelog records contain the parent FID"
17612
17613 test_160m() {
17614         remote_mds_nodsh && skip "remote MDS with nodsh" && return
17615         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
17616                 skip "Need MDS version at least 2.14.51"
17617         local cl_users
17618         local cl_user1
17619         local cl_user2
17620         local pid1
17621
17622         # Create a user
17623         changelog_register || error "first changelog_register failed"
17624         changelog_register || error "second changelog_register failed"
17625
17626         cl_users=(${CL_USERS[mds1]})
17627         cl_user1="${cl_users[0]}"
17628         cl_user2="${cl_users[1]}"
17629         # generate some changelog records to accumulate on MDT0
17630         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
17631         createmany -m $DIR/$tdir/$tfile 50 ||
17632                 error "create $DIR/$tdir/$tfile failed"
17633         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
17634         rm -f $DIR/$tdir
17635
17636         # check changelogs have been generated
17637         local nbcl=$(changelog_dump | wc -l)
17638         [[ $nbcl -eq 0 ]] && error "no changelogs found"
17639
17640 #define OBD_FAIL_MDS_CHANGELOG_RACE      0x15f
17641         do_facet mds1 $LCTL set_param fail_loc=0x8000015f fail_val=0
17642
17643         __changelog_clear mds1 $cl_user1 +10
17644         __changelog_clear mds1 $cl_user2 0 &
17645         pid1=$!
17646         sleep 2
17647         __changelog_clear mds1 $cl_user1 0 ||
17648                 error "fail to cancel record for $cl_user1"
17649         wait $pid1
17650         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
17651 }
17652 run_test 160m "Changelog clear race"
17653
17654 test_160n() {
17655         remote_mds_nodsh && skip "remote MDS with nodsh" && return
17656         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
17657                 skip "Need MDS version at least 2.14.51"
17658         local cl_users
17659         local cl_user1
17660         local cl_user2
17661         local pid1
17662         local first_rec
17663         local last_rec=0
17664
17665         # Create a user
17666         changelog_register || error "first changelog_register failed"
17667
17668         cl_users=(${CL_USERS[mds1]})
17669         cl_user1="${cl_users[0]}"
17670
17671         # generate some changelog records to accumulate on MDT0
17672         test_mkdir -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
17673         first_rec=$(changelog_users $SINGLEMDS |
17674                         awk '/^current.index:/ { print $NF }')
17675         while (( last_rec < (( first_rec + 65000)) )); do
17676                 createmany -m $DIR/$tdir/$tfile 10000 ||
17677                         error "create $DIR/$tdir/$tfile failed"
17678
17679                 for i in $(seq 0 10000); do
17680                         mrename $DIR/$tdir/$tfile$i $DIR/$tdir/$tfile-new$i \
17681                                 > /dev/null
17682                 done
17683
17684                 unlinkmany $DIR/$tdir/$tfile-new 10000 ||
17685                         error "unlinkmany failed unlink"
17686                 last_rec=$(changelog_users $SINGLEMDS |
17687                         awk '/^current.index:/ { print $NF }')
17688                 echo last record $last_rec
17689                 (( last_rec == 0 )) && error "no changelog found"
17690         done
17691
17692 #define OBD_FAIL_MDS_CHANGELOG_DEL       0x16c
17693         do_facet mds1 $LCTL set_param fail_loc=0x8000016c fail_val=0
17694
17695         __changelog_clear mds1 $cl_user1 0 &
17696         pid1=$!
17697         sleep 2
17698         __changelog_clear mds1 $cl_user1 0 ||
17699                 error "fail to cancel record for $cl_user1"
17700         wait $pid1
17701         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
17702 }
17703 run_test 160n "Changelog destroy race"
17704
17705 test_160o() {
17706         local mdt="$(facet_svc $SINGLEMDS)"
17707
17708         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
17709         remote_mds_nodsh && skip "remote MDS with nodsh"
17710         [ $MDS1_VERSION -ge $(version_code 2.14.52) ] ||
17711                 skip "Need MDS version at least 2.14.52"
17712
17713         changelog_register --user test_160o -m unlnk+close+open ||
17714                 error "changelog_register failed"
17715
17716         do_facet $SINGLEMDS $LCTL --device $mdt \
17717                                 changelog_register -u "Tt3_-#" &&
17718                 error "bad symbols in name should fail"
17719
17720         do_facet $SINGLEMDS $LCTL --device $mdt \
17721                                 changelog_register -u test_160o &&
17722                 error "the same name registration should fail"
17723
17724         do_facet $SINGLEMDS $LCTL --device $mdt \
17725                         changelog_register -u test_160toolongname &&
17726                 error "too long name registration should fail"
17727
17728         changelog_chmask "MARK+HSM"
17729         lctl get_param mdd.*.changelog*mask
17730         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
17731         changelog_users $SINGLEMDS | grep -q $cl_user ||
17732                 error "User $cl_user not found in changelog_users"
17733         #verify username
17734         echo $cl_user | grep -q test_160o ||
17735                 error "User $cl_user has no specific name 'test160o'"
17736
17737         # change something
17738         changelog_clear 0 || error "changelog_clear failed"
17739         # generate some changelog records to accumulate on MDT0
17740         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
17741         touch $DIR/$tdir/$tfile                 # open 1
17742
17743         OPENS=$(changelog_dump | grep -c "OPEN")
17744         [[ $OPENS -eq 1 ]] || error "OPEN changelog mask count $OPENS != 1"
17745
17746         # must be no MKDIR it wasn't set as user mask
17747         MKDIR=$(changelog_dump | grep -c "MKDIR")
17748         [[ $MKDIR -eq 0 ]] || error "MKDIR changelog mask found $MKDIR > 0"
17749
17750         oldmask=$(do_facet $SINGLEMDS $LCTL get_param \
17751                                 mdd.$mdt.changelog_current_mask -n)
17752         # register maskless user
17753         changelog_register || error "changelog_register failed"
17754         # effective mask should be not changed because it is not minimal
17755         mask=$(do_facet $SINGLEMDS $LCTL get_param \
17756                                 mdd.$mdt.changelog_current_mask -n)
17757         [[ $mask == $oldmask ]] || error "mask was changed: $mask vs $oldmask"
17758         # set server mask to minimal value
17759         changelog_chmask "MARK"
17760         # check effective mask again, should be treated as DEFMASK now
17761         mask=$(do_facet $SINGLEMDS $LCTL get_param \
17762                                 mdd.$mdt.changelog_current_mask -n)
17763         [[ $mask == *"HLINK"* ]] || error "mask is not DEFMASK as expected"
17764
17765         if (( $MDS1_VERSION >= $(version_code 2.15.52) )) ; then
17766                 # set server mask back to some value
17767                 changelog_chmask "CLOSE,UNLNK"
17768                 # check effective mask again, should not remain as DEFMASK
17769                 mask=$(do_facet $SINGLEMDS $LCTL get_param \
17770                                 mdd.$mdt.changelog_current_mask -n)
17771                 [[ $mask != *"HLINK"* ]] || error "mask is still DEFMASK"
17772         fi
17773
17774         do_facet $SINGLEMDS $LCTL --device $mdt \
17775                                 changelog_deregister -u test_160o ||
17776                 error "cannot deregister by name"
17777 }
17778 run_test 160o "changelog user name and mask"
17779
17780 test_160p() {
17781         remote_mds_nodsh && skip "remote MDS with nodsh" && return
17782         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
17783                 skip "Need MDS version at least 2.14.51"
17784         [[ "$mds1_FSTYPE" == "ldiskfs" ]] || skip "ldiskfs only test"
17785         local cl_users
17786         local cl_user1
17787         local entry_count
17788
17789         # Create a user
17790         changelog_register || error "first changelog_register failed"
17791
17792         cl_users=(${CL_USERS[mds1]})
17793         cl_user1="${cl_users[0]}"
17794
17795         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
17796         createmany -m $DIR/$tdir/$tfile 50 ||
17797                 error "create $DIR/$tdir/$tfile failed"
17798         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
17799         rm -rf $DIR/$tdir
17800
17801         # check changelogs have been generated
17802         entry_count=$(changelog_dump | wc -l)
17803         ((entry_count != 0)) || error "no changelog entries found"
17804
17805         # remove changelog_users and check that orphan entries are removed
17806         stop mds1
17807         local dev=$(mdsdevname 1)
17808         do_facet mds1 "$DEBUGFS -w -R 'rm changelog_users' $dev"
17809         start mds1 $dev $MDS_MOUNT_OPTS || error "cannot start mds1"
17810         entry_count=$(changelog_dump | wc -l)
17811         ((entry_count == 0)) ||
17812                 error "found $entry_count changelog entries, expected none"
17813 }
17814 run_test 160p "Changelog orphan cleanup with no users"
17815
17816 test_160q() {
17817         local mdt="$(facet_svc $SINGLEMDS)"
17818         local clu
17819
17820         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
17821         remote_mds_nodsh && skip "remote MDS with nodsh"
17822         [ $MDS1_VERSION -ge $(version_code 2.14.54) ] ||
17823                 skip "Need MDS version at least 2.14.54"
17824
17825         # set server mask to minimal value like server init does
17826         changelog_chmask "MARK"
17827         clu=$(do_facet $SINGLEMDS $LCTL --device $mdt changelog_register -n) ||
17828                 error "changelog_register failed"
17829         # check effective mask again, should be treated as DEFMASK now
17830         mask=$(do_facet $SINGLEMDS $LCTL get_param \
17831                                 mdd.$mdt.changelog_current_mask -n)
17832         do_facet $SINGLEMDS $LCTL --device $mdt changelog_deregister $clu ||
17833                 error "changelog_deregister failed"
17834         [[ $mask == *"HLINK"* ]] || error "mask is not DEFMASK as expected"
17835 }
17836 run_test 160q "changelog effective mask is DEFMASK if not set"
17837
17838 test_160s() {
17839         remote_mds_nodsh && skip "remote MDS with nodsh"
17840         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
17841                 skip "Need MDS version at least 2.14.55"
17842
17843         local mdts=$(comma_list $(mdts_nodes))
17844
17845         #define OBD_FAIL_TIME_IN_CHLOG_USER     0x1314
17846         do_nodes $mdts $LCTL set_param fail_loc=0x1314 \
17847                                        fail_val=$((24 * 3600 * 10))
17848
17849         # Create a user which is 10 days old
17850         changelog_register || error "first changelog_register failed"
17851         local cl_users
17852         declare -A cl_user1
17853         local i
17854
17855         # generate some changelog records to accumulate on each MDT
17856         # use all_char because created files should be evenly distributed
17857         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
17858                 error "test_mkdir $tdir failed"
17859         for ((i = 0; i < MDSCOUNT; i++)); do
17860                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
17861                         error "create $DIR/$tdir/d$i.1 failed"
17862         done
17863
17864         # check changelogs have been generated
17865         local nbcl=$(changelog_dump | wc -l)
17866         (( nbcl > 0 )) || error "no changelogs found"
17867
17868         # reduce the max_idle_indexes value to make sure we exceed it
17869         for param in "changelog_max_idle_indexes=2097446912" \
17870                      "changelog_max_idle_time=2592000" \
17871                      "changelog_gc=1" \
17872                      "changelog_min_gc_interval=2"; do
17873                 local MDT0=$(facet_svc $SINGLEMDS)
17874                 local var="${param%=*}"
17875                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
17876
17877                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
17878                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
17879                         error "unable to set mdd.*.$param"
17880         done
17881
17882         local start=$SECONDS
17883         for i in $(seq $MDSCOUNT); do
17884                 cl_users=(${CL_USERS[mds$i]})
17885                 cl_user1[mds$i]="${cl_users[0]}"
17886
17887                 [[ -n "${cl_user1[mds$i]}" ]] ||
17888                         error "mds$i: no user registered"
17889         done
17890
17891         #define OBD_FAIL_MDS_CHANGELOG_IDX_PUMP   0x16d
17892         do_nodes $mdts $LCTL set_param fail_loc=0x16d fail_val=500000000
17893
17894         # ensure we are past the previous changelog_min_gc_interval set above
17895         local sleep2=$((start + 2 - SECONDS))
17896         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
17897
17898         # Generate one more changelog to trigger GC
17899         for ((i = 0; i < MDSCOUNT; i++)); do
17900                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 $DIR/$tdir/d$i.4 ||
17901                         error "create $DIR/$tdir/d$i.3 failed"
17902         done
17903
17904         # ensure gc thread is done
17905         for node in $(mdts_nodes); do
17906                 wait_update $node "pgrep chlg_gc_thread" "" 20 ||
17907                         error "$node: GC-thread not done"
17908         done
17909
17910         do_nodes $mdts $LCTL set_param fail_loc=0
17911
17912         for (( i = 1; i <= MDSCOUNT; i++ )); do
17913                 # check cl_user1 is purged
17914                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" &&
17915                         error "mds$i: User ${cl_user1[mds$i]} is registered"
17916         done
17917         return 0
17918 }
17919 run_test 160s "changelog garbage collect on idle records * time"
17920
17921 test_160t() {
17922         remote_mds_nodsh && skip "remote MDS with nodsh"
17923         (( $MDS1_VERSION >= $(version_code 2.15.50) )) ||
17924                 skip "Need MDS version at least 2.15.50"
17925
17926         local MDT0=$(facet_svc $SINGLEMDS)
17927         local cl_users
17928         local cl_user1
17929         local cl_user2
17930         local start
17931
17932         changelog_register --user user1 -m all ||
17933                 error "user1 failed to register"
17934
17935         mkdir_on_mdt0 $DIR/$tdir
17936         # create default overstripe to maximize changelog size
17937         $LFS setstripe  -C 8 $DIR/$tdir || error "setstripe failed"
17938         createmany -o $DIR/$tdir/u1_ 2000 || error "createmany for user1 failed"
17939         llog_size1=$(do_facet mds1 $LCTL get_param -n mdd.$MDT0.changelog_size)
17940
17941         # user2 consumes less records so less space
17942         changelog_register --user user2 || error "user2 failed to register"
17943         createmany -o $DIR/$tdir/u2_ 500 || error "createmany for user2 failed"
17944         llog_size2=$(do_facet mds1 $LCTL get_param -n mdd.$MDT0.changelog_size)
17945
17946         # check changelogs have been generated
17947         local nbcl=$(changelog_dump | wc -l)
17948         (( nbcl > 0 )) || error "no changelogs found"
17949
17950         # reduce the changelog_min_gc_interval to force check
17951         for param in "changelog_gc=1" "changelog_min_gc_interval=2"; do
17952                 local var="${param%=*}"
17953                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
17954
17955                 stack_trap "do_facet mds1 $LCTL set_param mdd.$MDT0.$var=$old"
17956                 do_facet mds1 $LCTL set_param mdd.$MDT0.$param ||
17957                         error "unable to set mdd.*.$param"
17958         done
17959
17960         start=$SECONDS
17961         cl_users=(${CL_USERS[mds1]})
17962         cl_user1="${cl_users[0]}"
17963         cl_user2="${cl_users[1]}"
17964
17965         [[ -n $cl_user1 ]] ||
17966                 error "mds1: user #1 isn't registered"
17967         [[ -n $cl_user2 ]] ||
17968                 error "mds1: user #2 isn't registered"
17969
17970         # ensure we are past the previous changelog_min_gc_interval set above
17971         local sleep2=$((start + 2 - SECONDS))
17972         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
17973
17974         #define OBD_FAIL_MDS_CHANGELOG_ENOSPC 0x018c
17975         do_facet mds1 $LCTL set_param fail_loc=0x018c \
17976                         fail_val=$(((llog_size1 + llog_size2) / 2))
17977
17978         # Generate more changelog to trigger GC
17979         createmany -o $DIR/$tdir/u3_ 4 ||
17980                 error "create failed for more files"
17981
17982         # ensure gc thread is done
17983         wait_update_facet mds1 "pgrep chlg_gc_thread" "" 20 ||
17984                 error "mds1: GC-thread not done"
17985
17986         do_facet mds1 $LCTL set_param fail_loc=0
17987
17988         # check cl_user1 is purged
17989         changelog_users mds1 | grep -q "$cl_user1" &&
17990                 error "User $cl_user1 is registered"
17991         # check cl_user2 is not purged
17992         changelog_users mds1 | grep -q "$cl_user2" ||
17993                 error "User $cl_user2 is not registered"
17994 }
17995 run_test 160t "changelog garbage collect on lack of space"
17996
17997 test_161a() {
17998         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17999
18000         test_mkdir -c1 $DIR/$tdir
18001         cp /etc/hosts $DIR/$tdir/$tfile
18002         test_mkdir -c1 $DIR/$tdir/foo1
18003         test_mkdir -c1 $DIR/$tdir/foo2
18004         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/sofia
18005         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/zachary
18006         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/luna
18007         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/thor
18008         local FID=$($LFS path2fid $DIR/$tdir/$tfile | tr -d '[]')
18009         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
18010                 $LFS fid2path $DIR $FID
18011                 error "bad link ea"
18012         fi
18013         # middle
18014         rm $DIR/$tdir/foo2/zachary
18015         # last
18016         rm $DIR/$tdir/foo2/thor
18017         # first
18018         rm $DIR/$tdir/$tfile
18019         # rename
18020         mv $DIR/$tdir/foo1/sofia $DIR/$tdir/foo2/maggie
18021         [ "$($LFS fid2path $FSNAME --link 1 $FID)" != "$tdir/foo2/maggie" ] &&
18022                 { $LFS fid2path $DIR $FID; error "bad link rename"; }
18023         rm $DIR/$tdir/foo2/maggie
18024
18025         # overflow the EA
18026         local longname=$tfile.avg_len_is_thirty_two_
18027         stack_trap "unlinkmany $DIR/$tdir/foo2/$longname 1000 || \
18028                 error_noexit 'failed to unlink many hardlinks'" EXIT
18029         createmany -l$DIR/$tdir/foo1/luna $DIR/$tdir/foo2/$longname 1000 ||
18030                 error "failed to hardlink many files"
18031         links=$($LFS fid2path $DIR $FID | wc -l)
18032         echo -n "${links}/1000 links in link EA"
18033         [[ $links -gt 60 ]] || error "expected at least 60 links in link EA"
18034 }
18035 run_test 161a "link ea sanity"
18036
18037 test_161b() {
18038         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18039         [ $MDSCOUNT -lt 2 ] && skip_env "skipping remote directory test"
18040
18041         local MDTIDX=1
18042         local remote_dir=$DIR/$tdir/remote_dir
18043
18044         mkdir -p $DIR/$tdir
18045         $LFS mkdir -i $MDTIDX $remote_dir ||
18046                 error "create remote directory failed"
18047
18048         cp /etc/hosts $remote_dir/$tfile
18049         mkdir -p $remote_dir/foo1
18050         mkdir -p $remote_dir/foo2
18051         ln $remote_dir/$tfile $remote_dir/foo1/sofia
18052         ln $remote_dir/$tfile $remote_dir/foo2/zachary
18053         ln $remote_dir/$tfile $remote_dir/foo1/luna
18054         ln $remote_dir/$tfile $remote_dir/foo2/thor
18055
18056         local FID=$($LFS path2fid $remote_dir/$tfile | tr -d '[' |
18057                      tr -d ']')
18058         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
18059                 $LFS fid2path $DIR $FID
18060                 error "bad link ea"
18061         fi
18062         # middle
18063         rm $remote_dir/foo2/zachary
18064         # last
18065         rm $remote_dir/foo2/thor
18066         # first
18067         rm $remote_dir/$tfile
18068         # rename
18069         mv $remote_dir/foo1/sofia $remote_dir/foo2/maggie
18070         local link_path=$($LFS fid2path $FSNAME --link 1 $FID)
18071         if [ "$DIR/$link_path" != "$remote_dir/foo2/maggie" ]; then
18072                 $LFS fid2path $DIR $FID
18073                 error "bad link rename"
18074         fi
18075         rm $remote_dir/foo2/maggie
18076
18077         # overflow the EA
18078         local longname=filename_avg_len_is_thirty_two_
18079         createmany -l$remote_dir/foo1/luna $remote_dir/foo2/$longname 1000 ||
18080                 error "failed to hardlink many files"
18081         links=$($LFS fid2path $DIR $FID | wc -l)
18082         echo -n "${links}/1000 links in link EA"
18083         [[ ${links} -gt 60 ]] ||
18084                 error "expected at least 60 links in link EA"
18085         unlinkmany $remote_dir/foo2/$longname 1000 ||
18086         error "failed to unlink many hardlinks"
18087 }
18088 run_test 161b "link ea sanity under remote directory"
18089
18090 test_161c() {
18091         remote_mds_nodsh && skip "remote MDS with nodsh"
18092         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18093         [[ $MDS1_VERSION -lt $(version_code 2.1.5) ]] &&
18094                 skip "Need MDS version at least 2.1.5"
18095
18096         # define CLF_RENAME_LAST 0x0001
18097         # rename overwrite a target having nlink = 1 (changelog flag 0x1)
18098         changelog_register || error "changelog_register failed"
18099
18100         rm -rf $DIR/$tdir
18101         test_mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir
18102         touch $DIR/$tdir/foo_161c
18103         touch $DIR/$tdir/bar_161c
18104         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
18105         changelog_dump | grep RENME | tail -n 5
18106         local flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
18107         changelog_clear 0 || error "changelog_clear failed"
18108         if [ x$flags != "x0x1" ]; then
18109                 error "flag $flags is not 0x1"
18110         fi
18111
18112         echo "rename overwrite target with nlink = 1, changelog flags=$flags"
18113         # rename overwrite a target having nlink > 1 (changelog flag 0x0)
18114         touch $DIR/$tdir/foo_161c
18115         touch $DIR/$tdir/bar_161c
18116         ln $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
18117         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
18118         changelog_dump | grep RENME | tail -n 5
18119         flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
18120         changelog_clear 0 || error "changelog_clear failed"
18121         if [ x$flags != "x0x0" ]; then
18122                 error "flag $flags is not 0x0"
18123         fi
18124         echo "rename overwrite a target having nlink > 1," \
18125                 "changelog record has flags of $flags"
18126
18127         # rename doesn't overwrite a target (changelog flag 0x0)
18128         touch $DIR/$tdir/foo_161c
18129         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/foo2_161c
18130         changelog_dump | grep RENME | tail -n 5
18131         flags=$(changelog_dump | grep RENME | tail -1 | cut -f5 -d' ')
18132         changelog_clear 0 || error "changelog_clear failed"
18133         if [ x$flags != "x0x0" ]; then
18134                 error "flag $flags is not 0x0"
18135         fi
18136         echo "rename doesn't overwrite a target," \
18137                 "changelog record has flags of $flags"
18138
18139         # define CLF_UNLINK_LAST 0x0001
18140         # unlink a file having nlink = 1 (changelog flag 0x1)
18141         rm -f $DIR/$tdir/foo2_161c
18142         changelog_dump | grep UNLNK | tail -n 5
18143         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
18144         changelog_clear 0 || error "changelog_clear failed"
18145         if [ x$flags != "x0x1" ]; then
18146                 error "flag $flags is not 0x1"
18147         fi
18148         echo "unlink a file having nlink = 1," \
18149                 "changelog record has flags of $flags"
18150
18151         # unlink a file having nlink > 1 (changelog flag 0x0)
18152         ln -f $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
18153         rm -f $DIR/$tdir/foobar_161c
18154         changelog_dump | grep UNLNK | tail -n 5
18155         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
18156         changelog_clear 0 || error "changelog_clear failed"
18157         if [ x$flags != "x0x0" ]; then
18158                 error "flag $flags is not 0x0"
18159         fi
18160         echo "unlink a file having nlink > 1, changelog record flags '$flags'"
18161 }
18162 run_test 161c "check CL_RENME[UNLINK] changelog record flags"
18163
18164 test_161d() {
18165         remote_mds_nodsh && skip "remote MDS with nodsh"
18166         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
18167
18168         local pid
18169         local fid
18170
18171         changelog_register || error "changelog_register failed"
18172
18173         # work in a standalone dir to avoid locking on $DIR/$MOUNT to
18174         # interfer with $MOUNT/.lustre/fid/ access
18175         mkdir $DIR/$tdir
18176         [[ $? -eq 0 ]] || error "mkdir failed"
18177
18178         #define OBD_FAIL_LLITE_CREATE_NODE_PAUSE 0x140c | CFS_FAIL_ONCE
18179         $LCTL set_param fail_loc=0x8000140c
18180         # 5s pause
18181         $LCTL set_param fail_val=5
18182
18183         # create file
18184         echo foofoo > $DIR/$tdir/$tfile &
18185         pid=$!
18186
18187         # wait for create to be delayed
18188         sleep 2
18189
18190         ps -p $pid
18191         [[ $? -eq 0 ]] || error "create should be blocked"
18192
18193         local tempfile="$(mktemp --tmpdir $tfile.XXXXXX)"
18194         stack_trap "rm -f $tempfile"
18195         fid=$(changelog_extract_field "CREAT" "$tfile" "t=")
18196         cat $MOUNT/.lustre/fid/$fid 2>/dev/null >$tempfile || error "cat failed"
18197         # some delay may occur during ChangeLog publishing and file read just
18198         # above, that could allow file write to happen finally
18199         [[ -s $tempfile ]] && echo "file should be empty"
18200
18201         $LCTL set_param fail_loc=0
18202
18203         wait $pid
18204         [[ $? -eq 0 ]] || error "create failed"
18205 }
18206 run_test 161d "create with concurrent .lustre/fid access"
18207
18208 check_path() {
18209         local expected="$1"
18210         shift
18211         local fid="$2"
18212
18213         local path
18214         path=$($LFS fid2path "$@")
18215         local rc=$?
18216
18217         if [ $rc -ne 0 ]; then
18218                 error "path looked up of '$expected' failed: rc=$rc"
18219         elif [ "$path" != "$expected" ]; then
18220                 error "path looked up '$path' instead of '$expected'"
18221         else
18222                 echo "FID '$fid' resolves to path '$path' as expected"
18223         fi
18224 }
18225
18226 test_162a() { # was test_162
18227         test_mkdir -p -c1 $DIR/$tdir/d2
18228         touch $DIR/$tdir/d2/$tfile
18229         touch $DIR/$tdir/d2/x1
18230         touch $DIR/$tdir/d2/x2
18231         test_mkdir -p -c1 $DIR/$tdir/d2/a/b/c
18232         test_mkdir -p -c1 $DIR/$tdir/d2/p/q/r
18233         # regular file
18234         local fid=$($LFS path2fid $DIR/$tdir/d2/$tfile | tr -d '[]')
18235         check_path "$tdir/d2/$tfile" $FSNAME "$fid" --link 0
18236
18237         # softlink
18238         ln -s $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/slink
18239         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink | tr -d '[]')
18240         check_path "$tdir/d2/p/q/r/slink" $FSNAME "$fid" --link 0
18241
18242         # softlink to wrong file
18243         ln -s /this/is/garbage $DIR/$tdir/d2/p/q/r/slink.wrong
18244         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink.wrong | tr -d '[]')
18245         check_path "$tdir/d2/p/q/r/slink.wrong" $FSNAME "$fid" --link 0
18246
18247         # hardlink
18248         ln $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/hlink
18249         mv $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/a/b/c/new_file
18250         fid=$($LFS path2fid $DIR/$tdir/d2/a/b/c/new_file | tr -d '[]')
18251         # fid2path dir/fsname should both work
18252         check_path "$tdir/d2/a/b/c/new_file" $FSNAME "$fid" --link 1
18253         check_path "$DIR/$tdir/d2/p/q/r/hlink" $DIR "$fid" --link 0
18254
18255         # hardlink count: check that there are 2 links
18256         local nlinks=$($LFS fid2path $DIR "$fid" | wc -l)
18257         [ $nlinks -eq 2 ] || error "expect 2 links, found $nlinks"
18258
18259         # hardlink indexing: remove the first link
18260         rm $DIR/$tdir/d2/p/q/r/hlink
18261         check_path "$tdir/d2/a/b/c/new_file" $FSNAME $fid --link 0
18262 }
18263 run_test 162a "path lookup sanity"
18264
18265 test_162b() {
18266         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18267         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18268
18269         mkdir $DIR/$tdir
18270         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
18271                                 error "create striped dir failed"
18272
18273         local FID=$($LFS getdirstripe $DIR/$tdir/striped_dir |
18274                                         tail -n 1 | awk '{print $2}')
18275         stat $MOUNT/.lustre/fid/$FID && error "sub_stripe can be accessed"
18276
18277         touch $DIR/$tdir/striped_dir/f{0..4} || error "touch f0..4 failed"
18278         mkdir $DIR/$tdir/striped_dir/d{0..4} || error "mkdir d0..4 failed"
18279
18280         # regular file
18281         for ((i=0;i<5;i++)); do
18282                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/f$i | tr -d '[]') ||
18283                         error "get fid for f$i failed"
18284                 check_path "$tdir/striped_dir/f$i" $FSNAME $FID --link 0
18285
18286                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/d$i | tr -d '[]') ||
18287                         error "get fid for d$i failed"
18288                 check_path "$tdir/striped_dir/d$i" $FSNAME $FID --link 0
18289         done
18290
18291         return 0
18292 }
18293 run_test 162b "striped directory path lookup sanity"
18294
18295 # LU-4239: Verify fid2path works with paths 100 or more directories deep
18296 test_162c() {
18297         [[ $MDS1_VERSION -lt $(version_code 2.7.51) ]] &&
18298                 skip "Need MDS version at least 2.7.51"
18299
18300         local lpath=$tdir.local
18301         local rpath=$tdir.remote
18302
18303         test_mkdir $DIR/$lpath
18304         test_mkdir $DIR/$rpath
18305
18306         for ((i = 0; i <= 101; i++)); do
18307                 lpath="$lpath/$i"
18308                 mkdir $DIR/$lpath
18309                 FID=$($LFS path2fid $DIR/$lpath | tr -d '[]') ||
18310                         error "get fid for local directory $DIR/$lpath failed"
18311                 check_path "$DIR/$lpath" $MOUNT $FID --link 0
18312
18313                 rpath="$rpath/$i"
18314                 test_mkdir $DIR/$rpath
18315                 FID=$($LFS path2fid $DIR/$rpath | tr -d '[]') ||
18316                         error "get fid for remote directory $DIR/$rpath failed"
18317                 check_path "$DIR/$rpath" $MOUNT $FID --link 0
18318         done
18319
18320         return 0
18321 }
18322 run_test 162c "fid2path works with paths 100 or more directories deep"
18323
18324 oalr_event_count() {
18325         local event="${1}"
18326         local trace="${2}"
18327
18328         awk -v name="${FSNAME}-OST0000" \
18329             -v event="${event}" \
18330             '$1 == "TRACE" && $2 == event && $3 == name' \
18331             "${trace}" |
18332         wc -l
18333 }
18334
18335 oalr_expect_event_count() {
18336         local event="${1}"
18337         local trace="${2}"
18338         local expect="${3}"
18339         local count
18340
18341         count=$(oalr_event_count "${event}" "${trace}")
18342         if ((count == expect)); then
18343                 return 0
18344         fi
18345
18346         error_noexit "${event} event count was '${count}', expected ${expect}"
18347         cat "${trace}" >&2
18348         exit 1
18349 }
18350
18351 cleanup_165() {
18352         do_facet ost1 killall --quiet -KILL ofd_access_log_reader || true
18353         stop ost1
18354         start ost1 "$(ostdevname 1)" $OST_MOUNT_OPTS
18355 }
18356
18357 setup_165() {
18358         sync # Flush previous IOs so we can count log entries.
18359         do_facet ost1 $LCTL set_param "obdfilter.${FSNAME}-OST0000.access_log_size=4096"
18360         stack_trap cleanup_165 EXIT
18361 }
18362
18363 test_165a() {
18364         local trace="/tmp/${tfile}.trace"
18365         local rc
18366         local count
18367
18368         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
18369                 skip "OFD access log unsupported"
18370
18371         setup_165
18372         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
18373         sleep 5
18374
18375         do_facet ost1 ofd_access_log_reader --list
18376         stop ost1
18377
18378         do_facet ost1 killall -TERM ofd_access_log_reader
18379         wait
18380         rc=$?
18381
18382         if ((rc != 0)); then
18383                 error "ofd_access_log_reader exited with rc = '${rc}'"
18384         fi
18385
18386         # Parse trace file for discovery events:
18387         oalr_expect_event_count alr_log_add "${trace}" 1
18388         oalr_expect_event_count alr_log_eof "${trace}" 1
18389         oalr_expect_event_count alr_log_free "${trace}" 1
18390 }
18391 run_test 165a "ofd access log discovery"
18392
18393 test_165b() {
18394         local trace="/tmp/${tfile}.trace"
18395         local file="${DIR}/${tfile}"
18396         local pfid1
18397         local pfid2
18398         local -a entry
18399         local rc
18400         local count
18401         local size
18402         local flags
18403
18404         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
18405                 skip "OFD access log unsupported"
18406
18407         setup_165
18408         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
18409         sleep 5
18410
18411         do_facet ost1 ofd_access_log_reader --list
18412
18413         lfs setstripe -c 1 -i 0 "${file}"
18414         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
18415                 error "cannot create '${file}'"
18416
18417         sleep 5
18418         do_facet ost1 killall -TERM ofd_access_log_reader
18419         wait
18420         rc=$?
18421
18422         if ((rc != 0)); then
18423                 error "ofd_access_log_reader exited with rc = '${rc}'"
18424         fi
18425
18426         oalr_expect_event_count alr_log_entry "${trace}" 1
18427
18428         pfid1=$($LFS path2fid "${file}")
18429
18430         # 1     2             3   4    5     6   7    8    9     10
18431         # TRACE alr_log_entry OST PFID BEGIN END TIME SIZE COUNT FLAGS
18432         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
18433
18434         echo "entry = '${entry[*]}'" >&2
18435
18436         pfid2=${entry[4]}
18437         if [[ "${pfid1}" != "${pfid2}" ]]; then
18438                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
18439         fi
18440
18441         size=${entry[8]}
18442         if ((size != 1048576)); then
18443                 error "entry '${entry[*]}' has invalid io size '${size}', expected 1048576"
18444         fi
18445
18446         flags=${entry[10]}
18447         if [[ "${flags}" != "w" ]]; then
18448                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'w'"
18449         fi
18450
18451         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
18452         sleep 5
18453
18454         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r524288c ||
18455                 error "cannot read '${file}'"
18456         sleep 5
18457
18458         do_facet ost1 killall -TERM ofd_access_log_reader
18459         wait
18460         rc=$?
18461
18462         if ((rc != 0)); then
18463                 error "ofd_access_log_reader exited with rc = '${rc}'"
18464         fi
18465
18466         oalr_expect_event_count alr_log_entry "${trace}" 1
18467
18468         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
18469         echo "entry = '${entry[*]}'" >&2
18470
18471         pfid2=${entry[4]}
18472         if [[ "${pfid1}" != "${pfid2}" ]]; then
18473                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
18474         fi
18475
18476         size=${entry[8]}
18477         if ((size != 524288)); then
18478                 error "entry '${entry[*]}' has invalid io size '${size}', 524288"
18479         fi
18480
18481         flags=${entry[10]}
18482         if [[ "${flags}" != "r" ]]; then
18483                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'r'"
18484         fi
18485 }
18486 run_test 165b "ofd access log entries are produced and consumed"
18487
18488 test_165c() {
18489         local trace="/tmp/${tfile}.trace"
18490         local file="${DIR}/${tdir}/${tfile}"
18491
18492         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
18493                 skip "OFD access log unsupported"
18494
18495         test_mkdir "${DIR}/${tdir}"
18496
18497         setup_165
18498         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
18499         sleep 5
18500
18501         lfs setstripe -c 1 -i 0 "${DIR}/${tdir}"
18502
18503         # 4096 / 64 = 64. Create twice as many entries.
18504         for ((i = 0; i < 128; i++)); do
18505                 $MULTIOP "${file}-${i}" oO_CREAT:O_WRONLY:w512c ||
18506                         error "cannot create file"
18507         done
18508
18509         sync
18510
18511         do_facet ost1 killall -TERM ofd_access_log_reader
18512         wait
18513         rc=$?
18514         if ((rc != 0)); then
18515                 error "ofd_access_log_reader exited with rc = '${rc}'"
18516         fi
18517
18518         unlinkmany  "${file}-%d" 128
18519 }
18520 run_test 165c "full ofd access logs do not block IOs"
18521
18522 oal_get_read_count() {
18523         local stats="$1"
18524
18525         # STATS lustre-OST0001 alr_read_count 1
18526
18527         do_facet ost1 cat "${stats}" |
18528         awk '$1 == "STATS" && $3 == "alr_read_count" { count = $4; }
18529              END { print count; }'
18530 }
18531
18532 oal_expect_read_count() {
18533         local stats="$1"
18534         local count
18535         local expect="$2"
18536
18537         # Ask ofd_access_log_reader to write stats.
18538         do_facet ost1 killall -USR1 ofd_access_log_reader
18539
18540         # Allow some time for things to happen.
18541         sleep 1
18542
18543         count=$(oal_get_read_count "${stats}")
18544         if ((count == expect)); then
18545                 return 0
18546         fi
18547
18548         error_noexit "bad read count, got ${count}, expected ${expect}"
18549         do_facet ost1 cat "${stats}" >&2
18550         exit 1
18551 }
18552
18553 test_165d() {
18554         local stats="/tmp/${tfile}.stats"
18555         local file="${DIR}/${tdir}/${tfile}"
18556         local param="obdfilter.${FSNAME}-OST0000.access_log_mask"
18557
18558         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
18559                 skip "OFD access log unsupported"
18560
18561         test_mkdir "${DIR}/${tdir}"
18562
18563         setup_165
18564         do_facet ost1 ofd_access_log_reader --stats="${stats}" &
18565         sleep 5
18566
18567         lfs setstripe -c 1 -i 0 "${file}"
18568
18569         do_facet ost1 lctl set_param "${param}=rw"
18570         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
18571                 error "cannot create '${file}'"
18572         oal_expect_read_count "${stats}" 1
18573
18574         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
18575                 error "cannot read '${file}'"
18576         oal_expect_read_count "${stats}" 2
18577
18578         do_facet ost1 lctl set_param "${param}=r"
18579         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
18580                 error "cannot create '${file}'"
18581         oal_expect_read_count "${stats}" 2
18582
18583         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
18584                 error "cannot read '${file}'"
18585         oal_expect_read_count "${stats}" 3
18586
18587         do_facet ost1 lctl set_param "${param}=w"
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 lctl set_param "${param}=0"
18597         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
18598                 error "cannot create '${file}'"
18599         oal_expect_read_count "${stats}" 4
18600
18601         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
18602                 error "cannot read '${file}'"
18603         oal_expect_read_count "${stats}" 4
18604
18605         do_facet ost1 killall -TERM ofd_access_log_reader
18606         wait
18607         rc=$?
18608         if ((rc != 0)); then
18609                 error "ofd_access_log_reader exited with rc = '${rc}'"
18610         fi
18611 }
18612 run_test 165d "ofd_access_log mask works"
18613
18614 test_165e() {
18615         local stats="/tmp/${tfile}.stats"
18616         local file0="${DIR}/${tdir}-0/${tfile}"
18617         local file1="${DIR}/${tdir}-1/${tfile}"
18618
18619         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
18620                 skip "OFD access log unsupported"
18621
18622         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
18623
18624         test_mkdir -c 1 -i 0 "${DIR}/${tdir}-0"
18625         test_mkdir -c 1 -i 1 "${DIR}/${tdir}-1"
18626
18627         lfs setstripe -c 1 -i 0 "${file0}"
18628         lfs setstripe -c 1 -i 0 "${file1}"
18629
18630         setup_165
18631         do_facet ost1 ofd_access_log_reader -I 1 --stats="${stats}" &
18632         sleep 5
18633
18634         $MULTIOP "${file0}" oO_CREAT:O_WRONLY:w512c ||
18635                 error "cannot create '${file0}'"
18636         sync
18637         oal_expect_read_count "${stats}" 0
18638
18639         $MULTIOP "${file1}" oO_CREAT:O_WRONLY:w512c ||
18640                 error "cannot create '${file1}'"
18641         sync
18642         oal_expect_read_count "${stats}" 1
18643
18644         do_facet ost1 killall -TERM ofd_access_log_reader
18645         wait
18646         rc=$?
18647         if ((rc != 0)); then
18648                 error "ofd_access_log_reader exited with rc = '${rc}'"
18649         fi
18650 }
18651 run_test 165e "ofd_access_log MDT index filter works"
18652
18653 test_165f() {
18654         local trace="/tmp/${tfile}.trace"
18655         local rc
18656         local count
18657
18658         setup_165
18659         do_facet ost1 timeout 60 ofd_access_log_reader \
18660                 --exit-on-close --debug=- --trace=- > "${trace}" &
18661         sleep 5
18662         stop ost1
18663
18664         wait
18665         rc=$?
18666
18667         if ((rc != 0)); then
18668                 error_noexit "ofd_access_log_reader exited with rc = '${rc}'"
18669                 cat "${trace}"
18670                 exit 1
18671         fi
18672 }
18673 run_test 165f "ofd_access_log_reader --exit-on-close works"
18674
18675 test_169() {
18676         # do directio so as not to populate the page cache
18677         log "creating a 10 Mb file"
18678         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c ||
18679                 error "multiop failed while creating a file"
18680         log "starting reads"
18681         dd if=$DIR/$tfile of=/dev/null bs=4096 &
18682         log "truncating the file"
18683         $MULTIOP $DIR/$tfile oO_TRUNC:c ||
18684                 error "multiop failed while truncating the file"
18685         log "killing dd"
18686         kill %+ || true # reads might have finished
18687         echo "wait until dd is finished"
18688         wait
18689         log "removing the temporary file"
18690         rm -rf $DIR/$tfile || error "tmp file removal failed"
18691 }
18692 run_test 169 "parallel read and truncate should not deadlock"
18693
18694 test_170() {
18695         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18696
18697         $LCTL clear     # bug 18514
18698         $LCTL debug_daemon start $TMP/${tfile}_log_good
18699         touch $DIR/$tfile
18700         $LCTL debug_daemon stop
18701         sed -e "s/^...../a/g" $TMP/${tfile}_log_good > $TMP/${tfile}_log_bad ||
18702                 error "sed failed to read log_good"
18703
18704         $LCTL debug_daemon start $TMP/${tfile}_log_good
18705         rm -rf $DIR/$tfile
18706         $LCTL debug_daemon stop
18707
18708         $LCTL df $TMP/${tfile}_log_bad > $TMP/${tfile}_log_bad.out 2>&1 ||
18709                error "lctl df log_bad failed"
18710
18711         local bad_line=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
18712         local good_line1=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
18713
18714         $LCTL df $TMP/${tfile}_log_good > $TMP/${tfile}_log_good.out 2>&1
18715         local good_line2=$(tail -n 1 $TMP/${tfile}_log_good.out | awk '{print $5}')
18716
18717         [ "$bad_line" ] && [ "$good_line1" ] && [ "$good_line2" ] ||
18718                 error "bad_line good_line1 good_line2 are empty"
18719
18720         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
18721         cat $TMP/${tfile}_log_bad >> $TMP/${tfile}_logs_corrupt
18722         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
18723
18724         $LCTL df $TMP/${tfile}_logs_corrupt > $TMP/${tfile}_log_bad.out 2>&1
18725         local bad_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
18726         local good_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
18727
18728         [ "$bad_line_new" ] && [ "$good_line_new" ] ||
18729                 error "bad_line_new good_line_new are empty"
18730
18731         local expected_good=$((good_line1 + good_line2*2))
18732
18733         rm -f $TMP/${tfile}*
18734         # LU-231, short malformed line may not be counted into bad lines
18735         if [ $bad_line -ne $bad_line_new ] &&
18736                    [ $bad_line -ne $((bad_line_new - 1)) ]; then
18737                 error "expected $bad_line bad lines, but got $bad_line_new"
18738                 return 1
18739         fi
18740
18741         if [ $expected_good -ne $good_line_new ]; then
18742                 error "expected $expected_good good lines, but got $good_line_new"
18743                 return 2
18744         fi
18745         true
18746 }
18747 run_test 170 "test lctl df to handle corrupted log ====================="
18748
18749 test_171() { # bug20592
18750         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18751
18752         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
18753         $LCTL set_param fail_loc=0x50e
18754         $LCTL set_param fail_val=3000
18755         multiop_bg_pause $DIR/$tfile O_s || true
18756         local MULTIPID=$!
18757         kill -USR1 $MULTIPID
18758         # cause log dump
18759         sleep 3
18760         wait $MULTIPID
18761         if dmesg | grep "recursive fault"; then
18762                 error "caught a recursive fault"
18763         fi
18764         $LCTL set_param fail_loc=0
18765         true
18766 }
18767 run_test 171 "test libcfs_debug_dumplog_thread stuck in do_exit() ======"
18768
18769 test_172() {
18770
18771         #define OBD_FAIL_OBD_CLEANUP  0x60e
18772         $LCTL set_param fail_loc=0x60e
18773         umount $MOUNT || error "umount $MOUNT failed"
18774         stack_trap "mount_client $MOUNT"
18775
18776         (( $($LCTL dl | egrep -c " osc | lov | lmv | mdc ") > 0 )) ||
18777                 error "no client OBDs are remained"
18778
18779         $LCTL dl | while read devno state type name foo; do
18780                 case $type in
18781                 lov|osc|lmv|mdc)
18782                         $LCTL --device $name cleanup
18783                         $LCTL --device $name detach
18784                         ;;
18785                 *)
18786                         # skip server devices
18787                         ;;
18788                 esac
18789         done
18790
18791         if (( $($LCTL dl | egrep -c " osc | lov | lmv | mdc ") > 0 )); then
18792                 $LCTL dl | egrep " osc | lov | lmv | mdc "
18793                 error "some client OBDs are still remained"
18794         fi
18795
18796 }
18797 run_test 172 "manual device removal with lctl cleanup/detach ======"
18798
18799 # it would be good to share it with obdfilter-survey/iokit-libecho code
18800 setup_obdecho_osc () {
18801         local rc=0
18802         local ost_nid=$1
18803         local obdfilter_name=$2
18804         echo "Creating new osc for $obdfilter_name on $ost_nid"
18805         # make sure we can find loopback nid
18806         $LCTL add_uuid $ost_nid $ost_nid >/dev/null 2>&1
18807
18808         [ $rc -eq 0 ] && { $LCTL attach osc ${obdfilter_name}_osc     \
18809                            ${obdfilter_name}_osc_UUID || rc=2; }
18810         [ $rc -eq 0 ] && { $LCTL --device ${obdfilter_name}_osc setup \
18811                            ${obdfilter_name}_UUID  $ost_nid || rc=3; }
18812         return $rc
18813 }
18814
18815 cleanup_obdecho_osc () {
18816         local obdfilter_name=$1
18817         $LCTL --device ${obdfilter_name}_osc cleanup >/dev/null
18818         $LCTL --device ${obdfilter_name}_osc detach  >/dev/null
18819         return 0
18820 }
18821
18822 obdecho_test() {
18823         local OBD=$1
18824         local node=$2
18825         local pages=${3:-64}
18826         local rc=0
18827         local id
18828
18829         local count=10
18830         local obd_size=$(get_obd_size $node $OBD)
18831         local page_size=$(get_page_size $node)
18832         if [[ -n "$obd_size" ]]; then
18833                 local new_count=$((obd_size / (pages * page_size / 1024)))
18834                 [[ $new_count -ge $count ]] || count=$new_count
18835         fi
18836
18837         do_facet $node "$LCTL attach echo_client ec ec_uuid" || rc=1
18838         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec setup $OBD" ||
18839                            rc=2; }
18840         if [ $rc -eq 0 ]; then
18841             id=$(do_facet $node "$LCTL --device ec create 1"  | awk '/object id/ {print $6}')
18842             [ ${PIPESTATUS[0]} -eq 0 -a -n "$id" ] || rc=3
18843         fi
18844         echo "New object id is $id"
18845         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec getattr $id" ||
18846                            rc=4; }
18847         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec "                 \
18848                            "test_brw $count w v $pages $id" || rc=4; }
18849         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec destroy $id 1" ||
18850                            rc=4; }
18851         [ $rc -eq 0 ] || [ $rc -gt 2 ] &&
18852                 { do_facet $node "$LCTL --device ec cleanup" || rc=5; }
18853         [ $rc -eq 0 ] || [ $rc -gt 1 ] &&
18854                 { do_facet $node "$LCTL --device ec detach" || rc=6; }
18855         [ $rc -ne 0 ] && echo "obecho_create_test failed: $rc"
18856         return $rc
18857 }
18858
18859 test_180a() {
18860         skip "obdecho on osc is no longer supported"
18861 }
18862 run_test 180a "test obdecho on osc"
18863
18864 test_180b() {
18865         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18866         remote_ost_nodsh && skip "remote OST with nodsh"
18867
18868         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
18869                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
18870                 error "failed to load module obdecho"
18871
18872         local target=$(do_facet ost1 $LCTL dl |
18873                        awk '/obdfilter/ { print $4; exit; }')
18874
18875         if [ -n "$target" ]; then
18876                 obdecho_test $target ost1 || error "obdecho_test failed with $?"
18877         else
18878                 do_facet ost1 $LCTL dl
18879                 error "there is no obdfilter target on ost1"
18880         fi
18881 }
18882 run_test 180b "test obdecho directly on obdfilter"
18883
18884 test_180c() { # LU-2598
18885         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18886         remote_ost_nodsh && skip "remote OST with nodsh"
18887         [[ $MDS1_VERSION -lt $(version_code 2.4.0) ]] &&
18888                 skip "Need MDS version at least 2.4.0"
18889
18890         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
18891                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
18892                 error "failed to load module obdecho"
18893
18894         local target=$(do_facet ost1 $LCTL dl |
18895                        awk '/obdfilter/ { print $4; exit; }')
18896
18897         if [ -n "$target" ]; then
18898                 local pages=16384 # 64MB bulk I/O RPC size
18899
18900                 obdecho_test "$target" ost1 "$pages" ||
18901                         error "obdecho_test with pages=$pages failed with $?"
18902         else
18903                 do_facet ost1 $LCTL dl
18904                 error "there is no obdfilter target on ost1"
18905         fi
18906 }
18907 run_test 180c "test huge bulk I/O size on obdfilter, don't LASSERT"
18908
18909 test_181() { # bug 22177
18910         test_mkdir $DIR/$tdir
18911         # create enough files to index the directory
18912         createmany -o $DIR/$tdir/foobar 4000
18913         # print attributes for debug purpose
18914         lsattr -d .
18915         # open dir
18916         multiop_bg_pause $DIR/$tdir D_Sc || return 1
18917         MULTIPID=$!
18918         # remove the files & current working dir
18919         unlinkmany $DIR/$tdir/foobar 4000
18920         rmdir $DIR/$tdir
18921         kill -USR1 $MULTIPID
18922         wait $MULTIPID
18923         stat $DIR/$tdir && error "open-unlinked dir was not removed!"
18924         return 0
18925 }
18926 run_test 181 "Test open-unlinked dir ========================"
18927
18928 test_182a() {
18929         local fcount=1000
18930         local tcount=10
18931
18932         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
18933
18934         $LCTL set_param mdc.*.rpc_stats=clear
18935
18936         for (( i = 0; i < $tcount; i++ )) ; do
18937                 mkdir $DIR/$tdir/$i
18938         done
18939
18940         for (( i = 0; i < $tcount; i++ )) ; do
18941                 createmany -o $DIR/$tdir/$i/f- $fcount &
18942         done
18943         wait
18944
18945         for (( i = 0; i < $tcount; i++ )) ; do
18946                 unlinkmany $DIR/$tdir/$i/f- $fcount &
18947         done
18948         wait
18949
18950         $LCTL get_param mdc.*.rpc_stats
18951
18952         rm -rf $DIR/$tdir
18953 }
18954 run_test 182a "Test parallel modify metadata operations from mdc"
18955
18956 test_182b() {
18957         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
18958         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
18959         local dcount=1000
18960         local tcount=10
18961         local stime
18962         local etime
18963         local delta
18964
18965         do_facet mds1 $LCTL list_param \
18966                 osp.$FSNAME-MDT*-osp-MDT*.rpc_stats ||
18967                 skip "MDS lacks parallel RPC handling"
18968
18969         $LFS mkdir -i 0 $DIR/$tdir || error "creating dir $DIR/$tdir"
18970
18971         rpc_count=$(do_facet mds1 $LCTL get_param -n \
18972                     osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight)
18973
18974         stime=$(date +%s)
18975         createmany -i 0 -d $DIR/$tdir/t- $tcount
18976
18977         for (( i = 0; i < $tcount; i++ )) ; do
18978                 createmany -i 0 -d $DIR/$tdir/t-$i/d- 0 $dcount &
18979         done
18980         wait
18981         etime=$(date +%s)
18982         delta=$((etime - stime))
18983         echo "Time for file creation $delta sec for $rpc_count parallel RPCs"
18984
18985         stime=$(date +%s)
18986         for (( i = 0; i < $tcount; i++ )) ; do
18987                 unlinkmany -d $DIR/$tdir/$i/d- $dcount &
18988         done
18989         wait
18990         etime=$(date +%s)
18991         delta=$((etime - stime))
18992         echo "Time for file removal $delta sec for $rpc_count parallel RPCs"
18993
18994         rm -rf $DIR/$tdir
18995
18996         $LFS mkdir -i 0 $DIR/$tdir || error "creating dir $DIR/$tdir"
18997
18998         do_facet mds1 $LCTL set_param osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight=1
18999
19000         stime=$(date +%s)
19001         createmany -i 0 -d $DIR/$tdir/t- $tcount
19002
19003         for (( i = 0; i < $tcount; i++ )) ; do
19004                 createmany -i 0 -d $DIR/$tdir/t-$i/d- 0 $dcount &
19005         done
19006         wait
19007         etime=$(date +%s)
19008         delta=$((etime - stime))
19009         echo "Time for file creation $delta sec for 1 RPC sent at a time"
19010
19011         stime=$(date +%s)
19012         for (( i = 0; i < $tcount; i++ )) ; do
19013                 unlinkmany -d $DIR/$tdir/t-$i/d- $dcount &
19014         done
19015         wait
19016         etime=$(date +%s)
19017         delta=$((etime - stime))
19018         echo "Time for file removal $delta sec for 1 RPC sent at a time"
19019
19020         do_facet mds1 $LCTL set_param osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight=$rpc_count
19021 }
19022 run_test 182b "Test parallel modify metadata operations from osp"
19023
19024 test_183() { # LU-2275
19025         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19026         remote_mds_nodsh && skip "remote MDS with nodsh"
19027         [[ $MDS1_VERSION -lt $(version_code 2.3.56) ]] &&
19028                 skip "Need MDS version at least 2.3.56"
19029
19030         mkdir_on_mdt0 $DIR/$tdir || error "creating dir $DIR/$tdir"
19031         echo aaa > $DIR/$tdir/$tfile
19032
19033 #define OBD_FAIL_MDS_NEGATIVE_POSITIVE  0x148
19034         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x148
19035
19036         ls -l $DIR/$tdir && error "ls succeeded, should have failed"
19037         cat $DIR/$tdir/$tfile && error "cat succeeded, should have failed"
19038
19039         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
19040
19041         # Flush negative dentry cache
19042         touch $DIR/$tdir/$tfile
19043
19044         # We are not checking for any leaked references here, they'll
19045         # become evident next time we do cleanup with module unload.
19046         rm -rf $DIR/$tdir
19047 }
19048 run_test 183 "No crash or request leak in case of strange dispositions ========"
19049
19050 # test suite 184 is for LU-2016, LU-2017
19051 test_184a() {
19052         check_swap_layouts_support
19053
19054         dir0=$DIR/$tdir/$testnum
19055         test_mkdir -p -c1 $dir0
19056         ref1=/etc/passwd
19057         ref2=/etc/group
19058         file1=$dir0/f1
19059         file2=$dir0/f2
19060         $LFS setstripe -c1 $file1
19061         cp $ref1 $file1
19062         $LFS setstripe -c2 $file2
19063         cp $ref2 $file2
19064         gen1=$($LFS getstripe -g $file1)
19065         gen2=$($LFS getstripe -g $file2)
19066
19067         $LFS swap_layouts $file1 $file2 || error "swap of file layout failed"
19068         gen=$($LFS getstripe -g $file1)
19069         [[ $gen1 != $gen ]] ||
19070                 error "Layout generation on $file1 does not change"
19071         gen=$($LFS getstripe -g $file2)
19072         [[ $gen2 != $gen ]] ||
19073                 error "Layout generation on $file2 does not change"
19074
19075         cmp $ref1 $file2 || error "content compare failed ($ref1 != $file2)"
19076         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
19077
19078         lfsck_verify_pfid $file1 $file2 || error "PFID are not transferred"
19079 }
19080 run_test 184a "Basic layout swap"
19081
19082 test_184b() {
19083         check_swap_layouts_support
19084
19085         dir0=$DIR/$tdir/$testnum
19086         mkdir -p $dir0 || error "creating dir $dir0"
19087         file1=$dir0/f1
19088         file2=$dir0/f2
19089         file3=$dir0/f3
19090         dir1=$dir0/d1
19091         dir2=$dir0/d2
19092         mkdir $dir1 $dir2
19093         $LFS setstripe -c1 $file1
19094         $LFS setstripe -c2 $file2
19095         $LFS setstripe -c1 $file3
19096         chown $RUNAS_ID $file3
19097         gen1=$($LFS getstripe -g $file1)
19098         gen2=$($LFS getstripe -g $file2)
19099
19100         $LFS swap_layouts $dir1 $dir2 &&
19101                 error "swap of directories layouts should fail"
19102         $LFS swap_layouts $dir1 $file1 &&
19103                 error "swap of directory and file layouts should fail"
19104         $RUNAS $LFS swap_layouts $file1 $file2 &&
19105                 error "swap of file we cannot write should fail"
19106         $LFS swap_layouts $file1 $file3 &&
19107                 error "swap of file with different owner should fail"
19108         /bin/true # to clear error code
19109 }
19110 run_test 184b "Forbidden layout swap (will generate errors)"
19111
19112 test_184c() {
19113         local cmpn_arg=$(cmp -n 2>&1 | grep "invalid option")
19114         [ -n "$cmpn_arg" ] && skip_env "cmp does not support -n"
19115         check_swap_layouts_support
19116         check_swap_layout_no_dom $DIR
19117
19118         local dir0=$DIR/$tdir/$testnum
19119         mkdir -p $dir0 || error "creating dir $dir0"
19120
19121         local ref1=$dir0/ref1
19122         local ref2=$dir0/ref2
19123         local file1=$dir0/file1
19124         local file2=$dir0/file2
19125         # create a file large enough for the concurrent test
19126         dd if=/dev/urandom of=$ref1 bs=1M count=$((RANDOM % 50 + 20))
19127         dd if=/dev/urandom of=$ref2 bs=1M count=$((RANDOM % 50 + 20))
19128         echo "ref file size: ref1($(stat -c %s $ref1))," \
19129              "ref2($(stat -c %s $ref2))"
19130
19131         cp $ref2 $file2
19132         dd if=$ref1 of=$file1 bs=16k &
19133         local DD_PID=$!
19134
19135         # Make sure dd starts to copy file, but wait at most 5 seconds
19136         local loops=0
19137         while [ ! -s $file1 -a $((loops++)) -lt 50 ]; do sleep 0.1; done
19138
19139         $LFS swap_layouts $file1 $file2
19140         local rc=$?
19141         wait $DD_PID
19142         [[ $? == 0 ]] || error "concurrent write on $file1 failed"
19143         [[ $rc == 0 ]] || error "swap of $file1 and $file2 failed"
19144
19145         # how many bytes copied before swapping layout
19146         local copied=$(stat -c %s $file2)
19147         local remaining=$(stat -c %s $ref1)
19148         remaining=$((remaining - copied))
19149         echo "Copied $copied bytes before swapping layout..."
19150
19151         cmp -n $copied $file1 $ref2 | grep differ &&
19152                 error "Content mismatch [0, $copied) of ref2 and file1"
19153         cmp -n $copied $file2 $ref1 ||
19154                 error "Content mismatch [0, $copied) of ref1 and file2"
19155         cmp -i $copied:$copied -n $remaining $file1 $ref1 ||
19156                 error "Content mismatch [$copied, EOF) of ref1 and file1"
19157
19158         # clean up
19159         rm -f $ref1 $ref2 $file1 $file2
19160 }
19161 run_test 184c "Concurrent write and layout swap"
19162
19163 test_184d() {
19164         check_swap_layouts_support
19165         check_swap_layout_no_dom $DIR
19166         [ -z "$(which getfattr 2>/dev/null)" ] &&
19167                 skip_env "no getfattr command"
19168
19169         local file1=$DIR/$tdir/$tfile-1
19170         local file2=$DIR/$tdir/$tfile-2
19171         local file3=$DIR/$tdir/$tfile-3
19172         local lovea1
19173         local lovea2
19174
19175         mkdir -p $DIR/$tdir
19176         touch $file1 || error "create $file1 failed"
19177         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
19178                 error "create $file2 failed"
19179         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
19180                 error "create $file3 failed"
19181         lovea1=$(get_layout_param $file1)
19182
19183         $LFS swap_layouts $file2 $file3 ||
19184                 error "swap $file2 $file3 layouts failed"
19185         $LFS swap_layouts $file1 $file2 ||
19186                 error "swap $file1 $file2 layouts failed"
19187
19188         lovea2=$(get_layout_param $file2)
19189         echo "$lovea1"
19190         echo "$lovea2"
19191         [ "$lovea1" == "$lovea2" ] || error "lovea $lovea1 != $lovea2"
19192
19193         lovea1=$(getfattr -n trusted.lov $file1 | grep ^trusted)
19194         [[ -z "$lovea1" ]] || error "$file1 shouldn't have lovea"
19195 }
19196 run_test 184d "allow stripeless layouts swap"
19197
19198 test_184e() {
19199         [[ $MDS1_VERSION -ge $(version_code 2.6.94) ]] ||
19200                 skip "Need MDS version at least 2.6.94"
19201         check_swap_layouts_support
19202         check_swap_layout_no_dom $DIR
19203         [ -z "$(which getfattr 2>/dev/null)" ] &&
19204                 skip_env "no getfattr command"
19205
19206         local file1=$DIR/$tdir/$tfile-1
19207         local file2=$DIR/$tdir/$tfile-2
19208         local file3=$DIR/$tdir/$tfile-3
19209         local lovea
19210
19211         mkdir -p $DIR/$tdir
19212         touch $file1 || error "create $file1 failed"
19213         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
19214                 error "create $file2 failed"
19215         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
19216                 error "create $file3 failed"
19217
19218         $LFS swap_layouts $file1 $file2 ||
19219                 error "swap $file1 $file2 layouts failed"
19220
19221         lovea=$(getfattr -n trusted.lov $file1 | grep ^trusted)
19222         [[ -z "$lovea" ]] || error "$file1 shouldn't have lovea"
19223
19224         echo 123 > $file1 || error "Should be able to write into $file1"
19225
19226         $LFS swap_layouts $file1 $file3 ||
19227                 error "swap $file1 $file3 layouts failed"
19228
19229         echo 123 > $file1 || error "Should be able to write into $file1"
19230
19231         rm -rf $file1 $file2 $file3
19232 }
19233 run_test 184e "Recreate layout after stripeless layout swaps"
19234
19235 test_184f() {
19236         # Create a file with name longer than sizeof(struct stat) ==
19237         # 144 to see if we can get chars from the file name to appear
19238         # in the returned striping. Note that 'f' == 0x66.
19239         local file=$(for ((i = 0; i < 200; i++)); do echo -n f; done)
19240
19241         mkdir -p $DIR/$tdir
19242         mcreate $DIR/$tdir/$file
19243         if lfs find --stripe-count 0x6666 $DIR/$tdir | grep $file; then
19244                 error "IOC_MDC_GETFILEINFO returned garbage striping"
19245         fi
19246 }
19247 run_test 184f "IOC_MDC_GETFILEINFO for files with long names but no striping"
19248
19249 test_185() { # LU-2441
19250         # LU-3553 - no volatile file support in old servers
19251         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
19252                 skip "Need MDS version at least 2.3.60"
19253
19254         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
19255         touch $DIR/$tdir/spoo
19256         local mtime1=$(stat -c "%Y" $DIR/$tdir)
19257         local fid=$($MULTIOP $DIR/$tdir VFw4096c) ||
19258                 error "cannot create/write a volatile file"
19259         [ "$FILESET" == "" ] &&
19260         $CHECKSTAT -t file $MOUNT/.lustre/fid/$fid 2>/dev/null &&
19261                 error "FID is still valid after close"
19262
19263         multiop_bg_pause $DIR/$tdir vVw4096_c
19264         local multi_pid=$!
19265
19266         local OLD_IFS=$IFS
19267         IFS=":"
19268         local fidv=($fid)
19269         IFS=$OLD_IFS
19270         # assume that the next FID for this client is sequential, since stdout
19271         # is unfortunately eaten by multiop_bg_pause
19272         local n=$((${fidv[1]} + 1))
19273         local next_fid="${fidv[0]}:$(printf "0x%x" $n):${fidv[2]}"
19274         if [ "$FILESET" == "" ]; then
19275                 $CHECKSTAT -t file $MOUNT/.lustre/fid/$next_fid ||
19276                         error "FID is missing before close"
19277         fi
19278         kill -USR1 $multi_pid
19279         # 1 second delay, so if mtime change we will see it
19280         sleep 1
19281         local mtime2=$(stat -c "%Y" $DIR/$tdir)
19282         [[ $mtime1 == $mtime2 ]] || error "mtime has changed"
19283 }
19284 run_test 185 "Volatile file support"
19285
19286 function create_check_volatile() {
19287         local idx=$1
19288         local tgt
19289
19290         $MULTIOP $MOUNT/.lustre/fid V${idx}Fw4096_c >&/tmp/${tfile}.fid &
19291         local PID=$!
19292         sleep 1
19293         local FID=$(cat /tmp/${tfile}.fid)
19294         [ "$FID" == "" ] && error "can't get FID for volatile"
19295         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID || error "can't stat $FID"
19296         tgt=$($LFS getstripe -m $MOUNT/.lustre/fid/$FID)
19297         [ "$tgt" != "$idx" ] && error "wrong MDS $tgt, expected $idx"
19298         kill -USR1 $PID
19299         wait
19300         sleep 1
19301         cancel_lru_locks mdc # flush opencache
19302         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID && error "can stat $FID"
19303         return 0
19304 }
19305
19306 test_185a(){
19307         # LU-12516 - volatile creation via .lustre
19308         [[ $MDS1_VERSION -ge $(version_code 2.12.55) ]] ||
19309                 skip "Need MDS version at least 2.3.55"
19310
19311         create_check_volatile 0
19312         [ $MDSCOUNT -lt 2 ] && return 0
19313
19314         # DNE case
19315         create_check_volatile 1
19316
19317         return 0
19318 }
19319 run_test 185a "Volatile file creation in .lustre/fid/"
19320
19321 test_187a() {
19322         remote_mds_nodsh && skip "remote MDS with nodsh"
19323         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
19324                 skip "Need MDS version at least 2.3.0"
19325
19326         local dir0=$DIR/$tdir/$testnum
19327         mkdir -p $dir0 || error "creating dir $dir0"
19328
19329         local file=$dir0/file1
19330         dd if=/dev/urandom of=$file count=10 bs=1M conv=fsync
19331         stack_trap "rm -f $file"
19332         local dv1=$($LFS data_version $file)
19333         dd if=/dev/urandom of=$file seek=10 count=1 bs=1M conv=fsync
19334         local dv2=$($LFS data_version $file)
19335         [[ $dv1 != $dv2 ]] ||
19336                 error "data version did not change on write $dv1 == $dv2"
19337 }
19338 run_test 187a "Test data version change"
19339
19340 test_187b() {
19341         remote_mds_nodsh && skip "remote MDS with nodsh"
19342         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
19343                 skip "Need MDS version at least 2.3.0"
19344
19345         local dir0=$DIR/$tdir/$testnum
19346         mkdir -p $dir0 || error "creating dir $dir0"
19347
19348         declare -a DV=$($MULTIOP $dir0 Vw1000xYw1000xY | cut -f3 -d" ")
19349         [[ ${DV[0]} != ${DV[1]} ]] ||
19350                 error "data version did not change on write"\
19351                       " ${DV[0]} == ${DV[1]}"
19352
19353         # clean up
19354         rm -f $file1
19355 }
19356 run_test 187b "Test data version change on volatile file"
19357
19358 test_200() {
19359         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19360         remote_mgs_nodsh && skip "remote MGS with nodsh"
19361         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
19362
19363         local POOL=${POOL:-cea1}
19364         local POOL_ROOT=${POOL_ROOT:-$DIR/d200.pools}
19365         local POOL_DIR_NAME=${POOL_DIR_NAME:-dir_tst}
19366         # Pool OST targets
19367         local first_ost=0
19368         local last_ost=$(($OSTCOUNT - 1))
19369         local ost_step=2
19370         local ost_list=$(seq $first_ost $ost_step $last_ost)
19371         local ost_range="$first_ost $last_ost $ost_step"
19372         local test_path=$POOL_ROOT/$POOL_DIR_NAME
19373         local file_dir=$POOL_ROOT/file_tst
19374         local subdir=$test_path/subdir
19375         local rc=0
19376
19377         while : ; do
19378                 # former test_200a test_200b
19379                 pool_add $POOL                          || { rc=$? ; break; }
19380                 pool_add_targets  $POOL $ost_range      || { rc=$? ; break; }
19381                 # former test_200c test_200d
19382                 mkdir -p $test_path
19383                 pool_set_dir      $POOL $test_path      || { rc=$? ; break; }
19384                 pool_check_dir    $POOL $test_path      || { rc=$? ; break; }
19385                 mkdir -p $subdir
19386                 pool_check_dir    $POOL $subdir         || { rc=$? ; break; }
19387                 pool_dir_rel_path $POOL $POOL_DIR_NAME $POOL_ROOT \
19388                                                         || { rc=$? ; break; }
19389                 # former test_200e test_200f
19390                 local files=$((OSTCOUNT*3))
19391                 pool_alloc_files  $POOL $test_path $files "$ost_list" \
19392                                                         || { rc=$? ; break; }
19393                 pool_create_files $POOL $file_dir $files "$ost_list" \
19394                                                         || { rc=$? ; break; }
19395                 # former test_200g test_200h
19396                 pool_lfs_df $POOL                       || { rc=$? ; break; }
19397                 pool_file_rel_path $POOL $test_path     || { rc=$? ; break; }
19398
19399                 # former test_201a test_201b test_201c
19400                 pool_remove_first_target $POOL          || { rc=$? ; break; }
19401
19402                 local f=$test_path/$tfile
19403                 pool_remove_all_targets $POOL $f        || { rc=$? ; break; }
19404                 pool_remove $POOL $f                    || { rc=$? ; break; }
19405                 break
19406         done
19407
19408         destroy_test_pools
19409
19410         return $rc
19411 }
19412 run_test 200 "OST pools"
19413
19414 # usage: default_attr <count | size | offset>
19415 default_attr() {
19416         $LCTL get_param -n lov.$FSNAME-clilov-\*.stripe${1}
19417 }
19418
19419 # usage: check_default_stripe_attr
19420 check_default_stripe_attr() {
19421         ACTUAL=$($LFS getstripe $* $DIR/$tdir)
19422         case $1 in
19423         --stripe-count|-c)
19424                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr count);;
19425         --stripe-size|-S)
19426                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr size);;
19427         --stripe-index|-i)
19428                 EXPECTED=-1;;
19429         *)
19430                 error "unknown getstripe attr '$1'"
19431         esac
19432
19433         [ $ACTUAL == $EXPECTED ] ||
19434                 error "$DIR/$tdir has $1 '$ACTUAL', not '$EXPECTED'"
19435 }
19436
19437 test_204a() {
19438         test_mkdir $DIR/$tdir
19439         $LFS setstripe --stripe-count 0 --stripe-size 0 --stripe-index -1 $DIR/$tdir
19440
19441         check_default_stripe_attr --stripe-count
19442         check_default_stripe_attr --stripe-size
19443         check_default_stripe_attr --stripe-index
19444 }
19445 run_test 204a "Print default stripe attributes"
19446
19447 test_204b() {
19448         test_mkdir $DIR/$tdir
19449         $LFS setstripe --stripe-count 1 $DIR/$tdir
19450
19451         check_default_stripe_attr --stripe-size
19452         check_default_stripe_attr --stripe-index
19453 }
19454 run_test 204b "Print default stripe size and offset"
19455
19456 test_204c() {
19457         test_mkdir $DIR/$tdir
19458         $LFS setstripe --stripe-size 65536 $DIR/$tdir
19459
19460         check_default_stripe_attr --stripe-count
19461         check_default_stripe_attr --stripe-index
19462 }
19463 run_test 204c "Print default stripe count and offset"
19464
19465 test_204d() {
19466         test_mkdir $DIR/$tdir
19467         $LFS setstripe --stripe-index 0 $DIR/$tdir
19468
19469         check_default_stripe_attr --stripe-count
19470         check_default_stripe_attr --stripe-size
19471 }
19472 run_test 204d "Print default stripe count and size"
19473
19474 test_204e() {
19475         test_mkdir $DIR/$tdir
19476         $LFS setstripe -d $DIR/$tdir
19477
19478         check_default_stripe_attr --stripe-count --raw
19479         check_default_stripe_attr --stripe-size --raw
19480         check_default_stripe_attr --stripe-index --raw
19481 }
19482 run_test 204e "Print raw stripe attributes"
19483
19484 test_204f() {
19485         test_mkdir $DIR/$tdir
19486         $LFS setstripe --stripe-count 1 $DIR/$tdir
19487
19488         check_default_stripe_attr --stripe-size --raw
19489         check_default_stripe_attr --stripe-index --raw
19490 }
19491 run_test 204f "Print raw stripe size and offset"
19492
19493 test_204g() {
19494         test_mkdir $DIR/$tdir
19495         $LFS setstripe --stripe-size 65536 $DIR/$tdir
19496
19497         check_default_stripe_attr --stripe-count --raw
19498         check_default_stripe_attr --stripe-index --raw
19499 }
19500 run_test 204g "Print raw stripe count and offset"
19501
19502 test_204h() {
19503         test_mkdir $DIR/$tdir
19504         $LFS setstripe --stripe-index 0 $DIR/$tdir
19505
19506         check_default_stripe_attr --stripe-count --raw
19507         check_default_stripe_attr --stripe-size --raw
19508 }
19509 run_test 204h "Print raw stripe count and size"
19510
19511 # Figure out which job scheduler is being used, if any,
19512 # or use a fake one
19513 if [ -n "$SLURM_JOB_ID" ]; then # SLURM
19514         JOBENV=SLURM_JOB_ID
19515 elif [ -n "$LSB_JOBID" ]; then # Load Sharing Facility
19516         JOBENV=LSB_JOBID
19517 elif [ -n "$PBS_JOBID" ]; then # PBS/Maui/Moab
19518         JOBENV=PBS_JOBID
19519 elif [ -n "$LOADL_STEPID" ]; then # LoadLeveller
19520         JOBENV=LOADL_STEP_ID
19521 elif [ -n "$JOB_ID" ]; then # Sun Grid Engine
19522         JOBENV=JOB_ID
19523 else
19524         $LCTL list_param jobid_name > /dev/null 2>&1
19525         if [ $? -eq 0 ]; then
19526                 JOBENV=nodelocal
19527         else
19528                 JOBENV=FAKE_JOBID
19529         fi
19530 fi
19531 LUSTRE_JOBID_SIZE=31 # plus NUL terminator
19532
19533 verify_jobstats() {
19534         local cmd=($1)
19535         shift
19536         local facets="$@"
19537
19538 # we don't really need to clear the stats for this test to work, since each
19539 # command has a unique jobid, but it makes debugging easier if needed.
19540 #       for facet in $facets; do
19541 #               local dev=$(convert_facet2label $facet)
19542 #               # clear old jobstats
19543 #               do_facet $facet lctl set_param *.$dev.job_stats="clear"
19544 #       done
19545
19546         # use a new JobID for each test, or we might see an old one
19547         [ "$JOBENV" = "FAKE_JOBID" ] &&
19548                 FAKE_JOBID=id.$testnum.$(basename ${cmd[0]}).$RANDOM
19549
19550         JOBVAL=${!JOBENV:0:$LUSTRE_JOBID_SIZE}
19551
19552         [ "$JOBENV" = "nodelocal" ] && {
19553                 FAKE_JOBID=id.$testnum.%e.$RANDOM
19554                 $LCTL set_param jobid_name=$FAKE_JOBID
19555                 JOBVAL=${FAKE_JOBID/\%e/$(basename ${cmd[0]})}
19556         }
19557
19558         log "Test: ${cmd[*]}"
19559         log "Using JobID environment $($LCTL get_param -n jobid_var)=$JOBVAL"
19560
19561         if [ $JOBENV = "FAKE_JOBID" ]; then
19562                 FAKE_JOBID=$JOBVAL ${cmd[*]}
19563         else
19564                 ${cmd[*]}
19565         fi
19566
19567         # all files are created on OST0000
19568         for facet in $facets; do
19569                 local stats="*.$(convert_facet2label $facet).job_stats"
19570
19571                 # strip out libtool wrappers for in-tree executables
19572                 if (( $(do_facet $facet lctl get_param $stats |
19573                         sed -e 's/\.lt-/./' | grep -cw $JOBVAL) != 1 )); then
19574                         do_facet $facet lctl get_param $stats
19575                         error "No jobstats for $JOBVAL found on $facet::$stats"
19576                 fi
19577         done
19578 }
19579
19580 jobstats_set() {
19581         local new_jobenv=$1
19582
19583         set_persistent_param_and_check client "jobid_var" \
19584                 "$FSNAME.sys.jobid_var" $new_jobenv
19585 }
19586
19587 test_205a() { # Job stats
19588         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19589         [[ $MDS1_VERSION -ge $(version_code 2.7.1) ]] ||
19590                 skip "Need MDS version with at least 2.7.1"
19591         remote_mgs_nodsh && skip "remote MGS with nodsh"
19592         remote_mds_nodsh && skip "remote MDS with nodsh"
19593         remote_ost_nodsh && skip "remote OST with nodsh"
19594         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep jobstats)" ] &&
19595                 skip "Server doesn't support jobstats"
19596         [[ $JOBID_VAR = disable ]] && skip_env "jobstats is disabled"
19597
19598         local old_jobenv=$($LCTL get_param -n jobid_var)
19599         [ $old_jobenv != $JOBENV ] && jobstats_set $JOBENV
19600         stack_trap "jobstats_set $old_jobenv" EXIT
19601
19602         changelog_register
19603
19604         local old_jobid_name=$($LCTL get_param jobid_name)
19605         stack_trap "$LCTL set_param $old_jobid_name" EXIT
19606
19607         local old_interval=$(do_facet $SINGLEMDS lctl get_param -n \
19608                                 mdt.*.job_cleanup_interval | head -n 1)
19609         local new_interval=5
19610         do_facet $SINGLEMDS \
19611                 $LCTL set_param mdt.*.job_cleanup_interval=$new_interval
19612         stack_trap "do_facet $SINGLEMDS \
19613                 $LCTL set_param mdt.*.job_cleanup_interval=$old_interval" EXIT
19614         local start=$SECONDS
19615
19616         local cmd
19617         # mkdir
19618         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir"
19619         verify_jobstats "$cmd" "$SINGLEMDS"
19620         # rmdir
19621         cmd="rmdir $DIR/$tdir"
19622         verify_jobstats "$cmd" "$SINGLEMDS"
19623         # mkdir on secondary MDT
19624         if [ $MDSCOUNT -gt 1 ]; then
19625                 cmd="lfs mkdir -i 1 $DIR/$tdir.remote"
19626                 verify_jobstats "$cmd" "mds2"
19627         fi
19628         # mknod
19629         cmd="mknod $DIR/$tfile c 1 3"
19630         verify_jobstats "$cmd" "$SINGLEMDS"
19631         # unlink
19632         cmd="rm -f $DIR/$tfile"
19633         verify_jobstats "$cmd" "$SINGLEMDS"
19634         # create all files on OST0000 so verify_jobstats can find OST stats
19635         # open & close
19636         cmd="$LFS setstripe -i 0 -c 1 $DIR/$tfile"
19637         verify_jobstats "$cmd" "$SINGLEMDS"
19638         # setattr
19639         cmd="touch $DIR/$tfile"
19640         verify_jobstats "$cmd" "$SINGLEMDS ost1"
19641         # write
19642         cmd="dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=sync"
19643         verify_jobstats "$cmd" "ost1"
19644         # read
19645         cancel_lru_locks osc
19646         cmd="dd if=$DIR/$tfile of=/dev/null bs=1M count=1 iflag=direct"
19647         verify_jobstats "$cmd" "ost1"
19648         # truncate
19649         cmd="$TRUNCATE $DIR/$tfile 0"
19650         verify_jobstats "$cmd" "$SINGLEMDS ost1"
19651         # rename
19652         cmd="mv -f $DIR/$tfile $DIR/$tdir.rename"
19653         verify_jobstats "$cmd" "$SINGLEMDS"
19654         # jobstats expiry - sleep until old stats should be expired
19655         local left=$((new_interval + 5 - (SECONDS - start)))
19656         [ $left -ge 0 ] && wait_update_facet $SINGLEMDS \
19657                 "lctl get_param *.*.job_stats | grep -c 'job_id.*mkdir'" \
19658                         "0" $left
19659         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir.expire"
19660         verify_jobstats "$cmd" "$SINGLEMDS"
19661         [ $(do_facet $SINGLEMDS lctl get_param *.*.job_stats |
19662             grep -c "job_id.*mkdir") -gt 1 ] && error "old jobstats not expired"
19663
19664         # Ensure that jobid are present in changelog (if supported by MDS)
19665         if [ $MDS1_VERSION -ge $(version_code 2.6.52) ];then
19666                 changelog_dump | tail -10
19667                 jobids=$(changelog_dump | tail -9 | grep -c "j=")
19668                 [ $jobids -eq 9 ] ||
19669                         error "Wrong changelog jobid count $jobids != 9"
19670
19671                 # LU-5862
19672                 JOBENV="disable"
19673                 jobstats_set $JOBENV
19674                 touch $DIR/$tfile
19675                 changelog_dump | grep $tfile
19676                 jobids=$(changelog_dump | grep $tfile | tail -1 | grep -c "j=")
19677                 [ $jobids -eq 0 ] ||
19678                         error "Unexpected jobids when jobid_var=$JOBENV"
19679         fi
19680
19681         # test '%j' access to environment variable - if supported
19682         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%h.E"; then
19683                 JOBENV="JOBCOMPLEX"
19684                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
19685
19686                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
19687         fi
19688
19689         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%H.E"; then
19690                 JOBENV="JOBCOMPLEX"
19691                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname -s).E"
19692
19693                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
19694         fi
19695
19696         # test '%j' access to per-session jobid - if supported
19697         if lctl list_param jobid_this_session > /dev/null 2>&1
19698         then
19699                 lctl set_param jobid_var=session jobid_name="S.%j.%e.%u.%h.E"
19700                 lctl set_param jobid_this_session=$USER
19701
19702                 JOBENV="JOBCOMPLEX"
19703                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
19704
19705                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
19706         fi
19707 }
19708 run_test 205a "Verify job stats"
19709
19710 # LU-13117, LU-13597, LU-16599
19711 test_205b() {
19712         (( $MDS1_VERSION >= $(version_code 2.13.54.91) )) ||
19713                 skip "Need MDS version at least 2.13.54.91"
19714
19715         local job_stats="mdt.*.job_stats"
19716         local old_jobid=$(do_facet mds1 $LCTL get_param jobid_var)
19717
19718         do_facet mds1 $LCTL set_param $job_stats=clear
19719
19720         # Setting jobid_var to USER might not be supported
19721         [[ -n "$old_jobid" ]] && stack_trap "$LCTL set_param $old_jobid"
19722         $LCTL set_param jobid_var=USER || true
19723         stack_trap "$LCTL set_param $($LCTL get_param jobid_name)"
19724         $LCTL set_param jobid_name="%j.%e.%u"
19725
19726         env -i USERTESTJOBSTATS=foolish touch $DIR/$tfile.1
19727         do_facet mds1 $LCTL get_param $job_stats | grep "job_id:.*foolish" &&
19728                 { do_facet mds1 $LCTL get_param $job_stats;
19729                   error "Unexpected jobid found"; }
19730         do_facet mds1 $LCTL get_param $job_stats | grep "open:.*min.*max.*sum"||
19731                 { do_facet mds1 $LCTL get_param $job_stats;
19732                   error "wrong job_stats format found"; }
19733
19734         (( $MDS1_VERSION <= $(version_code 2.15.0) )) &&
19735                 echo "MDS does not yet escape jobid" && return 0
19736
19737         mkdir_on_mdt0 $DIR/$tdir
19738         $LCTL set_param jobid_var=TEST205b
19739         env -i TEST205b="has sp" touch $DIR/$tdir/$tfile.2
19740         local jobid=$(do_facet mds1 $LCTL get_param $job_stats |
19741                       awk '/has\\x20sp/ {print $3}')
19742         [[ -n "$jobid" ]] || { do_facet mds1 $LCTL get_param $job_stats;
19743                   error "jobid not escaped"; }
19744
19745         if (( $MDS1_VERSION >= $(version_code 2.15.53.139) )); then
19746                 # need to run such a command on mds1:
19747                 # lctl set_param mdt.$FSNAME-MDT0000.job_stats='"has\x20sp.touch.0"'
19748                 #
19749                 # there might be multiple MDTs on single mds server, so need to
19750                 # specifiy MDT0000. Or the command will fail due to other MDTs
19751                 do_facet_vp mds1 $LCTL set_param mdt.$FSNAME-MDT0000.job_stats=$jobid ||
19752                         error "cannot clear escaped jobid in job_stats";
19753         else
19754                 echo "MDS does not support clearing escaped jobid"
19755         fi
19756 }
19757 run_test 205b "Verify job stats jobid and output format"
19758
19759 # LU-13733
19760 test_205c() {
19761         $LCTL set_param llite.*.stats=0
19762         dd if=/dev/zero of=$DIR/$tfile.1 bs=4k count=1
19763         $LCTL get_param llite.*.stats
19764         $LCTL get_param llite.*.stats | grep \
19765                 "write_bytes *1 samples \[bytes\] 4096 4096 4096 16777216" ||
19766                         error "wrong client stats format found"
19767 }
19768 run_test 205c "Verify client stats format"
19769
19770 test_205d() {
19771         local file=$DIR/$tdir/$tfile
19772
19773         (( $MDS1_VERSION >= $(version_code 2.15.53) )) ||
19774                 skip "need lustre >= 2.15.53 for lljobstat"
19775         (( $OST1_VERSION >= $(version_code 2.15.53) )) ||
19776                 skip "need lustre >= 2.15.53 for lljobstat"
19777         verify_yaml_available || skip_env "YAML verification not installed"
19778
19779         test_mkdir -i 0 $DIR/$tdir
19780         $LFS setstripe -E 1M -L mdt -E -1 $file || error "create file failed"
19781         stack_trap "rm -rf $DIR/$tdir"
19782
19783         dd if=/dev/zero of=$file bs=1M count=10 conv=sync ||
19784                 error "failed to write data to $file"
19785         mv $file $file.2
19786
19787         do_facet mds1 "$LCTL get_param -n mdt.$FSNAME-MDT0000.rename_stats"
19788         echo -n 'verify rename_stats...'
19789         do_facet mds1 "$LCTL get_param -n mdt.$FSNAME-MDT0000.rename_stats" |
19790                 verify_yaml || error "rename_stats is not valid YAML"
19791         echo " OK"
19792
19793         echo -n 'verify mdt job_stats...'
19794         do_facet mds1 "$LCTL get_param -n mdt.$FSNAME-MDT0000.job_stats" |
19795                 verify_yaml || error "job_stats on mds1 is not valid YAML"
19796         echo " OK"
19797
19798         echo -n 'verify ost job_stats...'
19799         do_facet ost1 "$LCTL get_param -n obdfilter.$FSNAME-OST0000.job_stats" |
19800                 verify_yaml || error "job_stats on ost1 is not valid YAML"
19801         echo " OK"
19802 }
19803 run_test 205d "verify the format of some stats files"
19804
19805 test_205e() {
19806         local ops_comma
19807         local file=$DIR/$tdir/$tfile
19808         local -a cli_params
19809
19810         (( $MDS1_VERSION >= $(version_code 2.15.53) )) ||
19811                 skip "need lustre >= 2.15.53 for lljobstat"
19812         (( $OST1_VERSION >= $(version_code 2.15.53) )) ||
19813                 skip "need lustre >= 2.15.53 for lljobstat"
19814         verify_yaml_available || skip_env "YAML verification not installed"
19815
19816         cli_params=( $($LCTL get_param jobid_name jobid_var) )
19817         $LCTL set_param jobid_var=nodelocal jobid_name=205e.%e.%u
19818         stack_trap "$LCTL set_param ${cli_params[*]}" EXIT
19819
19820         mkdir_on_mdt0 $DIR/$tdir || error "failed to create dir"
19821         stack_trap "rm -rf $DIR/$tdir"
19822
19823         $LFS setstripe -E EOF -i 0 -c 1 $file ||
19824                 error "failed to create $file on ost1"
19825         dd if=/dev/zero of=$file bs=1M count=10 oflag=sync ||
19826                 error "failed to write data to $file"
19827
19828         do_facet mds1 "$LCTL get_param *.*.job_stats"
19829         do_facet ost1 "$LCTL get_param *.*.job_stats"
19830
19831         do_facet ost1 "lljobstat -n 1 -i 0 -c 1000"
19832         do_facet ost1 "lljobstat -n 1 -i 0 -c 1000" | verify_yaml ||
19833                 error "The output of lljobstat is not an valid YAML"
19834
19835         # verify that job dd.0 does exist and has some ops on ost1
19836         # typically this line is like:
19837         # - 205e.dd.0:            {ops: 20, ...}
19838         ops_comma=$(do_facet ost1 "lljobstat -n 1 -i 0 -c 1000" |
19839                     awk '$2=="205e.dd.0:" {print $4}')
19840
19841         (( ${ops_comma%,} >= 10 )) ||
19842                 error "cannot find job 205e.dd.0 with ops >= 10"
19843 }
19844 run_test 205e "verify the output of lljobstat"
19845
19846 test_205f() {
19847         verify_yaml_available || skip_env "YAML verification not installed"
19848
19849         # check both qos_ost_weights and qos_mdt_weights
19850         do_facet mds1 $LCTL get_param -n lod.*.qos*weights
19851         do_facet mds1 $LCTL get_param -n lod.*.qos*weights | verify_yaml ||
19852                 error "qos_ost_weights is not valid YAML"
19853 }
19854 run_test 205f "verify qos_ost_weights YAML format "
19855
19856 __test_205_jobstats_dump() {
19857         local -a pids
19858         local nbr_instance=$1
19859
19860         while true; do
19861                 if (( ${#pids[@]} >= nbr_instance )); then
19862                         wait ${pids[@]}
19863                         pids=()
19864                 fi
19865
19866                 do_facet mds1 "$LCTL get_param mdt.*.job_stats > /dev/null" &
19867                 pids+=( $! )
19868         done
19869 }
19870
19871 __test_205_cleanup() {
19872         kill $@
19873         # Clear all job entries
19874         do_facet mds1 "$LCTL set_param mdt.*.job_stats=clear"
19875 }
19876
19877 test_205g() {
19878         local -a mds1_params
19879         local -a cli_params
19880         local pids
19881         local interval=5
19882
19883         mds1_params=( $(do_facet mds1 $LCTL get_param mdt.*.job_cleanup_interval) )
19884         do_facet mds1 $LCTL set_param mdt.*.job_cleanup_interval=$interval
19885         stack_trap "do_facet mds1 $LCTL set_param ${mds1_params[*]}" EXIT
19886
19887         cli_params=( $($LCTL get_param jobid_name jobid_var) )
19888         $LCTL set_param jobid_var=TEST205G_ID jobid_name=%j.%p
19889         stack_trap "$LCTL set_param ${cli_params[*]}" EXIT
19890
19891         # start jobs loop
19892         export TEST205G_ID=205g
19893         stack_trap "unset TEST205G_ID" EXIT
19894         while true; do
19895                 printf $DIR/$tfile.{0001..1000} | xargs -P10 -n1 touch
19896         done & pids="$! "
19897
19898         __test_205_jobstats_dump 4 & pids+="$! "
19899         stack_trap "__test_205_cleanup $pids" EXIT INT
19900
19901         [[ $SLOW == "no" ]] && sleep 90 || sleep 240
19902 }
19903 run_test 205g "stress test for job_stats procfile"
19904
19905 # LU-1480, LU-1773 and LU-1657
19906 test_206() {
19907         mkdir -p $DIR/$tdir
19908         $LFS setstripe -c -1 $DIR/$tdir
19909 #define OBD_FAIL_LOV_INIT 0x1403
19910         $LCTL set_param fail_loc=0xa0001403
19911         $LCTL set_param fail_val=1
19912         touch $DIR/$tdir/$tfile || true
19913 }
19914 run_test 206 "fail lov_init_raid0() doesn't lbug"
19915
19916 test_207a() {
19917         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
19918         local fsz=`stat -c %s $DIR/$tfile`
19919         cancel_lru_locks mdc
19920
19921         # do not return layout in getattr intent
19922 #define OBD_FAIL_MDS_NO_LL_GETATTR 0x170
19923         $LCTL set_param fail_loc=0x170
19924         local sz=`stat -c %s $DIR/$tfile`
19925
19926         [ $fsz -eq $sz ] || error "file size expected $fsz, actual $sz"
19927
19928         rm -rf $DIR/$tfile
19929 }
19930 run_test 207a "can refresh layout at glimpse"
19931
19932 test_207b() {
19933         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
19934         local cksum=`md5sum $DIR/$tfile`
19935         local fsz=`stat -c %s $DIR/$tfile`
19936         cancel_lru_locks mdc
19937         cancel_lru_locks osc
19938
19939         # do not return layout in getattr intent
19940 #define OBD_FAIL_MDS_NO_LL_OPEN 0x171
19941         $LCTL set_param fail_loc=0x171
19942
19943         # it will refresh layout after the file is opened but before read issues
19944         echo checksum is "$cksum"
19945         echo "$cksum" |md5sum -c --quiet || error "file differs"
19946
19947         rm -rf $DIR/$tfile
19948 }
19949 run_test 207b "can refresh layout at open"
19950
19951 test_208() {
19952         # FIXME: in this test suite, only RD lease is used. This is okay
19953         # for now as only exclusive open is supported. After generic lease
19954         # is done, this test suite should be revised. - Jinshan
19955
19956         remote_mds_nodsh && skip "remote MDS with nodsh"
19957         [[ $MDS1_VERSION -ge $(version_code 2.4.52) ]] ||
19958                 skip "Need MDS version at least 2.4.52"
19959
19960         echo "==== test 1: verify get lease work"
19961         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eRE+eU || error "get lease error"
19962
19963         echo "==== test 2: verify lease can be broken by upcoming open"
19964         $MULTIOP $DIR/$tfile oO_RDWR:eR_E-eUc &
19965         local PID=$!
19966         sleep 2
19967
19968         $MULTIOP $DIR/$tfile oO_RDWR:c
19969         kill -USR1 $PID && wait $PID || error "break lease error"
19970
19971         echo "==== test 3: verify lease can't be granted if an open already exists"
19972         $MULTIOP $DIR/$tfile oO_RDWR:_c &
19973         local PID=$!
19974         sleep 2
19975
19976         $MULTIOP $DIR/$tfile oO_RDWR:eReUc && error "apply lease should fail"
19977         kill -USR1 $PID && wait $PID || error "open file error"
19978
19979         echo "==== test 4: lease can sustain over recovery"
19980         $MULTIOP $DIR/$tfile oO_RDWR:eR_E+eUc &
19981         PID=$!
19982         sleep 2
19983
19984         fail mds1
19985
19986         kill -USR1 $PID && wait $PID || error "lease broken over recovery"
19987
19988         echo "==== test 5: lease broken can't be regained by replay"
19989         $MULTIOP $DIR/$tfile oO_RDWR:eR_E-eUc &
19990         PID=$!
19991         sleep 2
19992
19993         # open file to break lease and then recovery
19994         $MULTIOP $DIR/$tfile oO_RDWR:c || error "open file error"
19995         fail mds1
19996
19997         kill -USR1 $PID && wait $PID || error "lease not broken over recovery"
19998
19999         rm -f $DIR/$tfile
20000 }
20001 run_test 208 "Exclusive open"
20002
20003 test_209() {
20004         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep disp_stripe)" ] &&
20005                 skip_env "must have disp_stripe"
20006
20007         touch $DIR/$tfile
20008         sync; sleep 5; sync;
20009
20010         echo 3 > /proc/sys/vm/drop_caches
20011         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
20012                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
20013         req_before=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
20014
20015         # open/close 500 times
20016         for i in $(seq 500); do
20017                 cat $DIR/$tfile
20018         done
20019
20020         echo 3 > /proc/sys/vm/drop_caches
20021         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
20022                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
20023         req_after=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
20024
20025         echo "before: $req_before, after: $req_after"
20026         [ $((req_after - req_before)) -ge 300 ] &&
20027                 error "open/close requests are not freed"
20028         return 0
20029 }
20030 run_test 209 "read-only open/close requests should be freed promptly"
20031
20032 test_210() {
20033         local pid
20034
20035         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eW_E+eUc &
20036         pid=$!
20037         sleep 1
20038
20039         $LFS getstripe $DIR/$tfile
20040         kill -USR1 $pid
20041         wait $pid || error "multiop failed"
20042
20043         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
20044         pid=$!
20045         sleep 1
20046
20047         $LFS getstripe $DIR/$tfile
20048         kill -USR1 $pid
20049         wait $pid || error "multiop failed"
20050 }
20051 run_test 210 "lfs getstripe does not break leases"
20052
20053 test_212() {
20054         size=`date +%s`
20055         size=$((size % 8192 + 1))
20056         dd if=/dev/urandom of=$DIR/f212 bs=1k count=$size
20057         sendfile $DIR/f212 $DIR/f212.xyz || error "sendfile wrong"
20058         rm -f $DIR/f212 $DIR/f212.xyz
20059 }
20060 run_test 212 "Sendfile test ============================================"
20061
20062 test_213() {
20063         dd if=/dev/zero of=$DIR/$tfile bs=4k count=4
20064         cancel_lru_locks osc
20065         lctl set_param fail_loc=0x8000040f
20066         # generate a read lock
20067         cat $DIR/$tfile > /dev/null
20068         # write to the file, it will try to cancel the above read lock.
20069         cat /etc/hosts >> $DIR/$tfile
20070 }
20071 run_test 213 "OSC lock completion and cancel race don't crash - bug 18829"
20072
20073 test_214() { # for bug 20133
20074         mkdir -p $DIR/$tdir/d214c || error "mkdir $DIR/$tdir/d214c failed"
20075         for (( i=0; i < 340; i++ )) ; do
20076                 touch $DIR/$tdir/d214c/a$i
20077         done
20078
20079         ls -l $DIR/$tdir || error "ls -l $DIR/d214p failed"
20080         mv $DIR/$tdir/d214c $DIR/ || error "mv $DIR/d214p/d214c $DIR/ failed"
20081         ls $DIR/d214c || error "ls $DIR/d214c failed"
20082         rm -rf $DIR/$tdir || error "rm -rf $DIR/d214* failed"
20083         rm -rf $DIR/d214* || error "rm -rf $DIR/d214* failed"
20084 }
20085 run_test 214 "hash-indexed directory test - bug 20133"
20086
20087 # having "abc" as 1st arg, creates $TMP/lnet_abc.out and $TMP/lnet_abc.sys
20088 create_lnet_proc_files() {
20089         lctl get_param -n $1 >$TMP/lnet_$1.sys || error "cannot read lnet.$1"
20090 }
20091
20092 # counterpart of create_lnet_proc_files
20093 remove_lnet_proc_files() {
20094         rm -f $TMP/lnet_$1.sys
20095 }
20096
20097 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
20098 # 3rd arg as regexp for body
20099 check_lnet_proc_stats() {
20100         local l=$(cat "$TMP/lnet_$1" |wc -l)
20101         [ $l = 1 ] || (cat "$TMP/lnet_$1" && error "$2 is not of 1 line: $l")
20102
20103         grep -E "$3" "$TMP/lnet_$1" || (cat "$TMP/lnet_$1" && error "$2 misformatted")
20104 }
20105
20106 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
20107 # 3rd arg as regexp for body, 4th arg as regexp for 1st line, 5th arg is
20108 # optional and can be regexp for 2nd line (lnet.routes case)
20109 check_lnet_proc_entry() {
20110         local blp=2          # blp stands for 'position of 1st line of body'
20111         [ -z "$5" ] || blp=3 # lnet.routes case
20112
20113         local l=$(cat "$TMP/lnet_$1" |wc -l)
20114         # subtracting one from $blp because the body can be empty
20115         [ "$l" -ge "$(($blp - 1))" ] || (cat "$TMP/lnet_$1" && error "$2 is too short: $l")
20116
20117         sed -n '1 p' "$TMP/lnet_$1" |grep -E "$4" >/dev/null ||
20118                 (cat "$TMP/lnet_$1" && error "1st line of $2 misformatted")
20119
20120         [ "$5" = "" ] || sed -n '2 p' "$TMP/lnet_$1" |grep -E "$5" >/dev/null ||
20121                 (cat "$TMP/lnet_$1" && error "2nd line of $2 misformatted")
20122
20123         # bail out if any unexpected line happened
20124         sed -n "$blp p" "$TMP/lnet_$1" | grep -Ev "$3"
20125         [ "$?" != 0 ] || error "$2 misformatted"
20126 }
20127
20128 test_215() { # for bugs 18102, 21079, 21517
20129         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20130
20131         local N='(0|[1-9][0-9]*)'       # non-negative numeric
20132         local P='[1-9][0-9]*'           # positive numeric
20133         local I='(0|-?[1-9][0-9]*|NA)'  # any numeric (0 | >0 | <0) or NA if no value
20134         local NET='[a-z][a-z0-9]*'      # LNET net like o2ib2
20135         local ADDR='[0-9.]+'            # LNET addr like 10.0.0.1
20136         local NID="$ADDR@$NET"          # LNET nid like 10.0.0.1@o2ib2
20137
20138         local L1 # regexp for 1st line
20139         local L2 # regexp for 2nd line (optional)
20140         local BR # regexp for the rest (body)
20141
20142         # lnet.stats should look as 11 space-separated non-negative numerics
20143         BR="^$N $N $N $N $N $N $N $N $N $N $N$"
20144         create_lnet_proc_files "stats"
20145         check_lnet_proc_stats "stats.sys" "lnet.stats" "$BR"
20146         remove_lnet_proc_files "stats"
20147
20148         # lnet.routes should look like this:
20149         # Routing disabled/enabled
20150         # net hops priority state router
20151         # where net is a string like tcp0, hops > 0, priority >= 0,
20152         # state is up/down,
20153         # router is a string like 192.168.1.1@tcp2
20154         L1="^Routing (disabled|enabled)$"
20155         L2="^net +hops +priority +state +router$"
20156         BR="^$NET +$N +(0|1) +(up|down) +$NID$"
20157         create_lnet_proc_files "routes"
20158         check_lnet_proc_entry "routes.sys" "lnet.routes" "$BR" "$L1" "$L2"
20159         remove_lnet_proc_files "routes"
20160
20161         # lnet.routers should look like this:
20162         # ref rtr_ref alive_cnt state last_ping ping_sent deadline down_ni router
20163         # where ref > 0, rtr_ref > 0, alive_cnt >= 0, state is up/down,
20164         # last_ping >= 0, ping_sent is boolean (0/1), deadline and down_ni are
20165         # numeric (0 or >0 or <0), router is a string like 192.168.1.1@tcp2
20166         L1="^ref +rtr_ref +alive +router$"
20167         BR="^$P +$P +(up|down) +$NID$"
20168         create_lnet_proc_files "routers"
20169         check_lnet_proc_entry "routers.sys" "lnet.routers" "$BR" "$L1"
20170         remove_lnet_proc_files "routers"
20171
20172         # lnet.peers should look like this:
20173         # nid refs state last max rtr min tx min queue
20174         # where nid is a string like 192.168.1.1@tcp2, refs > 0,
20175         # state is up/down/NA, max >= 0. last, rtr, min, tx, min are
20176         # numeric (0 or >0 or <0), queue >= 0.
20177         L1="^nid +refs +state +last +max +rtr +min +tx +min +queue$"
20178         BR="^$NID +$P +(up|down|NA) +$I +$N +$I +$I +$I +$I +$N$"
20179         create_lnet_proc_files "peers"
20180         check_lnet_proc_entry "peers.sys" "lnet.peers" "$BR" "$L1"
20181         remove_lnet_proc_files "peers"
20182
20183         # lnet.buffers  should look like this:
20184         # pages count credits min
20185         # where pages >=0, count >=0, credits and min are numeric (0 or >0 or <0)
20186         L1="^pages +count +credits +min$"
20187         BR="^ +$N +$N +$I +$I$"
20188         create_lnet_proc_files "buffers"
20189         check_lnet_proc_entry "buffers.sys" "lnet.buffers" "$BR" "$L1"
20190         remove_lnet_proc_files "buffers"
20191
20192         # lnet.nis should look like this:
20193         # nid status alive refs peer rtr max tx min
20194         # where nid is a string like 192.168.1.1@tcp2, status is up/down,
20195         # alive is numeric (0 or >0 or <0), refs >= 0, peer >= 0,
20196         # rtr >= 0, max >=0, tx and min are numeric (0 or >0 or <0).
20197         L1="^nid +status +alive +refs +peer +rtr +max +tx +min$"
20198         BR="^$NID +(up|down) +$I +$N +$N +$N +$N +$I +$I$"
20199         create_lnet_proc_files "nis"
20200         check_lnet_proc_entry "nis.sys" "lnet.nis" "$BR" "$L1"
20201         remove_lnet_proc_files "nis"
20202
20203         # can we successfully write to lnet.stats?
20204         lctl set_param -n stats=0 || error "cannot write to lnet.stats"
20205 }
20206 run_test 215 "lnet exists and has proper content - bugs 18102, 21079, 21517"
20207
20208 test_216() { # bug 20317
20209         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20210         remote_ost_nodsh && skip "remote OST with nodsh"
20211
20212         local node
20213         local facets=$(get_facets OST)
20214         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
20215
20216         save_lustre_params client "osc.*.contention_seconds" > $p
20217         save_lustre_params $facets \
20218                 "ldlm.namespaces.filter-*.max_nolock_bytes" >> $p
20219         save_lustre_params $facets \
20220                 "ldlm.namespaces.filter-*.contended_locks" >> $p
20221         save_lustre_params $facets \
20222                 "ldlm.namespaces.filter-*.contention_seconds" >> $p
20223         clear_stats osc.*.osc_stats
20224
20225         # agressive lockless i/o settings
20226         do_nodes $(comma_list $(osts_nodes)) \
20227                 "lctl set_param -n ldlm.namespaces.*.max_nolock_bytes=2000000 \
20228                         ldlm.namespaces.filter-*.contended_locks=0 \
20229                         ldlm.namespaces.filter-*.contention_seconds=60"
20230         lctl set_param -n osc.*.contention_seconds=60
20231
20232         $DIRECTIO write $DIR/$tfile 0 10 4096
20233         $CHECKSTAT -s 40960 $DIR/$tfile
20234
20235         # disable lockless i/o
20236         do_nodes $(comma_list $(osts_nodes)) \
20237                 "lctl set_param -n ldlm.namespaces.filter-*.max_nolock_bytes=0 \
20238                         ldlm.namespaces.filter-*.contended_locks=32 \
20239                         ldlm.namespaces.filter-*.contention_seconds=0"
20240         lctl set_param -n osc.*.contention_seconds=0
20241         clear_stats osc.*.osc_stats
20242
20243         dd if=/dev/zero of=$DIR/$tfile count=0
20244         $CHECKSTAT -s 0 $DIR/$tfile
20245
20246         restore_lustre_params <$p
20247         rm -f $p
20248         rm $DIR/$tfile
20249 }
20250 run_test 216 "check lockless direct write updates file size and kms correctly"
20251
20252 test_217() { # bug 22430
20253         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20254
20255         local node
20256
20257         for node in $(nodes_list); do
20258                 local nid=$(host_nids_address $node $NETTYPE)
20259                 local node_ip=$(do_node $node getent ahostsv4 $node |
20260                                 awk '{ print $1; exit; }')
20261
20262                 echo "node: '$node', nid: '$nid', node_ip='$node_ip'"
20263                 # if hostname matches any NID, use hostname for better testing
20264                 if [[ -z "$nid" || "$nid" =~ "$node_ip" ]]; then
20265                         echo "lctl ping node $node@$NETTYPE"
20266                         lctl ping $node@$NETTYPE
20267                 else # otherwise, at least test 'lctl ping' is working
20268                         echo "lctl ping nid $(h2nettype $nid)"
20269                         lctl ping $(h2nettype $nid)
20270                         echo "skipping $node (no hyphen detected)"
20271                 fi
20272         done
20273 }
20274 run_test 217 "check lctl ping for hostnames with embedded hyphen ('-')"
20275
20276 test_218() {
20277         # do directio so as not to populate the page cache
20278         log "creating a 10 Mb file"
20279         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c ||
20280                 error "multiop failed while creating a file"
20281         log "starting reads"
20282         dd if=$DIR/$tfile of=/dev/null bs=4096 &
20283         log "truncating the file"
20284         $MULTIOP $DIR/$tfile oO_TRUNC:c ||
20285                 error "multiop failed while truncating the file"
20286         log "killing dd"
20287         kill %+ || true # reads might have finished
20288         echo "wait until dd is finished"
20289         wait
20290         log "removing the temporary file"
20291         rm -rf $DIR/$tfile || error "tmp file removal failed"
20292 }
20293 run_test 218 "parallel read and truncate should not deadlock"
20294
20295 test_219() {
20296         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20297
20298         # write one partial page
20299         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1
20300         # set no grant so vvp_io_commit_write will do sync write
20301         $LCTL set_param fail_loc=0x411
20302         # write a full page at the end of file
20303         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=1 conv=notrunc
20304
20305         $LCTL set_param fail_loc=0
20306         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=3
20307         $LCTL set_param fail_loc=0x411
20308         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1 seek=2 conv=notrunc
20309
20310         # LU-4201
20311         dd if=/dev/zero of=$DIR/$tfile-2 bs=1024 count=1
20312         $CHECKSTAT -s 1024 $DIR/$tfile-2 || error "checkstat wrong size"
20313 }
20314 run_test 219 "LU-394: Write partial won't cause uncontiguous pages vec at LND"
20315
20316 test_220() { #LU-325
20317         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20318         remote_ost_nodsh && skip "remote OST with nodsh"
20319         remote_mds_nodsh && skip "remote MDS with nodsh"
20320         remote_mgs_nodsh && skip "remote MGS with nodsh"
20321
20322         local OSTIDX=0
20323
20324         # create on MDT0000 so the last_id and next_id are correct
20325         mkdir_on_mdt0 $DIR/$tdir
20326         local OST=$($LFS df $DIR | awk '/OST:'$OSTIDX'/ { print $1 }')
20327         OST=${OST%_UUID}
20328
20329         # on the mdt's osc
20330         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $OST)
20331         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
20332                         osp.$mdtosc_proc1.prealloc_last_id)
20333         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
20334                         osp.$mdtosc_proc1.prealloc_next_id)
20335
20336         $LFS df -i
20337
20338         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=-1
20339         #define OBD_FAIL_OST_ENOINO              0x229
20340         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0x229
20341         create_pool $FSNAME.$TESTNAME || return 1
20342         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $OST || return 2
20343
20344         $LFS setstripe $DIR/$tdir -i $OSTIDX -c 1 -p $FSNAME.$TESTNAME
20345
20346         MDSOBJS=$((last_id - next_id))
20347         echo "preallocated objects on MDS is $MDSOBJS" "($last_id - $next_id)"
20348
20349         blocks=$($LFS df $MOUNT | awk '($1 == '$OSTIDX') { print $4 }')
20350         echo "OST still has $count kbytes free"
20351
20352         echo "create $MDSOBJS files @next_id..."
20353         createmany -o $DIR/$tdir/f $MDSOBJS || return 3
20354
20355         local last_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
20356                         osp.$mdtosc_proc1.prealloc_last_id)
20357         local next_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
20358                         osp.$mdtosc_proc1.prealloc_next_id)
20359
20360         echo "after creation, last_id=$last_id2, next_id=$next_id2"
20361         $LFS df -i
20362
20363         echo "cleanup..."
20364
20365         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=0
20366         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0
20367
20368         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $OST ||
20369                 error "$LCTL pool_remove $FSNAME.$TESTNAME $OST failed"
20370         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
20371                 error "$LCTL pool_destroy $FSNAME.$TESTNAME failed"
20372         echo "unlink $MDSOBJS files @$next_id..."
20373         unlinkmany $DIR/$tdir/f $MDSOBJS || error "unlinkmany failed"
20374 }
20375 run_test 220 "preallocated MDS objects still used if ENOSPC from OST"
20376
20377 test_221() {
20378         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20379
20380         dd if=`which date` of=$MOUNT/date oflag=sync
20381         chmod +x $MOUNT/date
20382
20383         #define OBD_FAIL_LLITE_FAULT_TRUNC_RACE  0x1401
20384         $LCTL set_param fail_loc=0x80001401
20385
20386         $MOUNT/date > /dev/null
20387         rm -f $MOUNT/date
20388 }
20389 run_test 221 "make sure fault and truncate race to not cause OOM"
20390
20391 test_222a () {
20392         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20393
20394         rm -rf $DIR/$tdir
20395         test_mkdir $DIR/$tdir
20396         $LFS setstripe -c 1 -i 0 $DIR/$tdir
20397         createmany -o $DIR/$tdir/$tfile 10
20398         cancel_lru_locks mdc
20399         cancel_lru_locks osc
20400         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
20401         $LCTL set_param fail_loc=0x31a
20402         ls -l $DIR/$tdir > /dev/null || error "AGL for ls failed"
20403         $LCTL set_param fail_loc=0
20404         rm -r $DIR/$tdir
20405 }
20406 run_test 222a "AGL for ls should not trigger CLIO lock failure"
20407
20408 test_222b () {
20409         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20410
20411         rm -rf $DIR/$tdir
20412         test_mkdir $DIR/$tdir
20413         $LFS setstripe -c 1 -i 0 $DIR/$tdir
20414         createmany -o $DIR/$tdir/$tfile 10
20415         cancel_lru_locks mdc
20416         cancel_lru_locks osc
20417         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
20418         $LCTL set_param fail_loc=0x31a
20419         rm -r $DIR/$tdir || error "AGL for rmdir failed"
20420         $LCTL set_param fail_loc=0
20421 }
20422 run_test 222b "AGL for rmdir should not trigger CLIO lock failure"
20423
20424 test_223 () {
20425         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20426
20427         rm -rf $DIR/$tdir
20428         test_mkdir $DIR/$tdir
20429         $LFS setstripe -c 1 -i 0 $DIR/$tdir
20430         createmany -o $DIR/$tdir/$tfile 10
20431         cancel_lru_locks mdc
20432         cancel_lru_locks osc
20433         #define OBD_FAIL_LDLM_AGL_NOLOCK          0x31b
20434         $LCTL set_param fail_loc=0x31b
20435         ls -l $DIR/$tdir > /dev/null || error "reenqueue failed"
20436         $LCTL set_param fail_loc=0
20437         rm -r $DIR/$tdir
20438 }
20439 run_test 223 "osc reenqueue if without AGL lock granted ======================="
20440
20441 test_224a() { # LU-1039, MRP-303
20442         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20443         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB   0x508
20444         $LCTL set_param fail_loc=0x508
20445         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 conv=fsync
20446         $LCTL set_param fail_loc=0
20447         df $DIR
20448 }
20449 run_test 224a "Don't panic on bulk IO failure"
20450
20451 test_224bd_sub() { # LU-1039, MRP-303
20452         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20453         local timeout=$1
20454
20455         shift
20456         dd if=/dev/urandom of=$TMP/$tfile bs=1M count=1
20457
20458         $LFS setstripe -c 1 -i 0 $DIR/$tfile
20459
20460         dd if=$TMP/$tfile of=$DIR/$tfile bs=1M count=1
20461         cancel_lru_locks osc
20462         set_checksums 0
20463         stack_trap "set_checksums $ORIG_CSUM" EXIT
20464         local at_max_saved=0
20465
20466         # adaptive timeouts may prevent seeing the issue
20467         if at_is_enabled; then
20468                 at_max_saved=$(at_max_get mds)
20469                 at_max_set 0 mds client
20470                 stack_trap "at_max_set $at_max_saved mds client" EXIT
20471         fi
20472
20473         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB2   0x515
20474         do_facet ost1 $LCTL set_param fail_val=$timeout fail_loc=0x80000515
20475         dd of=$TMP/$tfile.new if=$DIR/$tfile bs=1M count=1 || "$@"
20476
20477         do_facet ost1 $LCTL set_param fail_loc=0
20478         cmp $TMP/$tfile $TMP/$tfile.new || error "file contents wrong"
20479         df $DIR
20480 }
20481
20482 test_224b() {
20483         test_224bd_sub 3 error "dd failed"
20484 }
20485 run_test 224b "Don't panic on bulk IO failure"
20486
20487 test_224c() { # LU-6441
20488         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20489         remote_mds_nodsh && skip "remote MDS with nodsh"
20490
20491         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
20492         save_writethrough $p
20493         set_cache writethrough on
20494
20495         local pages_per_rpc=$($LCTL get_param osc.*.max_pages_per_rpc)
20496         local at_max=$($LCTL get_param -n at_max)
20497         local timeout=$($LCTL get_param -n timeout)
20498         local test_at="at_max"
20499         local param_at="$FSNAME.sys.at_max"
20500         local test_timeout="timeout"
20501         local param_timeout="$FSNAME.sys.timeout"
20502
20503         $LCTL set_param -n osc.*.max_pages_per_rpc=1024
20504
20505         set_persistent_param_and_check client "$test_at" "$param_at" 0
20506         set_persistent_param_and_check client "$test_timeout" "$param_timeout" 5
20507
20508         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB3 0x520
20509         do_facet ost1 "$LCTL set_param fail_loc=0x520"
20510         $LFS setstripe -c 1 -i 0 $DIR/$tfile
20511         stack_trap "rm -f $DIR/$tfile"
20512         dd if=/dev/zero of=$DIR/$tfile bs=8MB count=1
20513         sync
20514         do_facet ost1 "$LCTL set_param fail_loc=0"
20515
20516         set_persistent_param_and_check client "$test_at" "$param_at" $at_max
20517         set_persistent_param_and_check client "$test_timeout" "$param_timeout" \
20518                 $timeout
20519
20520         $LCTL set_param -n $pages_per_rpc
20521         restore_lustre_params < $p
20522         rm -f $p
20523 }
20524 run_test 224c "Don't hang if one of md lost during large bulk RPC"
20525
20526 test_224d() { # LU-11169
20527         test_224bd_sub $((TIMEOUT + 2)) error "dd failed"
20528 }
20529 run_test 224d "Don't corrupt data on bulk IO timeout"
20530
20531 MDSSURVEY=${MDSSURVEY:-$(which mds-survey 2>/dev/null || true)}
20532 test_225a () {
20533         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20534         if [ -z ${MDSSURVEY} ]; then
20535                 skip_env "mds-survey not found"
20536         fi
20537         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
20538                 skip "Need MDS version at least 2.2.51"
20539
20540         local mds=$(facet_host $SINGLEMDS)
20541         local target=$(do_nodes $mds 'lctl dl' |
20542                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
20543
20544         local cmd1="file_count=1000 thrhi=4"
20545         local cmd2="dir_count=2 layer=mdd stripe_count=0"
20546         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
20547         local cmd="$cmd1 $cmd2 $cmd3"
20548
20549         rm -f ${TMP}/mds_survey*
20550         echo + $cmd
20551         eval $cmd || error "mds-survey with zero-stripe failed"
20552         cat ${TMP}/mds_survey*
20553         rm -f ${TMP}/mds_survey*
20554 }
20555 run_test 225a "Metadata survey sanity with zero-stripe"
20556
20557 test_225b () {
20558         if [ -z ${MDSSURVEY} ]; then
20559                 skip_env "mds-survey not found"
20560         fi
20561         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
20562                 skip "Need MDS version at least 2.2.51"
20563         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20564         remote_mds_nodsh && skip "remote MDS with nodsh"
20565         if [ $($LCTL dl | grep -c osc) -eq 0 ]; then
20566                 skip_env "Need to mount OST to test"
20567         fi
20568
20569         local mds=$(facet_host $SINGLEMDS)
20570         local target=$(do_nodes $mds 'lctl dl' |
20571                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
20572
20573         local cmd1="file_count=1000 thrhi=4"
20574         local cmd2="dir_count=2 layer=mdd stripe_count=1"
20575         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
20576         local cmd="$cmd1 $cmd2 $cmd3"
20577
20578         rm -f ${TMP}/mds_survey*
20579         echo + $cmd
20580         eval $cmd || error "mds-survey with stripe_count failed"
20581         cat ${TMP}/mds_survey*
20582         rm -f ${TMP}/mds_survey*
20583 }
20584 run_test 225b "Metadata survey sanity with stripe_count = 1"
20585
20586 mcreate_path2fid () {
20587         local mode=$1
20588         local major=$2
20589         local minor=$3
20590         local name=$4
20591         local desc=$5
20592         local path=$DIR/$tdir/$name
20593         local fid
20594         local rc
20595         local fid_path
20596
20597         $MCREATE --mode=$1 --major=$2 --minor=$3 $path ||
20598                 error "cannot create $desc"
20599
20600         fid=$($LFS path2fid $path | tr -d '[' | tr -d ']')
20601         rc=$?
20602         [ $rc -ne 0 ] && error "cannot get fid of a $desc"
20603
20604         fid_path=$($LFS fid2path $MOUNT $fid)
20605         rc=$?
20606         [ $rc -ne 0 ] && error "cannot get path of $desc by $DIR $path $fid"
20607
20608         [ "$path" == "$fid_path" ] ||
20609                 error "fid2path returned $fid_path, expected $path"
20610
20611         echo "pass with $path and $fid"
20612 }
20613
20614 test_226a () {
20615         rm -rf $DIR/$tdir
20616         mkdir -p $DIR/$tdir
20617
20618         mcreate_path2fid 0010666 0 0 fifo "FIFO"
20619         mcreate_path2fid 0020666 1 3 null "character special file (null)"
20620         mcreate_path2fid 0020666 1 255 none "character special file (no device)"
20621         mcreate_path2fid 0040666 0 0 dir "directory"
20622         mcreate_path2fid 0060666 7 0 loop0 "block special file (loop)"
20623         mcreate_path2fid 0100666 0 0 file "regular file"
20624         mcreate_path2fid 0120666 0 0 link "symbolic link"
20625         mcreate_path2fid 0140666 0 0 sock "socket"
20626 }
20627 run_test 226a "call path2fid and fid2path on files of all type"
20628
20629 test_226b () {
20630         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20631
20632         local MDTIDX=1
20633
20634         rm -rf $DIR/$tdir
20635         mkdir -p $DIR/$tdir
20636         $LFS setdirstripe -i $MDTIDX $DIR/$tdir/remote_dir ||
20637                 error "create remote directory failed"
20638         mcreate_path2fid 0010666 0 0 "remote_dir/fifo" "FIFO"
20639         mcreate_path2fid 0020666 1 3 "remote_dir/null" \
20640                                 "character special file (null)"
20641         mcreate_path2fid 0020666 1 255 "remote_dir/none" \
20642                                 "character special file (no device)"
20643         mcreate_path2fid 0040666 0 0 "remote_dir/dir" "directory"
20644         mcreate_path2fid 0060666 7 0 "remote_dir/loop0" \
20645                                 "block special file (loop)"
20646         mcreate_path2fid 0100666 0 0 "remote_dir/file" "regular file"
20647         mcreate_path2fid 0120666 0 0 "remote_dir/link" "symbolic link"
20648         mcreate_path2fid 0140666 0 0 "remote_dir/sock" "socket"
20649 }
20650 run_test 226b "call path2fid and fid2path on files of all type under remote dir"
20651
20652 test_226c () {
20653         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20654         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
20655                 skip "Need MDS version at least 2.13.55"
20656
20657         local submnt=/mnt/submnt
20658         local srcfile=/etc/passwd
20659         local dstfile=$submnt/passwd
20660         local path
20661         local fid
20662
20663         rm -rf $DIR/$tdir
20664         rm -rf $submnt
20665         $LFS setdirstripe -c -1 -i 1 $DIR/$tdir ||
20666                 error "create remote directory failed"
20667         mkdir -p $submnt || error "create $submnt failed"
20668         $MOUNT_CMD $MGSNID:/$FSNAME/$tdir $submnt ||
20669                 error "mount $submnt failed"
20670         stack_trap "umount $submnt" EXIT
20671
20672         cp $srcfile $dstfile
20673         fid=$($LFS path2fid $dstfile)
20674         path=$($LFS fid2path $submnt "$fid")
20675         [ "$path" = "$dstfile" ] ||
20676                 error "fid2path $submnt $fid failed ($path != $dstfile)"
20677 }
20678 run_test 226c "call path2fid and fid2path under remote dir with subdir mount"
20679
20680 # LU-1299 Executing or running ldd on a truncated executable does not
20681 # cause an out-of-memory condition.
20682 test_227() {
20683         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20684         [ -z "$(which ldd)" ] && skip_env "should have ldd tool"
20685
20686         dd if=$(which date) of=$MOUNT/date bs=1k count=1
20687         chmod +x $MOUNT/date
20688
20689         $MOUNT/date > /dev/null
20690         ldd $MOUNT/date > /dev/null
20691         rm -f $MOUNT/date
20692 }
20693 run_test 227 "running truncated executable does not cause OOM"
20694
20695 # LU-1512 try to reuse idle OI blocks
20696 test_228a() {
20697         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20698         remote_mds_nodsh && skip "remote MDS with nodsh"
20699         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
20700
20701         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
20702         local myDIR=$DIR/$tdir
20703
20704         mkdir -p $myDIR
20705         #define OBD_FAIL_SEQ_EXHAUST             0x1002
20706         $LCTL set_param fail_loc=0x80001002
20707         createmany -o $myDIR/t- 10000
20708         $LCTL set_param fail_loc=0
20709         # The guard is current the largest FID holder
20710         touch $myDIR/guard
20711         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
20712                     tr -d '[')
20713         local IDX=$(($SEQ % 64))
20714
20715         do_facet $SINGLEMDS sync
20716         # Make sure journal flushed.
20717         sleep 6
20718         local blk1=$(do_facet $SINGLEMDS \
20719                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
20720                      grep Blockcount | awk '{print $4}')
20721
20722         # Remove old files, some OI blocks will become idle.
20723         unlinkmany $myDIR/t- 10000
20724         # Create new files, idle OI blocks should be reused.
20725         createmany -o $myDIR/t- 2000
20726         do_facet $SINGLEMDS sync
20727         # Make sure journal flushed.
20728         sleep 6
20729         local blk2=$(do_facet $SINGLEMDS \
20730                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
20731                      grep Blockcount | awk '{print $4}')
20732
20733         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
20734 }
20735 run_test 228a "try to reuse idle OI blocks"
20736
20737 test_228b() {
20738         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20739         remote_mds_nodsh && skip "remote MDS with nodsh"
20740         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
20741
20742         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
20743         local myDIR=$DIR/$tdir
20744
20745         mkdir -p $myDIR
20746         #define OBD_FAIL_SEQ_EXHAUST             0x1002
20747         $LCTL set_param fail_loc=0x80001002
20748         createmany -o $myDIR/t- 10000
20749         $LCTL set_param fail_loc=0
20750         # The guard is current the largest FID holder
20751         touch $myDIR/guard
20752         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
20753                     tr -d '[')
20754         local IDX=$(($SEQ % 64))
20755
20756         do_facet $SINGLEMDS sync
20757         # Make sure journal flushed.
20758         sleep 6
20759         local blk1=$(do_facet $SINGLEMDS \
20760                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
20761                      grep Blockcount | awk '{print $4}')
20762
20763         # Remove old files, some OI blocks will become idle.
20764         unlinkmany $myDIR/t- 10000
20765
20766         # stop the MDT
20767         stop $SINGLEMDS || error "Fail to stop MDT."
20768         # remount the MDT
20769         start $SINGLEMDS $(facet_device $SINGLEMDS) $MDS_MOUNT_OPTS ||
20770                 error "Fail to start MDT."
20771
20772         client_up || error "Fail to df."
20773         # Create new files, idle OI blocks should be reused.
20774         createmany -o $myDIR/t- 2000
20775         do_facet $SINGLEMDS sync
20776         # Make sure journal flushed.
20777         sleep 6
20778         local blk2=$(do_facet $SINGLEMDS \
20779                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
20780                      grep Blockcount | awk '{print $4}')
20781
20782         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
20783 }
20784 run_test 228b "idle OI blocks can be reused after MDT restart"
20785
20786 #LU-1881
20787 test_228c() {
20788         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20789         remote_mds_nodsh && skip "remote MDS with nodsh"
20790         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
20791
20792         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
20793         local myDIR=$DIR/$tdir
20794
20795         mkdir -p $myDIR
20796         #define OBD_FAIL_SEQ_EXHAUST             0x1002
20797         $LCTL set_param fail_loc=0x80001002
20798         # 20000 files can guarantee there are index nodes in the OI file
20799         createmany -o $myDIR/t- 20000
20800         $LCTL set_param fail_loc=0
20801         # The guard is current the largest FID holder
20802         touch $myDIR/guard
20803         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
20804                     tr -d '[')
20805         local IDX=$(($SEQ % 64))
20806
20807         do_facet $SINGLEMDS sync
20808         # Make sure journal flushed.
20809         sleep 6
20810         local blk1=$(do_facet $SINGLEMDS \
20811                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
20812                      grep Blockcount | awk '{print $4}')
20813
20814         # Remove old files, some OI blocks will become idle.
20815         unlinkmany $myDIR/t- 20000
20816         rm -f $myDIR/guard
20817         # The OI file should become empty now
20818
20819         # Create new files, idle OI blocks should be reused.
20820         createmany -o $myDIR/t- 2000
20821         do_facet $SINGLEMDS sync
20822         # Make sure journal flushed.
20823         sleep 6
20824         local blk2=$(do_facet $SINGLEMDS \
20825                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
20826                      grep Blockcount | awk '{print $4}')
20827
20828         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
20829 }
20830 run_test 228c "NOT shrink the last entry in OI index node to recycle idle leaf"
20831
20832 test_229() { # LU-2482, LU-3448
20833         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20834         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
20835         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
20836                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
20837
20838         rm -f $DIR/$tfile
20839
20840         # Create a file with a released layout and stripe count 2.
20841         $MULTIOP $DIR/$tfile H2c ||
20842                 error "failed to create file with released layout"
20843
20844         $LFS getstripe -v $DIR/$tfile
20845
20846         local pattern=$($LFS getstripe -L $DIR/$tfile)
20847         [ X"$pattern" = X"released" ] || error "pattern error ($pattern)"
20848
20849         local stripe_count=$($LFS getstripe -c $DIR/$tfile) ||
20850                 error "getstripe"
20851         [ $stripe_count -eq 2 ] || error "stripe count not 2 ($stripe_count)"
20852         stat $DIR/$tfile || error "failed to stat released file"
20853
20854         chown $RUNAS_ID $DIR/$tfile ||
20855                 error "chown $RUNAS_ID $DIR/$tfile failed"
20856
20857         chgrp $RUNAS_ID $DIR/$tfile ||
20858                 error "chgrp $RUNAS_ID $DIR/$tfile failed"
20859
20860         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
20861         rm $DIR/$tfile || error "failed to remove released file"
20862 }
20863 run_test 229 "getstripe/stat/rm/attr changes work on released files"
20864
20865 test_230a() {
20866         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20867         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20868         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20869                 skip "Need MDS version at least 2.11.52"
20870
20871         local MDTIDX=1
20872
20873         test_mkdir $DIR/$tdir
20874         test_mkdir -i0 -c1 $DIR/$tdir/test_230_local
20875         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230_local)
20876         [ $mdt_idx -ne 0 ] &&
20877                 error "create local directory on wrong MDT $mdt_idx"
20878
20879         $LFS mkdir -i $MDTIDX $DIR/$tdir/test_230 ||
20880                         error "create remote directory failed"
20881         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230)
20882         [ $mdt_idx -ne $MDTIDX ] &&
20883                 error "create remote directory on wrong MDT $mdt_idx"
20884
20885         createmany -o $DIR/$tdir/test_230/t- 10 ||
20886                 error "create files on remote directory failed"
20887         mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230/t-0)
20888         [ $mdt_idx -ne $MDTIDX ] && error "create files on wrong MDT $mdt_idx"
20889         rm -r $DIR/$tdir || error "unlink remote directory failed"
20890 }
20891 run_test 230a "Create remote directory and files under the remote directory"
20892
20893 test_230b() {
20894         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20895         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20896         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20897                 skip "Need MDS version at least 2.11.52"
20898
20899         local MDTIDX=1
20900         local mdt_index
20901         local i
20902         local file
20903         local pid
20904         local stripe_count
20905         local migrate_dir=$DIR/$tdir/migrate_dir
20906         local other_dir=$DIR/$tdir/other_dir
20907
20908         test_mkdir $DIR/$tdir
20909         test_mkdir -i0 -c1 $migrate_dir
20910         test_mkdir -i0 -c1 $other_dir
20911         for ((i=0; i<10; i++)); do
20912                 mkdir -p $migrate_dir/dir_${i}
20913                 createmany -o $migrate_dir/dir_${i}/f 10 ||
20914                         error "create files under remote dir failed $i"
20915         done
20916
20917         cp /etc/passwd $migrate_dir/$tfile
20918         cp /etc/passwd $other_dir/$tfile
20919         chattr +SAD $migrate_dir
20920         chattr +SAD $migrate_dir/$tfile
20921
20922         local old_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
20923         local old_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
20924         local old_dir_mode=$(stat -c%f $migrate_dir)
20925         local old_file_mode=$(stat -c%f $migrate_dir/$tfile)
20926
20927         mkdir -p $migrate_dir/dir_default_stripe2
20928         $LFS setstripe -c 2 $migrate_dir/dir_default_stripe2
20929         $LFS setstripe -c 2 $migrate_dir/${tfile}_stripe2
20930
20931         mkdir -p $other_dir
20932         ln $migrate_dir/$tfile $other_dir/luna
20933         ln $migrate_dir/$tfile $migrate_dir/sofia
20934         ln $other_dir/$tfile $migrate_dir/david
20935         ln -s $migrate_dir/$tfile $other_dir/zachary
20936         ln -s $migrate_dir/$tfile $migrate_dir/${tfile}_ln
20937         ln -s $other_dir/$tfile $migrate_dir/${tfile}_ln_other
20938
20939         local len
20940         local lnktgt
20941
20942         # inline symlink
20943         for len in 58 59 60; do
20944                 lnktgt=$(str_repeat 'l' $len)
20945                 touch $migrate_dir/$lnktgt
20946                 ln -s $lnktgt $migrate_dir/${len}char_ln
20947         done
20948
20949         # PATH_MAX
20950         for len in 4094 4095; do
20951                 lnktgt=$(str_repeat 'l' $len)
20952                 ln -s $lnktgt $migrate_dir/${len}char_ln
20953         done
20954
20955         # NAME_MAX
20956         for len in 254 255; do
20957                 touch $migrate_dir/$(str_repeat 'l' $len)
20958         done
20959
20960         $LFS migrate -m $MDTIDX $migrate_dir ||
20961                 error "fails on migrating remote dir to MDT1"
20962
20963         echo "migratate to MDT1, then checking.."
20964         for ((i = 0; i < 10; i++)); do
20965                 for file in $(find $migrate_dir/dir_${i}); do
20966                         mdt_index=$($LFS getstripe -m $file)
20967                         # broken symlink getstripe will fail
20968                         [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
20969                                 error "$file is not on MDT${MDTIDX}"
20970                 done
20971         done
20972
20973         # the multiple link file should still in MDT0
20974         mdt_index=$($LFS getstripe -m $migrate_dir/$tfile)
20975         [ $mdt_index == 0 ] ||
20976                 error "$file is not on MDT${MDTIDX}"
20977
20978         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
20979         [ "$old_dir_flag" = "$new_dir_flag" ] ||
20980                 error " expect $old_dir_flag get $new_dir_flag"
20981
20982         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
20983         [ "$old_file_flag" = "$new_file_flag" ] ||
20984                 error " expect $old_file_flag get $new_file_flag"
20985
20986         local new_dir_mode=$(stat -c%f $migrate_dir)
20987         [ "$old_dir_mode" = "$new_dir_mode" ] ||
20988                 error "expect mode $old_dir_mode get $new_dir_mode"
20989
20990         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
20991         [ "$old_file_mode" = "$new_file_mode" ] ||
20992                 error "expect mode $old_file_mode get $new_file_mode"
20993
20994         diff /etc/passwd $migrate_dir/$tfile ||
20995                 error "$tfile different after migration"
20996
20997         diff /etc/passwd $other_dir/luna ||
20998                 error "luna different after migration"
20999
21000         diff /etc/passwd $migrate_dir/sofia ||
21001                 error "sofia different after migration"
21002
21003         diff /etc/passwd $migrate_dir/david ||
21004                 error "david different after migration"
21005
21006         diff /etc/passwd $other_dir/zachary ||
21007                 error "zachary different after migration"
21008
21009         diff /etc/passwd $migrate_dir/${tfile}_ln ||
21010                 error "${tfile}_ln different after migration"
21011
21012         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
21013                 error "${tfile}_ln_other different after migration"
21014
21015         stripe_count=$($LFS getstripe -c $migrate_dir/dir_default_stripe2)
21016         [ $stripe_count = 2 ] ||
21017                 error "dir strpe_count $d != 2 after migration."
21018
21019         stripe_count=$($LFS getstripe -c $migrate_dir/${tfile}_stripe2)
21020         [ $stripe_count = 2 ] ||
21021                 error "file strpe_count $d != 2 after migration."
21022
21023         #migrate back to MDT0
21024         MDTIDX=0
21025
21026         $LFS migrate -m $MDTIDX $migrate_dir ||
21027                 error "fails on migrating remote dir to MDT0"
21028
21029         echo "migrate back to MDT0, checking.."
21030         for file in $(find $migrate_dir); do
21031                 mdt_index=$($LFS getstripe -m $file)
21032                 [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
21033                         error "$file is not on MDT${MDTIDX}"
21034         done
21035
21036         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
21037         [ "$old_dir_flag" = "$new_dir_flag" ] ||
21038                 error " expect $old_dir_flag get $new_dir_flag"
21039
21040         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
21041         [ "$old_file_flag" = "$new_file_flag" ] ||
21042                 error " expect $old_file_flag get $new_file_flag"
21043
21044         local new_dir_mode=$(stat -c%f $migrate_dir)
21045         [ "$old_dir_mode" = "$new_dir_mode" ] ||
21046                 error "expect mode $old_dir_mode get $new_dir_mode"
21047
21048         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
21049         [ "$old_file_mode" = "$new_file_mode" ] ||
21050                 error "expect mode $old_file_mode get $new_file_mode"
21051
21052         diff /etc/passwd ${migrate_dir}/$tfile ||
21053                 error "$tfile different after migration"
21054
21055         diff /etc/passwd ${other_dir}/luna ||
21056                 error "luna different after migration"
21057
21058         diff /etc/passwd ${migrate_dir}/sofia ||
21059                 error "sofia different after migration"
21060
21061         diff /etc/passwd ${other_dir}/zachary ||
21062                 error "zachary different after migration"
21063
21064         diff /etc/passwd $migrate_dir/${tfile}_ln ||
21065                 error "${tfile}_ln different after migration"
21066
21067         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
21068                 error "${tfile}_ln_other different after migration"
21069
21070         stripe_count=$($LFS getstripe -c ${migrate_dir}/dir_default_stripe2)
21071         [ $stripe_count = 2 ] ||
21072                 error "dir strpe_count $d != 2 after migration."
21073
21074         stripe_count=$($LFS getstripe -c ${migrate_dir}/${tfile}_stripe2)
21075         [ $stripe_count = 2 ] ||
21076                 error "file strpe_count $d != 2 after migration."
21077
21078         rm -rf $DIR/$tdir || error "rm dir failed after migration"
21079 }
21080 run_test 230b "migrate directory"
21081
21082 test_230c() {
21083         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21084         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21085         remote_mds_nodsh && skip "remote MDS with nodsh"
21086         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21087                 skip "Need MDS version at least 2.11.52"
21088
21089         local MDTIDX=1
21090         local total=3
21091         local mdt_index
21092         local file
21093         local migrate_dir=$DIR/$tdir/migrate_dir
21094
21095         #If migrating directory fails in the middle, all entries of
21096         #the directory is still accessiable.
21097         test_mkdir $DIR/$tdir
21098         test_mkdir -i0 -c1 $migrate_dir
21099         test_mkdir -i1 -c1 $DIR/$tdir/remote_dir
21100         stat $migrate_dir
21101         createmany -o $migrate_dir/f $total ||
21102                 error "create files under ${migrate_dir} failed"
21103
21104         # fail after migrating top dir, and this will fail only once, so the
21105         # first sub file migration will fail (currently f3), others succeed.
21106         #OBD_FAIL_MIGRATE_ENTRIES       0x1801
21107         do_facet mds1 lctl set_param fail_loc=0x1801
21108         local t=$(ls $migrate_dir | wc -l)
21109         $LFS migrate --mdt-index $MDTIDX $migrate_dir &&
21110                 error "migrate should fail"
21111         local u=$(ls $migrate_dir | wc -l)
21112         [ "$u" == "$t" ] || error "$u != $t during migration"
21113
21114         # add new dir/file should succeed
21115         mkdir $migrate_dir/dir ||
21116                 error "mkdir failed under migrating directory"
21117         touch $migrate_dir/file ||
21118                 error "create file failed under migrating directory"
21119
21120         # add file with existing name should fail
21121         for file in $migrate_dir/f*; do
21122                 stat $file > /dev/null || error "stat $file failed"
21123                 $OPENFILE -f O_CREAT:O_EXCL $file &&
21124                         error "open(O_CREAT|O_EXCL) $file should fail"
21125                 $MULTIOP $file m && error "create $file should fail"
21126                 touch $DIR/$tdir/remote_dir/$tfile ||
21127                         error "touch $tfile failed"
21128                 ln $DIR/$tdir/remote_dir/$tfile $file &&
21129                         error "link $file should fail"
21130                 mdt_index=$($LFS getstripe -m $file)
21131                 if [ $mdt_index == 0 ]; then
21132                         # file failed to migrate is not allowed to rename to
21133                         mv $DIR/$tdir/remote_dir/$tfile $file &&
21134                                 error "rename to $file should fail"
21135                 else
21136                         mv $DIR/$tdir/remote_dir/$tfile $file ||
21137                                 error "rename to $file failed"
21138                 fi
21139                 echo hello >> $file || error "write $file failed"
21140         done
21141
21142         # resume migration with different options should fail
21143         $LFS migrate -m 0 $migrate_dir &&
21144                 error "migrate -m 0 $migrate_dir should fail"
21145
21146         $LFS migrate -m $MDTIDX -c 2 $migrate_dir &&
21147                 error "migrate -c 2 $migrate_dir should fail"
21148
21149         # resume migration should succeed
21150         $LFS migrate -m $MDTIDX $migrate_dir ||
21151                 error "migrate $migrate_dir failed"
21152
21153         echo "Finish migration, then checking.."
21154         for file in $(find $migrate_dir); do
21155                 mdt_index=$($LFS getstripe -m $file)
21156                 [ $mdt_index == $MDTIDX ] ||
21157                         error "$file is not on MDT${MDTIDX}"
21158         done
21159
21160         rm -rf $DIR/$tdir || error "rm dir failed after migration"
21161 }
21162 run_test 230c "check directory accessiblity if migration failed"
21163
21164 test_230d() {
21165         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21166         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21167         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21168                 skip "Need MDS version at least 2.11.52"
21169         # LU-11235
21170         [ "$mds1_FSTYPE" == "zfs" ] && skip "skip ZFS backend"
21171
21172         local migrate_dir=$DIR/$tdir/migrate_dir
21173         local old_index
21174         local new_index
21175         local old_count
21176         local new_count
21177         local new_hash
21178         local mdt_index
21179         local i
21180         local j
21181
21182         old_index=$((RANDOM % MDSCOUNT))
21183         old_count=$((MDSCOUNT - old_index))
21184         new_index=$((RANDOM % MDSCOUNT))
21185         new_count=$((MDSCOUNT - new_index))
21186         new_hash=1 # for all_char
21187
21188         [ $old_count -gt 1 ] && old_count=$((old_count - RANDOM % old_count))
21189         [ $new_count -gt 1 ] && new_count=$((new_count - RANDOM % new_count))
21190
21191         test_mkdir $DIR/$tdir
21192         test_mkdir -i $old_index -c $old_count $migrate_dir
21193
21194         for ((i=0; i<100; i++)); do
21195                 test_mkdir -i0 -c1 $migrate_dir/dir_${i}
21196                 createmany -o $migrate_dir/dir_${i}/f 100 ||
21197                         error "create files under remote dir failed $i"
21198         done
21199
21200         echo -n "Migrate from MDT$old_index "
21201         [ $old_count -gt 1 ] && echo -n "... MDT$((old_index + old_count - 1)) "
21202         echo -n "to MDT$new_index"
21203         [ $new_count -gt 1 ] && echo -n " ... MDT$((new_index + new_count - 1))"
21204         echo
21205
21206         echo "$LFS migrate -m$new_index -c$new_count -H $new_hash $migrate_dir"
21207         $LFS migrate -m $new_index -c $new_count -H $new_hash $migrate_dir ||
21208                 error "migrate remote dir error"
21209
21210         echo "Finish migration, then checking.."
21211         for file in $(find $migrate_dir -maxdepth 1); do
21212                 mdt_index=$($LFS getstripe -m $file)
21213                 if [ $mdt_index -lt $new_index ] ||
21214                    [ $mdt_index -gt $((new_index + new_count - 1)) ]; then
21215                         error "$file is on MDT$mdt_index"
21216                 fi
21217         done
21218
21219         rm -rf $DIR/$tdir || error "rm dir failed after migration"
21220 }
21221 run_test 230d "check migrate big directory"
21222
21223 test_230e() {
21224         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21225         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21226         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21227                 skip "Need MDS version at least 2.11.52"
21228
21229         local i
21230         local j
21231         local a_fid
21232         local b_fid
21233
21234         mkdir_on_mdt0 $DIR/$tdir
21235         mkdir $DIR/$tdir/migrate_dir
21236         mkdir $DIR/$tdir/other_dir
21237         touch $DIR/$tdir/migrate_dir/a
21238         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/b
21239         ls $DIR/$tdir/other_dir
21240
21241         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
21242                 error "migrate dir fails"
21243
21244         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
21245         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
21246
21247         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
21248         [ $mdt_index == 0 ] || error "a is not on MDT0"
21249
21250         $LFS migrate -m 1 $DIR/$tdir/other_dir ||
21251                 error "migrate dir fails"
21252
21253         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir)
21254         [ $mdt_index == 1 ] || error "other_dir is not on MDT1"
21255
21256         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
21257         [ $mdt_index == 1 ] || error "a is not on MDT1"
21258
21259         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir/b)
21260         [ $mdt_index == 1 ] || error "b is not on MDT1"
21261
21262         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
21263         b_fid=$($LFS path2fid $DIR/$tdir/other_dir/b)
21264
21265         [ "$a_fid" = "$b_fid" ] || error "different fid after migration"
21266
21267         rm -rf $DIR/$tdir || error "rm dir failed after migration"
21268 }
21269 run_test 230e "migrate mulitple local link files"
21270
21271 test_230f() {
21272         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21273         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21274         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21275                 skip "Need MDS version at least 2.11.52"
21276
21277         local a_fid
21278         local ln_fid
21279
21280         mkdir -p $DIR/$tdir
21281         mkdir $DIR/$tdir/migrate_dir
21282         $LFS mkdir -i1 $DIR/$tdir/other_dir
21283         touch $DIR/$tdir/migrate_dir/a
21284         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln1
21285         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln2
21286         ls $DIR/$tdir/other_dir
21287
21288         # a should be migrated to MDT1, since no other links on MDT0
21289         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
21290                 error "#1 migrate dir fails"
21291         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
21292         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
21293         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
21294         [ $mdt_index == 1 ] || error "a is not on MDT1"
21295
21296         # a should stay on MDT1, because it is a mulitple link file
21297         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
21298                 error "#2 migrate dir fails"
21299         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
21300         [ $mdt_index == 1 ] || error "a is not on MDT1"
21301
21302         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
21303                 error "#3 migrate dir fails"
21304
21305         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
21306         ln_fid=$($LFS path2fid $DIR/$tdir/other_dir/ln1)
21307         [ "$a_fid" = "$ln_fid" ] || error "different fid after migrate to MDT1"
21308
21309         rm -rf $DIR/$tdir/other_dir/ln1 || error "unlink ln1 fails"
21310         rm -rf $DIR/$tdir/other_dir/ln2 || error "unlink ln2 fails"
21311
21312         # a should be migrated to MDT0, since no other links on MDT1
21313         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
21314                 error "#4 migrate dir fails"
21315         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
21316         [ $mdt_index == 0 ] || error "a is not on MDT0"
21317
21318         rm -rf $DIR/$tdir || error "rm dir failed after migration"
21319 }
21320 run_test 230f "migrate mulitple remote link files"
21321
21322 test_230g() {
21323         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21324         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21325         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21326                 skip "Need MDS version at least 2.11.52"
21327
21328         mkdir -p $DIR/$tdir/migrate_dir
21329
21330         $LFS migrate -m 1000 $DIR/$tdir/migrate_dir &&
21331                 error "migrating dir to non-exist MDT succeeds"
21332         true
21333 }
21334 run_test 230g "migrate dir to non-exist MDT"
21335
21336 test_230h() {
21337         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21338         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21339         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21340                 skip "Need MDS version at least 2.11.52"
21341
21342         local mdt_index
21343
21344         mkdir -p $DIR/$tdir/migrate_dir
21345
21346         $LFS migrate -m1 $DIR &&
21347                 error "migrating mountpoint1 should fail"
21348
21349         $LFS migrate -m1 $DIR/$tdir/.. &&
21350                 error "migrating mountpoint2 should fail"
21351
21352         # same as mv
21353         $LFS migrate -m1 $DIR/$tdir/migrate_dir/.. &&
21354                 error "migrating $tdir/migrate_dir/.. should fail"
21355
21356         true
21357 }
21358 run_test 230h "migrate .. and root"
21359
21360 test_230i() {
21361         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21362         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21363         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21364                 skip "Need MDS version at least 2.11.52"
21365
21366         mkdir -p $DIR/$tdir/migrate_dir
21367
21368         $LFS migrate -m 1 $DIR/$tdir/migrate_dir/ ||
21369                 error "migration fails with a tailing slash"
21370
21371         $LFS migrate -m 0 $DIR/$tdir/migrate_dir// ||
21372                 error "migration fails with two tailing slashes"
21373 }
21374 run_test 230i "lfs migrate -m tolerates trailing slashes"
21375
21376 test_230j() {
21377         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
21378         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
21379                 skip "Need MDS version at least 2.11.52"
21380
21381         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
21382         $LFS setstripe -E 1M -L mdt $DIR/$tdir/$tfile ||
21383                 error "create $tfile failed"
21384         cat /etc/passwd > $DIR/$tdir/$tfile
21385
21386         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
21387
21388         cmp /etc/passwd $DIR/$tdir/$tfile ||
21389                 error "DoM file mismatch after migration"
21390 }
21391 run_test 230j "DoM file data not changed after dir migration"
21392
21393 test_230k() {
21394         [ $MDSCOUNT -lt 4 ] && skip "needs >= 4 MDTs"
21395         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
21396                 skip "Need MDS version at least 2.11.56"
21397
21398         local total=20
21399         local files_on_starting_mdt=0
21400
21401         $LFS mkdir -i -1 -c 2 $DIR/$tdir || error "mkdir failed"
21402         $LFS getdirstripe $DIR/$tdir
21403         for i in $(seq $total); do
21404                 echo $((i*i - i)) > $DIR/$tdir/$tfile.$i || error "write failed"
21405                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
21406                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
21407         done
21408
21409         echo "$files_on_starting_mdt files on MDT0"
21410
21411         $LFS migrate -m 1,3 $DIR/$tdir || error "migrate -m 1,3 failed"
21412         $LFS getdirstripe $DIR/$tdir
21413
21414         files_on_starting_mdt=0
21415         for i in $(seq $total); do
21416                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
21417                         error "file $tfile.$i mismatch after migration"
21418                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 1 ]] &&
21419                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
21420         done
21421
21422         echo "$files_on_starting_mdt files on MDT1 after migration"
21423         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT1"
21424
21425         $LFS migrate -m 0 -c 2 $DIR/$tdir || error "migrate -m 0 -c 2 failed"
21426         $LFS getdirstripe $DIR/$tdir
21427
21428         files_on_starting_mdt=0
21429         for i in $(seq $total); do
21430                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
21431                         error "file $tfile.$i mismatch after 2nd migration"
21432                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
21433                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
21434         done
21435
21436         echo "$files_on_starting_mdt files on MDT0 after 2nd migration"
21437         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT0"
21438
21439         true
21440 }
21441 run_test 230k "file data not changed after dir migration"
21442
21443 test_230l() {
21444         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
21445         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
21446                 skip "Need MDS version at least 2.11.56"
21447
21448         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir failed"
21449         createmany -o $DIR/$tdir/f___________________________________ 1000 ||
21450                 error "create files under remote dir failed $i"
21451         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
21452 }
21453 run_test 230l "readdir between MDTs won't crash"
21454
21455 test_230m() {
21456         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
21457         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
21458                 skip "Need MDS version at least 2.11.56"
21459
21460         local MDTIDX=1
21461         local mig_dir=$DIR/$tdir/migrate_dir
21462         local longstr="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
21463         local shortstr="b"
21464         local val
21465
21466         echo "Creating files and dirs with xattrs"
21467         test_mkdir $DIR/$tdir
21468         test_mkdir -i0 -c1 $mig_dir
21469         mkdir $mig_dir/dir
21470         setfattr -n user.attr1 -v $longstr $mig_dir/dir ||
21471                 error "cannot set xattr attr1 on dir"
21472         setfattr -n user.attr2 -v $shortstr $mig_dir/dir ||
21473                 error "cannot set xattr attr2 on dir"
21474         touch $mig_dir/dir/f0
21475         setfattr -n user.attr1 -v $longstr $mig_dir/dir/f0 ||
21476                 error "cannot set xattr attr1 on file"
21477         setfattr -n user.attr2 -v $shortstr $mig_dir/dir/f0 ||
21478                 error "cannot set xattr attr2 on file"
21479         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
21480         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
21481         [ "$val" = $longstr ] || error "xattr attr1 not set properly on dir"
21482         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
21483         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on dir"
21484         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
21485         [ "$val" = $longstr ] || error "xattr attr1 not set properly on file"
21486         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
21487         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on file"
21488
21489         echo "Migrating to MDT1"
21490         $LFS migrate -m $MDTIDX $mig_dir ||
21491                 error "fails on migrating dir to MDT1"
21492
21493         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
21494         echo "Checking xattrs"
21495         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
21496         [ "$val" = $longstr ] ||
21497                 error "expecting xattr1 $longstr on dir, found $val"
21498         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
21499         [ "$val" = $shortstr ] ||
21500                 error "expecting xattr2 $shortstr on dir, found $val"
21501         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
21502         [ "$val" = $longstr ] ||
21503                 error "expecting xattr1 $longstr on file, found $val"
21504         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
21505         [ "$val" = $shortstr ] ||
21506                 error "expecting xattr2 $shortstr on file, found $val"
21507 }
21508 run_test 230m "xattrs not changed after dir migration"
21509
21510 test_230n() {
21511         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
21512         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
21513                 skip "Need MDS version at least 2.13.53"
21514
21515         $LFS mkdir -i 0 $DIR/$tdir || error "mkdir $tdir failed"
21516         cat /etc/hosts > $DIR/$tdir/$tfile
21517         $LFS mirror extend -N1 $DIR/$tdir/$tfile || error "Mirroring failed"
21518         $LFS migrate -m 1 $DIR/$tdir || error "Migration failed"
21519
21520         cmp /etc/hosts $DIR/$tdir/$tfile ||
21521                 error "File data mismatch after migration"
21522 }
21523 run_test 230n "Dir migration with mirrored file"
21524
21525 test_230o() {
21526         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
21527         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
21528                 skip "Need MDS version at least 2.13.52"
21529
21530         local mdts=$(comma_list $(mdts_nodes))
21531         local timeout=100
21532         local restripe_status
21533         local delta
21534         local i
21535
21536         [[ $mds1_FSTYPE == zfs ]] && timeout=300
21537
21538         # in case "crush" hash type is not set
21539         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
21540
21541         restripe_status=$(do_facet mds1 $LCTL get_param -n \
21542                            mdt.*MDT0000.enable_dir_restripe)
21543         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
21544         stack_trap "do_nodes $mdts $LCTL set_param \
21545                     mdt.*.enable_dir_restripe=$restripe_status"
21546
21547         mkdir $DIR/$tdir
21548         createmany -m $DIR/$tdir/f 100 ||
21549                 error "create files under remote dir failed $i"
21550         createmany -d $DIR/$tdir/d 100 ||
21551                 error "create dirs under remote dir failed $i"
21552
21553         for i in $(seq 2 $MDSCOUNT); do
21554                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
21555                 $LFS setdirstripe -c $i $DIR/$tdir ||
21556                         error "split -c $i $tdir failed"
21557                 wait_update $HOSTNAME \
21558                         "$LFS getdirstripe -H $DIR/$tdir" "crush" $timeout ||
21559                         error "dir split not finished"
21560                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
21561                         awk '/migrate/ {sum += $2} END { print sum }')
21562                 echo "$delta migrated when dir split $((i - 1)) to $i stripes"
21563                 # delta is around total_files/stripe_count
21564                 (( $delta < 200 / (i - 1) + 4 )) ||
21565                         error "$delta files migrated >= $((200 / (i - 1) + 4))"
21566         done
21567 }
21568 run_test 230o "dir split"
21569
21570 test_230p() {
21571         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
21572         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
21573                 skip "Need MDS version at least 2.13.52"
21574
21575         local mdts=$(comma_list $(mdts_nodes))
21576         local timeout=100
21577         local restripe_status
21578         local delta
21579         local c
21580
21581         [[ $mds1_FSTYPE == zfs ]] && timeout=300
21582
21583         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
21584
21585         restripe_status=$(do_facet mds1 $LCTL get_param -n \
21586                            mdt.*MDT0000.enable_dir_restripe)
21587         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
21588         stack_trap "do_nodes $mdts $LCTL set_param \
21589                     mdt.*.enable_dir_restripe=$restripe_status"
21590
21591         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir
21592         createmany -m $DIR/$tdir/f 100 ||
21593                 error "create files under remote dir failed"
21594         createmany -d $DIR/$tdir/d 100 ||
21595                 error "create dirs under remote dir failed"
21596
21597         for c in $(seq $((MDSCOUNT - 1)) -1 1); do
21598                 local mdt_hash="crush"
21599
21600                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
21601                 $LFS setdirstripe -c $c $DIR/$tdir ||
21602                         error "split -c $c $tdir failed"
21603                 if (( MDS1_VERSION >= $(version_code 2.14.51) )); then
21604                         mdt_hash="$mdt_hash,fixed"
21605                 elif [ $c -eq 1 ]; then
21606                         mdt_hash="none"
21607                 fi
21608                 wait_update $HOSTNAME \
21609                         "$LFS getdirstripe -H $DIR/$tdir" $mdt_hash $timeout ||
21610                         error "dir merge not finished"
21611                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
21612                         awk '/migrate/ {sum += $2} END { print sum }')
21613                 echo "$delta migrated when dir merge $((c + 1)) to $c stripes"
21614                 # delta is around total_files/stripe_count
21615                 (( delta < 200 / c + 4 )) ||
21616                         error "$delta files migrated >= $((200 / c + 4))"
21617         done
21618 }
21619 run_test 230p "dir merge"
21620
21621 test_230q() {
21622         (( MDSCOUNT > 1)) || skip "needs >= 2 MDTs"
21623         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
21624                 skip "Need MDS version at least 2.13.52"
21625
21626         local mdts=$(comma_list $(mdts_nodes))
21627         local saved_threshold=$(do_facet mds1 \
21628                         $LCTL get_param -n mdt.*-MDT0000.dir_split_count)
21629         local saved_delta=$(do_facet mds1 \
21630                         $LCTL get_param -n mdt.*-MDT0000.dir_split_delta)
21631         local threshold=100
21632         local delta=2
21633         local total=0
21634         local stripe_count=0
21635         local stripe_index
21636         local nr_files
21637         local create
21638
21639         # test with fewer files on ZFS
21640         [ "$mds1_FSTYPE" == "zfs" ] && threshold=40
21641
21642         stack_trap "do_nodes $mdts $LCTL set_param \
21643                     mdt.*.dir_split_count=$saved_threshold"
21644         stack_trap "do_nodes $mdts $LCTL set_param \
21645                     mdt.*.dir_split_delta=$saved_delta"
21646         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.dir_restripe_nsonly=1"
21647         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_auto_split=1"
21648         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_count=$threshold"
21649         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_delta=$delta"
21650         do_nodes $mdts "$LCTL set_param mdt.*.dir_restripe_nsonly=0"
21651         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
21652
21653         $LFS mkdir -i -1 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
21654         stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
21655
21656         create=$((threshold * 3 / 2))
21657         while [ $stripe_count -lt $MDSCOUNT ]; do
21658                 createmany -m $DIR/$tdir/f $total $create ||
21659                         error "create sub files failed"
21660                 stat $DIR/$tdir > /dev/null
21661                 total=$((total + create))
21662                 stripe_count=$((stripe_count + delta))
21663                 [ $stripe_count -gt $MDSCOUNT ] && stripe_count=$MDSCOUNT
21664
21665                 wait_update $HOSTNAME \
21666                         "$LFS getdirstripe -c $DIR/$tdir" "$stripe_count" 40 ||
21667                         error "stripe count $($LFS getdirstripe -c $DIR/$tdir) != $stripe_count"
21668
21669                 wait_update $HOSTNAME \
21670                         "$LFS getdirstripe -H $DIR/$tdir" "crush" 200 ||
21671                         error "stripe hash $($LFS getdirstripe -H $DIR/$tdir) != crush"
21672
21673                 nr_files=$($LFS find -m 1 $DIR/$tdir | grep -c -w $stripe_index)
21674                 echo "$nr_files/$total files on MDT$stripe_index after split"
21675                 # allow 10% margin of imbalance with crush hash
21676                 (( $nr_files <= $total / $stripe_count + $create / 10)) ||
21677                         error "$nr_files files on MDT$stripe_index after split"
21678
21679                 nr_files=$($LFS find -type f $DIR/$tdir | wc -l)
21680                 [ $nr_files -eq $total ] ||
21681                         error "total sub files $nr_files != $total"
21682         done
21683
21684         (( MDS1_VERSION >= $(version_code 2.14.51) )) || return 0
21685
21686         echo "fixed layout directory won't auto split"
21687         $LFS migrate -m 0 $DIR/$tdir || error "migrate $tdir failed"
21688         wait_update $HOSTNAME "$LFS getdirstripe -H $DIR/$tdir" "crush,fixed" \
21689                 10 || error "stripe hash $($LFS getdirstripe -H $DIR/$tdir)"
21690         wait_update $HOSTNAME "$LFS getdirstripe -c $DIR/$tdir" 1 10 ||
21691                 error "stripe count $($LFS getdirstripe -c $DIR/$tdir)"
21692 }
21693 run_test 230q "dir auto split"
21694
21695 test_230r() {
21696         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
21697         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
21698         [[ $MDS1_VERSION -ge $(version_code 2.13.54) ]] ||
21699                 skip "Need MDS version at least 2.13.54"
21700
21701         # maximum amount of local locks:
21702         # parent striped dir - 2 locks
21703         # new stripe in parent to migrate to - 1 lock
21704         # source and target - 2 locks
21705         # Total 5 locks for regular file
21706         mkdir -p $DIR/$tdir
21707         $LFS mkdir -i1 -c2 $DIR/$tdir/dir1
21708         touch $DIR/$tdir/dir1/eee
21709
21710         # create 4 hardlink for 4 more locks
21711         # Total: 9 locks > RS_MAX_LOCKS (8)
21712         $LFS mkdir -i1 -c1 $DIR/$tdir/dir2
21713         $LFS mkdir -i1 -c1 $DIR/$tdir/dir3
21714         $LFS mkdir -i1 -c1 $DIR/$tdir/dir4
21715         $LFS mkdir -i1 -c1 $DIR/$tdir/dir5
21716         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir2/eee
21717         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir3/eee
21718         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir4/eee
21719         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir5/eee
21720
21721         cancel_lru_locks mdc
21722
21723         $LFS migrate -m1 -c1 $DIR/$tdir/dir1 ||
21724                 error "migrate dir fails"
21725
21726         rm -rf $DIR/$tdir || error "rm dir failed after migration"
21727 }
21728 run_test 230r "migrate with too many local locks"
21729
21730 test_230s() {
21731         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
21732                 skip "Need MDS version at least 2.14.52"
21733
21734         local mdts=$(comma_list $(mdts_nodes))
21735         local restripe_status=$(do_facet mds1 $LCTL get_param -n \
21736                                 mdt.*MDT0000.enable_dir_restripe)
21737
21738         stack_trap "do_nodes $mdts $LCTL set_param \
21739                     mdt.*.enable_dir_restripe=$restripe_status"
21740
21741         local st
21742         for st in 0 1; do
21743                 do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=$st"
21744                 test_mkdir $DIR/$tdir
21745                 $LFS mkdir $DIR/$tdir |& grep "File exists" ||
21746                         error "$LFS mkdir should return EEXIST if target exists"
21747                 rmdir $DIR/$tdir
21748         done
21749 }
21750 run_test 230s "lfs mkdir should return -EEXIST if target exists"
21751
21752 test_230t()
21753 {
21754         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
21755         [[ $MDS1_VERSION -ge $(version_code 2.14.50) ]] ||
21756                 skip "Need MDS version at least 2.14.50"
21757
21758         test_mkdir $DIR/$tdir || error "mkdir $tdir failed"
21759         test_mkdir $DIR/$tdir/subdir || error "mkdir subdir failed"
21760         $LFS project -p 1 -s $DIR/$tdir ||
21761                 error "set $tdir project id failed"
21762         $LFS project -p 2 -s $DIR/$tdir/subdir ||
21763                 error "set subdir project id failed"
21764         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir || error "migrate failed"
21765 }
21766 run_test 230t "migrate directory with project ID set"
21767
21768 test_230u()
21769 {
21770         (( MDSCOUNT > 3 )) || skip_env "needs >= 4 MDTs"
21771         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
21772                 skip "Need MDS version at least 2.14.53"
21773
21774         local count
21775
21776         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
21777         mkdir $DIR/$tdir/sub{0..99} || error "mkdir sub failed"
21778         $LFS migrate -m -1 $DIR/$tdir/sub{0..99} || error "migrate sub failed"
21779         for i in $(seq 0 $((MDSCOUNT - 1))); do
21780                 count=$($LFS getstripe -m $DIR/$tdir/sub* | grep -c ^$i)
21781                 echo "$count dirs migrated to MDT$i"
21782         done
21783         count=$($LFS getstripe -m $DIR/$tdir/sub* | sort -u | wc -l)
21784         (( count >= MDSCOUNT - 1 )) || error "dirs migrated to $count MDTs"
21785 }
21786 run_test 230u "migrate directory by QOS"
21787
21788 test_230v()
21789 {
21790         (( MDSCOUNT > 3 )) || skip_env "needs >= 4 MDTs"
21791         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
21792                 skip "Need MDS version at least 2.14.53"
21793
21794         local count
21795
21796         mkdir $DIR/$tdir || error "mkdir $tdir failed"
21797         mkdir $DIR/$tdir/sub{0..99} || error "mkdir sub failed"
21798         $LFS migrate -m 0,2,1 $DIR/$tdir || error "migrate $tdir failed"
21799         for i in $(seq 0 $((MDSCOUNT - 1))); do
21800                 count=$($LFS getstripe -m $DIR/$tdir/sub* | grep -c ^$i)
21801                 echo "$count subdirs migrated to MDT$i"
21802                 (( i == 3 )) && (( count > 0 )) &&
21803                         error "subdir shouldn't be migrated to MDT3"
21804         done
21805         count=$($LFS getstripe -m $DIR/$tdir/sub* | sort -u | wc -l)
21806         (( count == 3 )) || error "dirs migrated to $count MDTs"
21807 }
21808 run_test 230v "subdir migrated to the MDT where its parent is located"
21809
21810 test_230w() {
21811         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
21812         (( MDS1_VERSION >= $(version_code 2.15.0) )) ||
21813                 skip "Need MDS version at least 2.15.0"
21814
21815         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
21816         createmany -o $DIR/$tdir/f 10 || error "create files failed"
21817         createmany -d $DIR/$tdir/d 10 || error "create dirs failed"
21818
21819         $LFS migrate -m 1 -c $MDSCOUNT -d $DIR/$tdir ||
21820                 error "migrate failed"
21821
21822         (( $($LFS getdirstripe -c $DIR/$tdir) == MDSCOUNT )) ||
21823                 error "$tdir stripe count mismatch"
21824
21825         for i in $(seq 0 9); do
21826                 (( $($LFS getdirstripe -c $DIR/$tdir/d$i) == 0 )) ||
21827                         error "d$i is striped"
21828         done
21829 }
21830 run_test 230w "non-recursive mode dir migration"
21831
21832 test_230x() {
21833         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
21834         (( MDS1_VERSION >= $(version_code 2.15.0) )) ||
21835                 skip "Need MDS version at least 2.15.0"
21836
21837         mkdir -p $DIR/$tdir || error "mkdir failed"
21838         createmany -d $DIR/$tdir/sub 100 || error "createmany failed"
21839
21840         local mdt_name=$(mdtname_from_index 0)
21841         local low=$(do_facet mds2 $LCTL get_param -n \
21842                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low)
21843         local high=$(do_facet mds2 $LCTL get_param -n \
21844                 osp.*$mdt_name-osp-MDT0001.reserved_ino_high)
21845         local ffree=$($LFS df -i $MOUNT | awk "/$mdt_name/ { print \$4 }")
21846         local maxage=$(do_facet mds2 $LCTL get_param -n \
21847                 osp.*$mdt_name-osp-MDT0001.maxage)
21848
21849         stack_trap "do_facet mds2 $LCTL set_param -n \
21850                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low=$low \
21851                 osp.*$mdt_name-osp-MDT0001.reserved_ino_high=$high" EXIT
21852         stack_trap "do_facet mds2 $LCTL set_param -n \
21853                 osp.*$mdt_name-osp-MDT0001.maxage=$maxage" EXIT
21854
21855         do_facet mds2 $LCTL set_param -n \
21856                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low=$((ffree + 1))
21857         do_facet mds2 $LCTL set_param -n osp.*$mdt_name-osp-MDT0001.maxage=1
21858         sleep 4
21859         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir &&
21860                 error "migrate $tdir should fail"
21861
21862         do_facet mds2 $LCTL set_param -n \
21863                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low=$low
21864         do_facet mds2 $LCTL set_param -n \
21865                 osp.*$mdt_name-osp-MDT0001.reserved_ino_high=$high
21866         sleep 4
21867         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir ||
21868                 error "migrate failed"
21869         (( $($LFS getdirstripe -c $DIR/$tdir) == $MDSCOUNT )) ||
21870                 error "$tdir stripe count mismatch"
21871 }
21872 run_test 230x "dir migration check space"
21873
21874 test_230y() {
21875         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
21876         (( MDS1_VERSION >= $(version_code 2.15.55.45) )) ||
21877                 skip "Need MDS version at least 2.15.55.45"
21878
21879         local pid
21880
21881         test_mkdir -c -1 $DIR/$tdir || error "mkdir $tdir failed"
21882         $LFS getdirstripe $DIR/$tdir
21883         createmany -d $DIR/$tdir/d 100 || error "createmany failed"
21884         $LFS migrate -m 1 -c 2 $DIR/$tdir &
21885         pid=$!
21886         sleep 1
21887
21888         #OBD_FAIL_MIGRATE_BAD_HASH      0x1802
21889         do_facet mds2 lctl set_param fail_loc=0x1802
21890
21891         wait $pid
21892         do_facet mds2 lctl set_param fail_loc=0
21893         $LFS getdirstripe $DIR/$tdir
21894         unlinkmany -d $DIR/$tdir/d 100 || error "unlinkmany failed"
21895         rmdir $DIR/$tdir || error "rmdir $tdir failed"
21896 }
21897 run_test 230y "unlink dir with bad hash type"
21898
21899 test_230z() {
21900         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
21901         (( MDS1_VERSION >= $(version_code 2.15.55.45) )) ||
21902                 skip "Need MDS version at least 2.15.55.45"
21903
21904         local pid
21905
21906         test_mkdir -c -1 $DIR/$tdir || error "mkdir $tdir failed"
21907         $LFS getdirstripe $DIR/$tdir
21908         createmany -d $DIR/$tdir/d 100 || error "createmany failed"
21909         $LFS migrate -m 1 -c 2 -H fnv_1a_64 $DIR/$tdir &
21910         pid=$!
21911         sleep 1
21912
21913         #OBD_FAIL_MIGRATE_BAD_HASH      0x1802
21914         do_facet mds2 lctl set_param fail_loc=0x1802
21915
21916         wait $pid
21917         do_facet mds2 lctl set_param fail_loc=0
21918         $LFS getdirstripe $DIR/$tdir
21919
21920         # resume migration
21921         $LFS migrate -m 1 -c 2 -H fnv_1a_64 $DIR/$tdir ||
21922                 error "resume migration failed"
21923         $LFS getdirstripe $DIR/$tdir
21924         [ $($LFS getdirstripe -H $DIR/$tdir) == "fnv_1a_64,fixed" ] ||
21925                 error "migration is not finished"
21926 }
21927 run_test 230z "resume dir migration with bad hash type"
21928
21929 test_231a()
21930 {
21931         # For simplicity this test assumes that max_pages_per_rpc
21932         # is the same across all OSCs
21933         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
21934         local bulk_size=$((max_pages * PAGE_SIZE))
21935         local brw_size=$(do_facet ost1 $LCTL get_param -n obdfilter.*.brw_size |
21936                                        head -n 1)
21937
21938         mkdir -p $DIR/$tdir
21939         $LFS setstripe -S ${brw_size}M $DIR/$tdir ||
21940                 error "failed to set stripe with -S ${brw_size}M option"
21941         stack_trap "rm -rf $DIR/$tdir"
21942
21943         # clear the OSC stats
21944         $LCTL set_param osc.*.stats=0 &>/dev/null
21945         stop_writeback
21946
21947         # Client writes $bulk_size - there must be 1 rpc for $max_pages.
21948         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=$bulk_size count=1 \
21949                 oflag=direct &>/dev/null || error "dd failed"
21950
21951         sync; sleep 1; sync # just to be safe
21952         local nrpcs=$($LCTL get_param osc.*.stats |awk '/ost_write/ {print $2}')
21953         if [ x$nrpcs != "x1" ]; then
21954                 $LCTL get_param osc.*.stats
21955                 error "found $nrpcs ost_write RPCs, not 1 as expected"
21956         fi
21957
21958         start_writeback
21959         # Drop the OSC cache, otherwise we will read from it
21960         cancel_lru_locks osc
21961
21962         # clear the OSC stats
21963         $LCTL set_param osc.*.stats=0 &>/dev/null
21964
21965         # Client reads $bulk_size.
21966         dd if=$DIR/$tdir/$tfile of=/dev/null bs=$bulk_size count=1 \
21967                 iflag=direct &>/dev/null || error "dd failed"
21968
21969         nrpcs=$($LCTL get_param osc.*.stats | awk '/ost_read/ { print $2 }')
21970         if [ x$nrpcs != "x1" ]; then
21971                 $LCTL get_param osc.*.stats
21972                 error "found $nrpcs ost_read RPCs, not 1 as expected"
21973         fi
21974 }
21975 run_test 231a "checking that reading/writing of BRW RPC size results in one RPC"
21976
21977 test_231b() {
21978         mkdir -p $DIR/$tdir
21979         stack_trap "rm -rf $DIR/$tdir"
21980         local i
21981         for i in {0..1023}; do
21982                 dd if=/dev/zero of=$DIR/$tdir/$tfile conv=notrunc \
21983                         seek=$((2 * i)) bs=4096 count=1 &>/dev/null ||
21984                         error "dd of=$DIR/$tdir/$tfile seek=$((2 * i)) failed"
21985         done
21986         sync
21987 }
21988 run_test 231b "must not assert on fully utilized OST request buffer"
21989
21990 test_232a() {
21991         mkdir -p $DIR/$tdir
21992         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
21993
21994         #define OBD_FAIL_LDLM_OST_LVB            0x31c
21995         do_facet ost1 $LCTL set_param fail_loc=0x31c
21996
21997         # ignore dd failure
21998         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1 || true
21999         stack_trap "rm -f $DIR/$tdir/$tfile"
22000
22001         do_facet ost1 $LCTL set_param fail_loc=0
22002         umount_client $MOUNT || error "umount failed"
22003         mount_client $MOUNT || error "mount failed"
22004         stop ost1 || error "cannot stop ost1"
22005         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
22006 }
22007 run_test 232a "failed lock should not block umount"
22008
22009 test_232b() {
22010         [ $MDS1_VERSION -ge $(version_code 2.10.58) ] ||
22011                 skip "Need MDS version at least 2.10.58"
22012
22013         mkdir -p $DIR/$tdir
22014         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
22015         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1
22016         stack_trap "rm -f $DIR/$tdir/$tfile"
22017         sync
22018         cancel_lru_locks osc
22019
22020         #define OBD_FAIL_LDLM_OST_LVB            0x31c
22021         do_facet ost1 $LCTL set_param fail_loc=0x31c
22022
22023         # ignore failure
22024         $LFS data_version $DIR/$tdir/$tfile || true
22025
22026         do_facet ost1 $LCTL set_param fail_loc=0
22027         umount_client $MOUNT || error "umount failed"
22028         mount_client $MOUNT || error "mount failed"
22029         stop ost1 || error "cannot stop ost1"
22030         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
22031 }
22032 run_test 232b "failed data version lock should not block umount"
22033
22034 test_233a() {
22035         [ $MDS1_VERSION -ge $(version_code 2.3.64) ] ||
22036                 skip "Need MDS version at least 2.3.64"
22037         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
22038
22039         local fid=$($LFS path2fid $MOUNT)
22040
22041         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
22042                 error "cannot access $MOUNT using its FID '$fid'"
22043 }
22044 run_test 233a "checking that OBF of the FS root succeeds"
22045
22046 test_233b() {
22047         [ $MDS1_VERSION -ge $(version_code 2.5.90) ] ||
22048                 skip "Need MDS version at least 2.5.90"
22049         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
22050
22051         local fid=$($LFS path2fid $MOUNT/.lustre)
22052
22053         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
22054                 error "cannot access $MOUNT/.lustre using its FID '$fid'"
22055
22056         fid=$($LFS path2fid $MOUNT/.lustre/fid)
22057         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
22058                 error "cannot access $MOUNT/.lustre/fid using its FID '$fid'"
22059 }
22060 run_test 233b "checking that OBF of the FS .lustre succeeds"
22061
22062 test_234() {
22063         local p="$TMP/sanityN-$TESTNAME.parameters"
22064         save_lustre_params client "llite.*.xattr_cache" > $p
22065         lctl set_param llite.*.xattr_cache 1 ||
22066                 skip_env "xattr cache is not supported"
22067
22068         mkdir -p $DIR/$tdir || error "mkdir failed"
22069         touch $DIR/$tdir/$tfile || error "touch failed"
22070         # OBD_FAIL_LLITE_XATTR_ENOMEM
22071         $LCTL set_param fail_loc=0x1405
22072         getfattr -n user.attr $DIR/$tdir/$tfile &&
22073                 error "getfattr should have failed with ENOMEM"
22074         $LCTL set_param fail_loc=0x0
22075         rm -rf $DIR/$tdir
22076
22077         restore_lustre_params < $p
22078         rm -f $p
22079 }
22080 run_test 234 "xattr cache should not crash on ENOMEM"
22081
22082 test_235() {
22083         [ $MDS1_VERSION -lt $(version_code 2.4.52) ] &&
22084                 skip "Need MDS version at least 2.4.52"
22085
22086         flock_deadlock $DIR/$tfile
22087         local RC=$?
22088         case $RC in
22089                 0)
22090                 ;;
22091                 124) error "process hangs on a deadlock"
22092                 ;;
22093                 *) error "error executing flock_deadlock $DIR/$tfile"
22094                 ;;
22095         esac
22096 }
22097 run_test 235 "LU-1715: flock deadlock detection does not work properly"
22098
22099 #LU-2935
22100 test_236() {
22101         check_swap_layouts_support
22102
22103         local ref1=/etc/passwd
22104         local ref2=/etc/group
22105         local file1=$DIR/$tdir/f1
22106         local file2=$DIR/$tdir/f2
22107
22108         test_mkdir -c1 $DIR/$tdir
22109         $LFS setstripe -c 1 $file1 || error "cannot setstripe on '$file1': rc = $?"
22110         cp $ref1 $file1 || error "cp $ref1 $file1 failed: rc = $?"
22111         $LFS setstripe -c 2 $file2 || error "cannot setstripe on '$file2': rc = $?"
22112         cp $ref2 $file2 || error "cp $ref2 $file2 failed: rc = $?"
22113         local fd=$(free_fd)
22114         local cmd="exec $fd<>$file2"
22115         eval $cmd
22116         rm $file2
22117         $LFS swap_layouts $file1 /proc/self/fd/${fd} ||
22118                 error "cannot swap layouts of '$file1' and /proc/self/fd/${fd}"
22119         cmd="exec $fd>&-"
22120         eval $cmd
22121         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
22122
22123         #cleanup
22124         rm -rf $DIR/$tdir
22125 }
22126 run_test 236 "Layout swap on open unlinked file"
22127
22128 # LU-4659 linkea consistency
22129 test_238() {
22130         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
22131                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
22132                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
22133                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
22134
22135         touch $DIR/$tfile
22136         ln $DIR/$tfile $DIR/$tfile.lnk
22137         touch $DIR/$tfile.new
22138         mv $DIR/$tfile.new $DIR/$tfile
22139         local fid1=$($LFS path2fid $DIR/$tfile)
22140         local fid2=$($LFS path2fid $DIR/$tfile.lnk)
22141         local path1=$($LFS fid2path $FSNAME "$fid1")
22142         [ $tfile == $path1 ] || error "linkea inconsistent: $tfile $fid1 $path1"
22143         local path2=$($LFS fid2path $FSNAME "$fid2")
22144         [ $tfile.lnk == $path2 ] ||
22145                 error "linkea inconsistent: $tfile.lnk $fid2 $path2!"
22146         rm -f $DIR/$tfile*
22147 }
22148 run_test 238 "Verify linkea consistency"
22149
22150 test_239A() { # was test_239
22151         [ $MDS1_VERSION -lt $(version_code 2.5.60) ] &&
22152                 skip "Need MDS version at least 2.5.60"
22153
22154         local list=$(comma_list $(mdts_nodes))
22155
22156         mkdir -p $DIR/$tdir
22157         createmany -o $DIR/$tdir/f- 5000
22158         unlinkmany $DIR/$tdir/f- 5000
22159         [ $MDS1_VERSION -gt $(version_code 2.10.4) ] &&
22160                 do_nodes $list "lctl set_param -n osp.*.force_sync=1"
22161         changes=$(do_nodes $list "lctl get_param -n osp.*MDT*.sync_changes \
22162                         osp.*MDT*.sync_in_flight" | calc_sum)
22163         [ "$changes" -eq 0 ] || error "$changes not synced"
22164 }
22165 run_test 239A "osp_sync test"
22166
22167 test_239a() { #LU-5297
22168         remote_mds_nodsh && skip "remote MDS with nodsh"
22169
22170         touch $DIR/$tfile
22171         #define OBD_FAIL_OSP_CHECK_INVALID_REC     0x2100
22172         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2100
22173         chgrp $RUNAS_GID $DIR/$tfile
22174         wait_delete_completed
22175 }
22176 run_test 239a "process invalid osp sync record correctly"
22177
22178 test_239b() { #LU-5297
22179         remote_mds_nodsh && skip "remote MDS with nodsh"
22180
22181         touch $DIR/$tfile1
22182         #define OBD_FAIL_OSP_CHECK_ENOMEM     0x2101
22183         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2101
22184         chgrp $RUNAS_GID $DIR/$tfile1
22185         wait_delete_completed
22186         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
22187         touch $DIR/$tfile2
22188         chgrp $RUNAS_GID $DIR/$tfile2
22189         wait_delete_completed
22190 }
22191 run_test 239b "process osp sync record with ENOMEM error correctly"
22192
22193 test_240() {
22194         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22195         remote_mds_nodsh && skip "remote MDS with nodsh"
22196
22197         mkdir -p $DIR/$tdir
22198
22199         $LFS mkdir -i 0 $DIR/$tdir/d0 ||
22200                 error "failed to mkdir $DIR/$tdir/d0 on MDT0"
22201         $LFS mkdir -i 1 $DIR/$tdir/d0/d1 ||
22202                 error "failed to mkdir $DIR/$tdir/d0/d1 on MDT1"
22203
22204         umount_client $MOUNT || error "umount failed"
22205         #define OBD_FAIL_TGT_DELAY_CONDITIONAL   0x713
22206         do_facet mds2 lctl set_param fail_loc=0x713 fail_val=1
22207         mount_client $MOUNT || error "failed to mount client"
22208
22209         echo "stat $DIR/$tdir/d0/d1, should not fail/ASSERT"
22210         stat $DIR/$tdir/d0/d1 || error "fail to stat $DIR/$tdir/d0/d1"
22211 }
22212 run_test 240 "race between ldlm enqueue and the connection RPC (no ASSERT)"
22213
22214 test_241_bio() {
22215         local count=$1
22216         local bsize=$2
22217
22218         for LOOP in $(seq $count); do
22219                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 2>/dev/null
22220                 cancel_lru_locks $OSC || true
22221         done
22222 }
22223
22224 test_241_dio() {
22225         local count=$1
22226         local bsize=$2
22227
22228         for LOOP in $(seq $1); do
22229                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 iflag=direct \
22230                         2>/dev/null
22231         done
22232 }
22233
22234 test_241a() { # was test_241
22235         local bsize=$PAGE_SIZE
22236
22237         (( bsize < 40960 )) && bsize=40960
22238         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
22239         ls -la $DIR/$tfile
22240         cancel_lru_locks $OSC
22241         test_241_bio 1000 $bsize &
22242         PID=$!
22243         test_241_dio 1000 $bsize
22244         wait $PID
22245 }
22246 run_test 241a "bio vs dio"
22247
22248 test_241b() {
22249         local bsize=$PAGE_SIZE
22250
22251         (( bsize < 40960 )) && bsize=40960
22252         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
22253         ls -la $DIR/$tfile
22254         test_241_dio 1000 $bsize &
22255         PID=$!
22256         test_241_dio 1000 $bsize
22257         wait $PID
22258 }
22259 run_test 241b "dio vs dio"
22260
22261 test_242() {
22262         remote_mds_nodsh && skip "remote MDS with nodsh"
22263
22264         mkdir_on_mdt0 $DIR/$tdir
22265         touch $DIR/$tdir/$tfile
22266
22267         #define OBD_FAIL_MDS_READPAGE_PACK      0x105
22268         do_facet mds1 lctl set_param fail_loc=0x105
22269         /bin/ls $DIR/$tdir && error "ls $DIR/$tdir should fail"
22270
22271         do_facet mds1 lctl set_param fail_loc=0
22272         /bin/ls $DIR/$tdir || error "ls $DIR/$tdir failed"
22273 }
22274 run_test 242 "mdt_readpage failure should not cause directory unreadable"
22275
22276 test_243()
22277 {
22278         test_mkdir $DIR/$tdir
22279         group_lock_test -d $DIR/$tdir || error "A group lock test failed"
22280 }
22281 run_test 243 "various group lock tests"
22282
22283 test_244a()
22284 {
22285         test_mkdir $DIR/$tdir
22286         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=35
22287         sendfile_grouplock $DIR/$tdir/$tfile || \
22288                 error "sendfile+grouplock failed"
22289         rm -rf $DIR/$tdir
22290 }
22291 run_test 244a "sendfile with group lock tests"
22292
22293 test_244b()
22294 {
22295         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
22296
22297         local threads=50
22298         local size=$((1024*1024))
22299
22300         test_mkdir $DIR/$tdir
22301         for i in $(seq 1 $threads); do
22302                 local file=$DIR/$tdir/file_$((i / 10))
22303                 $MULTIOP $file OG1234w$size_$((i % 3))w$size_$((i % 4))g1234c &
22304                 local pids[$i]=$!
22305         done
22306         for i in $(seq 1 $threads); do
22307                 wait ${pids[$i]}
22308         done
22309 }
22310 run_test 244b "multi-threaded write with group lock"
22311
22312 test_245a() {
22313         local flagname="multi_mod_rpcs"
22314         local connect_data_name="max_mod_rpcs"
22315         local out
22316
22317         # check if multiple modify RPCs flag is set
22318         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import |
22319                 grep "connect_flags:")
22320         echo "$out"
22321
22322         echo "$out" | grep -qw $flagname
22323         if [ $? -ne 0 ]; then
22324                 echo "connect flag $flagname is not set"
22325                 return
22326         fi
22327
22328         # check if multiple modify RPCs data is set
22329         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import)
22330         echo "$out"
22331
22332         echo "$out" | grep -qw $connect_data_name ||
22333                 error "import should have connect data $connect_data_name"
22334 }
22335 run_test 245a "check mdc connection flag/data: multiple modify RPCs"
22336
22337 test_245b() {
22338         local flagname="multi_mod_rpcs"
22339         local connect_data_name="max_mod_rpcs"
22340         local out
22341
22342         remote_mds_nodsh && skip "remote MDS with nodsh"
22343         [[ $MDSCOUNT -ge 2 ]] || skip "needs >= 2 MDTs"
22344
22345         # check if multiple modify RPCs flag is set
22346         out=$(do_facet mds1 \
22347               $LCTL get_param osp.$FSNAME-MDT0001-osp-MDT0000.import |
22348               grep "connect_flags:")
22349         echo "$out"
22350
22351         [[ "$out" =~ $flagname ]] || skip "connect flag $flagname is not set"
22352
22353         # check if multiple modify RPCs data is set
22354         out=$(do_facet mds1 \
22355               $LCTL get_param osp.$FSNAME-MDT0001-osp-MDT0000.import)
22356
22357         [[ "$out" =~ $connect_data_name ]] ||
22358                 {
22359                         echo "$out"
22360                         error "missing connect data $connect_data_name"
22361                 }
22362 }
22363 run_test 245b "check osp connection flag/data: multiple modify RPCs"
22364
22365 cleanup_247() {
22366         local submount=$1
22367
22368         trap 0
22369         umount_client $submount
22370         rmdir $submount
22371 }
22372
22373 test_247a() {
22374         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
22375                 grep -q subtree ||
22376                 skip_env "Fileset feature is not supported"
22377
22378         local submount=${MOUNT}_$tdir
22379
22380         mkdir $MOUNT/$tdir
22381         mkdir -p $submount || error "mkdir $submount failed"
22382         FILESET="$FILESET/$tdir" mount_client $submount ||
22383                 error "mount $submount failed"
22384         trap "cleanup_247 $submount" EXIT
22385         echo foo > $submount/$tfile || error "write $submount/$tfile failed"
22386         [ $(cat $MOUNT/$tdir/$tfile) = "foo" ] ||
22387                 error "read $MOUNT/$tdir/$tfile failed"
22388         cleanup_247 $submount
22389 }
22390 run_test 247a "mount subdir as fileset"
22391
22392 test_247b() {
22393         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
22394                 skip_env "Fileset feature is not supported"
22395
22396         local submount=${MOUNT}_$tdir
22397
22398         rm -rf $MOUNT/$tdir
22399         mkdir -p $submount || error "mkdir $submount failed"
22400         SKIP_FILESET=1
22401         FILESET="$FILESET/$tdir" mount_client $submount &&
22402                 error "mount $submount should fail"
22403         rmdir $submount
22404 }
22405 run_test 247b "mount subdir that dose not exist"
22406
22407 test_247c() {
22408         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
22409                 skip_env "Fileset feature is not supported"
22410
22411         local submount=${MOUNT}_$tdir
22412
22413         mkdir -p $MOUNT/$tdir/dir1
22414         mkdir -p $submount || error "mkdir $submount failed"
22415         trap "cleanup_247 $submount" EXIT
22416         FILESET="$FILESET/$tdir" mount_client $submount ||
22417                 error "mount $submount failed"
22418         local fid=$($LFS path2fid $MOUNT/)
22419         $LFS fid2path $submount $fid && error "fid2path should fail"
22420         cleanup_247 $submount
22421 }
22422 run_test 247c "running fid2path outside subdirectory root"
22423
22424 test_247d() {
22425         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
22426                 skip "Fileset feature is not supported"
22427
22428         local submount=${MOUNT}_$tdir
22429
22430         mkdir -p $MOUNT/$tdir/dir1
22431         mkdir -p $submount || error "mkdir $submount failed"
22432         FILESET="$FILESET/$tdir" mount_client $submount ||
22433                 error "mount $submount failed"
22434         trap "cleanup_247 $submount" EXIT
22435
22436         local td=$submount/dir1
22437         local fid=$($LFS path2fid $td)
22438         [ -z "$fid" ] && error "path2fid unable to get $td FID"
22439
22440         # check that we get the same pathname back
22441         local rootpath
22442         local found
22443         for rootpath in "$submount" "$submount///" "$submount/dir1"; do
22444                 echo "$rootpath $fid"
22445                 found=$($LFS fid2path $rootpath "$fid")
22446                 [ -n "$found" ] || error "fid2path should succeed"
22447                 [ "$found" == "$td" ] || error "fid2path $found != $td"
22448         done
22449         # check wrong root path format
22450         rootpath=$submount"_wrong"
22451         found=$($LFS fid2path $rootpath "$fid")
22452         [ -z "$found" ] || error "fid2path should fail ($rootpath != $submount)"
22453
22454         cleanup_247 $submount
22455 }
22456 run_test 247d "running fid2path inside subdirectory root"
22457
22458 # LU-8037
22459 test_247e() {
22460         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
22461                 grep -q subtree ||
22462                 skip "Fileset feature is not supported"
22463
22464         local submount=${MOUNT}_$tdir
22465
22466         mkdir $MOUNT/$tdir
22467         mkdir -p $submount || error "mkdir $submount failed"
22468         FILESET="$FILESET/.." mount_client $submount &&
22469                 error "mount $submount should fail"
22470         rmdir $submount
22471 }
22472 run_test 247e "mount .. as fileset"
22473
22474 test_247f() {
22475         (( $MDSCOUNT > 1 )) || skip_env "needs >= 2 MDTs"
22476         (( $MDS1_VERSION >= $(version_code 2.14.50.162) )) ||
22477                 skip "Need at least version 2.14.50.162"
22478         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
22479                 skip "Fileset feature is not supported"
22480
22481         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
22482         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote ||
22483                 error "mkdir remote failed"
22484         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote/subdir ||
22485                 error "mkdir remote/subdir failed"
22486         $LFS mkdir -i 0 -c $MDSCOUNT $DIR/$tdir/striped ||
22487                 error "mkdir striped failed"
22488         mkdir $DIR/$tdir/striped/subdir || error "mkdir striped/subdir failed"
22489
22490         local submount=${MOUNT}_$tdir
22491
22492         mkdir -p $submount || error "mkdir $submount failed"
22493         stack_trap "rmdir $submount"
22494
22495         local dir
22496         local fileset=$FILESET
22497         local mdts=$(comma_list $(mdts_nodes))
22498
22499         do_nodes $mdts "$LCTL set_param mdt.*.enable_remote_subdir_mount=1"
22500         for dir in $tdir/remote $tdir/remote/subdir $tdir/striped \
22501                 $tdir/striped/subdir $tdir/striped/.; do
22502                 FILESET="$fileset/$dir" mount_client $submount ||
22503                         error "mount $dir failed"
22504                 umount_client $submount
22505         done
22506 }
22507 run_test 247f "mount striped or remote directory as fileset"
22508
22509 test_subdir_mount_lock()
22510 {
22511         local testdir=$1
22512         local submount=${MOUNT}_$(basename $testdir)
22513
22514         touch $DIR/$testdir/$tfile || error "touch $tfile failed"
22515
22516         mkdir -p $submount || error "mkdir $submount failed"
22517         stack_trap "rmdir $submount"
22518
22519         FILESET="$fileset/$testdir" mount_client $submount ||
22520                 error "mount $FILESET failed"
22521         stack_trap "umount $submount"
22522
22523         local mdts=$(comma_list $(mdts_nodes))
22524
22525         local nrpcs
22526
22527         stat $submount > /dev/null || error "stat $submount failed"
22528         cancel_lru_locks $MDC
22529         stat $submount > /dev/null || error "stat $submount failed"
22530         stat $submount/$tfile > /dev/null || error "stat $tfile failed"
22531         do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear > /dev/null"
22532         stat $submount/$tfile > /dev/null || error "stat $tfile failed"
22533         nrpcs=$(do_nodes $mdts "lctl get_param -n mdt.*.md_stats" |
22534                 awk '/getattr/ {sum += $2} END {print sum}')
22535
22536         [ -z "$nrpcs" ] || error "$nrpcs extra getattr sent"
22537 }
22538
22539 test_247g() {
22540         (( $MDSCOUNT > 1 )) || skip_env "needs > 1 MDTs"
22541
22542         $LFS mkdir -i 0 -c 4 -H fnv_1a_64 $DIR/$tdir ||
22543                 error "mkdir $tdir failed"
22544         test_subdir_mount_lock $tdir
22545 }
22546 run_test 247g "striped directory submount revalidate ROOT from cache"
22547
22548 test_247h() {
22549         (( $MDSCOUNT > 1 )) || skip_env "needs > 1 MDTs"
22550         (( $MDS1_VERSION >= $(version_code 2.15.51) )) ||
22551                 skip "Need MDS version at least 2.15.51"
22552
22553         $LFS mkdir -i 1 -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
22554         test_subdir_mount_lock $tdir
22555         mkdir_on_mdt -i 0 $DIR/$tdir/$tdir.0 || error "mkdir $tdir.0 failed"
22556         mkdir_on_mdt -i 1 $DIR/$tdir/$tdir.0/$tdir.1 ||
22557                 error "mkdir $tdir.1 failed"
22558         test_subdir_mount_lock $tdir/$tdir.0/$tdir.1
22559 }
22560 run_test 247h "remote directory submount revalidate ROOT from cache"
22561
22562 test_248a() {
22563         local fast_read_sav=$($LCTL get_param -n llite.*.fast_read 2>/dev/null)
22564         [ -z "$fast_read_sav" ] && skip "no fast read support"
22565
22566         # create a large file for fast read verification
22567         dd if=/dev/zero of=$DIR/$tfile bs=1M count=128 > /dev/null 2>&1
22568
22569         # make sure the file is created correctly
22570         $CHECKSTAT -s $((128*1024*1024)) $DIR/$tfile ||
22571                 { rm -f $DIR/$tfile; skip "file creation error"; }
22572
22573         echo "Test 1: verify that fast read is 4 times faster on cache read"
22574
22575         # small read with fast read enabled
22576         $LCTL set_param -n llite.*.fast_read=1
22577         local t_fast=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
22578                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
22579                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
22580         # small read with fast read disabled
22581         $LCTL set_param -n llite.*.fast_read=0
22582         local t_slow=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
22583                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
22584                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
22585
22586         # verify that fast read is 4 times faster for cache read
22587         [ $(bc <<< "4 * $t_fast < $t_slow") -eq 1 ] ||
22588                 error_not_in_vm "fast read was not 4 times faster: " \
22589                            "$t_fast vs $t_slow"
22590
22591         echo "Test 2: verify the performance between big and small read"
22592         $LCTL set_param -n llite.*.fast_read=1
22593
22594         # 1k non-cache read
22595         cancel_lru_locks osc
22596         local t_1k=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
22597                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
22598                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
22599
22600         # 1M non-cache read
22601         cancel_lru_locks osc
22602         local t_1m=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
22603                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
22604                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
22605
22606         # verify that big IO is not 4 times faster than small IO
22607         [ $(bc <<< "4 * $t_1k >= $t_1m") -eq 1 ] ||
22608                 error_not_in_vm "bigger IO is way too fast: $t_1k vs $t_1m"
22609
22610         $LCTL set_param -n llite.*.fast_read=$fast_read_sav
22611         rm -f $DIR/$tfile
22612 }
22613 run_test 248a "fast read verification"
22614
22615 test_248b() {
22616         # Default short_io_bytes=16384, try both smaller and larger sizes.
22617         # Lustre O_DIRECT read and write needs to be a multiple of PAGE_SIZE.
22618         # 6017024 = 2^12*13*113 = 47008*128 = 11752*512 = 4096*1469 = 53248*113
22619         echo "bs=53248 count=113 normal buffered write"
22620         dd if=/dev/urandom of=$TMP/$tfile.0 bs=53248 count=113 ||
22621                 error "dd of initial data file failed"
22622         stack_trap "rm -f $DIR/$tfile.[0-3] $TMP/$tfile.[0-3]" EXIT
22623
22624         echo "bs=47008 count=128 oflag=dsync normal write $tfile.0"
22625         dd if=$TMP/$tfile.0 of=$DIR/$tfile.0 bs=47008 count=128 oflag=dsync ||
22626                 error "dd with sync normal writes failed"
22627         cmp $TMP/$tfile.0 $DIR/$tfile.0 || error "compare $DIR/$tfile.0 failed"
22628
22629         echo "bs=11752 count=512 oflag=dsync small write $tfile.1"
22630         dd if=$TMP/$tfile.0 of=$DIR/$tfile.1 bs=11752 count=512 oflag=dsync ||
22631                 error "dd with sync small writes failed"
22632         cmp $TMP/$tfile.0 $DIR/$tfile.1 || error "compare $DIR/$tfile.1 failed"
22633
22634         cancel_lru_locks osc
22635
22636         # calculate the small O_DIRECT size and count for the client PAGE_SIZE
22637         local num=$((13 * 113 / (PAGE_SIZE / 4096)))
22638         echo "bs=$PAGE_SIZE count=$num iflag=direct small read $tfile.1"
22639         dd if=$DIR/$tfile.1 of=$TMP/$tfile.1 bs=$PAGE_SIZE count=$num \
22640                 iflag=direct || error "dd with O_DIRECT small read failed"
22641         # adjust bytes checked to handle larger PAGE_SIZE for ARM/PPC
22642         cmp --bytes=$((PAGE_SIZE * num)) $TMP/$tfile.0 $TMP/$tfile.1 ||
22643                 error "compare $TMP/$tfile.1 failed"
22644
22645         local save=$($LCTL get_param -n osc.*OST000*.short_io_bytes | head -n 1)
22646         stack_trap "$LCTL set_param osc.$FSNAME-*.short_io_bytes=$save" EXIT
22647
22648         # just to see what the maximum tunable value is, and test parsing
22649         echo "test invalid parameter 2MB"
22650         $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=2M &&
22651                 error "too-large short_io_bytes allowed"
22652         echo "test maximum parameter 512KB"
22653         # if we can set a larger short_io_bytes, run test regardless of version
22654         if ! $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=512K; then
22655                 # older clients may not allow setting it this large, that's OK
22656                 [ $CLIENT_VERSION -ge $(version_code 2.13.50) ] ||
22657                         skip "Need at least client version 2.13.50"
22658                 error "medium short_io_bytes failed"
22659         fi
22660         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
22661         size=$($LCTL get_param -n osc.$FSNAME-OST0000*.short_io_bytes)
22662
22663         echo "test large parameter 64KB"
22664         $LCTL set_param osc.$FSNAME-*.short_io_bytes=65536
22665         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
22666
22667         echo "bs=47008 count=128 oflag=dsync large write $tfile.2"
22668         dd if=$TMP/$tfile.0 of=$DIR/$tfile.2 bs=47008 count=128 oflag=dsync ||
22669                 error "dd with sync large writes failed"
22670         cmp $TMP/$tfile.0 $DIR/$tfile.2 || error "compare $DIR/$tfile.2 failed"
22671
22672         # calculate the large O_DIRECT size and count for the client PAGE_SIZE
22673         local size=$(((4096 * 13 + PAGE_SIZE - 1) / PAGE_SIZE * PAGE_SIZE))
22674         num=$((113 * 4096 / PAGE_SIZE))
22675         echo "bs=$size count=$num oflag=direct large write $tfile.3"
22676         dd if=$TMP/$tfile.0 of=$DIR/$tfile.3 bs=$size count=$num oflag=direct ||
22677                 error "dd with O_DIRECT large writes failed"
22678         cmp --bytes=$((size * num)) $TMP/$tfile.0 $DIR/$tfile.3 ||
22679                 error "compare $DIR/$tfile.3 failed"
22680
22681         cancel_lru_locks osc
22682
22683         echo "bs=$size count=$num iflag=direct large read $tfile.2"
22684         dd if=$DIR/$tfile.2 of=$TMP/$tfile.2 bs=$size count=$num iflag=direct ||
22685                 error "dd with O_DIRECT large read failed"
22686         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.2 ||
22687                 error "compare $TMP/$tfile.2 failed"
22688
22689         echo "bs=$size count=$num iflag=direct large read $tfile.3"
22690         dd if=$DIR/$tfile.3 of=$TMP/$tfile.3 bs=$size count=$num iflag=direct ||
22691                 error "dd with O_DIRECT large read failed"
22692         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.3 ||
22693                 error "compare $TMP/$tfile.3 failed"
22694 }
22695 run_test 248b "test short_io read and write for both small and large sizes"
22696
22697 test_249() { # LU-7890
22698         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
22699                 skip "Need at least version 2.8.54"
22700
22701         rm -f $DIR/$tfile
22702         $LFS setstripe -c 1 $DIR/$tfile
22703         # Offset 2T == 4k * 512M
22704         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 seek=512M ||
22705                 error "dd to 2T offset failed"
22706 }
22707 run_test 249 "Write above 2T file size"
22708
22709 test_250() {
22710         [ "$(facet_fstype ost$(($($LFS getstripe -i $DIR/$tfile) + 1)))" = "zfs" ] \
22711          && skip "no 16TB file size limit on ZFS"
22712
22713         $LFS setstripe -c 1 $DIR/$tfile
22714         # ldiskfs extent file size limit is (16TB - 4KB - 1) bytes
22715         local size=$((16 * 1024 * 1024 * 1024 * 1024 - 4096 - 1))
22716         $TRUNCATE $DIR/$tfile $size || error "truncate $tfile to $size failed"
22717         dd if=/dev/zero of=$DIR/$tfile bs=10 count=1 oflag=append \
22718                 conv=notrunc,fsync && error "append succeeded"
22719         return 0
22720 }
22721 run_test 250 "Write above 16T limit"
22722
22723 test_251() {
22724         $LFS setstripe -c -1 -S 1048576 $DIR/$tfile
22725
22726         #define OBD_FAIL_LLITE_LOST_LAYOUT 0x1407
22727         #Skip once - writing the first stripe will succeed
22728         $LCTL set_param fail_loc=0xa0001407 fail_val=1
22729         $MULTIOP $DIR/$tfile o:O_RDWR:w2097152c 2>&1 | grep -q "short write" &&
22730                 error "short write happened"
22731
22732         $LCTL set_param fail_loc=0xa0001407 fail_val=1
22733         $MULTIOP $DIR/$tfile or2097152c 2>&1 | grep -q "short read" &&
22734                 error "short read happened"
22735
22736         rm -f $DIR/$tfile
22737 }
22738 run_test 251 "Handling short read and write correctly"
22739
22740 test_252() {
22741         remote_mds_nodsh && skip "remote MDS with nodsh"
22742         remote_ost_nodsh && skip "remote OST with nodsh"
22743         if [ "$ost1_FSTYPE" != ldiskfs ] || [ "$mds1_FSTYPE" != ldiskfs ]; then
22744                 skip_env "ldiskfs only test"
22745         fi
22746
22747         local tgt
22748         local dev
22749         local out
22750         local uuid
22751         local num
22752         local gen
22753
22754         # check lr_reader on OST0000
22755         tgt=ost1
22756         dev=$(facet_device $tgt)
22757         out=$(do_facet $tgt $LR_READER $dev)
22758         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
22759         echo "$out"
22760         uuid=$(echo "$out" | grep -i uuid | awk '{ print $2 }')
22761         [ "$uuid" == "$(ostuuid_from_index 0)" ] ||
22762                 error "Invalid uuid returned by $LR_READER on target $tgt"
22763         echo -e "uuid returned by $LR_READER is '$uuid'\n"
22764
22765         # check lr_reader -c on MDT0000
22766         tgt=mds1
22767         dev=$(facet_device $tgt)
22768         if ! do_facet $tgt $LR_READER -h | grep -q OPTIONS; then
22769                 skip "$LR_READER does not support additional options"
22770         fi
22771         out=$(do_facet $tgt $LR_READER -c $dev)
22772         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
22773         echo "$out"
22774         num=$(echo "$out" | grep -c "mdtlov")
22775         [ "$num" -eq $((MDSCOUNT - 1)) ] ||
22776                 error "Invalid number of mdtlov clients returned by $LR_READER"
22777         echo -e "Number of mdtlov clients returned by $LR_READER is '$num'\n"
22778
22779         # check lr_reader -cr on MDT0000
22780         out=$(do_facet $tgt $LR_READER -cr $dev)
22781         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
22782         echo "$out"
22783         echo "$out" | grep -q "^reply_data:$" ||
22784                 error "$LR_READER should have returned 'reply_data' section"
22785         num=$(echo "$out" | grep -c "client_generation")
22786         echo -e "Number of reply data returned by $LR_READER is '$num'\n"
22787 }
22788 run_test 252 "check lr_reader tool"
22789
22790 test_253() {
22791         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22792         remote_mds_nodsh && skip "remote MDS with nodsh"
22793         remote_mgs_nodsh && skip "remote MGS with nodsh"
22794
22795         local ostidx=0
22796         local rc=0
22797         local ost_name=$(ostname_from_index $ostidx)
22798
22799         # on the mdt's osc
22800         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $ost_name)
22801         do_facet $SINGLEMDS $LCTL get_param -n \
22802                 osp.$mdtosc_proc1.reserved_mb_high ||
22803                 skip  "remote MDS does not support reserved_mb_high"
22804
22805         rm -rf $DIR/$tdir
22806         wait_mds_ost_sync
22807         wait_delete_completed
22808         mkdir $DIR/$tdir
22809         stack_trap "rm -rf $DIR/$tdir"
22810
22811         pool_add $TESTNAME || error "Pool creation failed"
22812         pool_add_targets $TESTNAME 0 || error "Pool add targets failed"
22813
22814         $LFS setstripe $DIR/$tdir -i $ostidx -c 1 -p $FSNAME.$TESTNAME ||
22815                 error "Setstripe failed"
22816
22817         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M count=10
22818
22819         local wms=$(ost_watermarks_set_enospc $tfile $ostidx |
22820                     grep "watermarks")
22821         stack_trap "ost_watermarks_clear_enospc $tfile $ostidx $wms" EXIT
22822
22823         local oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
22824                         osp.$mdtosc_proc1.prealloc_status)
22825         echo "prealloc_status $oa_status"
22826
22827         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1M count=1 &&
22828                 error "File creation should fail"
22829
22830         #object allocation was stopped, but we still able to append files
22831         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M seek=6 count=5 \
22832                 oflag=append || error "Append failed"
22833
22834         rm -f $DIR/$tdir/$tfile.0
22835
22836         # For this test, we want to delete the files we created to go out of
22837         # space but leave the watermark, so we remain nearly out of space
22838         ost_watermarks_enospc_delete_files $tfile $ostidx
22839
22840         wait_delete_completed
22841
22842         sleep_maxage
22843
22844         for i in $(seq 10 12); do
22845                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$i bs=1M count=1 \
22846                         2>/dev/null || error "File creation failed after rm"
22847         done
22848
22849         oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
22850                         osp.$mdtosc_proc1.prealloc_status)
22851         echo "prealloc_status $oa_status"
22852
22853         if (( oa_status != 0 )); then
22854                 error "Object allocation still disable after rm"
22855         fi
22856 }
22857 run_test 253 "Check object allocation limit"
22858
22859 test_254() {
22860         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22861         remote_mds_nodsh && skip "remote MDS with nodsh"
22862
22863         local mdt=$(facet_svc $SINGLEMDS)
22864
22865         do_facet $SINGLEMDS $LCTL get_param -n mdd.$mdt.changelog_size ||
22866                 skip "MDS does not support changelog_size"
22867
22868         local cl_user
22869
22870         changelog_register || error "changelog_register failed"
22871
22872         changelog_clear 0 || error "changelog_clear failed"
22873
22874         local size1=$(do_facet $SINGLEMDS \
22875                       $LCTL get_param -n mdd.$mdt.changelog_size)
22876         echo "Changelog size $size1"
22877
22878         rm -rf $DIR/$tdir
22879         $LFS mkdir -i 0 $DIR/$tdir
22880         # change something
22881         mkdir -p $DIR/$tdir/pics/2008/zachy
22882         touch $DIR/$tdir/pics/2008/zachy/timestamp
22883         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg
22884         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
22885         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
22886         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
22887         rm $DIR/$tdir/pics/desktop.jpg
22888
22889         local size2=$(do_facet $SINGLEMDS \
22890                       $LCTL get_param -n mdd.$mdt.changelog_size)
22891         echo "Changelog size after work $size2"
22892
22893         (( $size2 > $size1 )) ||
22894                 error "new Changelog size=$size2 less than old size=$size1"
22895 }
22896 run_test 254 "Check changelog size"
22897
22898 ladvise_no_type()
22899 {
22900         local type=$1
22901         local file=$2
22902
22903         lfs ladvise -a invalid $file 2>&1 | grep "Valid types" |
22904                 awk -F: '{print $2}' | grep $type > /dev/null
22905         if [ $? -ne 0 ]; then
22906                 return 0
22907         fi
22908         return 1
22909 }
22910
22911 ladvise_no_ioctl()
22912 {
22913         local file=$1
22914
22915         lfs ladvise -a willread $file > /dev/null 2>&1
22916         if [ $? -eq 0 ]; then
22917                 return 1
22918         fi
22919
22920         lfs ladvise -a willread $file 2>&1 |
22921                 grep "Inappropriate ioctl for device" > /dev/null
22922         if [ $? -eq 0 ]; then
22923                 return 0
22924         fi
22925         return 1
22926 }
22927
22928 percent() {
22929         bc <<<"scale=2; ($1 - $2) * 100 / $2"
22930 }
22931
22932 # run a random read IO workload
22933 # usage: random_read_iops <filename> <filesize> <iosize>
22934 random_read_iops() {
22935         local file=$1
22936         local fsize=$2
22937         local iosize=${3:-4096}
22938
22939         $READS -f $file -s $fsize -b $iosize -n $((fsize / iosize)) -t 60 |
22940                 sed -e '/^$/d' -e 's#.*s, ##' -e 's#MB/s##'
22941 }
22942
22943 drop_file_oss_cache() {
22944         local file="$1"
22945         local nodes="$2"
22946
22947         $LFS ladvise -a dontneed $file 2>/dev/null ||
22948                 do_nodes $nodes "echo 3 > /proc/sys/vm/drop_caches"
22949 }
22950
22951 ladvise_willread_performance()
22952 {
22953         local repeat=10
22954         local average_origin=0
22955         local average_cache=0
22956         local average_ladvise=0
22957
22958         for ((i = 1; i <= $repeat; i++)); do
22959                 echo "Iter $i/$repeat: reading without willread hint"
22960                 cancel_lru_locks osc
22961                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
22962                 local speed_origin=$(random_read_iops $DIR/$tfile $size)
22963                 echo "Iter $i/$repeat: uncached speed: $speed_origin"
22964                 average_origin=$(bc <<<"$average_origin + $speed_origin")
22965
22966                 cancel_lru_locks osc
22967                 local speed_cache=$(random_read_iops $DIR/$tfile $size)
22968                 echo "Iter $i/$repeat: OSS cache speed: $speed_cache"
22969                 average_cache=$(bc <<<"$average_cache + $speed_cache")
22970
22971                 cancel_lru_locks osc
22972                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
22973                 $LFS ladvise -a willread $DIR/$tfile || error "ladvise failed"
22974                 local speed_ladvise=$(random_read_iops $DIR/$tfile $size)
22975                 echo "Iter $i/$repeat: ladvise speed: $speed_ladvise"
22976                 average_ladvise=$(bc <<<"$average_ladvise + $speed_ladvise")
22977         done
22978         average_origin=$(bc <<<"scale=2; $average_origin / $repeat")
22979         average_cache=$(bc <<<"scale=2; $average_cache / $repeat")
22980         average_ladvise=$(bc <<<"scale=2; $average_ladvise / $repeat")
22981
22982         speedup_cache=$(percent $average_cache $average_origin)
22983         speedup_ladvise=$(percent $average_ladvise $average_origin)
22984
22985         echo "Average uncached read: $average_origin"
22986         echo "Average speedup with OSS cached read: " \
22987                 "$average_cache = +$speedup_cache%"
22988         echo "Average speedup with ladvise willread: " \
22989                 "$average_ladvise = +$speedup_ladvise%"
22990
22991         local lowest_speedup=20
22992         if (( ${average_cache%.*} < $lowest_speedup )); then
22993                 echo "Speedup with OSS cached read less than $lowest_speedup%,"\
22994                      " got $average_cache%. Skipping ladvise willread check."
22995                 return 0
22996         fi
22997
22998         # the test won't work on ZFS until it supports 'ladvise dontneed', but
22999         # it is still good to run until then to exercise 'ladvise willread'
23000         ! $LFS ladvise -a dontneed $DIR/$tfile &&
23001                 [ "$ost1_FSTYPE" = "zfs" ] &&
23002                 echo "osd-zfs does not support dontneed or drop_caches" &&
23003                 return 0
23004
23005         lowest_speedup=$(bc <<<"scale=2; $average_cache / 2")
23006         (( ${average_ladvise%.*} > ${lowest_speedup%.*} )) ||
23007                 error_not_in_vm "Speedup with willread is less than " \
23008                         "$lowest_speedup%, got $average_ladvise%"
23009 }
23010
23011 test_255a() {
23012         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
23013                 skip "lustre < 2.8.54 does not support ladvise "
23014         remote_ost_nodsh && skip "remote OST with nodsh"
23015
23016         stack_trap "rm -f $DIR/$tfile"
23017         lfs setstripe -c -1 -i 0 $DIR/$tfile || error "$tfile failed"
23018
23019         ladvise_no_type willread $DIR/$tfile &&
23020                 skip "willread ladvise is not supported"
23021
23022         ladvise_no_ioctl $DIR/$tfile &&
23023                 skip "ladvise ioctl is not supported"
23024
23025         local size_mb=100
23026         local size=$((size_mb * 1048576))
23027         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
23028                 error "dd to $DIR/$tfile failed"
23029
23030         lfs ladvise -a willread $DIR/$tfile ||
23031                 error "Ladvise failed with no range argument"
23032
23033         lfs ladvise -a willread -s 0 $DIR/$tfile ||
23034                 error "Ladvise failed with no -l or -e argument"
23035
23036         lfs ladvise -a willread -e 1 $DIR/$tfile ||
23037                 error "Ladvise failed with only -e argument"
23038
23039         lfs ladvise -a willread -l 1 $DIR/$tfile ||
23040                 error "Ladvise failed with only -l argument"
23041
23042         lfs ladvise -a willread -s 2 -e 1 $DIR/$tfile &&
23043                 error "End offset should not be smaller than start offset"
23044
23045         lfs ladvise -a willread -s 2 -e 2 $DIR/$tfile &&
23046                 error "End offset should not be equal to start offset"
23047
23048         lfs ladvise -a willread -s $size -l 1 $DIR/$tfile ||
23049                 error "Ladvise failed with overflowing -s argument"
23050
23051         lfs ladvise -a willread -s 1 -e $((size + 1)) $DIR/$tfile ||
23052                 error "Ladvise failed with overflowing -e argument"
23053
23054         lfs ladvise -a willread -s 1 -l $size $DIR/$tfile ||
23055                 error "Ladvise failed with overflowing -l argument"
23056
23057         lfs ladvise -a willread -l 1 -e 2 $DIR/$tfile &&
23058                 error "Ladvise succeeded with conflicting -l and -e arguments"
23059
23060         echo "Synchronous ladvise should wait"
23061         local delay=8
23062 #define OBD_FAIL_OST_LADVISE_PAUSE       0x237
23063         do_nodes $(comma_list $(osts_nodes)) \
23064                 $LCTL set_param fail_val=$delay fail_loc=0x237
23065         stack_trap "do_nodes $(comma_list $(osts_nodes)) \
23066                 $LCTL set_param fail_loc=0"
23067
23068         local start_ts=$SECONDS
23069         lfs ladvise -a willread $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 -lt $(($delay - 1)) ]; then
23075                 error "Synchronous advice didn't wait reply"
23076         fi
23077
23078         echo "Asynchronous ladvise shouldn't wait"
23079         local start_ts=$SECONDS
23080         lfs ladvise -a willread -b $DIR/$tfile ||
23081                 error "Ladvise failed with no range argument"
23082         local end_ts=$SECONDS
23083         local inteval_ts=$((end_ts - start_ts))
23084
23085         if [ $inteval_ts -gt $(($delay / 2)) ]; then
23086                 error "Asynchronous advice blocked"
23087         fi
23088
23089         ladvise_willread_performance
23090 }
23091 run_test 255a "check 'lfs ladvise -a willread'"
23092
23093 facet_meminfo() {
23094         local facet=$1
23095         local info=$2
23096
23097         do_facet $facet "cat /proc/meminfo | grep ^${info}:" | awk '{print $2}'
23098 }
23099
23100 test_255b() {
23101         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
23102                 skip "lustre < 2.8.54 does not support ladvise "
23103         remote_ost_nodsh && skip "remote OST with nodsh"
23104
23105         stack_trap "rm -f $DIR/$tfile"
23106         lfs setstripe -c 1 -i 0 $DIR/$tfile
23107
23108         ladvise_no_type dontneed $DIR/$tfile &&
23109                 skip "dontneed ladvise is not supported"
23110
23111         ladvise_no_ioctl $DIR/$tfile &&
23112                 skip "ladvise ioctl is not supported"
23113
23114         ! $LFS ladvise -a dontneed $DIR/$tfile &&
23115                 [ "$ost1_FSTYPE" = "zfs" ] &&
23116                 skip "zfs-osd does not support 'ladvise dontneed'"
23117
23118         local size_mb=100
23119         local size=$((size_mb * 1048576))
23120         # In order to prevent disturbance of other processes, only check 3/4
23121         # of the memory usage
23122         local kibibytes=$((size_mb * 1024 * 3 / 4))
23123
23124         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
23125                 error "dd to $DIR/$tfile failed"
23126
23127         #force write to complete before dropping OST cache & checking memory
23128         sync
23129
23130         local total=$(facet_meminfo ost1 MemTotal)
23131         echo "Total memory: $total KiB"
23132
23133         do_facet ost1 "sync && echo 3 > /proc/sys/vm/drop_caches"
23134         local before_read=$(facet_meminfo ost1 Cached)
23135         echo "Cache used before read: $before_read KiB"
23136
23137         lfs ladvise -a willread $DIR/$tfile ||
23138                 error "Ladvise willread failed"
23139         local after_read=$(facet_meminfo ost1 Cached)
23140         echo "Cache used after read: $after_read KiB"
23141
23142         lfs ladvise -a dontneed $DIR/$tfile ||
23143                 error "Ladvise dontneed again failed"
23144         local no_read=$(facet_meminfo ost1 Cached)
23145         echo "Cache used after dontneed ladvise: $no_read KiB"
23146
23147         if [ $total -lt $((before_read + kibibytes)) ]; then
23148                 echo "Memory is too small, abort checking"
23149                 return 0
23150         fi
23151
23152         if [ $((before_read + kibibytes)) -gt $after_read ]; then
23153                 error "Ladvise willread should use more memory" \
23154                         "than $kibibytes KiB"
23155         fi
23156
23157         if [ $((no_read + kibibytes)) -gt $after_read ]; then
23158                 error "Ladvise dontneed should release more memory" \
23159                         "than $kibibytes KiB"
23160         fi
23161 }
23162 run_test 255b "check 'lfs ladvise -a dontneed'"
23163
23164 test_255c() {
23165         [ $OST1_VERSION -lt $(version_code 2.10.50) ] &&
23166                 skip "lustre < 2.10.50 does not support lockahead"
23167
23168         local ost1_imp=$(get_osc_import_name client ost1)
23169         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
23170                          cut -d'.' -f2)
23171         local count
23172         local new_count
23173         local difference
23174         local i
23175         local rc
23176
23177         test_mkdir -p $DIR/$tdir
23178         $LFS setstripe -i 0 -c 1 $DIR/$tdir
23179
23180         #test 10 returns only success/failure
23181         i=10
23182         lockahead_test -d $DIR/$tdir -t $i -f $tfile
23183         rc=$?
23184         if [ $rc -eq 255 ]; then
23185                 error "Ladvise test${i} failed, ${rc}"
23186         fi
23187
23188         #test 11 counts lock enqueue requests, all others count new locks
23189         i=11
23190         count=$(do_facet ost1 \
23191                 $LCTL get_param -n ost.OSS.ost.stats)
23192         count=$(echo "$count" | grep ldlm_extent_enqueue | awk '{ print $2 }')
23193
23194         lockahead_test -d $DIR/$tdir -t $i -f $tfile
23195         rc=$?
23196         if [ $rc -eq 255 ]; then
23197                 error "Ladvise test${i} failed, ${rc}"
23198         fi
23199
23200         new_count=$(do_facet ost1 \
23201                 $LCTL get_param -n ost.OSS.ost.stats)
23202         new_count=$(echo "$new_count" | grep ldlm_extent_enqueue | \
23203                    awk '{ print $2 }')
23204
23205         difference="$((new_count - count))"
23206         if [ $difference -ne $rc ]; then
23207                 error "Ladvise test${i}, bad enqueue count, returned " \
23208                       "${rc}, actual ${difference}"
23209         fi
23210
23211         for i in $(seq 12 21); do
23212                 # If we do not do this, we run the risk of having too many
23213                 # locks and starting lock cancellation while we are checking
23214                 # lock counts.
23215                 cancel_lru_locks osc
23216
23217                 count=$($LCTL get_param -n \
23218                        ldlm.namespaces.$imp_name.lock_unused_count)
23219
23220                 lockahead_test -d $DIR/$tdir -t $i -f $tfile
23221                 rc=$?
23222                 if [ $rc -eq 255 ]; then
23223                         error "Ladvise test ${i} failed, ${rc}"
23224                 fi
23225
23226                 new_count=$($LCTL get_param -n \
23227                        ldlm.namespaces.$imp_name.lock_unused_count)
23228                 difference="$((new_count - count))"
23229
23230                 # Test 15 output is divided by 100 to map down to valid return
23231                 if [ $i -eq 15 ]; then
23232                         rc="$((rc * 100))"
23233                 fi
23234
23235                 if [ $difference -ne $rc ]; then
23236                         error "Ladvise test ${i}, bad lock count, returned " \
23237                               "${rc}, actual ${difference}"
23238                 fi
23239         done
23240
23241         #test 22 returns only success/failure
23242         i=22
23243         lockahead_test -d $DIR/$tdir -t $i -f $tfile
23244         rc=$?
23245         if [ $rc -eq 255 ]; then
23246                 error "Ladvise test${i} failed, ${rc}"
23247         fi
23248 }
23249 run_test 255c "suite of ladvise lockahead tests"
23250
23251 test_256() {
23252         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23253         remote_mds_nodsh && skip "remote MDS with nodsh"
23254         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
23255         changelog_users $SINGLEMDS | grep "^cl" &&
23256                 skip "active changelog user"
23257
23258         local cl_user
23259         local cat_sl
23260         local mdt_dev
23261
23262         mdt_dev=$(facet_device $SINGLEMDS)
23263         echo $mdt_dev
23264
23265         changelog_register || error "changelog_register failed"
23266
23267         rm -rf $DIR/$tdir
23268         mkdir_on_mdt -i$(($(facet_number $SINGLEMDS) - 1)) $DIR/$tdir
23269
23270         changelog_clear 0 || error "changelog_clear failed"
23271
23272         # change something
23273         touch $DIR/$tdir/{1..10}
23274
23275         # stop the MDT
23276         stop $SINGLEMDS || error "Fail to stop MDT"
23277
23278         # remount the MDT
23279         start $SINGLEMDS $(facet_device $SINGLEMDS) $MDS_MOUNT_OPTS ||
23280                 error "Fail to start MDT"
23281
23282         #after mount new plainllog is used
23283         touch $DIR/$tdir/{11..19}
23284         local tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
23285         stack_trap "rm -f $tmpfile"
23286         cat_sl=$(do_facet $SINGLEMDS "sync; \
23287                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
23288                  llog_reader $tmpfile | grep -c type=1064553b")
23289         do_facet $SINGLEMDS llog_reader $tmpfile
23290
23291         [ $cat_sl != 2 ] && error "Changelog catalog has $cat_sl != 2 slots"
23292
23293         changelog_clear 0 || error "changelog_clear failed"
23294
23295         cat_sl=$(do_facet $SINGLEMDS "sync; \
23296                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
23297                  llog_reader $tmpfile | grep -c type=1064553b")
23298
23299         if (( cat_sl == 2 )); then
23300                 error "Empty plain llog was not deleted from changelog catalog"
23301         elif (( cat_sl != 1 )); then
23302                 error "Active plain llog shouldn't be deleted from catalog"
23303         fi
23304 }
23305 run_test 256 "Check llog delete for empty and not full state"
23306
23307 test_257() {
23308         remote_mds_nodsh && skip "remote MDS with nodsh"
23309         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
23310                 skip "Need MDS version at least 2.8.55"
23311
23312         test_mkdir $DIR/$tdir
23313
23314         setfattr -n trusted.name1 -v value1 $DIR/$tdir ||
23315                 error "setfattr -n trusted.name1=value1 $DIR/$tdir failed"
23316         stat $DIR/$tdir
23317
23318 #define OBD_FAIL_MDS_XATTR_REP                  0x161
23319         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
23320         local facet=mds$((mdtidx + 1))
23321         set_nodes_failloc $(facet_active_host $facet) 0x80000161
23322         getfattr -n trusted.name1 $DIR/$tdir 2> /dev/null
23323
23324         stop $facet || error "stop MDS failed"
23325         start $facet $(mdsdevname $((mdtidx + 1))) $MDS_MOUNT_OPTS ||
23326                 error "start MDS fail"
23327         wait_recovery_complete $facet
23328 }
23329 run_test 257 "xattr locks are not lost"
23330
23331 # Verify we take the i_mutex when security requires it
23332 test_258a() {
23333 #define OBD_FAIL_IMUTEX_SEC 0x141c
23334         $LCTL set_param fail_loc=0x141c
23335         touch $DIR/$tfile
23336         chmod u+s $DIR/$tfile
23337         chmod a+rwx $DIR/$tfile
23338         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
23339         RC=$?
23340         if [ $RC -ne 0 ]; then
23341                 error "error, failed to take i_mutex, rc=$?"
23342         fi
23343         rm -f $DIR/$tfile
23344 }
23345 run_test 258a "verify i_mutex security behavior when suid attributes is set"
23346
23347 # Verify we do NOT take the i_mutex in the normal case
23348 test_258b() {
23349 #define OBD_FAIL_IMUTEX_NOSEC 0x141d
23350         $LCTL set_param fail_loc=0x141d
23351         touch $DIR/$tfile
23352         chmod a+rwx $DIR
23353         chmod a+rw $DIR/$tfile
23354         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
23355         RC=$?
23356         if [ $RC -ne 0 ]; then
23357                 error "error, took i_mutex unnecessarily, rc=$?"
23358         fi
23359         rm -f $DIR/$tfile
23360
23361 }
23362 run_test 258b "verify i_mutex security behavior"
23363
23364 test_259() {
23365         local file=$DIR/$tfile
23366         local before
23367         local after
23368
23369         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
23370
23371         stack_trap "rm -f $file" EXIT
23372
23373         wait_delete_completed
23374         before=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
23375         echo "before: $before"
23376
23377         $LFS setstripe -i 0 -c 1 $file
23378         dd if=/dev/zero of=$file bs=1M count=10 || error "couldn't write"
23379         sync_all_data
23380         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
23381         echo "after write: $after"
23382
23383 #define OBD_FAIL_OSD_FAIL_AT_TRUNCATE          0x2301
23384         do_facet ost1 $LCTL set_param fail_loc=0x2301
23385         $TRUNCATE $file 0
23386         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
23387         echo "after truncate: $after"
23388
23389         stop ost1
23390         do_facet ost1 $LCTL set_param fail_loc=0
23391         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
23392         sleep 2
23393         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
23394         echo "after restart: $after"
23395         [ $((after - before)) -ge $(fs_log_size ost1) ] &&
23396                 error "missing truncate?"
23397
23398         return 0
23399 }
23400 run_test 259 "crash at delayed truncate"
23401
23402 test_260() {
23403 #define OBD_FAIL_MDC_CLOSE               0x806
23404         $LCTL set_param fail_loc=0x80000806
23405         touch $DIR/$tfile
23406
23407 }
23408 run_test 260 "Check mdc_close fail"
23409
23410 ### Data-on-MDT sanity tests ###
23411 test_270a() {
23412         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23413                 skip "Need MDS version at least 2.10.55 for DoM"
23414
23415         # create DoM file
23416         local dom=$DIR/$tdir/dom_file
23417         local tmp=$DIR/$tdir/tmp_file
23418
23419         mkdir_on_mdt0 $DIR/$tdir
23420
23421         # basic checks for DoM component creation
23422         $LFS setstripe -E 1024K -E 2048K -L mdt $dom 2>/dev/null &&
23423                 error "Can set MDT layout to non-first entry"
23424
23425         $LFS setstripe -E 1024K -L mdt -E 2048K -L mdt $dom 2>/dev/null &&
23426                 error "Can define multiple entries as MDT layout"
23427
23428         $LFS setstripe -E 1M -L mdt $dom || error "Can't create DoM layout"
23429
23430         [ $($LFS getstripe -L $dom) == "mdt" ] || error "bad pattern"
23431         [ $($LFS getstripe -c $dom) == 0 ] || error "bad stripe count"
23432         [ $($LFS getstripe -S $dom) == 1048576 ] || error "bad stripe size"
23433
23434         local mdtidx=$($LFS getstripe -m $dom)
23435         local mdtname=MDT$(printf %04x $mdtidx)
23436         local facet=mds$((mdtidx + 1))
23437         local space_check=1
23438
23439         # Skip free space checks with ZFS
23440         [ "$(facet_fstype $facet)" == "zfs" ] && space_check=0
23441
23442         # write
23443         sync
23444         local size_tmp=$((65536 * 3))
23445         local mdtfree1=$(do_facet $facet \
23446                          lctl get_param -n osd*.*$mdtname.kbytesfree)
23447
23448         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
23449         # check also direct IO along write
23450         # IO size must be a multiple of PAGE_SIZE on all platforms (ARM=64KB)
23451         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
23452         sync
23453         cmp $tmp $dom || error "file data is different"
23454         [ $(stat -c%s $dom) == $size_tmp ] ||
23455                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
23456         if [ $space_check == 1 ]; then
23457                 local mdtfree2=$(do_facet $facet \
23458                                  lctl get_param -n osd*.*$mdtname.kbytesfree)
23459
23460                 # increase in usage from by $size_tmp
23461                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
23462                         error "MDT free space wrong after write: " \
23463                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
23464         fi
23465
23466         # truncate
23467         local size_dom=10000
23468
23469         $TRUNCATE $dom $size_dom
23470         [ $(stat -c%s $dom) == $size_dom ] ||
23471                 error "bad size after truncate: $(stat -c%s $dom) != $size_dom"
23472         if [ $space_check == 1 ]; then
23473                 mdtfree1=$(do_facet $facet \
23474                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23475                 # decrease in usage from $size_tmp to new $size_dom
23476                 [ $(($mdtfree1 - $mdtfree2)) -ge \
23477                   $(((size_tmp - size_dom) / 1024)) ] ||
23478                         error "MDT free space is wrong after truncate: " \
23479                               "$mdtfree1 >= $mdtfree2 + ($size_tmp - $size_dom) / 1024"
23480         fi
23481
23482         # append
23483         cat $tmp >> $dom
23484         sync
23485         size_dom=$((size_dom + size_tmp))
23486         [ $(stat -c%s $dom) == $size_dom ] ||
23487                 error "bad size after append: $(stat -c%s $dom) != $size_dom"
23488         if [ $space_check == 1 ]; then
23489                 mdtfree2=$(do_facet $facet \
23490                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23491                 # increase in usage by $size_tmp from previous
23492                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
23493                         error "MDT free space is wrong after append: " \
23494                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
23495         fi
23496
23497         # delete
23498         rm $dom
23499         if [ $space_check == 1 ]; then
23500                 mdtfree1=$(do_facet $facet \
23501                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23502                 # decrease in usage by $size_dom from previous
23503                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_dom / 1024)) ] ||
23504                         error "MDT free space is wrong after removal: " \
23505                               "$mdtfree1 >= $mdtfree2 + $size_dom/1024"
23506         fi
23507
23508         # combined striping
23509         $LFS setstripe -E 1024K -L mdt -E EOF $dom ||
23510                 error "Can't create DoM + OST striping"
23511
23512         size_tmp=2031616 # must be a multiple of PAGE_SIZE=65536 on ARM
23513         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
23514         # check also direct IO along write
23515         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
23516         sync
23517         cmp $tmp $dom || error "file data is different"
23518         [ $(stat -c%s $dom) == $size_tmp ] ||
23519                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
23520         rm $dom $tmp
23521
23522         return 0
23523 }
23524 run_test 270a "DoM: basic functionality tests"
23525
23526 test_270b() {
23527         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23528                 skip "Need MDS version at least 2.10.55"
23529
23530         local dom=$DIR/$tdir/dom_file
23531         local max_size=1048576
23532
23533         mkdir -p $DIR/$tdir
23534         $LFS setstripe -E $max_size -L mdt $dom
23535
23536         # truncate over the limit
23537         $TRUNCATE $dom $(($max_size + 1)) &&
23538                 error "successful truncate over the maximum size"
23539         # write over the limit
23540         dd if=/dev/zero of=$dom bs=$max_size seek=1 count=1 &&
23541                 error "successful write over the maximum size"
23542         # append over the limit
23543         dd if=/dev/zero of=$dom bs=$(($max_size - 3)) count=1
23544         echo "12345" >> $dom && error "successful append over the maximum size"
23545         rm $dom
23546
23547         return 0
23548 }
23549 run_test 270b "DoM: maximum size overflow checks for DoM-only file"
23550
23551 test_270c() {
23552         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23553                 skip "Need MDS version at least 2.10.55"
23554
23555         mkdir -p $DIR/$tdir
23556         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
23557
23558         # check files inherit DoM EA
23559         touch $DIR/$tdir/first
23560         [ $($LFS getstripe -L $DIR/$tdir/first) == "mdt" ] ||
23561                 error "bad pattern"
23562         [ $($LFS getstripe -c $DIR/$tdir/first) == 0 ] ||
23563                 error "bad stripe count"
23564         [ $($LFS getstripe -S $DIR/$tdir/first) == 1048576 ] ||
23565                 error "bad stripe size"
23566
23567         # check directory inherits DoM EA and uses it as default
23568         mkdir $DIR/$tdir/subdir
23569         touch $DIR/$tdir/subdir/second
23570         [ $($LFS getstripe -L $DIR/$tdir/subdir/second) == "mdt" ] ||
23571                 error "bad pattern in sub-directory"
23572         [ $($LFS getstripe -c $DIR/$tdir/subdir/second) == 0 ] ||
23573                 error "bad stripe count in sub-directory"
23574         [ $($LFS getstripe -S $DIR/$tdir/subdir/second) == 1048576 ] ||
23575                 error "bad stripe size in sub-directory"
23576         return 0
23577 }
23578 run_test 270c "DoM: DoM EA inheritance tests"
23579
23580 test_270d() {
23581         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23582                 skip "Need MDS version at least 2.10.55"
23583
23584         mkdir -p $DIR/$tdir
23585         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
23586
23587         # inherit default DoM striping
23588         mkdir $DIR/$tdir/subdir
23589         touch $DIR/$tdir/subdir/f1
23590
23591         # change default directory striping
23592         $LFS setstripe -c 1 $DIR/$tdir/subdir
23593         touch $DIR/$tdir/subdir/f2
23594         [ $($LFS getstripe -c $DIR/$tdir/subdir/f2) == 1 ] ||
23595                 error "wrong default striping in file 2"
23596         [ $($LFS getstripe -L $DIR/$tdir/subdir/f2) == "raid0" ] ||
23597                 error "bad pattern in file 2"
23598         return 0
23599 }
23600 run_test 270d "DoM: change striping from DoM to RAID0"
23601
23602 test_270e() {
23603         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23604                 skip "Need MDS version at least 2.10.55"
23605
23606         mkdir -p $DIR/$tdir/dom
23607         mkdir -p $DIR/$tdir/norm
23608         DOMFILES=20
23609         NORMFILES=10
23610         $LFS setstripe -E 1M -L mdt $DIR/$tdir/dom
23611         $LFS setstripe -i 0 -S 2M $DIR/$tdir/norm
23612
23613         createmany -o $DIR/$tdir/dom/dom- $DOMFILES
23614         createmany -o $DIR/$tdir/norm/norm- $NORMFILES
23615
23616         # find DoM files by layout
23617         NUM=$($LFS find -L mdt -type f $DIR/$tdir 2>/dev/null | wc -l)
23618         [ $NUM -eq  $DOMFILES ] ||
23619                 error "lfs find -L: found $NUM, expected $DOMFILES"
23620         echo "Test 1: lfs find 20 DOM files by layout: OK"
23621
23622         # there should be 1 dir with default DOM striping
23623         NUM=$($LFS find -L mdt -type d $DIR/$tdir 2>/dev/null | wc -l)
23624         [ $NUM -eq  1 ] ||
23625                 error "lfs find -L: found $NUM, expected 1 dir"
23626         echo "Test 2: lfs find 1 DOM dir by layout: OK"
23627
23628         # find DoM files by stripe size
23629         NUM=$($LFS find -S -1200K -type f $DIR/$tdir 2>/dev/null | wc -l)
23630         [ $NUM -eq  $DOMFILES ] ||
23631                 error "lfs find -S: found $NUM, expected $DOMFILES"
23632         echo "Test 4: lfs find 20 DOM files by stripe size: OK"
23633
23634         # find files by stripe offset except DoM files
23635         NUM=$($LFS find -i 0 -type f $DIR/$tdir 2>/dev/null | wc -l)
23636         [ $NUM -eq  $NORMFILES ] ||
23637                 error "lfs find -i: found $NUM, expected $NORMFILES"
23638         echo "Test 5: lfs find no DOM files by stripe index: OK"
23639         return 0
23640 }
23641 run_test 270e "DoM: lfs find with DoM files test"
23642
23643 test_270f() {
23644         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23645                 skip "Need MDS version at least 2.10.55"
23646
23647         local mdtname=${FSNAME}-MDT0000-mdtlov
23648         local dom=$DIR/$tdir/dom_file
23649         local dom_limit_saved=$(do_facet mds1 $LCTL get_param -n \
23650                                                 lod.$mdtname.dom_stripesize)
23651         local dom_limit=131072
23652
23653         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=$dom_limit
23654         local dom_current=$(do_facet mds1 $LCTL get_param -n \
23655                                                 lod.$mdtname.dom_stripesize)
23656         [ ${dom_limit} -eq ${dom_current} ] ||
23657                 error "Cannot change per-MDT DoM stripe limit to $dom_limit"
23658
23659         $LFS mkdir -i 0 -c 1 $DIR/$tdir
23660         $LFS setstripe -d $DIR/$tdir
23661         $LFS setstripe -E $dom_limit -L mdt $DIR/$tdir ||
23662                 error "Can't set directory default striping"
23663
23664         # exceed maximum stripe size
23665         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
23666                 error "Can't create file with $((dom_limit * 2)) DoM stripe"
23667         [ $($LFS getstripe -S $dom) -eq $((dom_limit * 2)) ] &&
23668                 error "Able to create DoM component size more than LOD limit"
23669
23670         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
23671         dom_current=$(do_facet mds1 $LCTL get_param -n \
23672                                                 lod.$mdtname.dom_stripesize)
23673         [ 0 -eq ${dom_current} ] ||
23674                 error "Can't set zero DoM stripe limit"
23675         rm $dom
23676
23677         # attempt to create DoM file on server with disabled DoM should
23678         # remove DoM entry from layout and be succeed
23679         $LFS setstripe -E $dom_limit -L mdt -E -1 $dom ||
23680                 error "Can't create DoM file (DoM is disabled)"
23681         [ $($LFS getstripe -L $dom) == "mdt" ] &&
23682                 error "File has DoM component while DoM is disabled"
23683         rm $dom
23684
23685         # attempt to create DoM file with only DoM stripe should return error
23686         $LFS setstripe -E $dom_limit -L mdt $dom &&
23687                 error "Able to create DoM-only file while DoM is disabled"
23688
23689         # too low values to be aligned with smallest stripe size 64K
23690         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=30000
23691         dom_current=$(do_facet mds1 $LCTL get_param -n \
23692                                                 lod.$mdtname.dom_stripesize)
23693         [ 30000 -eq ${dom_current} ] &&
23694                 error "Can set too small DoM stripe limit"
23695
23696         # 64K is a minimal stripe size in Lustre, expect limit of that size
23697         [ 65536 -eq ${dom_current} ] ||
23698                 error "Limit is not set to 64K but ${dom_current}"
23699
23700         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=2147483648
23701         dom_current=$(do_facet mds1 $LCTL get_param -n \
23702                                                 lod.$mdtname.dom_stripesize)
23703         echo $dom_current
23704         [ 2147483648 -eq ${dom_current} ] &&
23705                 error "Can set too large DoM stripe limit"
23706
23707         do_facet mds1 $LCTL set_param -n \
23708                                 lod.$mdtname.dom_stripesize=$((dom_limit * 2))
23709         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
23710                 error "Can't create DoM component size after limit change"
23711         do_facet mds1 $LCTL set_param -n \
23712                                 lod.$mdtname.dom_stripesize=$((dom_limit / 2))
23713         $LFS setstripe -E $dom_limit -L mdt ${dom}_big ||
23714                 error "Can't create DoM file after limit decrease"
23715         [ $($LFS getstripe -S ${dom}_big) -eq $((dom_limit / 2)) ] ||
23716                 error "Can create big DoM component after limit decrease"
23717         touch ${dom}_def ||
23718                 error "Can't create file with old default layout"
23719
23720         do_facet mds1 $LCTL set_param -n lod.*.dom_stripesize=$dom_limit_saved
23721         return 0
23722 }
23723 run_test 270f "DoM: maximum DoM stripe size checks"
23724
23725 test_270g() {
23726         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
23727                 skip "Need MDS version at least 2.13.52"
23728         local dom=$DIR/$tdir/$tfile
23729
23730         $LFS mkdir -i 0 -c 1 $DIR/$tdir
23731         local lodname=${FSNAME}-MDT0000-mdtlov
23732
23733         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
23734         save_lustre_params mds1 "lod.${lodname}.dom_stripesize_max_kb" > $save
23735         save_lustre_params mds1 "lod.${lodname}.dom_threshold_free_mb" >> $save
23736         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
23737
23738         local dom_limit=1024
23739         local dom_threshold="50%"
23740
23741         $LFS setstripe -d $DIR/$tdir
23742         $LFS setstripe -E ${dom_limit}K -L mdt $DIR/$tdir ||
23743                 error "Can't set directory default striping"
23744
23745         do_facet mds1 $LCTL set_param -n \
23746                                 lod.${lodname}.dom_stripesize_max_kb=$dom_limit
23747         # set 0 threshold and create DOM file to change tunable stripesize
23748         do_facet mds1 $LCTL set_param -n lod.${lodname}.dom_threshold_free_mb=0
23749         $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
23750                 error "Failed to create $dom file"
23751         # now tunable dom_cur_stripesize should reach maximum
23752         local dom_current=$(do_facet mds1 $LCTL get_param -n \
23753                                         lod.${lodname}.dom_stripesize_cur_kb)
23754         [[ $dom_current == $dom_limit ]] ||
23755                 error "Current DOM stripesize is not maximum"
23756         rm $dom
23757
23758         # set threshold for further tests
23759         do_facet mds1 $LCTL set_param -n \
23760                         lod.${lodname}.dom_threshold_free_mb=$dom_threshold
23761         echo "DOM threshold is $dom_threshold free space"
23762         local dom_def
23763         local dom_set
23764         # Spoof bfree to exceed threshold
23765         #define OBD_FAIL_MDS_STATFS_SPOOF   0x168
23766         do_facet mds1 $LCTL set_param -n fail_loc=0x0168
23767         for spfree in 40 20 0 15 30 55; do
23768                 do_facet mds1 $LCTL set_param -n fail_val=$spfree
23769                 $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
23770                         error "Failed to create $dom file"
23771                 dom_def=$(do_facet mds1 $LCTL get_param -n \
23772                                         lod.${lodname}.dom_stripesize_cur_kb)
23773                 echo "Free space: ${spfree}%, default DOM stripe: ${dom_def}K"
23774                 [[ $dom_def != $dom_current ]] ||
23775                         error "Default stripe size was not changed"
23776                 if (( spfree > 0 )) ; then
23777                         dom_set=$($LFS getstripe -S $dom)
23778                         (( dom_set == dom_def * 1024 )) ||
23779                                 error "DOM component size is still old"
23780                 else
23781                         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
23782                                 error "DoM component is set with no free space"
23783                 fi
23784                 rm $dom
23785                 dom_current=$dom_def
23786         done
23787 }
23788 run_test 270g "DoM: default DoM stripe size depends on free space"
23789
23790 test_270h() {
23791         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
23792                 skip "Need MDS version at least 2.13.53"
23793
23794         local mdtname=${FSNAME}-MDT0000-mdtlov
23795         local dom=$DIR/$tdir/$tfile
23796         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
23797
23798         save_lustre_params mds1 "lod.*.dom_stripesize" > $save
23799         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
23800
23801         $LFS mkdir -i 0 -c 1 $DIR/$tdir
23802         $LFS setstripe -E 1M -c1  -E -1 -c2 ${dom}_1 ||
23803                 error "can't create OST file"
23804         # mirrored file with DOM entry in the second mirror
23805         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 ${dom}_1 ||
23806                 error "can't create mirror with DoM component"
23807
23808         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
23809
23810         # DOM component in the middle and has other enries in the same mirror,
23811         # should succeed but lost DoM component
23812         $LFS setstripe --copy=${dom}_1 $dom ||
23813                 error "Can't create file from OST|DOM mirror layout"
23814         # check new file has no DoM layout after all
23815         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
23816                 error "File has DoM component while DoM is disabled"
23817 }
23818 run_test 270h "DoM: DoM stripe removal when disabled on server"
23819
23820 test_270i() {
23821         (( $MDS1_VERSION >= $(version_code 2.14.54) )) ||
23822                 skip "Need MDS version at least 2.14.54"
23823
23824         mkdir $DIR/$tdir
23825         # DoM with plain layout
23826         $LFS setstripe -L mdt -S 128k -c -1 $DIR/$tdir &&
23827                 error "default plain layout with DoM must fail"
23828         $LFS setstripe -L mdt -S 128k -c -1 $DIR/$tdir/$tfile &&
23829                 error "setstripe plain file layout with DoM must fail"
23830         $LFS setstripe -E 1M -L mdt -S 128k -c -1 -E eof $DIR/$tdir &&
23831                 error "default DoM layout with bad striping must fail"
23832         $LFS setstripe -E 1M -L mdt -S 128k -c -1 -E eof $DIR/$tdir/$tfile &&
23833                 error "setstripe to DoM layout with bad striping must fail"
23834         return 0
23835 }
23836 run_test 270i "DoM: setting invalid DoM striping should fail"
23837
23838 test_270j() {
23839         (( $MDS1_VERSION >= $(version_code 2.15.55.203) )) ||
23840                 skip "Need MDS version at least 2.15.55.203"
23841
23842         local dom=$DIR/$tdir/$tfile
23843         local odv
23844         local ndv
23845
23846         mkdir -p $DIR/$tdir
23847
23848         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
23849
23850         odv=$($LFS data_version $dom)
23851         chmod 666 $dom
23852         mv $dom ${dom}_moved
23853         link ${dom}_moved $dom
23854         setfattr -n user.attrx -v "some_attr" $dom
23855         ndv=$($LFS data_version $dom)
23856         (( $ndv == $odv )) ||
23857                 error "data version was changed by metadata operations"
23858
23859         dd if=/dev/urandom of=$dom bs=1M count=1 ||
23860                 error "failed to write data into $dom"
23861         cancel_lru_locks mdc
23862         ndv=$($LFS data_version $dom)
23863         (( $ndv != $odv )) ||
23864                 error "data version wasn't changed on write"
23865
23866         odv=$ndv
23867         $TRUNCATE $dom 1000 || error "failed to truncate $dom"
23868         ndv=$($LFS data_version $dom)
23869         (( $ndv != $odv )) ||
23870                 error "data version wasn't changed on truncate down"
23871
23872         odv=$ndv
23873         $TRUNCATE $dom 25000
23874         ndv=$($LFS data_version $dom)
23875         (( $ndv != $odv )) ||
23876                 error "data version wasn't changed on truncate up"
23877
23878         # check also fallocate for ldiskfs
23879         if [[ "$mds1_FSTYPE" == ldiskfs ]]; then
23880                 odv=$ndv
23881                 fallocate -l 1048576 $dom
23882                 ndv=$($LFS data_version $dom)
23883                 (( $ndv != $odv )) ||
23884                         error "data version wasn't changed on fallocate"
23885
23886                 odv=$ndv
23887                 fallocate -p --offset 4096 -l 4096 $dom
23888                 ndv=$($LFS data_version $dom)
23889                 (( $ndv != $odv )) ||
23890                         error "data version wasn't changed on fallocate punch"
23891         fi
23892 }
23893 run_test 270j "DoM migration: DOM file to the OST-striped file (plain)"
23894
23895 test_271a() {
23896         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23897                 skip "Need MDS version at least 2.10.55"
23898
23899         local dom=$DIR/$tdir/dom
23900
23901         mkdir -p $DIR/$tdir
23902
23903         $LFS setstripe -E 1024K -L mdt $dom
23904
23905         lctl set_param -n mdc.*.stats=clear
23906         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
23907         cat $dom > /dev/null
23908         local reads=$(lctl get_param -n mdc.*.stats | grep -c ost_read)
23909         [ $reads -eq 0 ] || error "Unexpected $reads READ RPCs"
23910         ls $dom
23911         rm -f $dom
23912 }
23913 run_test 271a "DoM: data is cached for read after write"
23914
23915 test_271b() {
23916         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23917                 skip "Need MDS version at least 2.10.55"
23918
23919         local dom=$DIR/$tdir/dom
23920
23921         mkdir -p $DIR/$tdir
23922
23923         $LFS setstripe -E 1024K -L mdt -E EOF $dom
23924
23925         lctl set_param -n mdc.*.stats=clear
23926         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
23927         cancel_lru_locks mdc
23928         $CHECKSTAT -t file -s 4096 $dom || error "stat #1 fails"
23929         # second stat to check size is cached on client
23930         $CHECKSTAT -t file -s 4096 $dom || error "stat #2 fails"
23931         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
23932         [ $gls -eq 0 ] || error "Unexpected $gls glimpse RPCs"
23933         rm -f $dom
23934 }
23935 run_test 271b "DoM: no glimpse RPC for stat (DoM only file)"
23936
23937 test_271ba() {
23938         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23939                 skip "Need MDS version at least 2.10.55"
23940
23941         local dom=$DIR/$tdir/dom
23942
23943         mkdir -p $DIR/$tdir
23944
23945         $LFS setstripe -E 1024K -L mdt -E EOF $dom
23946
23947         lctl set_param -n mdc.*.stats=clear
23948         lctl set_param -n osc.*.stats=clear
23949         dd if=/dev/zero of=$dom bs=2048K count=1 || return 1
23950         cancel_lru_locks mdc
23951         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
23952         # second stat to check size is cached on client
23953         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
23954         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
23955         [ $gls == 0 ] || error "Unexpected $gls glimpse RPCs"
23956         local gls=$(lctl get_param -n osc.*.stats | grep -c ldlm_glimpse)
23957         [ $gls == 0 ] || error "Unexpected $gls OSC glimpse RPCs"
23958         rm -f $dom
23959 }
23960 run_test 271ba "DoM: no glimpse RPC for stat (combined file)"
23961
23962
23963 get_mdc_stats() {
23964         local mdtidx=$1
23965         local param=$2
23966         local mdt=MDT$(printf %04x $mdtidx)
23967
23968         if [ -z $param ]; then
23969                 lctl get_param -n mdc.*$mdt*.stats
23970         else
23971                 lctl get_param -n mdc.*$mdt*.stats | awk "/$param/"'{print $2}'
23972         fi
23973 }
23974
23975 test_271c() {
23976         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23977                 skip "Need MDS version at least 2.10.55"
23978
23979         local dom=$DIR/$tdir/dom
23980
23981         mkdir -p $DIR/$tdir
23982
23983         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
23984
23985         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
23986         local facet=mds$((mdtidx + 1))
23987
23988         cancel_lru_locks mdc
23989         do_facet $facet lctl set_param -n mdt.*.dom_lock=0
23990         createmany -o $dom 1000
23991         lctl set_param -n mdc.*.stats=clear
23992         smalliomany -w $dom 1000 200
23993         get_mdc_stats $mdtidx
23994         local enq=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
23995         # Each file has 1 open, 1 IO enqueues, total 2000
23996         # but now we have also +1 getxattr for security.capability, total 3000
23997         [ $enq -ge 2000 ] || error "Too few enqueues $enq, expected > 2000"
23998         unlinkmany $dom 1000
23999
24000         cancel_lru_locks mdc
24001         do_facet $facet lctl set_param -n mdt.*.dom_lock=1
24002         createmany -o $dom 1000
24003         lctl set_param -n mdc.*.stats=clear
24004         smalliomany -w $dom 1000 200
24005         local enq_2=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
24006         # Expect to see reduced amount of RPCs by 1000 due to single enqueue
24007         # for OPEN and IO lock.
24008         [ $((enq - enq_2)) -ge 1000 ] ||
24009                 error "Too many enqueues $enq_2, expected about $((enq - 1000))"
24010         unlinkmany $dom 1000
24011         return 0
24012 }
24013 run_test 271c "DoM: IO lock at open saves enqueue RPCs"
24014
24015 cleanup_271def_tests() {
24016         trap 0
24017         rm -f $1
24018 }
24019
24020 test_271d() {
24021         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
24022                 skip "Need MDS version at least 2.10.57"
24023
24024         local dom=$DIR/$tdir/dom
24025         local tmp=$TMP/$tfile
24026         trap "cleanup_271def_tests $tmp" EXIT
24027
24028         mkdir -p $DIR/$tdir
24029
24030         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
24031
24032         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
24033
24034         cancel_lru_locks mdc
24035         dd if=/dev/urandom of=$tmp bs=1000 count=1
24036         dd if=$tmp of=$dom bs=1000 count=1
24037         cancel_lru_locks mdc
24038
24039         cat /etc/hosts >> $tmp
24040         lctl set_param -n mdc.*.stats=clear
24041
24042         # append data to the same file it should update local page
24043         echo "Append to the same page"
24044         cat /etc/hosts >> $dom
24045         local num=$(get_mdc_stats $mdtidx ost_read)
24046         local ra=$(get_mdc_stats $mdtidx req_active)
24047         local rw=$(get_mdc_stats $mdtidx req_waittime)
24048
24049         [ -z $num ] || error "$num READ RPC occured"
24050         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
24051         echo "... DONE"
24052
24053         # compare content
24054         cmp $tmp $dom || error "file miscompare"
24055
24056         cancel_lru_locks mdc
24057         lctl set_param -n mdc.*.stats=clear
24058
24059         echo "Open and read file"
24060         cat $dom > /dev/null
24061         local num=$(get_mdc_stats $mdtidx ost_read)
24062         local ra=$(get_mdc_stats $mdtidx req_active)
24063         local rw=$(get_mdc_stats $mdtidx req_waittime)
24064
24065         [ -z $num ] || error "$num READ RPC occured"
24066         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
24067         echo "... DONE"
24068
24069         # compare content
24070         cmp $tmp $dom || error "file miscompare"
24071
24072         return 0
24073 }
24074 run_test 271d "DoM: read on open (1K file in reply buffer)"
24075
24076 test_271f() {
24077         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
24078                 skip "Need MDS version at least 2.10.57"
24079
24080         local dom=$DIR/$tdir/dom
24081         local tmp=$TMP/$tfile
24082         trap "cleanup_271def_tests $tmp" EXIT
24083
24084         mkdir -p $DIR/$tdir
24085
24086         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
24087
24088         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
24089
24090         cancel_lru_locks mdc
24091         dd if=/dev/urandom of=$tmp bs=265000 count=1
24092         dd if=$tmp of=$dom bs=265000 count=1
24093         cancel_lru_locks mdc
24094         cat /etc/hosts >> $tmp
24095         lctl set_param -n mdc.*.stats=clear
24096
24097         echo "Append to the same page"
24098         cat /etc/hosts >> $dom
24099         local num=$(get_mdc_stats $mdtidx ost_read)
24100         local ra=$(get_mdc_stats $mdtidx req_active)
24101         local rw=$(get_mdc_stats $mdtidx req_waittime)
24102
24103         [ -z $num ] || error "$num READ RPC occured"
24104         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
24105         echo "... DONE"
24106
24107         # compare content
24108         cmp $tmp $dom || error "file miscompare"
24109
24110         cancel_lru_locks mdc
24111         lctl set_param -n mdc.*.stats=clear
24112
24113         echo "Open and read file"
24114         cat $dom > /dev/null
24115         local num=$(get_mdc_stats $mdtidx ost_read)
24116         local ra=$(get_mdc_stats $mdtidx req_active)
24117         local rw=$(get_mdc_stats $mdtidx req_waittime)
24118
24119         [ -z $num ] && num=0
24120         [ $num -eq 1 ] || error "expect 1 READ RPC, $num occured"
24121         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
24122         echo "... DONE"
24123
24124         # compare content
24125         cmp $tmp $dom || error "file miscompare"
24126
24127         return 0
24128 }
24129 run_test 271f "DoM: read on open (200K file and read tail)"
24130
24131 test_271g() {
24132         [[ $($LCTL get_param mdc.*.import) =~ async_discard ]] ||
24133                 skip "Skipping due to old client or server version"
24134
24135         $LFS setstripe -E 1024K -L mdt -E EOF $DIR1/$tfile
24136         # to get layout
24137         $CHECKSTAT -t file $DIR1/$tfile
24138
24139         $MULTIOP $DIR1/$tfile Ow40960_w4096c &
24140         MULTIOP_PID=$!
24141         sleep 1
24142         #define OBD_FAIL_LDLM_CANCEL_BL_CB_RACE
24143         $LCTL set_param fail_loc=0x80000314
24144         rm $DIR1/$tfile || error "Unlink fails"
24145         RC=$?
24146         kill -USR1 $MULTIOP_PID && wait $MULTIOP_PID || error "multiop failure"
24147         [ $RC -eq 0 ] || error "Failed write to stale object"
24148 }
24149 run_test 271g "Discard DoM data vs client flush race"
24150
24151 test_272a() {
24152         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
24153                 skip "Need MDS version at least 2.11.50"
24154
24155         local dom=$DIR/$tdir/dom
24156         mkdir -p $DIR/$tdir
24157
24158         $LFS setstripe -E 256K -L mdt -E -1 -c1 $dom
24159         dd if=/dev/urandom of=$dom bs=512K count=1 ||
24160                 error "failed to write data into $dom"
24161         local old_md5=$(md5sum $dom)
24162
24163         $LFS migrate -E 256K -L mdt -E -1 -c2 $dom ||
24164                 error "failed to migrate to the same DoM component"
24165
24166         local new_md5=$(md5sum $dom)
24167
24168         [ "$old_md5" == "$new_md5" ] ||
24169                 error "md5sum differ: $old_md5, $new_md5"
24170
24171         [ $($LFS getstripe -c $dom) -eq 2 ] ||
24172                 error "bad final stripe count: $($LFS getstripe -c $dom) != 2"
24173 }
24174 run_test 272a "DoM migration: new layout with the same DOM component"
24175
24176 test_272b() {
24177         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
24178                 skip "Need MDS version at least 2.11.50"
24179
24180         local dom=$DIR/$tdir/dom
24181         mkdir -p $DIR/$tdir
24182         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
24183         stack_trap "rm -rf $DIR/$tdir"
24184
24185         local mdtidx=$($LFS getstripe -m $dom)
24186         local mdtname=MDT$(printf %04x $mdtidx)
24187         local facet=mds$((mdtidx + 1))
24188
24189         local mdtfree1=$(do_facet $facet \
24190                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24191         dd if=/dev/urandom of=$dom bs=2M count=1 ||
24192                 error "failed to write data into $dom"
24193         local old_md5=$(md5sum $dom)
24194         cancel_lru_locks mdc
24195         local mdtfree1=$(do_facet $facet \
24196                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24197
24198         $LFS migrate -c2 $dom ||
24199                 error "failed to migrate to the new composite layout"
24200         [[ $($LFS getstripe --component-start=0 -L $dom) != 'mdt' ]] ||
24201                 error "MDT stripe was not removed"
24202         ! getfattr -n trusted.dataver $dom &> /dev/null ||
24203                 error "$dir1 shouldn't have DATAVER EA"
24204
24205         cancel_lru_locks mdc
24206         local new_md5=$(md5sum $dom)
24207         [ "$old_md5" == "$new_md5" ] ||
24208                 error "$old_md5 != $new_md5"
24209
24210         # Skip free space checks with ZFS
24211         if [ "$(facet_fstype $facet)" != "zfs" ]; then
24212                 local mdtfree2=$(do_facet $facet \
24213                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24214                 [ $mdtfree2 -gt $mdtfree1 ] ||
24215                         error "MDT space is not freed after migration"
24216         fi
24217         return 0
24218 }
24219 run_test 272b "DoM migration: DOM file to the OST-striped file (plain)"
24220
24221 test_272c() {
24222         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
24223                 skip "Need MDS version at least 2.11.50"
24224
24225         local dom=$DIR/$tdir/$tfile
24226         mkdir -p $DIR/$tdir
24227         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
24228         stack_trap "rm -rf $DIR/$tdir"
24229
24230         local mdtidx=$($LFS getstripe -m $dom)
24231         local mdtname=MDT$(printf %04x $mdtidx)
24232         local facet=mds$((mdtidx + 1))
24233
24234         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
24235                 error "failed to write data into $dom"
24236         local old_md5=$(md5sum $dom)
24237         cancel_lru_locks mdc
24238         local mdtfree1=$(do_facet $facet \
24239                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24240
24241         $LFS migrate -E 2M -c1 -E -1 -c2 $dom ||
24242                 error "failed to migrate to the new composite layout"
24243         [[ $($LFS getstripe --component-start=0 -L $dom) != 'mdt' ]] ||
24244                 error "MDT stripe was not removed"
24245
24246         cancel_lru_locks mdc
24247         local new_md5=$(md5sum $dom)
24248         [ "$old_md5" == "$new_md5" ] ||
24249                 error "$old_md5 != $new_md5"
24250
24251         # Skip free space checks with ZFS
24252         if [ "$(facet_fstype $facet)" != "zfs" ]; then
24253                 local mdtfree2=$(do_facet $facet \
24254                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24255                 [ $mdtfree2 -gt $mdtfree1 ] ||
24256                         error "MDS space is not freed after migration"
24257         fi
24258         return 0
24259 }
24260 run_test 272c "DoM migration: DOM file to the OST-striped file (composite)"
24261
24262 test_272d() {
24263         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
24264                 skip "Need MDS version at least 2.12.55"
24265
24266         local dom=$DIR/$tdir/$tfile
24267         mkdir -p $DIR/$tdir
24268         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
24269
24270         local mdtidx=$($LFS getstripe -m $dom)
24271         local mdtname=MDT$(printf %04x $mdtidx)
24272         local facet=mds$((mdtidx + 1))
24273
24274         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
24275                 error "failed to write data into $dom"
24276         local old_md5=$(md5sum $dom)
24277         cancel_lru_locks mdc
24278         local mdtfree1=$(do_facet $facet \
24279                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24280
24281         $LFS mirror extend -N -E 2M -c1 -E -1 -c2 $dom ||
24282                 error "failed mirroring to the new composite layout"
24283         $LFS mirror resync $dom ||
24284                 error "failed mirror resync"
24285         $LFS mirror split --mirror-id 1 -d $dom ||
24286                 error "failed mirror split"
24287
24288         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
24289                 error "MDT stripe was not removed"
24290
24291         cancel_lru_locks mdc
24292         local new_md5=$(md5sum $dom)
24293         [ "$old_md5" == "$new_md5" ] ||
24294                 error "$old_md5 != $new_md5"
24295
24296         # Skip free space checks with ZFS
24297         if [ "$(facet_fstype $facet)" != "zfs" ]; then
24298                 local mdtfree2=$(do_facet $facet \
24299                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24300                 [ $mdtfree2 -gt $mdtfree1 ] ||
24301                         error "MDS space is not freed after DOM mirror deletion"
24302         fi
24303         return 0
24304 }
24305 run_test 272d "DoM mirroring: OST-striped mirror to DOM file"
24306
24307 test_272e() {
24308         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
24309                 skip "Need MDS version at least 2.12.55"
24310
24311         local dom=$DIR/$tdir/$tfile
24312         mkdir -p $DIR/$tdir
24313         $LFS setstripe -c 2 $dom
24314
24315         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
24316                 error "failed to write data into $dom"
24317         local old_md5=$(md5sum $dom)
24318         cancel_lru_locks
24319
24320         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 $dom ||
24321                 error "failed mirroring to the DOM layout"
24322         $LFS mirror resync $dom ||
24323                 error "failed mirror resync"
24324         $LFS mirror split --mirror-id 1 -d $dom ||
24325                 error "failed mirror split"
24326
24327         [[ $($LFS getstripe -L --component-start=0 $dom) == 'mdt' ]] ||
24328                 error "MDT stripe wasn't set"
24329
24330         cancel_lru_locks
24331         local new_md5=$(md5sum $dom)
24332         [ "$old_md5" == "$new_md5" ] ||
24333                 error "$old_md5 != $new_md5"
24334
24335         return 0
24336 }
24337 run_test 272e "DoM mirroring: DOM mirror to the OST-striped file"
24338
24339 test_272f() {
24340         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
24341                 skip "Need MDS version at least 2.12.55"
24342
24343         local dom=$DIR/$tdir/$tfile
24344         mkdir -p $DIR/$tdir
24345         $LFS setstripe -c 2 $dom
24346
24347         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
24348                 error "failed to write data into $dom"
24349         local old_md5=$(md5sum $dom)
24350         cancel_lru_locks
24351
24352         $LFS migrate -E 1M -L mdt -E eof -c2 -v $dom ||
24353                 error "failed migrating to the DOM file"
24354
24355         [[ $($LFS getstripe -L --component-start=0 $dom) == 'mdt' ]] ||
24356                 error "MDT stripe wasn't set"
24357
24358         cancel_lru_locks
24359         local new_md5=$(md5sum $dom)
24360         [ "$old_md5" != "$new_md5" ] &&
24361                 error "$old_md5 != $new_md5"
24362
24363         return 0
24364 }
24365 run_test 272f "DoM migration: OST-striped file to DOM file"
24366
24367 test_273a() {
24368         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
24369                 skip "Need MDS version at least 2.11.50"
24370
24371         # Layout swap cannot be done if either file has DOM component,
24372         # this will never be supported, migration should be used instead
24373
24374         local dom=$DIR/$tdir/$tfile
24375         mkdir -p $DIR/$tdir
24376
24377         $LFS setstripe -c2 ${dom}_plain
24378         $LFS setstripe -E 1M -L mdt -E -1 -c2 ${dom}_dom
24379         $LFS swap_layouts ${dom}_plain ${dom}_dom &&
24380                 error "can swap layout with DoM component"
24381         $LFS swap_layouts ${dom}_dom ${dom}_plain &&
24382                 error "can swap layout with DoM component"
24383
24384         $LFS setstripe -E 1M -c1 -E -1 -c2 ${dom}_comp
24385         $LFS swap_layouts ${dom}_comp ${dom}_dom &&
24386                 error "can swap layout with DoM component"
24387         $LFS swap_layouts ${dom}_dom ${dom}_comp &&
24388                 error "can swap layout with DoM component"
24389         return 0
24390 }
24391 run_test 273a "DoM: layout swapping should fail with DOM"
24392
24393 test_273b() {
24394         mkdir -p $DIR/$tdir
24395         $LFS setstripe -E 1M -L mdt -E -1 -c -1 $DIR/$tdir
24396
24397 #define OBD_FAIL_MDS_COMMITRW_DELAY      0x16b
24398         do_facet mds1 $LCTL set_param fail_loc=0x8000016b fail_val=2
24399
24400         $MULTIOP $DIR/$tdir/$tfile Ouw2097152c
24401 }
24402 run_test 273b "DoM: race writeback and object destroy"
24403
24404 test_273c() {
24405         mkdir -p $DIR/$tdir
24406         $LFS setstripe -E 1M -E-1 -c-1 $DIR/$tdir
24407
24408         #define OBD_FAIL_OFD_COMMITRW_DELAY      0x1e1
24409         do_facet ost1 $LCTL set_param fail_loc=0x800001e1 fail_val=2
24410
24411         $MULTIOP $DIR/$tdir/$tfile Ouw2097152c
24412 }
24413 run_test 273c "race writeback and object destroy"
24414
24415 test_275() {
24416         remote_ost_nodsh && skip "remote OST with nodsh"
24417         [ $OST1_VERSION -lt $(version_code 2.10.57) ] &&
24418                 skip "Need OST version >= 2.10.57"
24419
24420         local file=$DIR/$tfile
24421         local oss
24422
24423         oss=$(comma_list $(osts_nodes))
24424
24425         dd if=/dev/urandom of=$file bs=1M count=2 ||
24426                 error "failed to create a file"
24427         stack_trap "rm -f $file"
24428         cancel_lru_locks osc
24429
24430         #lock 1
24431         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
24432                 error "failed to read a file"
24433
24434 #define OBD_FAIL_LDLM_PAUSE_CANCEL2      0x31f
24435         $LCTL set_param fail_loc=0x8000031f
24436
24437         cancel_lru_locks osc &
24438         sleep 1
24439
24440 #define OBD_FAIL_LDLM_PROLONG_PAUSE      0x32b
24441         do_nodes $oss $LCTL set_param fail_loc=0x8000032b
24442         #IO takes another lock, but matches the PENDING one
24443         #and places it to the IO RPC
24444         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
24445                 error "failed to read a file with PENDING lock"
24446 }
24447 run_test 275 "Read on a canceled duplicate lock"
24448
24449 test_276() {
24450         remote_ost_nodsh && skip "remote OST with nodsh"
24451         local pid
24452
24453         do_facet ost1 "(while true; do \
24454                 $LCTL get_param obdfilter.*.filesfree > /dev/null 2>&1; \
24455                 done) & pid=\\\$!; echo \\\$pid > $TMP/sanity_276_pid" &
24456         pid=$!
24457
24458         for LOOP in $(seq 20); do
24459                 stop ost1
24460                 start ost1 $(ostdevname 1) $OST_MOUNT_OPTS
24461         done
24462         kill -9 $pid
24463         do_facet ost1 "pid=\\\$(cat $TMP/sanity_276_pid); kill -9 \\\$pid; \
24464                 rm $TMP/sanity_276_pid"
24465 }
24466 run_test 276 "Race between mount and obd_statfs"
24467
24468 test_277() {
24469         $LCTL set_param ldlm.namespaces.*.lru_size=0
24470         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
24471         local cached_mb=$($LCTL get_param llite.*.max_cached_mb |
24472                         grep ^used_mb | awk '{print $2}')
24473         [ $cached_mb -eq 1 ] || error "expected mb 1 got $cached_mb"
24474         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 \
24475                 oflag=direct conv=notrunc
24476         cached_mb=$($LCTL get_param llite.*.max_cached_mb |
24477                         grep ^used_mb | awk '{print $2}')
24478         [ $cached_mb -eq 0 ] || error "expected mb 0 got $cached_mb"
24479 }
24480 run_test 277 "Direct IO shall drop page cache"
24481
24482 test_278() {
24483         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
24484         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
24485         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] &&
24486                 skip "needs the same host for mdt1 mdt2" && return
24487
24488         local pid1
24489         local pid2
24490
24491 #define OBD_FAIL_OBD_STOP_MDS_RACE     0x60b
24492         do_facet mds2 $LCTL set_param fail_loc=0x8000060c
24493         stop mds2 &
24494         pid2=$!
24495
24496         stop mds1
24497
24498         echo "Starting MDTs"
24499         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
24500         wait $pid2
24501 #For the error assertion will happen. lu_env_get_key(..., &mdt_thread_key)
24502 #will return NULL
24503         do_facet mds2 $LCTL set_param fail_loc=0
24504
24505         start mds2 $(mdsdevname 2) $MDS_MOUNT_OPTS
24506         wait_recovery_complete mds2
24507 }
24508 run_test 278 "Race starting MDS between MDTs stop/start"
24509
24510 test_280() {
24511         [ $MGS_VERSION -lt $(version_code 2.13.52) ] &&
24512                 skip "Need MGS version at least 2.13.52"
24513         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24514         combined_mgs_mds || skip "needs combined MGS/MDT"
24515
24516         umount_client $MOUNT
24517 #define OBD_FAIL_MDS_LLOG_UMOUNT_RACE   0x15e
24518         do_facet mgs $LCTL set_param fail_loc=0x8000015e fail_val=0
24519
24520         mount_client $MOUNT &
24521         sleep 1
24522         stop mgs || error "stop mgs failed"
24523         #for a race mgs would crash
24524         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
24525         # make sure we unmount client before remounting
24526         wait
24527         umount_client $MOUNT
24528         mount_client $MOUNT || error "mount client failed"
24529 }
24530 run_test 280 "Race between MGS umount and client llog processing"
24531
24532 cleanup_test_300() {
24533         trap 0
24534         umask $SAVE_UMASK
24535 }
24536 test_striped_dir() {
24537         local mdt_index=$1
24538         local stripe_count
24539         local stripe_index
24540
24541         mkdir -p $DIR/$tdir
24542
24543         SAVE_UMASK=$(umask)
24544         trap cleanup_test_300 RETURN EXIT
24545
24546         $LFS setdirstripe -i $mdt_index -c 2 -H all_char -o 755 \
24547                                                 $DIR/$tdir/striped_dir ||
24548                 error "set striped dir error"
24549
24550         local mode=$(stat -c%a $DIR/$tdir/striped_dir)
24551         [ "$mode" = "755" ] || error "expect 755 got $mode"
24552
24553         $LFS getdirstripe $DIR/$tdir/striped_dir > /dev/null 2>&1 ||
24554                 error "getdirstripe failed"
24555         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir)
24556         if [ "$stripe_count" != "2" ]; then
24557                 error "1:stripe_count is $stripe_count, expect 2"
24558         fi
24559         stripe_count=$($LFS getdirstripe -T $DIR/$tdir/striped_dir)
24560         if [ "$stripe_count" != "2" ]; then
24561                 error "2:stripe_count is $stripe_count, expect 2"
24562         fi
24563
24564         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir)
24565         if [ "$stripe_index" != "$mdt_index" ]; then
24566                 error "stripe_index is $stripe_index, expect $mdt_index"
24567         fi
24568
24569         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
24570                 error "nlink error after create striped dir"
24571
24572         mkdir $DIR/$tdir/striped_dir/a
24573         mkdir $DIR/$tdir/striped_dir/b
24574
24575         stat $DIR/$tdir/striped_dir/a ||
24576                 error "create dir under striped dir failed"
24577         stat $DIR/$tdir/striped_dir/b ||
24578                 error "create dir under striped dir failed"
24579
24580         [ $(stat -c%h $DIR/$tdir/striped_dir) == '4' ] ||
24581                 error "nlink error after mkdir"
24582
24583         rmdir $DIR/$tdir/striped_dir/a
24584         [ $(stat -c%h $DIR/$tdir/striped_dir) == '3' ] ||
24585                 error "nlink error after rmdir"
24586
24587         rmdir $DIR/$tdir/striped_dir/b
24588         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
24589                 error "nlink error after rmdir"
24590
24591         chattr +i $DIR/$tdir/striped_dir
24592         createmany -o $DIR/$tdir/striped_dir/f 10 &&
24593                 error "immutable flags not working under striped dir!"
24594         chattr -i $DIR/$tdir/striped_dir
24595
24596         rmdir $DIR/$tdir/striped_dir ||
24597                 error "rmdir striped dir error"
24598
24599         cleanup_test_300
24600
24601         true
24602 }
24603
24604 test_300a() {
24605         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
24606                 skip "skipped for lustre < 2.7.0"
24607         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24608         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24609
24610         test_striped_dir 0 || error "failed on striped dir on MDT0"
24611         test_striped_dir 1 || error "failed on striped dir on MDT0"
24612 }
24613 run_test 300a "basic striped dir sanity test"
24614
24615 test_300b() {
24616         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
24617                 skip "skipped for lustre < 2.7.0"
24618         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24619         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24620
24621         local i
24622         local mtime1
24623         local mtime2
24624         local mtime3
24625
24626         test_mkdir $DIR/$tdir || error "mkdir fail"
24627         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
24628                 error "set striped dir error"
24629         for i in {0..9}; do
24630                 mtime1=$(stat -c %Y $DIR/$tdir/striped_dir)
24631                 sleep 1
24632                 touch $DIR/$tdir/striped_dir/file_$i || error "touch error $i"
24633                 mtime2=$(stat -c %Y $DIR/$tdir/striped_dir)
24634                 [ $mtime1 -eq $mtime2 ] && error "mtime unchanged after create"
24635                 sleep 1
24636                 rm -f $DIR/$tdir/striped_dir/file_$i || error "unlink error $i"
24637                 mtime3=$(stat -c %Y $DIR/$tdir/striped_dir)
24638                 [ $mtime2 -eq $mtime3 ] && error "mtime unchanged after unlink"
24639         done
24640         true
24641 }
24642 run_test 300b "check ctime/mtime for striped dir"
24643
24644 test_300c() {
24645         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
24646                 skip "skipped for lustre < 2.7.0"
24647         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24648         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24649
24650         local file_count
24651
24652         mkdir_on_mdt0 $DIR/$tdir
24653         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir ||
24654                 error "set striped dir error"
24655
24656         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/striped_dir ||
24657                 error "chown striped dir failed"
24658
24659         $RUNAS createmany -o $DIR/$tdir/striped_dir/f 5000 ||
24660                 error "create 5k files failed"
24661
24662         file_count=$(ls $DIR/$tdir/striped_dir | wc -l)
24663
24664         [ "$file_count" = 5000 ] || error "file count $file_count != 5000"
24665
24666         rm -rf $DIR/$tdir
24667 }
24668 run_test 300c "chown && check ls under striped directory"
24669
24670 test_300d() {
24671         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
24672                 skip "skipped for lustre < 2.7.0"
24673         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24674         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24675
24676         local stripe_count
24677         local file
24678
24679         mkdir -p $DIR/$tdir
24680         $LFS setstripe -c 2 $DIR/$tdir
24681
24682         #local striped directory
24683         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
24684                 error "set striped dir error"
24685         #look at the directories for debug purposes
24686         ls -l $DIR/$tdir
24687         $LFS getdirstripe $DIR/$tdir
24688         ls -l $DIR/$tdir/striped_dir
24689         $LFS getdirstripe $DIR/$tdir/striped_dir
24690         createmany -o $DIR/$tdir/striped_dir/f 10 ||
24691                 error "create 10 files failed"
24692
24693         #remote striped directory
24694         $LFS setdirstripe -i 1 -c 2 $DIR/$tdir/remote_striped_dir ||
24695                 error "set striped dir error"
24696         #look at the directories for debug purposes
24697         ls -l $DIR/$tdir
24698         $LFS getdirstripe $DIR/$tdir
24699         ls -l $DIR/$tdir/remote_striped_dir
24700         $LFS getdirstripe $DIR/$tdir/remote_striped_dir
24701         createmany -o $DIR/$tdir/remote_striped_dir/f 10 ||
24702                 error "create 10 files failed"
24703
24704         for file in $(find $DIR/$tdir); do
24705                 stripe_count=$($LFS getstripe -c $file)
24706                 [ $stripe_count -eq 2 ] ||
24707                         error "wrong stripe $stripe_count for $file"
24708         done
24709
24710         rm -rf $DIR/$tdir
24711 }
24712 run_test 300d "check default stripe under striped directory"
24713
24714 test_300e() {
24715         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24716                 skip "Need MDS version at least 2.7.55"
24717         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24718         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24719
24720         local stripe_count
24721         local file
24722
24723         mkdir -p $DIR/$tdir
24724
24725         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
24726                 error "set striped dir error"
24727
24728         touch $DIR/$tdir/striped_dir/a
24729         touch $DIR/$tdir/striped_dir/b
24730         touch $DIR/$tdir/striped_dir/c
24731
24732         mkdir $DIR/$tdir/striped_dir/dir_a
24733         mkdir $DIR/$tdir/striped_dir/dir_b
24734         mkdir $DIR/$tdir/striped_dir/dir_c
24735
24736         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_a ||
24737                 error "set striped adir under striped dir error"
24738
24739         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_b ||
24740                 error "set striped bdir under striped dir error"
24741
24742         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_c ||
24743                 error "set striped cdir under striped dir error"
24744
24745         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir/dir_b ||
24746                 error "rename dir under striped dir fails"
24747
24748         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir/stp_b ||
24749                 error "rename dir under different stripes fails"
24750
24751         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir/c ||
24752                 error "rename file under striped dir should succeed"
24753
24754         mrename $DIR/$tdir/striped_dir/dir_b $DIR/$tdir/striped_dir/dir_c ||
24755                 error "rename dir under striped dir should succeed"
24756
24757         rm -rf $DIR/$tdir
24758 }
24759 run_test 300e "check rename under striped directory"
24760
24761 test_300f() {
24762         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24763         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24764         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24765                 skip "Need MDS version at least 2.7.55"
24766
24767         local stripe_count
24768         local file
24769
24770         rm -rf $DIR/$tdir
24771         mkdir -p $DIR/$tdir
24772
24773         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
24774                 error "set striped dir error"
24775
24776         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir1 ||
24777                 error "set striped dir error"
24778
24779         touch $DIR/$tdir/striped_dir/a
24780         mkdir $DIR/$tdir/striped_dir/dir_a
24781         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_a ||
24782                 error "create striped dir under striped dir fails"
24783
24784         touch $DIR/$tdir/striped_dir1/b
24785         mkdir $DIR/$tdir/striped_dir1/dir_b
24786         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_b ||
24787                 error "create striped dir under striped dir fails"
24788
24789         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir1/dir_b ||
24790                 error "rename dir under different striped dir should fail"
24791
24792         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir1/stp_b ||
24793                 error "rename striped dir under diff striped dir should fail"
24794
24795         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir1/a ||
24796                 error "rename file under diff striped dirs fails"
24797
24798         rm -rf $DIR/$tdir
24799 }
24800 run_test 300f "check rename cross striped directory"
24801
24802 test_300_check_default_striped_dir()
24803 {
24804         local dirname=$1
24805         local default_count=$2
24806         local default_index=$3
24807         local stripe_count
24808         local stripe_index
24809         local dir_stripe_index
24810         local dir
24811
24812         echo "checking $dirname $default_count $default_index"
24813         $LFS setdirstripe -D -c $default_count -i $default_index \
24814                                 -H all_char $DIR/$tdir/$dirname ||
24815                 error "set default stripe on striped dir error"
24816         stripe_count=$($LFS getdirstripe -D -c $DIR/$tdir/$dirname)
24817         [ $stripe_count -eq $default_count ] ||
24818                 error "expect $default_count get $stripe_count for $dirname"
24819
24820         stripe_index=$($LFS getdirstripe -D -i $DIR/$tdir/$dirname)
24821         [ $stripe_index -eq $default_index ] ||
24822                 error "expect $default_index get $stripe_index for $dirname"
24823
24824         mkdir $DIR/$tdir/$dirname/{test1,test2,test3,test4} ||
24825                                                 error "create dirs failed"
24826
24827         createmany -o $DIR/$tdir/$dirname/f- 10 || error "create files failed"
24828         unlinkmany $DIR/$tdir/$dirname/f- 10    || error "unlink files failed"
24829         for dir in $(find $DIR/$tdir/$dirname/*); do
24830                 stripe_count=$($LFS getdirstripe -c $dir)
24831                 (( $stripe_count == $default_count )) ||
24832                 (( $stripe_count == $MDSCOUNT && $default_count == -1 )) ||
24833                 (( $stripe_count == 0 )) || (( $default_count == 1 )) ||
24834                 error "stripe count $default_count != $stripe_count for $dir"
24835
24836                 stripe_index=$($LFS getdirstripe -i $dir)
24837                 [ $default_index -eq -1 ] ||
24838                         [ $stripe_index -eq $default_index ] ||
24839                         error "$stripe_index != $default_index for $dir"
24840
24841                 #check default stripe
24842                 stripe_count=$($LFS getdirstripe -D -c $dir)
24843                 [ $stripe_count -eq $default_count ] ||
24844                 error "default count $default_count != $stripe_count for $dir"
24845
24846                 stripe_index=$($LFS getdirstripe -D -i $dir)
24847                 [ $stripe_index -eq $default_index ] ||
24848                 error "default index $default_index != $stripe_index for $dir"
24849         done
24850         rmdir $DIR/$tdir/$dirname/* || error "rmdir failed"
24851 }
24852
24853 test_300g() {
24854         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24855         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24856                 skip "Need MDS version at least 2.7.55"
24857
24858         local dir
24859         local stripe_count
24860         local stripe_index
24861
24862         mkdir_on_mdt0 $DIR/$tdir
24863         mkdir $DIR/$tdir/normal_dir
24864
24865         #Checking when client cache stripe index
24866         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
24867         $LFS setdirstripe -D -i1 $DIR/$tdir/striped_dir ||
24868                 error "create striped_dir failed"
24869
24870         $LFS setdirstripe -i0 $DIR/$tdir/striped_dir/dir0 ||
24871                 error "create dir0 fails"
24872         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir0)
24873         [ $stripe_index -eq 0 ] ||
24874                 error "dir0 expect index 0 got $stripe_index"
24875
24876         mkdir $DIR/$tdir/striped_dir/dir1 ||
24877                 error "create dir1 fails"
24878         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir1)
24879         [ $stripe_index -eq 1 ] ||
24880                 error "dir1 expect index 1 got $stripe_index"
24881
24882         #check default stripe count/stripe index
24883         test_300_check_default_striped_dir normal_dir $MDSCOUNT 1
24884         test_300_check_default_striped_dir normal_dir 1 0
24885         test_300_check_default_striped_dir normal_dir -1 1
24886         test_300_check_default_striped_dir normal_dir 2 -1
24887
24888         #delete default stripe information
24889         echo "delete default stripeEA"
24890         $LFS setdirstripe -d $DIR/$tdir/normal_dir ||
24891                 error "set default stripe on striped dir error"
24892
24893         mkdir -p $DIR/$tdir/normal_dir/{test1,test2,test3,test4}
24894         for dir in $(find $DIR/$tdir/normal_dir/*); do
24895                 stripe_count=$($LFS getdirstripe -c $dir)
24896                 [ $stripe_count -eq 0 ] ||
24897                         error "expect 1 get $stripe_count for $dir"
24898         done
24899 }
24900 run_test 300g "check default striped directory for normal directory"
24901
24902 test_300h() {
24903         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24904         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24905                 skip "Need MDS version at least 2.7.55"
24906
24907         local dir
24908         local stripe_count
24909
24910         mkdir $DIR/$tdir
24911         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
24912                 error "set striped dir error"
24913
24914         test_300_check_default_striped_dir striped_dir $MDSCOUNT 1
24915         test_300_check_default_striped_dir striped_dir 1 0
24916         test_300_check_default_striped_dir striped_dir -1 1
24917         test_300_check_default_striped_dir striped_dir 2 -1
24918
24919         #delete default stripe information
24920         $LFS setdirstripe -d $DIR/$tdir/striped_dir ||
24921                 error "set default stripe on striped dir error"
24922
24923         mkdir -p $DIR/$tdir/striped_dir/{test1,test2,test3,test4}
24924         for dir in $(find $DIR/$tdir/striped_dir/*); do
24925                 stripe_count=$($LFS getdirstripe -c $dir)
24926                 [ $stripe_count -eq 0 ] ||
24927                         error "expect 1 get $stripe_count for $dir"
24928         done
24929 }
24930 run_test 300h "check default striped directory for striped directory"
24931
24932 test_300i() {
24933         [[ $PARALLEL == "yes" ]] && skip "skip parallel run"
24934         (( $MDSCOUNT >= 2 )) || skip_env "needs >= 2 MDTs"
24935         (( $MDS1_VERSION >= $(version_code 2.7.55) )) ||
24936                 skip "Need MDS version at least 2.7.55"
24937
24938         local stripe_count
24939         local file
24940
24941         mkdir $DIR/$tdir
24942
24943         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
24944                 error "set striped dir error"
24945
24946         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
24947                 error "create files under striped dir failed"
24948
24949         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir ||
24950                 error "set striped hashdir error"
24951
24952         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir/d0 ||
24953                 error "create dir0 under hash dir failed"
24954         $LFS setdirstripe -i0 -c$MDSCOUNT -H fnv_1a_64 $DIR/$tdir/hashdir/d1 ||
24955                 error "create dir1 under hash dir failed"
24956         $LFS setdirstripe -i0 -c$MDSCOUNT -H crush $DIR/$tdir/hashdir/d2 ||
24957                 error "create dir2 under hash dir failed"
24958
24959         # unfortunately, we need to umount to clear dir layout cache for now
24960         # once we fully implement dir layout, we can drop this
24961         umount_client $MOUNT || error "umount failed"
24962         mount_client $MOUNT || error "mount failed"
24963
24964         $LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir
24965         local dircnt=$($LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir | wc -l)
24966         (( $dircnt == 2 )) || error "lfs find striped dir got $dircnt != 2"
24967
24968         if (( $MDS1_VERSION > $(version_code 2.15.0) )); then
24969                 $LFS mkdir -i0 -c$MDSCOUNT -H crush2 $DIR/$tdir/hashdir/d3 ||
24970                         error "create crush2 dir $tdir/hashdir/d3 failed"
24971                 $LFS find -H crush2 $DIR/$tdir/hashdir
24972                 dircnt=$($LFS find -H crush2 $DIR/$tdir/hashdir | wc -l)
24973                 (( $dircnt == 1 )) || error "find crush2 dir got $dircnt != 1"
24974
24975                 # mkdir with an invalid hash type (hash=fail_val) from client
24976                 # should be replaced on MDS with a valid (default) hash type
24977                 #define OBD_FAIL_LMV_UNKNOWN_STRIPE     0x1901
24978                 $LCTL set_param fail_loc=0x1901 fail_val=99
24979                 $LFS mkdir -c2 $DIR/$tdir/hashdir/d99
24980
24981                 local hash=$($LFS getdirstripe -H $DIR/$tdir/hashdir/d99)
24982                 local expect=$(do_facet mds1 \
24983                         $LCTL get_param -n lod.$FSNAME-MDT0000-mdtlov.mdt_hash)
24984                 [[ $hash == $expect ]] ||
24985                         error "d99 hash '$hash' != expected hash '$expect'"
24986         fi
24987
24988         #set the stripe to be unknown hash type on read
24989         #define OBD_FAIL_LMV_UNKNOWN_STRIPE     0x1901
24990         $LCTL set_param fail_loc=0x1901 fail_val=99
24991         for ((i = 0; i < 10; i++)); do
24992                 $CHECKSTAT -t file $DIR/$tdir/striped_dir/f-$i ||
24993                         error "stat f-$i failed"
24994                 rm $DIR/$tdir/striped_dir/f-$i || error "unlink f-$i failed"
24995         done
24996
24997         touch $DIR/$tdir/striped_dir/f0 &&
24998                 error "create under striped dir with unknown hash should fail"
24999
25000         $LCTL set_param fail_loc=0
25001
25002         umount_client $MOUNT || error "umount failed"
25003         mount_client $MOUNT || error "mount failed"
25004
25005         return 0
25006 }
25007 run_test 300i "client handle unknown hash type striped directory"
25008
25009 test_300j() {
25010         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25011         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25012         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25013                 skip "Need MDS version at least 2.7.55"
25014
25015         local stripe_count
25016         local file
25017
25018         mkdir $DIR/$tdir
25019
25020         #define OBD_FAIL_SPLIT_UPDATE_REC       0x1702
25021         $LCTL set_param fail_loc=0x1702
25022         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
25023                 error "set striped dir error"
25024
25025         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
25026                 error "create files under striped dir failed"
25027
25028         $LCTL set_param fail_loc=0
25029
25030         rm -rf $DIR/$tdir || error "unlink striped dir fails"
25031
25032         return 0
25033 }
25034 run_test 300j "test large update record"
25035
25036 test_300k() {
25037         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25038         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25039         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25040                 skip "Need MDS version at least 2.7.55"
25041
25042         # this test needs a huge transaction
25043         local kb
25044         kb=$(do_facet $SINGLEMDS "$LCTL get_param -n \
25045              osd*.$FSNAME-MDT0000.kbytestotal")
25046         [ $kb -lt $((1024*1024)) ] && skip "MDT0 too small: $kb"
25047
25048         local stripe_count
25049         local file
25050
25051         mkdir $DIR/$tdir
25052
25053         #define OBD_FAIL_LARGE_STRIPE   0x1703
25054         $LCTL set_param fail_loc=0x1703
25055         $LFS setdirstripe -i 0 -c192 $DIR/$tdir/striped_dir ||
25056                 error "set striped dir error"
25057         $LCTL set_param fail_loc=0
25058
25059         $LFS getdirstripe $DIR/$tdir/striped_dir ||
25060                 error "getstripeddir fails"
25061         rm -rf $DIR/$tdir/striped_dir ||
25062                 error "unlink striped dir fails"
25063
25064         return 0
25065 }
25066 run_test 300k "test large striped directory"
25067
25068 test_300l() {
25069         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25070         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25071         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25072                 skip "Need MDS version at least 2.7.55"
25073
25074         local stripe_index
25075
25076         test_mkdir -p $DIR/$tdir/striped_dir
25077         chown $RUNAS_ID $DIR/$tdir/striped_dir ||
25078                         error "chown $RUNAS_ID failed"
25079         $LFS setdirstripe -i 1 -D $DIR/$tdir/striped_dir ||
25080                 error "set default striped dir failed"
25081
25082         #define OBD_FAIL_MDS_STALE_DIR_LAYOUT    0x158
25083         $LCTL set_param fail_loc=0x80000158
25084         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir || error "create dir fails"
25085
25086         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/test_dir)
25087         [ $stripe_index -eq 1 ] ||
25088                 error "expect 1 get $stripe_index for $dir"
25089 }
25090 run_test 300l "non-root user to create dir under striped dir with stale layout"
25091
25092 test_300m() {
25093         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25094         [ $MDSCOUNT -ge 2 ] && skip_env "Only for single MDT"
25095         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25096                 skip "Need MDS version at least 2.7.55"
25097
25098         mkdir -p $DIR/$tdir/striped_dir
25099         $LFS setdirstripe -D -c 1 $DIR/$tdir/striped_dir ||
25100                 error "set default stripes dir error"
25101
25102         mkdir $DIR/$tdir/striped_dir/a || error "mkdir a fails"
25103
25104         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/a)
25105         [ $stripe_count -eq 0 ] ||
25106                         error "expect 0 get $stripe_count for a"
25107
25108         $LFS setdirstripe -D -c 2 $DIR/$tdir/striped_dir ||
25109                 error "set default stripes dir error"
25110
25111         mkdir $DIR/$tdir/striped_dir/b || error "mkdir b fails"
25112
25113         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/b)
25114         [ $stripe_count -eq 0 ] ||
25115                         error "expect 0 get $stripe_count for b"
25116
25117         $LFS setdirstripe -D -c1 -i2 $DIR/$tdir/striped_dir ||
25118                 error "set default stripes dir error"
25119
25120         mkdir $DIR/$tdir/striped_dir/c &&
25121                 error "default stripe_index is invalid, mkdir c should fails"
25122
25123         rm -rf $DIR/$tdir || error "rmdir fails"
25124 }
25125 run_test 300m "setstriped directory on single MDT FS"
25126
25127 cleanup_300n() {
25128         local list=$(comma_list $(mdts_nodes))
25129
25130         trap 0
25131         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
25132 }
25133
25134 test_300n() {
25135         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25136         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25137         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25138                 skip "Need MDS version at least 2.7.55"
25139         remote_mds_nodsh && skip "remote MDS with nodsh"
25140
25141         local stripe_index
25142         local list=$(comma_list $(mdts_nodes))
25143
25144         trap cleanup_300n RETURN EXIT
25145         mkdir -p $DIR/$tdir
25146         chmod 777 $DIR/$tdir
25147         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT \
25148                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
25149                 error "create striped dir succeeds with gid=0"
25150
25151         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
25152         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
25153                 error "create striped dir fails with gid=-1"
25154
25155         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
25156         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D \
25157                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
25158                 error "set default striped dir succeeds with gid=0"
25159
25160
25161         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
25162         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D $DIR/$tdir/striped_dir ||
25163                 error "set default striped dir fails with gid=-1"
25164
25165
25166         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
25167         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir ||
25168                                         error "create test_dir fails"
25169         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir1 ||
25170                                         error "create test_dir1 fails"
25171         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir2 ||
25172                                         error "create test_dir2 fails"
25173         cleanup_300n
25174 }
25175 run_test 300n "non-root user to create dir under striped dir with default EA"
25176
25177 test_300o() {
25178         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25179         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25180         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25181                 skip "Need MDS version at least 2.7.55"
25182
25183         local numfree1
25184         local numfree2
25185
25186         mkdir -p $DIR/$tdir
25187
25188         numfree1=$(lctl get_param -n mdc.*MDT0000*.filesfree)
25189         numfree2=$(lctl get_param -n mdc.*MDT0001*.filesfree)
25190         if [ $numfree1 -lt 66000 ] || [ $numfree2 -lt 66000 ]; then
25191                 skip "not enough free inodes $numfree1 $numfree2"
25192         fi
25193
25194         numfree1=$(lctl get_param -n mdc.*MDT0000-mdc-*.kbytesfree)
25195         numfree2=$(lctl get_param -n mdc.*MDT0001-mdc-*.kbytesfree)
25196         if [ $numfree1 -lt 300000 ] || [ $numfree2 -lt 300000 ]; then
25197                 skip "not enough free space $numfree1 $numfree2"
25198         fi
25199
25200         $LFS setdirstripe -c2 $DIR/$tdir/striped_dir ||
25201                 error "setdirstripe fails"
25202
25203         createmany -d $DIR/$tdir/striped_dir/d 131000 ||
25204                 error "create dirs fails"
25205
25206         $LCTL set_param ldlm.namespaces.*mdc-*.lru_size=0
25207         ls $DIR/$tdir/striped_dir > /dev/null ||
25208                 error "ls striped dir fails"
25209         unlinkmany -d $DIR/$tdir/striped_dir/d 131000 ||
25210                 error "unlink big striped dir fails"
25211 }
25212 run_test 300o "unlink big sub stripe(> 65000 subdirs)"
25213
25214 test_300p() {
25215         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25216         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25217         remote_mds_nodsh && skip "remote MDS with nodsh"
25218
25219         mkdir_on_mdt0 $DIR/$tdir
25220
25221         #define OBD_FAIL_OUT_ENOSPC     0x1704
25222         do_facet mds2 lctl set_param fail_loc=0x80001704
25223         $LFS setdirstripe -i 0 -c2 $DIR/$tdir/bad_striped_dir > /dev/null 2>&1 \
25224                  && error "create striped directory should fail"
25225
25226         [ -e $DIR/$tdir/bad_striped_dir ] && error "striped dir exists"
25227
25228         $LFS setdirstripe -c2 $DIR/$tdir/bad_striped_dir
25229         true
25230 }
25231 run_test 300p "create striped directory without space"
25232
25233 test_300q() {
25234         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25235         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25236
25237         local fd=$(free_fd)
25238         local cmd="exec $fd<$tdir"
25239         cd $DIR
25240         $LFS mkdir -c $MDSCOUNT $tdir || error "create $tdir fails"
25241         eval $cmd
25242         cmd="exec $fd<&-"
25243         trap "eval $cmd" EXIT
25244         cd $tdir || error "cd $tdir fails"
25245         rmdir  ../$tdir || error "rmdir $tdir fails"
25246         mkdir local_dir && error "create dir succeeds"
25247         $LFS setdirstripe -i1 remote_dir && error "create remote dir succeeds"
25248         eval $cmd
25249         return 0
25250 }
25251 run_test 300q "create remote directory under orphan directory"
25252
25253 test_300r() {
25254         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25255                 skip "Need MDS version at least 2.7.55" && return
25256         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
25257
25258         mkdir $DIR/$tdir
25259
25260         $LFS setdirstripe -i 0 -c -1 $DIR/$tdir/striped_dir ||
25261                 error "set striped dir error"
25262
25263         $LFS getdirstripe $DIR/$tdir/striped_dir ||
25264                 error "getstripeddir fails"
25265
25266         local stripe_count
25267         stripe_count=$($LFS getdirstripe $DIR/$tdir/striped_dir |
25268                       awk '/lmv_stripe_count:/ { print $2 }')
25269
25270         [ $MDSCOUNT -ne $stripe_count ] &&
25271                 error "wrong stripe count $stripe_count expected $MDSCOUNT"
25272
25273         rm -rf $DIR/$tdir/striped_dir ||
25274                 error "unlink striped dir fails"
25275 }
25276 run_test 300r "test -1 striped directory"
25277
25278 test_300s_helper() {
25279         local count=$1
25280
25281         local stripe_dir=$DIR/$tdir/striped_dir.$count
25282
25283         $LFS mkdir -c $count $stripe_dir ||
25284                 error "lfs mkdir -c error"
25285
25286         $LFS getdirstripe $stripe_dir ||
25287                 error "lfs getdirstripe fails"
25288
25289         local stripe_count
25290         stripe_count=$($LFS getdirstripe $stripe_dir |
25291                       awk '/lmv_stripe_count:/ { print $2 }')
25292
25293         [ $count -ne $stripe_count ] &&
25294                 error_noexit "bad stripe count $stripe_count expected $count"
25295
25296         local dupe_stripes
25297         dupe_stripes=$($LFS getdirstripe $stripe_dir |
25298                 awk '/0x/ {count[$1] += 1}; END {
25299                         for (idx in count) {
25300                                 if (count[idx]>1) {
25301                                         print "index " idx " count " count[idx]
25302                                 }
25303                         }
25304                 }')
25305
25306         if [[ -n "$dupe_stripes" ]] ; then
25307                 lfs getdirstripe $stripe_dir
25308                 error_noexit "Dupe MDT above: $dupe_stripes "
25309         fi
25310
25311         rm -rf $stripe_dir ||
25312                 error_noexit "unlink $stripe_dir fails"
25313 }
25314
25315 test_300s() {
25316         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25317                 skip "Need MDS version at least 2.7.55" && return
25318         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
25319
25320         mkdir $DIR/$tdir
25321         for count in $(seq 2 $MDSCOUNT); do
25322                 test_300s_helper $count
25323         done
25324 }
25325 run_test 300s "test lfs mkdir -c without -i"
25326
25327 test_300t() {
25328         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
25329                 skip "need MDS 2.14.55 or later"
25330         (( $MDSCOUNT >= 2 )) || skip "needs at least 2 MDTs"
25331
25332         local testdir="$DIR/$tdir/striped_dir"
25333         local dir1=$testdir/dir1
25334         local dir2=$testdir/dir2
25335
25336         mkdir -p $testdir
25337
25338         $LFS setdirstripe -D -c -1 --max-inherit=3 $testdir ||
25339                 error "failed to set default stripe count for $testdir"
25340
25341         mkdir $dir1
25342         local stripe_count=$($LFS getdirstripe -c $dir1)
25343
25344         (( $stripe_count == $MDSCOUNT )) || error "wrong stripe count"
25345
25346         local max_count=$((MDSCOUNT - 1))
25347         local mdts=$(comma_list $(mdts_nodes))
25348
25349         do_nodes $mdts $LCTL set_param lod.*.max_mdt_stripecount=$max_count
25350         stack_trap "do_nodes $mdts $LCTL set_param lod.*.max_mdt_stripecount=0"
25351
25352         mkdir $dir2
25353         stripe_count=$($LFS getdirstripe -c $dir2)
25354
25355         (( $stripe_count == $max_count )) || error "wrong stripe count"
25356 }
25357 run_test 300t "test max_mdt_stripecount"
25358
25359 prepare_remote_file() {
25360         mkdir $DIR/$tdir/src_dir ||
25361                 error "create remote source failed"
25362
25363         cp /etc/hosts $DIR/$tdir/src_dir/a ||
25364                  error "cp to remote source failed"
25365         touch $DIR/$tdir/src_dir/a
25366
25367         $LFS mkdir -i 1 $DIR/$tdir/tgt_dir ||
25368                 error "create remote target dir failed"
25369
25370         touch $DIR/$tdir/tgt_dir/b
25371
25372         mrename $DIR/$tdir/src_dir/a $DIR/$tdir/tgt_dir/b ||
25373                 error "rename dir cross MDT failed!"
25374
25375         $CHECKSTAT -t file $DIR/$tdir/src_dir/a &&
25376                 error "src_child still exists after rename"
25377
25378         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/b ||
25379                 error "missing file(a) after rename"
25380
25381         diff /etc/hosts $DIR/$tdir/tgt_dir/b ||
25382                 error "diff after rename"
25383 }
25384
25385 test_310a() {
25386         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
25387         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25388
25389         local remote_file=$DIR/$tdir/tgt_dir/b
25390
25391         mkdir -p $DIR/$tdir
25392
25393         prepare_remote_file || error "prepare remote file failed"
25394
25395         #open-unlink file
25396         $OPENUNLINK $remote_file $remote_file ||
25397                 error "openunlink $remote_file failed"
25398         $CHECKSTAT -a $remote_file || error "$remote_file exists"
25399 }
25400 run_test 310a "open unlink remote file"
25401
25402 test_310b() {
25403         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
25404         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25405
25406         local remote_file=$DIR/$tdir/tgt_dir/b
25407
25408         mkdir -p $DIR/$tdir
25409
25410         prepare_remote_file || error "prepare remote file failed"
25411
25412         ln $remote_file $DIR/$tfile || error "link failed for remote file"
25413         $MULTIOP $DIR/$tfile Ouc || error "mulitop failed"
25414         $CHECKSTAT -t file $remote_file || error "check file failed"
25415 }
25416 run_test 310b "unlink remote file with multiple links while open"
25417
25418 test_310c() {
25419         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25420         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
25421
25422         local remote_file=$DIR/$tdir/tgt_dir/b
25423
25424         mkdir -p $DIR/$tdir
25425
25426         prepare_remote_file || error "prepare remote file failed"
25427
25428         ln $remote_file $DIR/$tfile || error "link failed for remote file"
25429         multiop_bg_pause $remote_file O_uc ||
25430                         error "mulitop failed for remote file"
25431         MULTIPID=$!
25432         $MULTIOP $DIR/$tfile Ouc
25433         kill -USR1 $MULTIPID
25434         wait $MULTIPID
25435 }
25436 run_test 310c "open-unlink remote file with multiple links"
25437
25438 #LU-4825
25439 test_311() {
25440         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25441         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
25442         [ $MDS1_VERSION -lt $(version_code 2.8.54) ] &&
25443                 skip "lustre < 2.8.54 does not contain LU-4825 fix"
25444         remote_mds_nodsh && skip "remote MDS with nodsh"
25445
25446         local old_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
25447         local mdts=$(comma_list $(mdts_nodes))
25448
25449         mkdir -p $DIR/$tdir
25450         $LFS setstripe -i 0 -c 1 $DIR/$tdir
25451         createmany -o $DIR/$tdir/$tfile. 1000
25452
25453         # statfs data is not real time, let's just calculate it
25454         old_iused=$((old_iused + 1000))
25455
25456         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
25457                         osp.*OST0000*MDT0000.create_count")
25458         local max_count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
25459                                 osp.*OST0000*MDT0000.max_create_count")
25460         do_nodes $mdts "$LCTL set_param -n osp.*OST0000*.max_create_count=0"
25461
25462         $LFS setstripe -i 0 $DIR/$tdir/$tfile || error "setstripe failed"
25463         local index=$($LFS getstripe -i $DIR/$tdir/$tfile)
25464         [ $index -ne 0 ] || error "$tfile stripe index is 0"
25465
25466         unlinkmany $DIR/$tdir/$tfile. 1000
25467
25468         do_nodes $mdts "$LCTL set_param -n \
25469                         osp.*OST0000*.max_create_count=$max_count"
25470         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
25471                 do_nodes $mdts "$LCTL set_param -n \
25472                                 osp.*OST0000*.create_count=$count"
25473         do_nodes $mdts "$LCTL get_param osp.*OST0000*.create_count" |
25474                         grep "=0" && error "create_count is zero"
25475
25476         local new_iused
25477         for i in $(seq 120); do
25478                 new_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
25479                 # system may be too busy to destroy all objs in time, use
25480                 # a somewhat small value to not fail autotest
25481                 [ $((old_iused - new_iused)) -gt 400 ] && break
25482                 sleep 1
25483         done
25484
25485         echo "waited $i sec, old Iused $old_iused, new Iused $new_iused"
25486         [ $((old_iused - new_iused)) -gt 400 ] ||
25487                 error "objs not destroyed after unlink"
25488 }
25489 run_test 311 "disable OSP precreate, and unlink should destroy objs"
25490
25491 zfs_get_objid()
25492 {
25493         local ost=$1
25494         local tf=$2
25495         local fid=($($LFS getstripe $tf | grep 0x))
25496         local seq=${fid[3]#0x}
25497         local objid=${fid[1]}
25498
25499         local vdevdir=$(dirname $(facet_vdevice $ost))
25500         local cmd="$ZDB -e -p $vdevdir -ddddd $(facet_device $ost)"
25501         local zfs_zapid=$(do_facet $ost $cmd |
25502                           grep -w "/O/$seq/d$((objid%32))" -C 5 |
25503                           awk '/Object/{getline; print $1}')
25504         local zfs_objid=$(do_facet $ost $cmd $zfs_zapid |
25505                           awk "/$objid = /"'{printf $3}')
25506
25507         echo $zfs_objid
25508 }
25509
25510 zfs_object_blksz() {
25511         local ost=$1
25512         local objid=$2
25513
25514         local vdevdir=$(dirname $(facet_vdevice $ost))
25515         local cmd="$ZDB -e -p $vdevdir -dddd $(facet_device $ost)"
25516         local blksz=$(do_facet $ost $cmd $objid |
25517                       awk '/dblk/{getline; printf $4}')
25518
25519         case "${blksz: -1}" in
25520                 k|K) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024)) ;;
25521                 m|M) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024*1024)) ;;
25522                 *) ;;
25523         esac
25524
25525         echo $blksz
25526 }
25527
25528 test_312() { # LU-4856
25529         remote_ost_nodsh && skip "remote OST with nodsh"
25530         [[ "$ost1_FSTYPE" == "zfs" ]] || skip "the test only applies to zfs"
25531
25532         local max_blksz=$(do_facet ost1 \
25533                           $ZFS get -p recordsize $(facet_device ost1) |
25534                           awk '!/VALUE/{print $3}')
25535         local tf=$DIR/$tfile
25536
25537         $LFS setstripe -c1 $tf
25538         local facet="ost$(($($LFS getstripe -i $tf) + 1))"
25539
25540         # Get ZFS object id
25541         local zfs_objid=$(zfs_get_objid $facet $tf)
25542         # block size change by sequential overwrite
25543         local bs
25544
25545         for ((bs=$PAGE_SIZE; bs <= max_blksz; bs *= 4)) ; do
25546                 dd if=/dev/zero of=$tf bs=$bs count=1 oflag=sync conv=notrunc
25547
25548                 local blksz=$(zfs_object_blksz $facet $zfs_objid)
25549                 [[ $blksz -eq $bs ]] || error "blksz error: $blksz, expected: $bs"
25550         done
25551         rm -f $tf
25552
25553         $LFS setstripe -c1 $tf
25554         facet="ost$(($($LFS getstripe -i $tf) + 1))"
25555
25556         # block size change by sequential append write
25557         dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=1 oflag=sync conv=notrunc
25558         zfs_objid=$(zfs_get_objid $facet $tf)
25559         local count
25560
25561         for ((count = 1; count < $((max_blksz / PAGE_SIZE)); count *= 2)); do
25562                 dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=$count seek=$count \
25563                         oflag=sync conv=notrunc
25564
25565                 blksz=$(zfs_object_blksz $facet $zfs_objid)
25566                 (( $blksz == 2 * count * PAGE_SIZE )) ||
25567                         error "blksz error, actual $blksz, " \
25568                                 "expected: 2 * $count * $PAGE_SIZE"
25569         done
25570         rm -f $tf
25571
25572         # random write
25573         $LFS setstripe -c1 $tf
25574         facet="ost$(($($LFS getstripe -i $tf) + 1))"
25575         zfs_objid=$(zfs_get_objid $facet $tf)
25576
25577         dd if=/dev/zero of=$tf bs=1K count=1 oflag=sync conv=notrunc
25578         blksz=$(zfs_object_blksz $facet $zfs_objid)
25579         (( blksz == PAGE_SIZE )) ||
25580                 error "blksz error: $blksz, expected: $PAGE_SIZE"
25581
25582         dd if=/dev/zero of=$tf bs=64K count=1 oflag=sync conv=notrunc seek=128
25583         blksz=$(zfs_object_blksz $facet $zfs_objid)
25584         (( blksz == 65536 )) || error "blksz error: $blksz, expected: 64k"
25585
25586         dd if=/dev/zero of=$tf bs=1M count=1 oflag=sync conv=notrunc
25587         blksz=$(zfs_object_blksz $facet $zfs_objid)
25588         (( blksz == 65536 )) || error "rewrite error: $blksz, expected: 64k"
25589 }
25590 run_test 312 "make sure ZFS adjusts its block size by write pattern"
25591
25592 test_313() {
25593         remote_ost_nodsh && skip "remote OST with nodsh"
25594
25595         local file=$DIR/$tfile
25596
25597         rm -f $file
25598         $LFS setstripe -c 1 -i 0 $file || error "setstripe failed"
25599
25600         # define OBD_FAIL_TGT_RCVD_EIO           0x720
25601         do_facet ost1 "$LCTL set_param fail_loc=0x720"
25602         dd if=/dev/zero of=$file bs=$PAGE_SIZE oflag=direct count=1 &&
25603                 error "write should failed"
25604         do_facet ost1 "$LCTL set_param fail_loc=0"
25605         rm -f $file
25606 }
25607 run_test 313 "io should fail after last_rcvd update fail"
25608
25609 test_314() {
25610         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
25611
25612         $LFS setstripe -c 2 -i 0 $DIR/$tfile || error "setstripe failed"
25613         do_facet ost1 "$LCTL set_param fail_loc=0x720"
25614         rm -f $DIR/$tfile
25615         wait_delete_completed
25616         do_facet ost1 "$LCTL set_param fail_loc=0"
25617 }
25618 run_test 314 "OSP shouldn't fail after last_rcvd update failure"
25619
25620 test_315() { # LU-618
25621         [ -f /proc/$$/io ] || skip_env "no IO accounting in kernel"
25622
25623         local file=$DIR/$tfile
25624         rm -f $file
25625
25626         $MULTIOP $file oO_CREAT:O_DIRECT:O_RDWR:w4063232c ||
25627                 error "multiop file write failed"
25628         $MULTIOP $file oO_RDONLY:r4063232_c &
25629         PID=$!
25630
25631         sleep 2
25632
25633         local rbytes=$(awk '/read_bytes/ { print $2 }' /proc/$PID/io)
25634         kill -USR1 $PID
25635
25636         [ $rbytes -gt 4000000 ] || error "read is not accounted ($rbytes)"
25637         rm -f $file
25638 }
25639 run_test 315 "read should be accounted"
25640
25641 test_316() {
25642         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
25643         large_xattr_enabled || skip "ea_inode feature disabled"
25644
25645         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
25646         mkdir $DIR/$tdir/d || error "mkdir $tdir/d failed"
25647         chown nobody $DIR/$tdir/d || error "chown $tdir/d failed"
25648         touch $DIR/$tdir/d/$tfile || error "touch $tdir/d/$tfile failed"
25649
25650         $LFS migrate -m1 $DIR/$tdir/d || error "lfs migrate -m1 failed"
25651 }
25652 run_test 316 "lfs migrate of file with large_xattr enabled"
25653
25654 test_317() {
25655         [ $MDS1_VERSION -lt $(version_code 2.11.53) ] &&
25656                 skip "Need MDS version at least 2.11.53"
25657         if [ "$ost1_FSTYPE" == "zfs" ]; then
25658                 skip "LU-10370: no implementation for ZFS"
25659         fi
25660
25661         local trunc_sz
25662         local grant_blk_size
25663
25664         grant_blk_size=$($LCTL get_param osc.$FSNAME*.import |
25665                         awk '/grant_block_size:/ { print $2; exit; }')
25666         #
25667         # Create File of size 5M. Truncate it to below size's and verify
25668         # blocks count.
25669         #
25670         dd if=/dev/zero of=$DIR/$tfile bs=5M count=1 conv=fsync ||
25671                 error "Create file $DIR/$tfile failed"
25672         stack_trap "rm -f $DIR/$tfile" EXIT
25673
25674         for trunc_sz in 2097152 4097 4000 509 0; do
25675                 $TRUNCATE $DIR/$tfile $trunc_sz ||
25676                         error "truncate $tfile to $trunc_sz failed"
25677                 local sz=$(stat --format=%s $DIR/$tfile)
25678                 local blk=$(stat --format=%b $DIR/$tfile)
25679                 local trunc_blk=$((((trunc_sz + (grant_blk_size - 1) ) /
25680                                      grant_blk_size) * 8))
25681
25682                 if [[ $blk -ne $trunc_blk ]]; then
25683                         $(which stat) $DIR/$tfile
25684                         error "Expected Block $trunc_blk got $blk for $tfile"
25685                 fi
25686
25687                 $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
25688                         error "Expected Size $trunc_sz got $sz for $tfile"
25689         done
25690
25691         #
25692         # sparse file test
25693         # Create file with a hole and write actual 65536 bytes which aligned
25694         # with 4K and 64K PAGE_SIZE. Block count must be 128.
25695         #
25696         local bs=65536
25697         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 seek=5 conv=fsync ||
25698                 error "Create file : $DIR/$tfile"
25699
25700         #
25701         # Truncate to size $trunc_sz bytes. Strip tail blocks and leave only 8
25702         # blocks. The block count must drop to 8.
25703         #
25704         trunc_sz=$(($(stat --format=%s $DIR/$tfile) -
25705                 ((bs - grant_blk_size) + 1)))
25706         $TRUNCATE $DIR/$tfile $trunc_sz ||
25707                 error "truncate $tfile to $trunc_sz failed"
25708
25709         local trunc_bsz=$((grant_blk_size / $(stat --format=%B $DIR/$tfile)))
25710         sz=$(stat --format=%s $DIR/$tfile)
25711         blk=$(stat --format=%b $DIR/$tfile)
25712
25713         if [[ $blk -ne $trunc_bsz ]]; then
25714                 $(which stat) $DIR/$tfile
25715                 error "Expected Block $trunc_bsz got $blk for $tfile"
25716         fi
25717
25718         $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
25719                 error "Expected Size $trunc_sz got $sz for $tfile"
25720 }
25721 run_test 317 "Verify blocks get correctly update after truncate"
25722
25723 test_318() {
25724         local llite_name="llite.$($LFS getname $MOUNT | awk '{print $1}')"
25725         local old_max_active=$($LCTL get_param -n \
25726                             ${llite_name}.max_read_ahead_async_active \
25727                             2>/dev/null)
25728
25729         $LCTL set_param llite.*.max_read_ahead_async_active=256
25730         local max_active=$($LCTL get_param -n \
25731                            ${llite_name}.max_read_ahead_async_active \
25732                            2>/dev/null)
25733         [ $max_active -ne 256 ] && error "expected 256 but got $max_active"
25734
25735         $LCTL set_param llite.*.max_read_ahead_async_active=0 ||
25736                 error "set max_read_ahead_async_active should succeed"
25737
25738         $LCTL set_param llite.*.max_read_ahead_async_active=512
25739         max_active=$($LCTL get_param -n \
25740                      ${llite_name}.max_read_ahead_async_active 2>/dev/null)
25741         [ $max_active -eq 512 ] || error "expected 512 but got $max_active"
25742
25743         # restore @max_active
25744         [ $old_max_active -ne 0 ] && $LCTL set_param \
25745                 llite.*.max_read_ahead_async_active=$old_max_active
25746
25747         local old_threshold=$($LCTL get_param -n \
25748                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
25749         local max_per_file_mb=$($LCTL get_param -n \
25750                 ${llite_name}.max_read_ahead_per_file_mb 2>/dev/null)
25751
25752         local invalid=$(($max_per_file_mb + 1))
25753         $LCTL set_param \
25754                 llite.*.read_ahead_async_file_threshold_mb=$invalid\
25755                         && error "set $invalid should fail"
25756
25757         local valid=$(($invalid - 1))
25758         $LCTL set_param \
25759                 llite.*.read_ahead_async_file_threshold_mb=$valid ||
25760                         error "set $valid should succeed"
25761         local threshold=$($LCTL get_param -n \
25762                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
25763         [ $threshold -eq $valid ] || error \
25764                 "expect threshold $valid got $threshold"
25765         $LCTL set_param \
25766                 llite.*.read_ahead_async_file_threshold_mb=$old_threshold
25767 }
25768 run_test 318 "Verify async readahead tunables"
25769
25770 test_319() {
25771         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
25772
25773         local before=$(date +%s)
25774         local evict
25775         local mdir=$DIR/$tdir
25776         local file=$mdir/xxx
25777
25778         $LFS mkdir -i0 $mdir || error "mkdir $mdir fails"
25779         touch $file
25780
25781 #define OBD_FAIL_LDLM_LOCAL_CANCEL_PAUSE 0x32c
25782         $LCTL set_param fail_val=5 fail_loc=0x8000032c
25783         $LFS migrate -m1 $mdir &
25784
25785         sleep 1
25786         dd if=$file of=/dev/null
25787         wait
25788         evict=$($LCTL get_param mdc.$FSNAME-MDT*.state |
25789           awk -F"[ [,]" '/EVICTED ]$/ { if (mx<$5) {mx=$5;} } END { print mx }')
25790
25791         [ -z "$evict" ] || [[ $evict -le $before ]] || error "eviction happened"
25792 }
25793 run_test 319 "lost lease lock on migrate error"
25794
25795 test_398a() { # LU-4198
25796         local ost1_imp=$(get_osc_import_name client ost1)
25797         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
25798                          cut -d'.' -f2)
25799
25800         $LFS setstripe -c 1 -i 0 $DIR/$tfile
25801         stack_trap "rm -f $DIR/$tfile"
25802         $LCTL set_param ldlm.namespaces.*.lru_size=clear
25803
25804         # request a new lock on client
25805         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
25806
25807         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
25808         local lock_count=$($LCTL get_param -n \
25809                            ldlm.namespaces.$imp_name.lru_size)
25810         [[ $lock_count -eq 0 ]] || error "lock should be cancelled by direct IO"
25811
25812         $LCTL set_param ldlm.namespaces.*-OST0000-osc-ffff*.lru_size=clear
25813
25814         # no lock cached, should use lockless DIO and not enqueue new lock
25815         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
25816         lock_count=$($LCTL get_param -n \
25817                      ldlm.namespaces.$imp_name.lru_size)
25818         [[ $lock_count -eq 0 ]] || error "no lock should be held by direct IO"
25819
25820         $LCTL set_param ldlm.namespaces.*-OST0000-osc-ffff*.lru_size=clear
25821
25822         # no lock cached, should use locked DIO append
25823         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct oflag=append \
25824                 conv=notrunc || error "DIO append failed"
25825         lock_count=$($LCTL get_param -n \
25826                      ldlm.namespaces.*-OST0000-osc-ffff*.lru_size)
25827         [[ $lock_count -ne 0 ]] || error "lock still must be held by DIO append"
25828 }
25829 run_test 398a "direct IO should cancel lock otherwise lockless"
25830
25831 test_398b() { # LU-4198
25832         local before=$(date +%s)
25833         local njobs=4
25834         local size=48
25835
25836         which fio || skip_env "no fio installed"
25837         $LFS setstripe -c -1 -S 1M $DIR/$tfile
25838         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size
25839
25840         # Single page, multiple pages, stripe size, 4*stripe size
25841         for bsize in $(( $PAGE_SIZE )) $(( 4*$PAGE_SIZE )) 1048576 4194304; do
25842                 echo "mix direct rw ${bsize} by fio with $njobs jobs..."
25843                 fio --name=rand-rw --rw=randrw --bs=$bsize --direct=1 \
25844                         --numjobs=$njobs --fallocate=none \
25845                         --iodepth=16 --allow_file_create=0 \
25846                         --size=$((size/njobs))M \
25847                         --filename=$DIR/$tfile &
25848                 bg_pid=$!
25849
25850                 echo "mix buffer rw ${bsize} by fio with $njobs jobs..."
25851                 fio --name=rand-rw --rw=randrw --bs=$bsize \
25852                         --numjobs=$njobs --fallocate=none \
25853                         --iodepth=16 --allow_file_create=0 \
25854                         --size=$((size/njobs))M \
25855                         --filename=$DIR/$tfile || true
25856                 wait $bg_pid
25857         done
25858
25859         evict=$(do_facet client $LCTL get_param \
25860                 osc.$FSNAME-OST*-osc-*/state |
25861             awk -F"[ [,]" '/EVICTED ]$/ { if (t<$5) {t=$5;} } END { print t }')
25862
25863         [ -z "$evict" ] || [[ $evict -le $before ]] ||
25864                 (do_facet client $LCTL get_param \
25865                         osc.$FSNAME-OST*-osc-*/state;
25866                     error "eviction happened: $evict before:$before")
25867
25868         rm -f $DIR/$tfile
25869 }
25870 run_test 398b "DIO and buffer IO race"
25871
25872 test_398c() { # LU-4198
25873         local ost1_imp=$(get_osc_import_name client ost1)
25874         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
25875                          cut -d'.' -f2)
25876
25877         which fio || skip_env "no fio installed"
25878
25879         saved_debug=$($LCTL get_param -n debug)
25880         $LCTL set_param debug=0
25881
25882         local size=$(lctl get_param -n osc.$FSNAME-OST0000*.kbytesavail | head -1)
25883         ((size /= 1024)) # by megabytes
25884         ((size /= 2)) # write half of the OST at most
25885         [ $size -gt 40 ] && size=40 #reduce test time anyway
25886
25887         $LFS setstripe -c 1 $DIR/$tfile
25888
25889         # it seems like ldiskfs reserves more space than necessary if the
25890         # writing blocks are not mapped, so it extends the file firstly
25891         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size && sync
25892         cancel_lru_locks osc
25893
25894         # clear and verify rpc_stats later
25895         $LCTL set_param osc.${FSNAME}-OST0000-osc-ffff*.rpc_stats=clear
25896
25897         local njobs=4
25898         echo "writing ${size}M to OST0 by fio with $njobs jobs..."
25899         fio --name=rand-write --rw=randwrite --bs=$PAGE_SIZE --direct=1 \
25900                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
25901                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
25902                 --filename=$DIR/$tfile
25903         [ $? -eq 0 ] || error "fio write error"
25904
25905         [ $($LCTL get_param -n ldlm.namespaces.$imp_name.lock_count) -eq 0 ] ||
25906                 error "Locks were requested while doing AIO"
25907
25908         # get the percentage of 1-page I/O
25909         pct=$($LCTL get_param osc.${imp_name}.rpc_stats |
25910                 grep -A 1 'pages per rpc' | grep -v 'pages per rpc' |
25911                 awk '{print $7}')
25912         [ $pct -le 50 ] || error "$pct% of I/O are 1-page"
25913
25914         echo "mix rw ${size}M to OST0 by fio with $njobs jobs..."
25915         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
25916                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
25917                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
25918                 --filename=$DIR/$tfile
25919         [ $? -eq 0 ] || error "fio mixed read write error"
25920
25921         echo "AIO with large block size ${size}M"
25922         fio --name=rand-rw --rw=randrw --bs=${size}M --direct=1 \
25923                 --numjobs=1 --fallocate=none --ioengine=libaio \
25924                 --iodepth=16 --allow_file_create=0 --size=${size}M \
25925                 --filename=$DIR/$tfile
25926         [ $? -eq 0 ] || error "fio large block size failed"
25927
25928         rm -f $DIR/$tfile
25929         $LCTL set_param debug="$saved_debug"
25930 }
25931 run_test 398c "run fio to test AIO"
25932
25933 test_398d() { #  LU-13846
25934         which aiocp || skip_env "no aiocp installed"
25935         local aio_file=$DIR/$tfile.aio
25936
25937         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
25938
25939         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=64
25940         aiocp -a $PAGE_SIZE -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file
25941         stack_trap "rm -f $DIR/$tfile $aio_file"
25942
25943         diff $DIR/$tfile $aio_file || error "file diff after aiocp"
25944
25945         # make sure we don't crash and fail properly
25946         aiocp -a 512 -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
25947                 error "aio not aligned with PAGE SIZE should fail"
25948
25949         rm -f $DIR/$tfile $aio_file
25950 }
25951 run_test 398d "run aiocp to verify block size > stripe size"
25952
25953 test_398e() {
25954         dd if=/dev/zero of=$DIR/$tfile bs=1234 count=1
25955         touch $DIR/$tfile.new
25956         dd if=$DIR/$tfile of=$DIR/$tfile.new bs=1M count=1 oflag=direct
25957 }
25958 run_test 398e "O_Direct open cleared by fcntl doesn't cause hang"
25959
25960 test_398f() { #  LU-14687
25961         which aiocp || skip_env "no aiocp installed"
25962         local aio_file=$DIR/$tfile.aio
25963
25964         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
25965
25966         dd if=/dev/zero of=$DIR/$tfile bs=1M count=64
25967         stack_trap "rm -f $DIR/$tfile $aio_file"
25968
25969         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
25970         $LCTL set_param fail_loc=0x1418
25971         # make sure we don't crash and fail properly
25972         aiocp -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
25973                 error "aio with page allocation failure succeeded"
25974         $LCTL set_param fail_loc=0
25975         diff $DIR/$tfile $aio_file
25976         [[ $? != 0 ]] || error "no diff after failed aiocp"
25977 }
25978 run_test 398f "verify aio handles ll_direct_rw_pages errors correctly"
25979
25980 # NB: To get the parallel DIO behavior in LU-13798, there must be > 1
25981 # stripe and i/o size must be > stripe size
25982 # Old style synchronous DIO waits after submitting each chunk, resulting in a
25983 # single RPC in flight.  This test shows async DIO submission is working by
25984 # showing multiple RPCs in flight.
25985 test_398g() { #  LU-13798
25986         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
25987
25988         # We need to do some i/o first to acquire enough grant to put our RPCs
25989         # in flight; otherwise a new connection may not have enough grant
25990         # available
25991         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
25992                 error "parallel dio failed"
25993         stack_trap "rm -f $DIR/$tfile"
25994
25995         # Reduce RPC size to 1M to avoid combination in to larger RPCs
25996         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
25997         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
25998         stack_trap "$LCTL set_param -n $pages_per_rpc"
25999
26000         # Recreate file so it's empty
26001         rm -f $DIR/$tfile
26002         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
26003         #Pause rpc completion to guarantee we see multiple rpcs in flight
26004         #define OBD_FAIL_OST_BRW_PAUSE_BULK
26005         do_facet ost1 $LCTL set_param fail_loc=0x214 fail_val=2
26006         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
26007
26008         # Clear rpc stats
26009         $LCTL set_param osc.*.rpc_stats=c
26010
26011         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
26012                 error "parallel dio failed"
26013         stack_trap "rm -f $DIR/$tfile"
26014
26015         $LCTL get_param osc.*-OST0000-*.rpc_stats
26016         pct=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
26017                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
26018                 grep "8:" | awk '{print $8}')
26019         # We look at the "8 rpcs in flight" field, and verify A) it is present
26020         # and B) it includes all RPCs.  This proves we had 8 RPCs in flight,
26021         # as expected for an 8M DIO to a file with 1M stripes.
26022         [ $pct -eq 100 ] || error "we should see 8 RPCs in flight"
26023
26024         # Verify turning off parallel dio works as expected
26025         # Clear rpc stats
26026         $LCTL set_param osc.*.rpc_stats=c
26027         $LCTL set_param llite.*.parallel_dio=0
26028         stack_trap '$LCTL set_param llite.*.parallel_dio=1'
26029
26030         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
26031                 error "dio with parallel dio disabled failed"
26032
26033         # Ideally, we would see only one RPC in flight here, but there is an
26034         # unavoidable race between i/o completion and RPC in flight counting,
26035         # so while only 1 i/o is in flight at a time, the RPC in flight counter
26036         # will sometimes exceed 1 (3 or 4 is not rare on VM testing).
26037         # So instead we just verify it's always < 8.
26038         $LCTL get_param osc.*-OST0000-*.rpc_stats
26039         ret=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
26040                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
26041                 grep '^$' -B1 | grep . | awk '{print $1}')
26042         [ $ret != "8:" ] ||
26043                 error "we should see fewer than 8 RPCs in flight (saw $ret)"
26044 }
26045 run_test 398g "verify parallel dio async RPC submission"
26046
26047 test_398h() { #  LU-13798
26048         local dio_file=$DIR/$tfile.dio
26049
26050         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
26051
26052         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
26053         stack_trap "rm -f $DIR/$tfile $dio_file"
26054
26055         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct ||
26056                 error "parallel dio failed"
26057         diff $DIR/$tfile $dio_file
26058         [[ $? == 0 ]] || error "file diff after aiocp"
26059 }
26060 run_test 398h "verify correctness of read & write with i/o size >> stripe size"
26061
26062 test_398i() { #  LU-13798
26063         local dio_file=$DIR/$tfile.dio
26064
26065         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
26066
26067         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
26068         stack_trap "rm -f $DIR/$tfile $dio_file"
26069
26070         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
26071         $LCTL set_param fail_loc=0x1418
26072         # make sure we don't crash and fail properly
26073         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct &&
26074                 error "parallel dio page allocation failure succeeded"
26075         diff $DIR/$tfile $dio_file
26076         [[ $? != 0 ]] || error "no diff after failed aiocp"
26077 }
26078 run_test 398i "verify parallel dio handles ll_direct_rw_pages errors correctly"
26079
26080 test_398j() { #  LU-13798
26081         # Stripe size > RPC size but less than i/o size tests split across
26082         # stripes and RPCs for individual i/o op
26083         $LFS setstripe -o 0,0 -S 4M $DIR/$tfile $DIR/$tfile.2
26084
26085         # Reduce RPC size to 1M to guarantee split to multiple RPCs per stripe
26086         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
26087         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
26088         stack_trap "$LCTL set_param -n $pages_per_rpc"
26089
26090         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
26091                 error "parallel dio write failed"
26092         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.2"
26093
26094         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct ||
26095                 error "parallel dio read failed"
26096         diff $DIR/$tfile $DIR/$tfile.2
26097         [[ $? == 0 ]] || error "file diff after parallel dio read"
26098 }
26099 run_test 398j "test parallel dio where stripe size > rpc_size"
26100
26101 test_398k() { #  LU-13798
26102         wait_delete_completed
26103         wait_mds_ost_sync
26104
26105         # 4 stripe file; we will cause out of space on OST0
26106         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
26107
26108         # Fill OST0 (if it's not too large)
26109         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
26110                    head -n1)
26111         if [[ $ORIGFREE -gt $MAXFREE ]]; then
26112                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
26113         fi
26114         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
26115         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
26116                 error "dd should fill OST0"
26117         stack_trap "rm -f $DIR/$tfile.1"
26118
26119         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
26120         err=$?
26121
26122         ls -la $DIR/$tfile
26123         $CHECKSTAT -t file -s 0 $DIR/$tfile ||
26124                 error "file is not 0 bytes in size"
26125
26126         # dd above should not succeed, but don't error until here so we can
26127         # get debug info above
26128         [[ $err != 0 ]] ||
26129                 error "parallel dio write with enospc succeeded"
26130         stack_trap "rm -f $DIR/$tfile"
26131 }
26132 run_test 398k "test enospc on first stripe"
26133
26134 test_398l() { #  LU-13798
26135         wait_delete_completed
26136         wait_mds_ost_sync
26137
26138         # 4 stripe file; we will cause out of space on OST0
26139         # Note the 1M stripe size and the > 1M i/o size mean this ENOSPC
26140         # happens on the second i/o chunk we issue
26141         $LFS setstripe -o 1,0,1,0 -S 1M $DIR/$tfile $DIR/$tfile.2
26142
26143         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=2 oflag=direct
26144         stack_trap "rm -f $DIR/$tfile"
26145
26146         # Fill OST0 (if it's not too large)
26147         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
26148                    head -n1)
26149         if [[ $ORIGFREE -gt $MAXFREE ]]; then
26150                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
26151         fi
26152         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
26153         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
26154                 error "dd should fill OST0"
26155         stack_trap "rm -f $DIR/$tfile.1"
26156
26157         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 oflag=direct
26158         err=$?
26159         stack_trap "rm -f $DIR/$tfile.2"
26160
26161         # Check that short write completed as expected
26162         ls -la $DIR/$tfile.2
26163         $CHECKSTAT -t file -s 1048576 $DIR/$tfile.2 ||
26164                 error "file is not 1M in size"
26165
26166         # dd above should not succeed, but don't error until here so we can
26167         # get debug info above
26168         [[ $err != 0 ]] ||
26169                 error "parallel dio write with enospc succeeded"
26170
26171         # Truncate source file to same length as output file and diff them
26172         $TRUNCATE $DIR/$tfile 1048576
26173         diff $DIR/$tfile $DIR/$tfile.2
26174         [[ $? == 0 ]] || error "data incorrect after short write"
26175 }
26176 run_test 398l "test enospc on intermediate stripe/RPC"
26177
26178 test_398m() { #  LU-13798
26179         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
26180
26181         # Set up failure on OST0, the first stripe:
26182         #define OBD_FAIL_OST_BRW_WRITE_BULK     0x20e
26183         #NB: Fail val is ost # + 1, because we cannot use cfs_fail_val = 0
26184         # OST0 is on ost1, OST1 is on ost2.
26185         # So this fail_val specifies OST0
26186         do_facet ost1 $LCTL set_param fail_loc=0x20e fail_val=1
26187         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
26188
26189         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
26190                 error "parallel dio write with failure on first stripe succeeded"
26191         stack_trap "rm -f $DIR/$tfile"
26192         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
26193
26194         # Place data in file for read
26195         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
26196                 error "parallel dio write failed"
26197
26198         # Fail read on OST0, first stripe
26199         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
26200         do_facet ost1 $LCTL set_param fail_loc=0x20f fail_val=1
26201         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
26202                 error "parallel dio read with error on first stripe succeeded"
26203         rm -f $DIR/$tfile.2
26204         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
26205
26206         # Switch to testing on OST1, second stripe
26207         # Clear file contents, maintain striping
26208         echo > $DIR/$tfile
26209         # Set up failure on OST1, second stripe:
26210         do_facet ost2 $LCTL set_param fail_loc=0x20e fail_val=2
26211         stack_trap "do_facet ost2 $LCTL set_param fail_loc=0"
26212
26213         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
26214                 error "parallel dio write with failure on second stripe succeeded"
26215         stack_trap "rm -f $DIR/$tfile"
26216         do_facet ost2 $LCTL set_param fail_loc=0 fail_val=0
26217
26218         # Place data in file for read
26219         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
26220                 error "parallel dio write failed"
26221
26222         # Fail read on OST1, second stripe
26223         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
26224         do_facet ost2 $LCTL set_param fail_loc=0x20f fail_val=2
26225         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
26226                 error "parallel dio read with error on second stripe succeeded"
26227         rm -f $DIR/$tfile.2
26228         do_facet ost2 $LCTL set_param fail_loc=0 fail_val=0
26229 }
26230 run_test 398m "test RPC failures with parallel dio"
26231
26232 # Parallel submission of DIO should not cause problems for append, but it's
26233 # important to verify.
26234 test_398n() { #  LU-13798
26235         $LFS setstripe -C 2 -S 1M $DIR/$tfile
26236
26237         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 ||
26238                 error "dd to create source file failed"
26239         stack_trap "rm -f $DIR/$tfile"
26240
26241         dd if=$DIR/$tfile of=$DIR/$tfile.1 bs=8M count=8 oflag=direct oflag=append ||
26242                 error "parallel dio write with failure on second stripe succeeded"
26243         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.1"
26244         diff $DIR/$tfile $DIR/$tfile.1
26245         [[ $? == 0 ]] || error "data incorrect after append"
26246
26247 }
26248 run_test 398n "test append with parallel DIO"
26249
26250 test_398o() {
26251         directio rdwr $DIR/$tfile 0 1 1 || error "bad KMS"
26252 }
26253 run_test 398o "right kms with DIO"
26254
26255 test_398p()
26256 {
26257         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
26258         which aiocp || skip_env "no aiocp installed"
26259
26260         local stripe_size=$((1024 * 1024)) #1 MiB
26261         # Max i/o below is ~ 4 * stripe_size, so this gives ~5 i/os
26262         local file_size=$((25 * stripe_size))
26263
26264         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
26265         stack_trap "rm -f $DIR/$tfile*"
26266         # Just a bit bigger than the largest size in the test set below
26267         dd if=/dev/urandom bs=$file_size count=1 of=$DIR/$tfile.1 ||
26268                 error "buffered i/o to create file failed"
26269
26270         for bs in $PAGE_SIZE $((PAGE_SIZE * 4)) $stripe_size \
26271                 $((stripe_size * 4)); do
26272
26273                 $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.2
26274
26275                 echo "bs: $bs, file_size $file_size"
26276                 aiocp -a $PAGE_SIZE -b $bs -s $file_size -f O_DIRECT \
26277                         $DIR/$tfile.1 $DIR/$tfile.2 &
26278                 pid_dio1=$!
26279                 # Buffered I/O with similar but not the same block size
26280                 dd if=$DIR/$tfile.1 bs=$((bs * 2)) of=$DIR/$tfile.2 \
26281                         conv=notrunc &
26282                 pid_bio2=$!
26283                 wait $pid_dio1
26284                 rc1=$?
26285                 wait $pid_bio2
26286                 rc2=$?
26287                 if (( rc1 != 0 )); then
26288                         error "aio copy 1 w/bsize $bs failed: $rc1"
26289                 fi
26290                 if (( rc2 != 0 )); then
26291                         error "buffered copy 2 w/bsize $bs failed: $rc2"
26292                 fi
26293
26294                 $CHECKSTAT -t file -s $file_size $DIR/$tfile.2 ||
26295                         error "size incorrect"
26296                 cmp --verbose $DIR/$tfile.1 $DIR/$tfile.2 ||
26297                         error "files differ, bsize $bs"
26298                 rm -f $DIR/$tfile.2
26299         done
26300 }
26301 run_test 398p "race aio with buffered i/o"
26302
26303 test_fake_rw() {
26304         local read_write=$1
26305         if [ "$read_write" = "write" ]; then
26306                 local dd_cmd="dd if=/dev/zero of=$DIR/$tfile"
26307         elif [ "$read_write" = "read" ]; then
26308                 local dd_cmd="dd of=/dev/null if=$DIR/$tfile"
26309         else
26310                 error "argument error"
26311         fi
26312
26313         # turn off debug for performance testing
26314         local saved_debug=$($LCTL get_param -n debug)
26315         $LCTL set_param debug=0
26316
26317         $LFS setstripe -c 1 -i 0 $DIR/$tfile
26318
26319         # get ost1 size - $FSNAME-OST0000
26320         local ost1_avail_size=$($LFS df $DIR | awk /${ost1_svc}/'{ print $4 }')
26321         local blocks=$((ost1_avail_size/2/1024)) # half avail space by megabytes
26322         [ $blocks -gt 1000 ] && blocks=1000 # 1G in maximum
26323
26324         if [ "$read_write" = "read" ]; then
26325                 $TRUNCATE $DIR/$tfile $(expr 1048576 \* $blocks)
26326         fi
26327
26328         local start_time=$(date +%s.%N)
26329         $dd_cmd bs=1M count=$blocks oflag=sync ||
26330                 error "real dd $read_write error"
26331         local duration=$(bc <<< "$(date +%s.%N) - $start_time")
26332
26333         if [ "$read_write" = "write" ]; then
26334                 rm -f $DIR/$tfile
26335         fi
26336
26337         # define OBD_FAIL_OST_FAKE_RW           0x238
26338         do_facet ost1 $LCTL set_param fail_loc=0x238
26339
26340         local start_time=$(date +%s.%N)
26341         $dd_cmd bs=1M count=$blocks oflag=sync ||
26342                 error "fake dd $read_write error"
26343         local duration_fake=$(bc <<< "$(date +%s.%N) - $start_time")
26344
26345         if [ "$read_write" = "write" ]; then
26346                 # verify file size
26347                 cancel_lru_locks osc
26348                 $CHECKSTAT -t file -s $((blocks * 1024 * 1024)) $DIR/$tfile ||
26349                         error "$tfile size not $blocks MB"
26350         fi
26351         do_facet ost1 $LCTL set_param fail_loc=0
26352
26353         echo "fake $read_write $duration_fake vs. normal $read_write" \
26354                 "$duration in seconds"
26355         [ $(bc <<< "$duration_fake < $duration") -eq 1 ] ||
26356                 error_not_in_vm "fake write is slower"
26357
26358         $LCTL set_param -n debug="$saved_debug"
26359         rm -f $DIR/$tfile
26360 }
26361 test_399a() { # LU-7655 for OST fake write
26362         remote_ost_nodsh && skip "remote OST with nodsh"
26363
26364         test_fake_rw write
26365 }
26366 run_test 399a "fake write should not be slower than normal write"
26367
26368 test_399b() { # LU-8726 for OST fake read
26369         remote_ost_nodsh && skip "remote OST with nodsh"
26370         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
26371                 skip_env "ldiskfs only test"
26372         fi
26373
26374         test_fake_rw read
26375 }
26376 run_test 399b "fake read should not be slower than normal read"
26377
26378 test_400a() { # LU-1606, was conf-sanity test_74
26379         if ! which $CC > /dev/null 2>&1; then
26380                 skip_env "$CC is not installed"
26381         fi
26382
26383         local extra_flags=''
26384         local out=$TMP/$tfile
26385         local prefix=/usr/include/lustre
26386         local prog
26387
26388         # Oleg removes .c files in his test rig so test if any c files exist
26389         [[ -n "$(ls -A $LUSTRE_TESTS_API_DIR)" ]] ||
26390                 skip_env "Needed .c test files are missing"
26391
26392         if ! [[ -d $prefix ]]; then
26393                 # Assume we're running in tree and fixup the include path.
26394                 extra_flags+=" -I$LUSTRE/../lnet/include/uapi"
26395                 extra_flags+=" -I$LUSTRE/include/uapi -I$LUSTRE/include"
26396                 extra_flags+=" -L$LUSTRE/utils/.libs"
26397         fi
26398
26399         for prog in $LUSTRE_TESTS_API_DIR/*.c; do
26400                 $CC -Wall -Werror $extra_flags -o $out $prog -llustreapi ||
26401                         error "client api broken"
26402         done
26403         rm -f $out
26404 }
26405 run_test 400a "Lustre client api program can compile and link"
26406
26407 test_400b() { # LU-1606, LU-5011
26408         local header
26409         local out=$TMP/$tfile
26410         local prefix=/usr/include/linux/lustre
26411
26412         # We use a hard coded prefix so that this test will not fail
26413         # when run in tree. There are headers in lustre/include/lustre/
26414         # that are not packaged (like lustre_idl.h) and have more
26415         # complicated include dependencies (like config.h and lnet/types.h).
26416         # Since this test about correct packaging we just skip them when
26417         # they don't exist (see below) rather than try to fixup cppflags.
26418
26419         if ! which $CC > /dev/null 2>&1; then
26420                 skip_env "$CC is not installed"
26421         fi
26422
26423         for header in $prefix/*.h; do
26424                 if ! [[ -f "$header" ]]; then
26425                         continue
26426                 fi
26427
26428                 if [[ "$(basename $header)" == lustre_ioctl.h ]]; then
26429                         continue # lustre_ioctl.h is internal header
26430                 fi
26431
26432                 $CC -Wall -Werror -include $header -c -x c /dev/null -o $out ||
26433                         error "cannot compile '$header'"
26434         done
26435         rm -f $out
26436 }
26437 run_test 400b "packaged headers can be compiled"
26438
26439 test_401a() { #LU-7437
26440         local printf_arg=$(find -printf 2>&1 | grep "unrecognized:")
26441         [ -n "$printf_arg" ] && skip_env "find does not support -printf"
26442
26443         #count the number of parameters by "list_param -R"
26444         local params=$($LCTL list_param -R '*' 2>/dev/null | wc -l)
26445         #count the number of parameters by listing proc files
26446         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
26447         echo "proc_dirs='$proc_dirs'"
26448         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
26449         local procs=$(find -L $proc_dirs -mindepth 1 -printf '%P\n' 2>/dev/null|
26450                       sort -u | wc -l)
26451
26452         [ $params -eq $procs ] ||
26453                 error "found $params parameters vs. $procs proc files"
26454
26455         # test the list_param -D option only returns directories
26456         params=$($LCTL list_param -R -D '*' 2>/dev/null | wc -l)
26457         #count the number of parameters by listing proc directories
26458         procs=$(find -L $proc_dirs -mindepth 1 -type d -printf '%P\n' 2>/dev/null |
26459                 sort -u | wc -l)
26460
26461         [ $params -eq $procs ] ||
26462                 error "found $params parameters vs. $procs proc files"
26463 }
26464 run_test 401a "Verify if 'lctl list_param -R' can list parameters recursively"
26465
26466 test_401b() {
26467         # jobid_var may not allow arbitrary values, so use jobid_name
26468         # if available
26469         if $LCTL list_param jobid_name > /dev/null 2>&1; then
26470                 local testname=jobid_name tmp='testing%p'
26471         else
26472                 local testname=jobid_var tmp=testing
26473         fi
26474
26475         local save=$($LCTL get_param -n $testname)
26476
26477         $LCTL set_param foo=bar $testname=$tmp bar=baz &&
26478                 error "no error returned when setting bad parameters"
26479
26480         local jobid_new=$($LCTL get_param -n foe $testname baz)
26481         [[ "$jobid_new" == "$tmp" ]] || error "jobid tmp $jobid_new != $tmp"
26482
26483         $LCTL set_param -n fog=bam $testname=$save bat=fog
26484         local jobid_old=$($LCTL get_param -n foe $testname bag)
26485         [[ "$jobid_old" == "$save" ]] || error "jobid new $jobid_old != $save"
26486 }
26487 run_test 401b "Verify 'lctl {get,set}_param' continue after error"
26488
26489 test_401c() {
26490         # jobid_var may not allow arbitrary values, so use jobid_name
26491         # if available
26492         if $LCTL list_param jobid_name > /dev/null 2>&1; then
26493                 local testname=jobid_name
26494         else
26495                 local testname=jobid_var
26496         fi
26497
26498         local jobid_var_old=$($LCTL get_param -n $testname)
26499         local jobid_var_new
26500
26501         $LCTL set_param $testname= &&
26502                 error "no error returned for 'set_param a='"
26503
26504         jobid_var_new=$($LCTL get_param -n $testname)
26505         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
26506                 error "$testname was changed by setting without value"
26507
26508         $LCTL set_param $testname &&
26509                 error "no error returned for 'set_param a'"
26510
26511         jobid_var_new=$($LCTL get_param -n $testname)
26512         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
26513                 error "$testname was changed by setting without value"
26514 }
26515 run_test 401c "Verify 'lctl set_param' without value fails in either format."
26516
26517 test_401d() {
26518         # jobid_var may not allow arbitrary values, so use jobid_name
26519         # if available
26520         if $LCTL list_param jobid_name > /dev/null 2>&1; then
26521                 local testname=jobid_name new_value='foo=bar%p'
26522         else
26523                 local testname=jobid_var new_valuie=foo=bar
26524         fi
26525
26526         local jobid_var_old=$($LCTL get_param -n $testname)
26527         local jobid_var_new
26528
26529         $LCTL set_param $testname=$new_value ||
26530                 error "'set_param a=b' did not accept a value containing '='"
26531
26532         jobid_var_new=$($LCTL get_param -n $testname)
26533         [[ "$jobid_var_new" == "$new_value" ]] ||
26534                 error "'set_param a=b' failed on a value containing '='"
26535
26536         # Reset the $testname to test the other format
26537         $LCTL set_param $testname=$jobid_var_old
26538         jobid_var_new=$($LCTL get_param -n $testname)
26539         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
26540                 error "failed to reset $testname"
26541
26542         $LCTL set_param $testname $new_value ||
26543                 error "'set_param a b' did not accept a value containing '='"
26544
26545         jobid_var_new=$($LCTL get_param -n $testname)
26546         [[ "$jobid_var_new" == "$new_value" ]] ||
26547                 error "'set_param a b' failed on a value containing '='"
26548
26549         $LCTL set_param $testname $jobid_var_old
26550         jobid_var_new=$($LCTL get_param -n $testname)
26551         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
26552                 error "failed to reset $testname"
26553 }
26554 run_test 401d "Verify 'lctl set_param' accepts values containing '='"
26555
26556 test_401e() { # LU-14779
26557         $LCTL list_param -R "ldlm.namespaces.MGC*" ||
26558                 error "lctl list_param MGC* failed"
26559         $LCTL get_param "ldlm.namespaces.MGC*" || error "lctl get_param failed"
26560         $LCTL get_param "ldlm.namespaces.MGC*.lru_size" ||
26561                 error "lctl get_param lru_size failed"
26562 }
26563 run_test 401e "verify 'lctl get_param' works with NID in parameter"
26564
26565 test_402() {
26566         [[ $MDS1_VERSION -ge $(version_code 2.7.66) ]] ||
26567         [[ $MDS1_VERSION -ge $(version_code 2.7.18.4) &&
26568                 $MDS1_VERSION -lt $(version_code 2.7.50) ]] ||
26569         [[ $MDS1_VERSION -ge $(version_code 2.7.2) &&
26570                 $MDS1_VERSION -lt $(version_code 2.7.11) ]] ||
26571                 skip "Need MDS version 2.7.2+ or 2.7.18.4+ or 2.7.66+"
26572         remote_mds_nodsh && skip "remote MDS with nodsh"
26573
26574         $LFS setdirstripe -i 0 $DIR/$tdir || error "setdirstripe -i 0 failed"
26575 #define OBD_FAIL_MDS_FLD_LOOKUP 0x15c
26576         do_facet mds1 "lctl set_param fail_loc=0x8000015c"
26577         touch $DIR/$tdir/$tfile && error "touch should fail with ENOENT" ||
26578                 echo "Touch failed - OK"
26579 }
26580 run_test 402 "Return ENOENT to lod_generate_and_set_lovea"
26581
26582 test_403() {
26583         local file1=$DIR/$tfile.1
26584         local file2=$DIR/$tfile.2
26585         local tfile=$TMP/$tfile
26586
26587         rm -f $file1 $file2 $tfile
26588
26589         touch $file1
26590         ln $file1 $file2
26591
26592         # 30 sec OBD_TIMEOUT in ll_getattr()
26593         # right before populating st_nlink
26594         $LCTL set_param fail_loc=0x80001409
26595         stat -c %h $file1 > $tfile &
26596
26597         # create an alias, drop all locks and reclaim the dentry
26598         < $file2
26599         cancel_lru_locks mdc
26600         cancel_lru_locks osc
26601         sysctl -w vm.drop_caches=2
26602
26603         wait
26604
26605         [ $(cat $tfile) -gt 0 ] || error "wrong nlink count: $(cat $tfile)"
26606
26607         rm -f $tfile $file1 $file2
26608 }
26609 run_test 403 "i_nlink should not drop to zero due to aliasing"
26610
26611 test_404() { # LU-6601
26612         [[ $MDS1_VERSION -ge $(version_code 2.8.53) ]] ||
26613                 skip "Need server version newer than 2.8.52"
26614         remote_mds_nodsh && skip "remote MDS with nodsh"
26615
26616         local mosps=$(do_facet $SINGLEMDS $LCTL dl |
26617                 awk '/osp .*-osc-MDT/ { print $4}')
26618
26619         local osp
26620         for osp in $mosps; do
26621                 echo "Deactivate: " $osp
26622                 do_facet $SINGLEMDS $LCTL --device %$osp deactivate
26623                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
26624                         awk -vp=$osp '$4 == p { print $2 }')
26625                 [ $stat = IN ] || {
26626                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
26627                         error "deactivate error"
26628                 }
26629                 echo "Activate: " $osp
26630                 do_facet $SINGLEMDS $LCTL --device %$osp activate
26631                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
26632                         awk -vp=$osp '$4 == p { print $2 }')
26633                 [ $stat = UP ] || {
26634                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
26635                         error "activate error"
26636                 }
26637         done
26638 }
26639 run_test 404 "validate manual {de}activated works properly for OSPs"
26640
26641 test_405() {
26642         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
26643         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] ||
26644                 [ $CLIENT_VERSION -lt $(version_code 2.6.99) ] &&
26645                         skip "Layout swap lock is not supported"
26646
26647         check_swap_layouts_support
26648         check_swap_layout_no_dom $DIR
26649
26650         test_mkdir $DIR/$tdir
26651         swap_lock_test -d $DIR/$tdir ||
26652                 error "One layout swap locked test failed"
26653 }
26654 run_test 405 "Various layout swap lock tests"
26655
26656 test_406() {
26657         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26658         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
26659         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
26660         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26661         [ $MDS1_VERSION -lt $(version_code 2.8.50) ] &&
26662                 skip "Need MDS version at least 2.8.50"
26663
26664         local def_stripe_size=$($LFS getstripe -S $MOUNT)
26665         local test_pool=$TESTNAME
26666
26667         pool_add $test_pool || error "pool_add failed"
26668         pool_add_targets $test_pool 0 $(($OSTCOUNT - 1)) 1 ||
26669                 error "pool_add_targets failed"
26670
26671         save_layout_restore_at_exit $MOUNT
26672
26673         # parent set default stripe count only, child will stripe from both
26674         # parent and fs default
26675         $LFS setstripe -c 1 -i 1 -S $((def_stripe_size * 2)) -p $test_pool $MOUNT ||
26676                 error "setstripe $MOUNT failed"
26677         $LFS mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
26678         $LFS setstripe -c $OSTCOUNT $DIR/$tdir || error "setstripe $tdir failed"
26679         for i in $(seq 10); do
26680                 local f=$DIR/$tdir/$tfile.$i
26681                 touch $f || error "touch failed"
26682                 local count=$($LFS getstripe -c $f)
26683                 [ $count -eq $OSTCOUNT ] ||
26684                         error "$f stripe count $count != $OSTCOUNT"
26685                 local offset=$($LFS getstripe -i $f)
26686                 [ $offset -eq 1 ] || error "$f stripe offset $offset != 1"
26687                 local size=$($LFS getstripe -S $f)
26688                 [ $size -eq $((def_stripe_size * 2)) ] ||
26689                         error "$f stripe size $size != $((def_stripe_size * 2))"
26690                 local pool=$($LFS getstripe -p $f)
26691                 [ $pool == $test_pool ] || error "$f pool $pool != $test_pool"
26692         done
26693
26694         # change fs default striping, delete parent default striping, now child
26695         # will stripe from new fs default striping only
26696         $LFS setstripe -c 1 -S $def_stripe_size -i 0 $MOUNT ||
26697                 error "change $MOUNT default stripe failed"
26698         $LFS setstripe -c 0 $DIR/$tdir ||
26699                 error "delete $tdir default stripe failed"
26700         for i in $(seq 11 20); do
26701                 local f=$DIR/$tdir/$tfile.$i
26702                 touch $f || error "touch $f failed"
26703                 local count=$($LFS getstripe -c $f)
26704                 [ $count -eq 1 ] || error "$f stripe count $count != 1"
26705                 local offset=$($LFS getstripe -i $f)
26706                 [ $offset -eq 0 ] || error "$f stripe offset $offset != 0"
26707                 local size=$($LFS getstripe -S $f)
26708                 [ $size -eq $def_stripe_size ] ||
26709                         error "$f stripe size $size != $def_stripe_size"
26710                 local pool=$($LFS getstripe -p $f)
26711                 [ $pool == $test_pool ] || error "$f pool $pool isn't set"
26712         done
26713
26714         unlinkmany $DIR/$tdir/$tfile. 1 20
26715
26716         local f=$DIR/$tdir/$tfile
26717         pool_remove_all_targets $test_pool $f
26718         pool_remove $test_pool $f
26719 }
26720 run_test 406 "DNE support fs default striping"
26721
26722 test_407() {
26723         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26724         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
26725                 skip "Need MDS version at least 2.8.55"
26726         remote_mds_nodsh && skip "remote MDS with nodsh"
26727
26728         $LFS mkdir -i 0 -c 1 $DIR/$tdir.0 ||
26729                 error "$LFS mkdir -i 0 -c 1 $tdir.0 failed"
26730         $LFS mkdir -i 1 -c 1 $DIR/$tdir.1 ||
26731                 error "$LFS mkdir -i 1 -c 1 $tdir.1 failed"
26732         touch $DIR/$tdir.0/$tfile.0 || error "touch $tdir.0/$tfile.0 failed"
26733
26734         #define OBD_FAIL_DT_TXN_STOP    0x2019
26735         for idx in $(seq $MDSCOUNT); do
26736                 do_facet mds$idx "lctl set_param fail_loc=0x2019"
26737         done
26738         $LFS mkdir -c 2 $DIR/$tdir && error "$LFS mkdir -c 2 $tdir should fail"
26739         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1/$tfile.1 &&
26740                 error "mv $tdir.0/$tfile.0 $tdir.1/$tfile.1 should fail"
26741         true
26742 }
26743 run_test 407 "transaction fail should cause operation fail"
26744
26745 test_408() {
26746         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
26747
26748         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
26749         lctl set_param fail_loc=0x8000040a
26750         # let ll_prepare_partial_page() fail
26751         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 conv=notrunc || true
26752
26753         rm -f $DIR/$tfile
26754
26755         # create at least 100 unused inodes so that
26756         # shrink_icache_memory(0) should not return 0
26757         touch $DIR/$tfile-{0..100}
26758         rm -f $DIR/$tfile-{0..100}
26759         sync
26760
26761         echo 2 > /proc/sys/vm/drop_caches
26762 }
26763 run_test 408 "drop_caches should not hang due to page leaks"
26764
26765 test_409()
26766 {
26767         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
26768
26769         mkdir -p $DIR/$tdir || error "(0) Fail to mkdir"
26770         $LFS mkdir -i 1 -c 2 $DIR/$tdir/foo || error "(1) Fail to mkdir"
26771         touch $DIR/$tdir/guard || error "(2) Fail to create"
26772
26773         local PREFIX=$(str_repeat 'A' 128)
26774         echo "Create 1K hard links start at $(date)"
26775         createmany -l $DIR/$tdir/guard $DIR/$tdir/foo/${PREFIX}_ 1000 ||
26776                 error "(3) Fail to hard link"
26777
26778         echo "Links count should be right although linkEA overflow"
26779         stat $DIR/$tdir/guard || error "(4) Fail to stat"
26780         local linkcount=$(stat --format=%h $DIR/$tdir/guard)
26781         [ $linkcount -eq 1001 ] ||
26782                 error "(5) Unexpected hard links count: $linkcount"
26783
26784         echo "List all links start at $(date)"
26785         ls -l $DIR/$tdir/foo > /dev/null ||
26786                 error "(6) Fail to list $DIR/$tdir/foo"
26787
26788         echo "Unlink hard links start at $(date)"
26789         unlinkmany $DIR/$tdir/foo/${PREFIX}_ 1000 ||
26790                 error "(7) Fail to unlink"
26791         echo "Unlink hard links finished at $(date)"
26792 }
26793 run_test 409 "Large amount of cross-MDTs hard links on the same file"
26794
26795 test_410()
26796 {
26797         [[ $CLIENT_VERSION -lt $(version_code 2.9.59) ]] &&
26798                 skip "Need client version at least 2.9.59"
26799         [ -f $LUSTRE/tests/kernel/kinode.ko ] ||
26800                 skip "Need MODULES build"
26801
26802         # Create a file, and stat it from the kernel
26803         local testfile=$DIR/$tfile
26804         touch $testfile
26805
26806         local run_id=$RANDOM
26807         local my_ino=$(stat --format "%i" $testfile)
26808
26809         # Try to insert the module. This will always fail as the
26810         # module is designed to not be inserted.
26811         insmod $LUSTRE/tests/kernel/kinode.ko run_id=$run_id fname=$testfile \
26812             &> /dev/null
26813
26814         # Anything but success is a test failure
26815         dmesg | grep -q \
26816             "lustre_kinode_$run_id: inode numbers are identical: $my_ino" ||
26817             error "no inode match"
26818 }
26819 run_test 410 "Test inode number returned from kernel thread"
26820
26821 cleanup_test411_cgroup() {
26822         trap 0
26823         rmdir "$1"
26824 }
26825
26826 test_411() {
26827         local cg_basedir=/sys/fs/cgroup/memory
26828         # LU-9966
26829         test -f "$cg_basedir/memory.kmem.limit_in_bytes" ||
26830                 skip "no setup for cgroup"
26831
26832         dd if=/dev/zero of=$DIR/$tfile bs=1M count=100 conv=fsync ||
26833                 error "test file creation failed"
26834         cancel_lru_locks osc
26835
26836         # Create a very small memory cgroup to force a slab allocation error
26837         local cgdir=$cg_basedir/osc_slab_alloc
26838         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
26839         trap "cleanup_test411_cgroup $cgdir" EXIT
26840         echo 2M > $cgdir/memory.kmem.limit_in_bytes
26841         echo 1M > $cgdir/memory.limit_in_bytes
26842
26843         # Should not LBUG, just be killed by oom-killer
26844         # dd will return 0 even allocation failure in some environment.
26845         # So don't check return value
26846         bash -c "echo \$$ > $cgdir/tasks && dd if=$DIR/$tfile of=/dev/null"
26847         cleanup_test411_cgroup $cgdir
26848
26849         return 0
26850 }
26851 run_test 411 "Slab allocation error with cgroup does not LBUG"
26852
26853 test_412() {
26854         (( $MDSCOUNT > 1 )) || skip_env "needs >= 2 MDTs"
26855         (( $MDS1_VERSION >= $(version_code 2.10.55) )) ||
26856                 skip "Need server version at least 2.10.55"
26857
26858         $LFS mkdir -i $((MDSCOUNT - 1)),$((MDSCOUNT - 2)) $DIR/$tdir ||
26859                 error "mkdir failed"
26860         $LFS getdirstripe $DIR/$tdir
26861         local stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
26862         [ $stripe_index -eq $((MDSCOUNT - 1)) ] ||
26863                 error "expect $((MDSCOUT - 1)) get $stripe_index"
26864         local stripe_count=$($LFS getdirstripe -T $DIR/$tdir)
26865         [ $stripe_count -eq 2 ] ||
26866                 error "expect 2 get $stripe_count"
26867
26868         (( $MDS1_VERSION >= $(version_code 2.14.55) )) || return 0
26869
26870         local index
26871         local index2
26872
26873         # subdirs should be on the same MDT as parent
26874         for i in $(seq 0 $((MDSCOUNT - 1))); do
26875                 $LFS mkdir -i $i $DIR/$tdir/mdt$i || error "mkdir mdt$i failed"
26876                 mkdir $DIR/$tdir/mdt$i/sub || error "mkdir sub failed"
26877                 index=$($LFS getstripe -m $DIR/$tdir/mdt$i/sub)
26878                 (( index == i )) || error "mdt$i/sub on MDT$index"
26879         done
26880
26881         # stripe offset -1, ditto
26882         for i in {1..10}; do
26883                 $LFS mkdir -i -1 $DIR/$tdir/qos$i || error "mkdir qos$i failed"
26884                 index=$($LFS getstripe -m $DIR/$tdir/qos$i)
26885                 mkdir $DIR/$tdir/qos$i/sub || error "mkdir sub failed"
26886                 index2=$($LFS getstripe -m $DIR/$tdir/qos$i/sub)
26887                 (( index == index2 )) ||
26888                         error "qos$i on MDT$index, sub on MDT$index2"
26889         done
26890
26891         local testdir=$DIR/$tdir/inherit
26892
26893         $LFS mkdir -i 1 --max-inherit=3 $testdir || error "mkdir inherit failed"
26894         # inherit 2 levels
26895         for i in 1 2; do
26896                 testdir=$testdir/s$i
26897                 mkdir $testdir || error "mkdir $testdir failed"
26898                 index=$($LFS getstripe -m $testdir)
26899                 (( index == 1 )) ||
26900                         error "$testdir on MDT$index"
26901         done
26902
26903         # not inherit any more
26904         testdir=$testdir/s3
26905         mkdir $testdir || error "mkdir $testdir failed"
26906         getfattr -d -m dmv $testdir | grep dmv &&
26907                 error "default LMV set on $testdir" || true
26908 }
26909 run_test 412 "mkdir on specific MDTs"
26910
26911 TEST413_COUNT=${TEST413_COUNT:-200}
26912
26913 #
26914 # set_maxage() is used by test_413 only.
26915 # This is a helper function to set maxage. Does not return any value.
26916 # Input: maxage to set
26917 #
26918 set_maxage() {
26919         local lmv_qos_maxage
26920         local lod_qos_maxage
26921         local new_maxage=$1
26922
26923         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
26924         $LCTL set_param lmv.*.qos_maxage=$new_maxage
26925         stack_trap "$LCTL set_param \
26926                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null"
26927         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
26928                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
26929         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
26930                 lod.*.mdt_qos_maxage=$new_maxage
26931         stack_trap "do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
26932                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null"
26933 }
26934
26935 generate_uneven_mdts() {
26936         local threshold=$1
26937         local ffree
26938         local bavail
26939         local max
26940         local min
26941         local max_index
26942         local min_index
26943         local tmp
26944         local i
26945
26946         echo
26947         echo "Check for uneven MDTs: "
26948
26949         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
26950         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
26951         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
26952
26953         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
26954         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
26955         max_index=0
26956         min_index=0
26957         for ((i = 1; i < ${#ffree[@]}; i++)); do
26958                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
26959                 if [ $tmp -gt $max ]; then
26960                         max=$tmp
26961                         max_index=$i
26962                 fi
26963                 if [ $tmp -lt $min ]; then
26964                         min=$tmp
26965                         min_index=$i
26966                 fi
26967         done
26968
26969         (( min > 0 )) || skip "low space on MDT$min_index"
26970         (( ${ffree[min_index]} > 0 )) ||
26971                 skip "no free files on MDT$min_index"
26972         (( ${ffree[min_index]} < 10000000 )) ||
26973                 skip "too many free files on MDT$min_index"
26974
26975         # Check if we need to generate uneven MDTs
26976         local diff=$(((max - min) * 100 / min))
26977         local testdirp=$DIR/$tdir-fillmdt # parent fill folder
26978         local testdir # individual folder within $testdirp
26979         local start
26980         local cmd
26981
26982         # fallocate is faster to consume space on MDT, if available
26983         if check_fallocate_supported mds$((min_index + 1)); then
26984                 cmd="fallocate -l 128K "
26985         else
26986                 cmd="dd if=/dev/zero bs=128K count=1 of="
26987         fi
26988
26989         echo "using cmd $cmd"
26990         for (( i = 0; diff < threshold; i++ )); do
26991                 testdir=${testdirp}/$i
26992                 [ -d $testdir ] && continue
26993
26994                 (( i % 10 > 0 )) || { $LFS df; $LFS df -i; }
26995
26996                 mkdir -p $testdirp
26997                 # generate uneven MDTs, create till $threshold% diff
26998                 echo -n "weight diff=$diff% must be > $threshold% ..."
26999                 echo "Fill MDT$min_index with $TEST413_COUNT files: loop $i"
27000                 $LFS mkdir -i $min_index $testdir ||
27001                         error "mkdir $testdir failed"
27002                 $LFS setstripe -E 1M -L mdt $testdir ||
27003                         error "setstripe $testdir failed"
27004                 start=$SECONDS
27005                 for (( f = 0; f < TEST413_COUNT; f++ )); do
27006                         $cmd$testdir/f.$f &> /dev/null || error "$cmd $f failed"
27007                 done
27008                 sync; sleep 1; sync
27009
27010                 # wait for QOS to update
27011                 (( SECONDS < start + 2 )) && sleep $((start + 2 - SECONDS))
27012
27013                 ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-*.filesfree))
27014                 bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-*.kbytesavail))
27015                 max=$(((${ffree[max_index]} >> 8) *
27016                         (${bavail[max_index]} * bsize >> 16)))
27017                 min=$(((${ffree[min_index]} >> 8) *
27018                         (${bavail[min_index]} * bsize >> 16)))
27019                 (( min > 0 )) || skip "low space on MDT$min_index"
27020                 diff=$(((max - min) * 100 / min))
27021         done
27022
27023         echo "MDT filesfree available: ${ffree[*]}"
27024         echo "MDT blocks available: ${bavail[*]}"
27025         echo "weight diff=$diff%"
27026 }
27027
27028 test_qos_mkdir() {
27029         local mkdir_cmd=$1
27030         local stripe_count=$2
27031         local mdts=$(comma_list $(mdts_nodes))
27032
27033         local testdir
27034         local lmv_qos_prio_free
27035         local lmv_qos_threshold_rr
27036         local lod_qos_prio_free
27037         local lod_qos_threshold_rr
27038         local total
27039         local count
27040         local i
27041
27042         # @total is total directories created if it's testing plain
27043         # directories, otherwise it's total stripe object count for
27044         # striped directories test.
27045         # remote/striped directory unlinking is slow on zfs and may
27046         # timeout, test with fewer directories
27047         [ "$mds1_FSTYPE" = "zfs" ] && total=120 || total=240
27048
27049         lmv_qos_prio_free=$($LCTL get_param -n lmv.*.qos_prio_free | head -n1)
27050         lmv_qos_prio_free=${lmv_qos_prio_free%%%}
27051         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
27052                 head -n1)
27053         lmv_qos_threshold_rr=${lmv_qos_threshold_rr%%%}
27054         stack_trap "$LCTL set_param \
27055                 lmv.*.qos_prio_free=$lmv_qos_prio_free > /dev/null"
27056         stack_trap "$LCTL set_param \
27057                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null"
27058
27059         lod_qos_prio_free=$(do_facet mds1 $LCTL get_param -n \
27060                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_prio_free | head -n1)
27061         lod_qos_prio_free=${lod_qos_prio_free%%%}
27062         lod_qos_threshold_rr=$(do_facet mds1 $LCTL get_param -n \
27063                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_threshold_rr | head -n1)
27064         lod_qos_threshold_rr=${lod_qos_threshold_rr%%%}
27065         stack_trap "do_nodes $mdts $LCTL set_param \
27066                 lod.*.mdt_qos_prio_free=$lod_qos_prio_free > /dev/null"
27067         stack_trap "do_nodes $mdts $LCTL set_param \
27068                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null"
27069
27070         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
27071         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=100 > /dev/null
27072
27073         testdir=$DIR/$tdir-s$stripe_count/rr
27074
27075         local stripe_index=$($LFS getstripe -m $testdir)
27076         local test_mkdir_rr=true
27077
27078         getfattr -d -m dmv -e hex $testdir | grep dmv
27079         if (( $? == 0 && $MDS1_VERSION >= $(version_code 2.14.51) )); then
27080                 echo "defstripe: '$($LFS getdirstripe -D $testdir)'"
27081                 (( $($LFS getdirstripe -D --max-inherit-rr $testdir) == 0 )) &&
27082                         test_mkdir_rr=false
27083         fi
27084
27085         echo
27086         $test_mkdir_rr &&
27087                 echo "Mkdir (stripe_count $stripe_count) roundrobin:" ||
27088                 echo "Mkdir (stripe_count $stripe_count) on stripe $stripe_index"
27089
27090         stack_trap "unlinkmany -d $testdir/subdir $((total / stripe_count))"
27091         for (( i = 0; i < total / stripe_count; i++ )); do
27092                 eval $mkdir_cmd $testdir/subdir$i ||
27093                         error "$mkdir_cmd subdir$i failed"
27094         done
27095
27096         for (( i = 0; i < $MDSCOUNT; i++ )); do
27097                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
27098                 echo "$count directories created on MDT$i"
27099                 if $test_mkdir_rr; then
27100                         (( count == total / stripe_count / MDSCOUNT )) ||
27101                                 error "subdirs are not evenly distributed"
27102                 elif (( i == stripe_index )); then
27103                         (( count == total / stripe_count )) ||
27104                                 error "$count subdirs created on MDT$i"
27105                 else
27106                         (( count == 0 )) ||
27107                                 error "$count subdirs created on MDT$i"
27108                 fi
27109
27110                 if $test_mkdir_rr && [ $stripe_count -gt 1 ]; then
27111                         count=$($LFS getdirstripe $testdir/* |
27112                                 grep -c -P "^\s+$i\t")
27113                         echo "$count stripes created on MDT$i"
27114                         # deviation should < 5% of average
27115                         delta=$((count - total / MDSCOUNT))
27116                         (( ${delta#-} <= total / MDSCOUNT / 20 )) ||
27117                                 error "stripes are not evenly distributed"
27118                 fi
27119         done
27120
27121         echo
27122         echo "Check for uneven MDTs: "
27123
27124         local ffree
27125         local bavail
27126         local max
27127         local min
27128         local max_index
27129         local min_index
27130         local tmp
27131
27132         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
27133         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
27134         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
27135
27136         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
27137         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
27138         max_index=0
27139         min_index=0
27140         for ((i = 1; i < ${#ffree[@]}; i++)); do
27141                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
27142                 if [ $tmp -gt $max ]; then
27143                         max=$tmp
27144                         max_index=$i
27145                 fi
27146                 if [ $tmp -lt $min ]; then
27147                         min=$tmp
27148                         min_index=$i
27149                 fi
27150         done
27151         echo "stripe_count=$stripe_count min_idx=$min_index max_idx=$max_index"
27152
27153         (( min > 0 )) || skip "low space on MDT$min_index"
27154         (( ${ffree[min_index]} < 10000000 )) ||
27155                 skip "too many free files on MDT$min_index"
27156
27157         generate_uneven_mdts 120
27158
27159         echo "MDT filesfree available: ${ffree[*]}"
27160         echo "MDT blocks available: ${bavail[*]}"
27161         echo "weight diff=$(((max - min) * 100 / min))%"
27162         echo
27163         echo "Mkdir (stripe_count $stripe_count) with balanced space usage:"
27164
27165         $LCTL set_param lmv.*.qos_threshold_rr=0 > /dev/null
27166         $LCTL set_param lmv.*.qos_prio_free=100 > /dev/null
27167         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=0 > /dev/null
27168         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_prio_free=100 > /dev/null
27169         # decrease statfs age, so that it can be updated in time
27170         $LCTL set_param lmv.*.qos_maxage=1 > /dev/null
27171         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_maxage=1 > /dev/null
27172
27173         sleep 1
27174
27175         testdir=$DIR/$tdir-s$stripe_count/qos
27176
27177         stack_trap "unlinkmany -d $testdir/subdir $((total / stripe_count))"
27178         for (( i = 0; i < total / stripe_count; i++ )); do
27179                 eval $mkdir_cmd $testdir/subdir$i ||
27180                         error "$mkdir_cmd subdir$i failed"
27181         done
27182
27183         max=0
27184         for (( i = 0; i < $MDSCOUNT; i++ )); do
27185                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
27186                 (( count > max )) && max=$count
27187                 echo "$count directories created on MDT$i : curmax=$max"
27188         done
27189
27190         min=$($LFS getdirstripe -i $testdir/* | grep -c "^$min_index$")
27191
27192         # D-value should > 10% of average
27193         (( max - min > total / stripe_count / MDSCOUNT / 10 )) ||
27194                 error "subdirs shouldn't be evenly distributed: $max - $min <= $((total / stripe_count / MDSCOUNT / 10))"
27195
27196         # ditto for stripes
27197         if (( stripe_count > 1 )); then
27198                 max=0
27199                 for (( i = 0; i < $MDSCOUNT; i++ )); do
27200                         count=$($LFS getdirstripe $testdir/* |
27201                                 grep -c -P "^\s+$i\t")
27202                         (( count > max )) && max=$count
27203                         echo "$count stripes created on MDT$i"
27204                 done
27205
27206                 min=$($LFS getdirstripe $testdir/* |
27207                         grep -c -P "^\s+$min_index\t")
27208                 (( max - min > total / MDSCOUNT / 10 )) ||
27209                         error "stripes shouldn't be evenly distributed: $max - $min <= $((total / MDSCOUNT / 10))"
27210         fi
27211 }
27212
27213 most_full_mdt() {
27214         local ffree
27215         local bavail
27216         local bsize
27217         local min
27218         local min_index
27219         local tmp
27220
27221         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
27222         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
27223         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
27224
27225         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
27226         min_index=0
27227         for ((i = 1; i < ${#ffree[@]}; i++)); do
27228                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
27229                 (( tmp < min )) && min=$tmp && min_index=$i
27230         done
27231
27232         echo -n $min_index
27233 }
27234
27235 test_413a() {
27236         [ $MDSCOUNT -lt 2 ] &&
27237                 skip "We need at least 2 MDTs for this test"
27238
27239         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
27240                 skip "Need server version at least 2.12.52"
27241
27242         local stripe_max=$((MDSCOUNT - 1))
27243         local stripe_count
27244
27245         # let caller set maxage for latest result
27246         set_maxage 1
27247
27248         # fill MDT unevenly
27249         generate_uneven_mdts 120
27250
27251         # test 4-stripe directory at most, otherwise it's too slow
27252         # We are being very defensive. Although Autotest uses 4 MDTs.
27253         # We make sure stripe_max does not go over 4.
27254         (( stripe_max > 4 )) && stripe_max=4
27255         # unlinking striped directory is slow on zfs, and may timeout, only test
27256         # plain directory
27257         [ "$mds1_FSTYPE" == "zfs" ] && stripe_max=1
27258         for stripe_count in $(seq 1 $stripe_max); do
27259                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
27260                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
27261                 $LFS mkdir -i $(most_full_mdt) $DIR/$tdir-s$stripe_count/qos ||
27262                         error "mkdir failed"
27263                 test_qos_mkdir "$LFS mkdir -i -1 -c $stripe_count" $stripe_count
27264         done
27265 }
27266 run_test 413a "QoS mkdir with 'lfs mkdir -i -1'"
27267
27268 test_413b() {
27269         [ $MDSCOUNT -lt 2 ] &&
27270                 skip "We need at least 2 MDTs for this test"
27271
27272         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
27273                 skip "Need server version at least 2.12.52"
27274
27275         local stripe_max=$((MDSCOUNT - 1))
27276         local testdir
27277         local stripe_count
27278
27279         # let caller set maxage for latest result
27280         set_maxage 1
27281
27282         # fill MDT unevenly
27283         generate_uneven_mdts 120
27284
27285         # test 4-stripe directory at most, otherwise it's too slow
27286         # We are being very defensive. Although Autotest uses 4 MDTs.
27287         # We make sure stripe_max does not go over 4.
27288         (( stripe_max > 4 )) && stripe_max=4
27289         [ "$mds1_FSTYPE" == "zfs" ] && stripe_max=1
27290         for stripe_count in $(seq 1 $stripe_max); do
27291                 testdir=$DIR/$tdir-s$stripe_count
27292                 mkdir $testdir || error "mkdir $testdir failed"
27293                 mkdir $testdir/rr || error "mkdir rr failed"
27294                 $LFS mkdir -i $(most_full_mdt) $testdir/qos ||
27295                         error "mkdir qos failed"
27296                 $LFS setdirstripe -D -c $stripe_count --max-inherit-rr 2 \
27297                         $testdir/rr || error "setdirstripe rr failed"
27298                 $LFS setdirstripe -D -c $stripe_count $testdir/qos ||
27299                         error "setdirstripe failed"
27300                 test_qos_mkdir "mkdir" $stripe_count
27301         done
27302 }
27303 run_test 413b "QoS mkdir under dir whose default LMV starting MDT offset is -1"
27304
27305 test_413c() {
27306         (( $MDSCOUNT >= 2 )) ||
27307                 skip "We need at least 2 MDTs for this test"
27308
27309         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
27310                 skip "Need server version at least 2.14.51"
27311
27312         local testdir
27313         local inherit
27314         local inherit_rr
27315         local lmv_qos_maxage
27316         local lod_qos_maxage
27317
27318         # let caller set maxage for latest result
27319         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
27320         $LCTL set_param lmv.*.qos_maxage=1
27321         stack_trap "$LCTL set_param \
27322                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null" RETURN
27323         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
27324                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
27325         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
27326                 lod.*.mdt_qos_maxage=1
27327         stack_trap "do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
27328                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null" RETURN
27329
27330         # fill MDT unevenly
27331         generate_uneven_mdts 120
27332
27333         testdir=$DIR/${tdir}-s1
27334         mkdir $testdir || error "mkdir $testdir failed"
27335         mkdir $testdir/rr || error "mkdir rr failed"
27336         $LFS mkdir -i $(most_full_mdt) $testdir/qos || error "mkdir qos failed"
27337         # default max_inherit is -1, default max_inherit_rr is 0
27338         $LFS setdirstripe -D -c 1 $testdir/rr ||
27339                 error "setdirstripe rr failed"
27340         $LFS setdirstripe -D -c 1 -i -1 -X 2 --max-inherit-rr 1 $testdir/qos ||
27341                 error "setdirstripe qos failed"
27342         test_qos_mkdir "mkdir" 1
27343
27344         mkdir $testdir/rr/level1 || error "mkdir rr/level1 failed"
27345         inherit=$($LFS getdirstripe -D -X $testdir/rr/level1)
27346         (( $inherit == -1 )) || error "rr/level1 inherit $inherit != -1"
27347         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/rr/level1)
27348         (( $inherit_rr == 0 )) || error "rr/level1 inherit-rr $inherit_rr != 0"
27349
27350         mkdir $testdir/qos/level1 || error "mkdir qos/level1 failed"
27351         inherit=$($LFS getdirstripe -D -X $testdir/qos/level1)
27352         (( $inherit == 1 )) || error "qos/level1 inherit $inherit != 1"
27353         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/qos/level1)
27354         (( $inherit_rr == 0 )) || error "qos/level1 inherit-rr $inherit_rr != 0"
27355         mkdir $testdir/qos/level1/level2 || error "mkdir level2 failed"
27356         getfattr -d -m dmv -e hex $testdir/qos/level1/level2 | grep dmv &&
27357                 error "level2 shouldn't have default LMV" || true
27358 }
27359 run_test 413c "mkdir with default LMV max inherit rr"
27360
27361 test_413d() {
27362         (( MDSCOUNT >= 2 )) ||
27363                 skip "We need at least 2 MDTs for this test"
27364
27365         (( MDS1_VERSION >= $(version_code 2.14.51) )) ||
27366                 skip "Need server version at least 2.14.51"
27367
27368         local lmv_qos_threshold_rr
27369
27370         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
27371                 head -n1)
27372         stack_trap "$LCTL set_param \
27373                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null" EXIT
27374
27375         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
27376         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
27377         getfattr -d -m dmv -e hex $DIR/$tdir | grep dmv &&
27378                 error "$tdir shouldn't have default LMV"
27379         createmany -d $DIR/$tdir/sub $((100 * MDSCOUNT)) ||
27380                 error "mkdir sub failed"
27381
27382         local count=$($LFS getstripe -m $DIR/$tdir/* | grep -c ^0)
27383
27384         (( count == 100 )) || error "$count subdirs on MDT0"
27385 }
27386 run_test 413d "inherit ROOT default LMV"
27387
27388 test_413e() {
27389         (( MDSCOUNT >= 2 )) ||
27390                 skip "We need at least 2 MDTs for this test"
27391         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
27392                 skip "Need server version at least 2.14.55"
27393
27394         local testdir=$DIR/$tdir
27395         local tmpfile=$TMP/temp.setdirstripe.stderr.$$
27396         local max_inherit
27397         local sub_max_inherit
27398
27399         mkdir -p $testdir || error "failed to create $testdir"
27400
27401         # set default max-inherit to -1 if stripe count is 0 or 1
27402         $LFS setdirstripe -D -c 1 $testdir ||
27403                 error "failed to set default LMV"
27404         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
27405         (( max_inherit == -1 )) ||
27406                 error "wrong max_inherit value $max_inherit"
27407
27408         # set default max_inherit to a fixed value if stripe count is not 0 or 1
27409         $LFS setdirstripe -D -c -1 $testdir ||
27410                 error "failed to set default LMV"
27411         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
27412         (( max_inherit > 0 )) ||
27413                 error "wrong max_inherit value $max_inherit"
27414
27415         # and the subdir will decrease the max_inherit by 1
27416         mkdir -p $testdir/subdir-1 || error "failed to make subdir"
27417         sub_max_inherit=$($LFS getdirstripe -D --max-inherit $testdir/subdir-1)
27418         (( sub_max_inherit == max_inherit - 1)) ||
27419                 error "wrong max-inherit of subdir $sub_max_inherit"
27420
27421         # check specified --max-inherit and warning message
27422         stack_trap "rm -f $tmpfile"
27423         $LFS setdirstripe -D -c 2 --max-inherit=-1 $testdir 2> $tmpfile ||
27424                 error "failed to set default LMV"
27425         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
27426         (( max_inherit == -1 )) ||
27427                 error "wrong max_inherit value $max_inherit"
27428
27429         # check the warning messages
27430         if ! [[ $(cat $tmpfile) =~ "max-inherit=" ]]; then
27431                 error "failed to detect warning string"
27432         fi
27433 }
27434 run_test 413e "check default max-inherit value"
27435
27436 test_fs_dmv_inherit()
27437 {
27438         local testdir=$DIR/$tdir
27439
27440         local count
27441         local inherit
27442         local inherit_rr
27443
27444         for i in 1 2; do
27445                 mkdir $testdir || error "mkdir $testdir failed"
27446                 count=$($LFS getdirstripe -D -c $testdir)
27447                 (( count == 1 )) ||
27448                         error "$testdir default LMV count mismatch $count != 1"
27449                 inherit=$($LFS getdirstripe -D -X $testdir)
27450                 (( inherit == 3 - i )) ||
27451                         error "$testdir default LMV max-inherit $inherit != $((3 - i))"
27452                 inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir)
27453                 (( inherit_rr == 3 - i )) ||
27454                         error "$testdir default LMV max-inherit-rr $inherit_rr != $((3 - i))"
27455                 testdir=$testdir/sub
27456         done
27457
27458         mkdir $testdir || error "mkdir $testdir failed"
27459         count=$($LFS getdirstripe -D -c $testdir)
27460         (( count == 0 )) ||
27461                 error "$testdir default LMV count not zero: $count"
27462 }
27463
27464 test_413f() {
27465         (( MDSCOUNT >= 2 )) || skip "We need at least 2 MDTs for this test"
27466
27467         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
27468                 skip "Need server version at least 2.14.55"
27469
27470         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
27471                 error "dump $DIR default LMV failed"
27472         stack_trap "setfattr --restore=$TMP/dmv.ea"
27473
27474         $LFS setdirstripe -D -i -1 -c 1 -X 3 --max-inherit-rr 3 $DIR ||
27475                 error "set $DIR default LMV failed"
27476
27477         test_fs_dmv_inherit
27478 }
27479 run_test 413f "lfs getdirstripe -D list ROOT default LMV if it's not set on dir"
27480
27481 test_413g() {
27482         (( MDSCOUNT >= 2 )) || skip "We need at least 2 MDTs for this test"
27483
27484         mkdir -p $DIR/$tdir/l2/l3/l4 || error "mkdir $tdir/l1/l2/l3 failed"
27485         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
27486                 error "dump $DIR default LMV failed"
27487         stack_trap "setfattr --restore=$TMP/dmv.ea"
27488
27489         $LFS setdirstripe -D -i -1 -c 1 -X 3 --max-inherit-rr 3 $DIR ||
27490                 error "set $DIR default LMV failed"
27491
27492         FILESET="$FILESET/$tdir/l2/l3/l4" mount_client $MOUNT2 ||
27493                 error "mount $MOUNT2 failed"
27494         stack_trap "umount_client $MOUNT2"
27495
27496         local saved_DIR=$DIR
27497
27498         export DIR=$MOUNT2
27499
27500         stack_trap "export DIR=$saved_DIR"
27501
27502         # first check filesystem-wide default LMV inheritance
27503         test_fs_dmv_inherit || error "incorrect fs default LMV inheritance"
27504
27505         # then check subdirs are spread to all MDTs
27506         createmany -d $DIR/s $((MDSCOUNT * 100)) || error "createmany failed"
27507
27508         local count=$($LFS getstripe -m $DIR/s* | sort -u | wc -l)
27509
27510         (( $count == $MDSCOUNT )) || error "dirs are spread to $count MDTs"
27511 }
27512 run_test 413g "enforce ROOT default LMV on subdir mount"
27513
27514 test_413h() {
27515         (( MDSCOUNT >= 2 )) ||
27516                 skip "We need at least 2 MDTs for this test"
27517
27518         (( MDS1_VERSION >= $(version_code 2.15.50.6) )) ||
27519                 skip "Need server version at least 2.15.50.6"
27520
27521         local lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
27522
27523         stack_trap "$LCTL set_param \
27524                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null"
27525         $LCTL set_param lmv.*.qos_maxage=1
27526
27527         local depth=5
27528         local rr_depth=4
27529         local dir=$DIR/$tdir/l1/l2/l3/l4/l5
27530         local count=$((MDSCOUNT * 20))
27531
27532         generate_uneven_mdts 50
27533
27534         mkdir -p $dir || error "mkdir $dir failed"
27535         stack_trap "rm -rf $dir"
27536         $LFS setdirstripe -D -c 1 -i -1 --max-inherit=$depth \
27537                 --max-inherit-rr=$rr_depth $dir
27538
27539         for ((d=0; d < depth + 2; d++)); do
27540                 log "dir=$dir:"
27541                 for ((sub=0; sub < count; sub++)); do
27542                         mkdir $dir/d$sub
27543                 done
27544                 $LFS getdirstripe -i $dir/d* | sort | uniq -c | sort -nr
27545                 local num=($($LFS getdirstripe -i $dir/d* | sort | uniq -c))
27546                 # subdirs within $rr_depth should be created round-robin
27547                 if (( d < rr_depth )); then
27548                         (( ${num[0]} != count )) ||
27549                                 error "all objects created on MDT ${num[1]}"
27550                 fi
27551
27552                 dir=$dir/d0
27553         done
27554 }
27555 run_test 413h "don't stick to parent for round-robin dirs"
27556
27557 test_413i() {
27558         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
27559
27560         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
27561                 skip "Need server version at least 2.14.55"
27562
27563         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
27564                 error "dump $DIR default LMV failed"
27565         stack_trap "setfattr --restore=$TMP/dmv.ea"
27566
27567         local testdir=$DIR/$tdir
27568         local def_max_rr=1
27569         local def_max=3
27570         local count
27571
27572         $LFS setdirstripe -D -i-1 -c1 --max-inherit=$def_max \
27573                 --max-inherit-rr=$def_max_rr $DIR ||
27574                 error "set $DIR default LMV failed"
27575
27576         for i in $(seq 2 3); do
27577                 def_max=$((def_max - 1))
27578                 (( def_max_rr == 0 )) || def_max_rr=$((def_max_rr - 1))
27579
27580                 mkdir $testdir
27581                 # RR is decremented and keeps zeroed once exhausted
27582                 count=$($LFS getdirstripe -D --max-inherit-rr $testdir)
27583                 (( count == def_max_rr )) ||
27584                         error_noexit "$testdir: max-inherit-rr $count != $def_max_rr"
27585
27586                 # max-inherit is decremented
27587                 count=$($LFS getdirstripe -D --max-inherit $testdir)
27588                 (( count == def_max )) ||
27589                         error_noexit "$testdir: max-inherit $count != $def_max"
27590
27591                 testdir=$testdir/d$i
27592         done
27593
27594         # d3 is the last inherited from ROOT, no inheritance anymore
27595         # i.e. no the default layout anymore
27596         mkdir -p $testdir/d4/d5
27597         count=$($LFS getdirstripe -D --max-inherit $testdir)
27598         (( count == -1 )) ||
27599                 error_noexit "$testdir: max-inherit $count != -1"
27600
27601         local p_count=$($LFS getdirstripe -i $testdir)
27602
27603         for i in $(seq 4 5); do
27604                 testdir=$testdir/d$i
27605
27606                 # the root default layout is not applied once exhausted
27607                 count=$($LFS getdirstripe -i $testdir)
27608                 (( count == p_count )) ||
27609                         error_noexit "$testdir: stripe-offset $count != parent offset $p_count"
27610         done
27611
27612         $LFS setdirstripe -i 0 $DIR/d2
27613         count=$($LFS getdirstripe -D --max-inherit $DIR/d2)
27614         (( count == -1 )) ||
27615                 error_noexit "$DIR/d2: max-inherit non-striped default $count != -1"
27616 }
27617 run_test 413i "check default layout inheritance"
27618
27619 test_413z() {
27620         local pids=""
27621         local subdir
27622         local pid
27623
27624         for subdir in $(\ls -1 -d $DIR/d413*-fillmdt/*); do
27625                 unlinkmany $subdir/f. $TEST413_COUNT &
27626                 pids="$pids $!"
27627         done
27628
27629         for pid in $pids; do
27630                 wait $pid
27631         done
27632
27633         true
27634 }
27635 run_test 413z "413 test cleanup"
27636
27637 test_414() {
27638 #define OBD_FAIL_PTLRPC_BULK_ATTACH      0x521
27639         $LCTL set_param fail_loc=0x80000521
27640         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
27641         rm -f $DIR/$tfile
27642 }
27643 run_test 414 "simulate ENOMEM in ptlrpc_register_bulk()"
27644
27645 test_415() {
27646         [[ $PARALLEL == "yes" ]] && skip "skip parallel run"
27647         (( $MDS1_VERSION >= $(version_code 2.11.52) )) ||
27648                 skip "Need server version at least 2.11.52"
27649
27650         # LU-11102
27651         local total=500
27652         local max=120
27653
27654         # this test may be slow on ZFS
27655         [[ "$mds1_FSTYPE" == "zfs" ]] && total=50
27656
27657         # though this test is designed for striped directory, let's test normal
27658         # directory too since lock is always saved as CoS lock.
27659         test_mkdir $DIR/$tdir || error "mkdir $tdir"
27660         createmany -o $DIR/$tdir/$tfile. $total || error "createmany"
27661         stack_trap "unlinkmany $DIR/$tdir/$tfile. $total || true"
27662         # if looping with ONLY_REPEAT, wait for previous deletions to finish
27663         wait_delete_completed_mds
27664
27665         # run a loop without concurrent touch to measure rename duration.
27666         # only for test debug/robustness, NOT part of COS functional test.
27667         local start_time=$SECONDS
27668         for ((i = 0; i < total; i++)); do
27669                 mrename $DIR/$tdir/$tfile.$i $DIR/$tdir/$tfile-new.$i \
27670                         > /dev/null
27671         done
27672         local baseline=$((SECONDS - start_time))
27673         echo "rename $total files without 'touch' took $baseline sec"
27674
27675         (
27676                 while true; do
27677                         touch $DIR/$tdir
27678                 done
27679         ) &
27680         local setattr_pid=$!
27681
27682         # rename files back to original name so unlinkmany works
27683         start_time=$SECONDS
27684         for ((i = 0; i < total; i++)); do
27685                 mrename $DIR/$tdir/$tfile-new.$i $DIR/$tdir/$tfile.$i\
27686                         > /dev/null
27687         done
27688         local duration=$((SECONDS - start_time))
27689
27690         kill -9 $setattr_pid
27691
27692         echo "rename $total files with 'touch' took $duration sec"
27693         (( max > 2 * baseline )) || max=$((2 * baseline + 5))
27694         (( duration <= max )) ||
27695                 error_not_in_vm "rename took $duration > $max sec"
27696 }
27697 run_test 415 "lock revoke is not missing"
27698
27699 test_416() {
27700         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
27701                 skip "Need server version at least 2.11.55"
27702
27703         # define OBD_FAIL_OSD_TXN_START    0x19a
27704         do_facet mds1 lctl set_param fail_loc=0x19a
27705
27706         lfs mkdir -c $MDSCOUNT $DIR/$tdir
27707
27708         true
27709 }
27710 run_test 416 "transaction start failure won't cause system hung"
27711
27712 cleanup_417() {
27713         trap 0
27714         do_nodes $(comma_list $(mdts_nodes)) \
27715                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=1"
27716         do_nodes $(comma_list $(mdts_nodes)) \
27717                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=1"
27718         do_nodes $(comma_list $(mdts_nodes)) \
27719                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=1"
27720 }
27721
27722 test_417() {
27723         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
27724         [[ $MDS1_VERSION -lt $(version_code 2.11.56) ]] &&
27725                 skip "Need MDS version at least 2.11.56"
27726
27727         trap cleanup_417 RETURN EXIT
27728
27729         $LFS mkdir -i 1 $DIR/$tdir.1 || error "create remote dir $tdir.1 failed"
27730         do_nodes $(comma_list $(mdts_nodes)) \
27731                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=0"
27732         $LFS migrate -m 0 $DIR/$tdir.1 &&
27733                 error "migrate dir $tdir.1 should fail"
27734
27735         do_nodes $(comma_list $(mdts_nodes)) \
27736                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=0"
27737         $LFS mkdir -i 1 $DIR/$tdir.2 &&
27738                 error "create remote dir $tdir.2 should fail"
27739
27740         do_nodes $(comma_list $(mdts_nodes)) \
27741                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=0"
27742         $LFS mkdir -c 2 $DIR/$tdir.3 &&
27743                 error "create striped dir $tdir.3 should fail"
27744         true
27745 }
27746 run_test 417 "disable remote dir, striped dir and dir migration"
27747
27748 # Checks that the outputs of df [-i] and lfs df [-i] match
27749 #
27750 # usage: check_lfs_df <blocks | inodes> <mountpoint>
27751 check_lfs_df() {
27752         local dir=$2
27753         local inodes
27754         local df_out
27755         local lfs_df_out
27756         local count
27757         local passed=false
27758
27759         # blocks or inodes
27760         [ "$1" == "blocks" ] && inodes= || inodes="-i"
27761
27762         for count in {1..100}; do
27763                 do_nodes "$CLIENTS" \
27764                         $LCTL set_param ldlm.namespaces.*.lru_size=clear
27765                 sync; sleep 0.2
27766
27767                 # read the lines of interest
27768                 df_out=($(df -P $inodes $dir | tail -n +2)) ||
27769                         error "df $inodes $dir | tail -n +2 failed"
27770                 lfs_df_out=($($LFS df $inodes $dir | grep summary:)) ||
27771                         error "lfs df $inodes $dir | grep summary: failed"
27772
27773                 # skip first substrings of each output as they are different
27774                 # "<NID>:/<fsname>" for df, "filesystem_summary:" for lfs df
27775                 # compare the two outputs
27776                 passed=true
27777                 #  skip "available" on MDT until LU-13997 is fixed.
27778                 #for i in {1..5}; do
27779                 for i in 1 2 4 5; do
27780                         [ "${df_out[i]}" != "${lfs_df_out[i]}" ] && passed=false
27781                 done
27782                 $passed && break
27783         done
27784
27785         if ! $passed; then
27786                 df -P $inodes $dir
27787                 echo
27788                 lfs df $inodes $dir
27789                 error "df and lfs df $1 output mismatch: "      \
27790                       "df ${inodes}: ${df_out[*]}, "            \
27791                       "lfs df ${inodes}: ${lfs_df_out[*]}"
27792         fi
27793 }
27794
27795 test_418() {
27796         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27797
27798         local dir=$DIR/$tdir
27799         local numfiles=$((RANDOM % 4096 + 2))
27800         local numblocks=$((RANDOM % 256 + 1))
27801
27802         wait_delete_completed
27803         test_mkdir $dir
27804
27805         # check block output
27806         check_lfs_df blocks $dir
27807         # check inode output
27808         check_lfs_df inodes $dir
27809
27810         # create a single file and retest
27811         echo "Creating a single file and testing"
27812         createmany -o $dir/$tfile- 1 &>/dev/null ||
27813                 error "creating 1 file in $dir failed"
27814         check_lfs_df blocks $dir
27815         check_lfs_df inodes $dir
27816
27817         # create a random number of files
27818         echo "Creating $((numfiles - 1)) files and testing"
27819         createmany -o $dir/$tfile- 1 $((numfiles - 1)) &>/dev/null ||
27820                 error "creating $((numfiles - 1)) files in $dir failed"
27821
27822         # write a random number of blocks to the first test file
27823         echo "Writing $numblocks 4K blocks and testing"
27824         dd if=/dev/urandom of=$dir/${tfile}-0 bs=4K conv=fsync \
27825                 count=$numblocks &>/dev/null ||
27826                 error "dd to $dir/${tfile}-0 failed"
27827
27828         # retest
27829         check_lfs_df blocks $dir
27830         check_lfs_df inodes $dir
27831
27832         unlinkmany $dir/$tfile- $numfiles &>/dev/null ||
27833                 error "unlinking $numfiles files in $dir failed"
27834 }
27835 run_test 418 "df and lfs df outputs match"
27836
27837 test_419()
27838 {
27839         local dir=$DIR/$tdir
27840
27841         mkdir -p $dir
27842         touch $dir/file
27843
27844         cancel_lru_locks mdc
27845
27846         #OBD_FAIL_LLITE_OPEN_BY_NAME    0x1410
27847         $LCTL set_param fail_loc=0x1410
27848         cat $dir/file
27849         $LCTL set_param fail_loc=0
27850         rm -rf $dir
27851 }
27852 run_test 419 "Verify open file by name doesn't crash kernel"
27853
27854 test_420()
27855 {
27856         [[ $MDS1_VERSION -ge $(version_code 2.12.53) ]] ||
27857                 skip "Need MDS version at least 2.12.53"
27858
27859         local SAVE_UMASK=$(umask)
27860         local dir=$DIR/$tdir
27861         local uname=$(getent passwd $RUNAS_ID | cut -d: -f1)
27862
27863         mkdir -p $dir
27864         umask 0000
27865         mkdir -m03777 $dir/testdir
27866         ls -dn $dir/testdir
27867         # Need to remove trailing '.' when SELinux is enabled
27868         local dirperms=$(ls -dn $dir/testdir |
27869                          awk '{ sub(/\.$/, "", $1); print $1}')
27870         [ $dirperms == "drwxrwsrwt" ] ||
27871                 error "incorrect perms on $dir/testdir"
27872
27873         su - $uname -c "PATH=$LUSTRE/tests:\$PATH; \
27874                 openfile -f O_RDONLY:O_CREAT -m 02755 $dir/testdir/testfile"
27875         ls -n $dir/testdir/testfile
27876         local fileperms=$(ls -n $dir/testdir/testfile |
27877                           awk '{ sub(/\.$/, "", $1); print $1}')
27878         [ $fileperms == "-rwxr-xr-x" ] ||
27879                 error "incorrect perms on $dir/testdir/testfile"
27880
27881         umask $SAVE_UMASK
27882 }
27883 run_test 420 "clear SGID bit on non-directories for non-members"
27884
27885 test_421a() {
27886         local cnt
27887         local fid1
27888         local fid2
27889
27890         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
27891                 skip "Need MDS version at least 2.12.54"
27892
27893         test_mkdir $DIR/$tdir
27894         createmany -o $DIR/$tdir/f 3
27895         cnt=$(ls -1 $DIR/$tdir | wc -l)
27896         [ $cnt != 3 ] && error "unexpected #files: $cnt"
27897
27898         fid1=$(lfs path2fid $DIR/$tdir/f1)
27899         fid2=$(lfs path2fid $DIR/$tdir/f2)
27900         $LFS rmfid $DIR $fid1 $fid2 || error "rmfid failed"
27901
27902         stat $DIR/$tdir/f1 && error "f1 still visible on the client"
27903         stat $DIR/$tdir/f2 && error "f2 still visible on the client"
27904
27905         cnt=$(ls -1 $DIR/$tdir | wc -l)
27906         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
27907
27908         rm -f $DIR/$tdir/f3 || error "can't remove f3"
27909         createmany -o $DIR/$tdir/f 3
27910         cnt=$(ls -1 $DIR/$tdir | wc -l)
27911         [ $cnt != 3 ] && error "unexpected #files: $cnt"
27912
27913         fid1=$(lfs path2fid $DIR/$tdir/f1)
27914         fid2=$(lfs path2fid $DIR/$tdir/f2)
27915         echo "remove using fsname $FSNAME"
27916         $LFS rmfid $FSNAME $fid1 $fid2 || error "rmfid with fsname failed"
27917
27918         cnt=$(ls -1 $DIR/$tdir | wc -l)
27919         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
27920 }
27921 run_test 421a "simple rm by fid"
27922
27923 test_421b() {
27924         local cnt
27925         local FID1
27926         local FID2
27927
27928         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
27929                 skip "Need MDS version at least 2.12.54"
27930
27931         test_mkdir $DIR/$tdir
27932         createmany -o $DIR/$tdir/f 3
27933         multiop_bg_pause $DIR/$tdir/f1 o_c || error "multiop failed to start"
27934         MULTIPID=$!
27935
27936         FID1=$(lfs path2fid $DIR/$tdir/f1)
27937         FID2=$(lfs path2fid $DIR/$tdir/f2)
27938         $LFS rmfid $DIR $FID1 $FID2 && error "rmfid didn't fail"
27939
27940         kill -USR1 $MULTIPID
27941         wait
27942
27943         cnt=$(ls $DIR/$tdir | wc -l)
27944         [ $cnt == 2 ] || error "unexpected #files after: $cnt"
27945 }
27946 run_test 421b "rm by fid on open file"
27947
27948 test_421c() {
27949         local cnt
27950         local FIDS
27951
27952         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
27953                 skip "Need MDS version at least 2.12.54"
27954
27955         test_mkdir $DIR/$tdir
27956         createmany -o $DIR/$tdir/f 3
27957         touch $DIR/$tdir/$tfile
27958         createmany -l$DIR/$tdir/$tfile $DIR/$tdir/h 180
27959         cnt=$(ls -1 $DIR/$tdir | wc -l)
27960         [ $cnt != 184 ] && error "unexpected #files: $cnt"
27961
27962         FID1=$(lfs path2fid $DIR/$tdir/$tfile)
27963         $LFS rmfid $DIR $FID1 || error "rmfid failed"
27964
27965         cnt=$(ls $DIR/$tdir | wc -l)
27966         [ $cnt == 3 ] || error "unexpected #files after: $cnt"
27967 }
27968 run_test 421c "rm by fid against hardlinked files"
27969
27970 test_421d() {
27971         local cnt
27972         local FIDS
27973
27974         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
27975                 skip "Need MDS version at least 2.12.54"
27976
27977         test_mkdir $DIR/$tdir
27978         createmany -o $DIR/$tdir/f 4097
27979         cnt=$(ls -1 $DIR/$tdir | wc -l)
27980         [ $cnt != 4097 ] && error "unexpected #files: $cnt"
27981
27982         FIDS=$(lfs path2fid $DIR/$tdir/f* | sed "s/[/][^:]*://g")
27983         $LFS rmfid $DIR $FIDS || error "rmfid failed"
27984
27985         cnt=$(ls $DIR/$tdir | wc -l)
27986         rm -rf $DIR/$tdir
27987         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
27988 }
27989 run_test 421d "rmfid en masse"
27990
27991 test_421e() {
27992         local cnt
27993         local FID
27994
27995         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
27996         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
27997                 skip "Need MDS version at least 2.12.54"
27998
27999         mkdir -p $DIR/$tdir
28000         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
28001         createmany -o $DIR/$tdir/striped_dir/f 512
28002         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
28003         [ $cnt != 512 ] && error "unexpected #files: $cnt"
28004
28005         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
28006                 sed "s/[/][^:]*://g")
28007         $LFS rmfid $DIR $FIDS || error "rmfid failed"
28008
28009         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
28010         rm -rf $DIR/$tdir
28011         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
28012 }
28013 run_test 421e "rmfid in DNE"
28014
28015 test_421f() {
28016         local cnt
28017         local FID
28018
28019         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
28020                 skip "Need MDS version at least 2.12.54"
28021
28022         test_mkdir $DIR/$tdir
28023         touch $DIR/$tdir/f
28024         cnt=$(ls -1 $DIR/$tdir | wc -l)
28025         [ $cnt != 1 ] && error "unexpected #files: $cnt"
28026
28027         FID=$(lfs path2fid $DIR/$tdir/f)
28028         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (1)"
28029         # rmfid should fail
28030         cnt=$(ls -1 $DIR/$tdir | wc -l)
28031         [ $cnt != 1 ] && error "unexpected #files after (2): $cnt"
28032
28033         chmod a+rw $DIR/$tdir
28034         ls -la $DIR/$tdir
28035         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (2)"
28036         # rmfid should fail
28037         cnt=$(ls -1 $DIR/$tdir | wc -l)
28038         [ $cnt != 1 ] && error "unexpected #files after (3): $cnt"
28039
28040         rm -f $DIR/$tdir/f
28041         $RUNAS touch $DIR/$tdir/f
28042         FID=$(lfs path2fid $DIR/$tdir/f)
28043         echo "rmfid as root"
28044         $LFS rmfid $DIR $FID || error "rmfid as root failed"
28045         cnt=$(ls -1 $DIR/$tdir | wc -l)
28046         [ $cnt == 0 ] || error "unexpected #files after (4): $cnt"
28047
28048         rm -f $DIR/$tdir/f
28049         $RUNAS touch $DIR/$tdir/f
28050         cnt=$(ls -1 $DIR/$tdir | wc -l)
28051         [ $cnt != 1 ] && error "unexpected #files (4): $cnt"
28052         FID=$(lfs path2fid $DIR/$tdir/f)
28053         # rmfid w/o user_fid2path mount option should fail
28054         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail(3)"
28055         cnt=$(ls -1 $DIR/$tdir | wc -l)
28056         [ $cnt == 1 ] || error "unexpected #files after (5): $cnt"
28057
28058         tmpdir=$(mktemp -d /tmp/lustre-XXXXXX)
28059         stack_trap "rmdir $tmpdir"
28060         mount_client $tmpdir "$MOUNT_OPTS,user_fid2path" ||
28061                 error "failed to mount client'"
28062         stack_trap "umount_client $tmpdir"
28063
28064         $RUNAS $LFS rmfid $tmpdir $FID || error "rmfid failed"
28065         # rmfid should succeed
28066         cnt=$(ls -1 $tmpdir/$tdir | wc -l)
28067         [ $cnt == 0 ] || error "unexpected #files after (6): $cnt"
28068
28069         # rmfid shouldn't allow to remove files due to dir's permission
28070         chmod a+rwx $tmpdir/$tdir
28071         touch $tmpdir/$tdir/f
28072         ls -la $tmpdir/$tdir
28073         FID=$(lfs path2fid $tmpdir/$tdir/f)
28074         $RUNAS $LFS rmfid $tmpdir $FID && error "rmfid didn't fail"
28075         return 0
28076 }
28077 run_test 421f "rmfid checks permissions"
28078
28079 test_421g() {
28080         local cnt
28081         local FIDS
28082
28083         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
28084         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
28085                 skip "Need MDS version at least 2.12.54"
28086
28087         mkdir -p $DIR/$tdir
28088         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
28089         createmany -o $DIR/$tdir/striped_dir/f 512
28090         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
28091         [ $cnt != 512 ] && error "unexpected #files: $cnt"
28092
28093         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
28094                 sed "s/[/][^:]*://g")
28095
28096         rm -f $DIR/$tdir/striped_dir/f1*
28097         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
28098         removed=$((512 - cnt))
28099
28100         # few files have been just removed, so we expect
28101         # rmfid to fail on their fids
28102         errors=$($LFS rmfid $DIR $FIDS 2>&1 | wc -l)
28103         [ $removed != $errors ] && error "$errors != $removed"
28104
28105         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
28106         rm -rf $DIR/$tdir
28107         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
28108 }
28109 run_test 421g "rmfid to return errors properly"
28110
28111 test_421h() {
28112         local mount_other
28113         local mount_ret
28114         local rmfid_ret
28115         local old_fid
28116         local fidA
28117         local fidB
28118         local fidC
28119         local fidD
28120
28121         (( MDS1_VERSION >= $(version_code 2.15.53) )) ||
28122                 skip "Need MDS version at least 2.15.53"
28123
28124         test_mkdir $DIR/$tdir
28125         test_mkdir $DIR/$tdir/subdir
28126         touch $DIR/$tdir/subdir/file0
28127         old_fid=$(lfs path2fid $DIR/$tdir/subdir/file0 | sed "s/[/][^:]*://g")
28128         echo File $DIR/$tdir/subdir/file0 FID $old_fid
28129         rm -f $DIR/$tdir/subdir/file0
28130         touch $DIR/$tdir/subdir/fileA
28131         fidA=$(lfs path2fid $DIR/$tdir/subdir/fileA | sed "s/[/][^:]*://g")
28132         echo File $DIR/$tdir/subdir/fileA FID $fidA
28133         touch $DIR/$tdir/subdir/fileB
28134         fidB=$(lfs path2fid $DIR/$tdir/subdir/fileB | sed "s/[/][^:]*://g")
28135         echo File $DIR/$tdir/subdir/fileB FID $fidB
28136         ln $DIR/$tdir/subdir/fileB $DIR/$tdir/subdir/fileB_hl
28137         touch $DIR/$tdir/subdir/fileC
28138         fidC=$(lfs path2fid $DIR/$tdir/subdir/fileC | sed "s/[/][^:]*://g")
28139         echo File $DIR/$tdir/subdir/fileC FID $fidC
28140         ln $DIR/$tdir/subdir/fileC $DIR/$tdir/fileC
28141         touch $DIR/$tdir/fileD
28142         fidD=$(lfs path2fid $DIR/$tdir/fileD | sed "s/[/][^:]*://g")
28143         echo File $DIR/$tdir/fileD FID $fidD
28144
28145         # mount another client mount point with subdirectory mount
28146         export FILESET=/$tdir/subdir
28147         mount_other=${MOUNT}_other
28148         mount_client $mount_other ${MOUNT_OPTS}
28149         mount_ret=$?
28150         export FILESET=""
28151         (( mount_ret == 0 )) || error "mount $mount_other failed"
28152
28153         echo Removing FIDs:
28154         echo $LFS rmfid $mount_other $old_fid $fidA $fidD $fidB $fidC
28155         $LFS rmfid $mount_other $old_fid $fidA $fidD $fidB $fidC
28156         rmfid_ret=$?
28157
28158         umount_client $mount_other || error "umount $mount_other failed"
28159
28160         (( rmfid_ret != 0 )) || error "rmfid should have failed"
28161
28162         # fileA should have been deleted
28163         stat $DIR/$tdir/subdir/fileA && error "fileA not deleted"
28164
28165         # fileB should have been deleted
28166         stat $DIR/$tdir/subdir/fileB && error "fileB not deleted"
28167
28168         # fileC should not have been deleted, fid also exists outside of fileset
28169         stat $DIR/$tdir/subdir/fileC || error "fileC deleted"
28170
28171         # fileD should not have been deleted, it exists outside of fileset
28172         stat $DIR/$tdir/fileD || error "fileD deleted"
28173 }
28174 run_test 421h "rmfid with fileset mount"
28175
28176 test_422() {
28177         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d1
28178         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d2
28179         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d3
28180         dd if=/dev/zero of=$DIR/$tdir/d1/file1 bs=1k count=1
28181         dd if=/dev/zero of=$DIR/$tdir/d2/file1 bs=1k count=1
28182
28183         local amc=$(at_max_get client)
28184         local amo=$(at_max_get mds1)
28185         local timeout=`lctl get_param -n timeout`
28186
28187         at_max_set 0 client
28188         at_max_set 0 mds1
28189
28190 #define OBD_FAIL_PTLRPC_PAUSE_REQ        0x50a
28191         do_facet mds1 $LCTL set_param fail_loc=0x8000050a \
28192                         fail_val=$(((2*timeout + 10)*1000))
28193         touch $DIR/$tdir/d3/file &
28194         sleep 2
28195 #define OBD_FAIL_TGT_REPLY_DATA_RACE     0x722
28196         do_facet mds1 $LCTL set_param fail_loc=0x80000722 \
28197                         fail_val=$((2*timeout + 5))
28198         mv $DIR/$tdir/d1/file1 $DIR/$tdir/d1/file2 &
28199         local pid=$!
28200         sleep 1
28201         kill -9 $pid
28202         sleep $((2 * timeout))
28203         echo kill $pid
28204         kill -9 $pid
28205         lctl mark touch
28206         touch $DIR/$tdir/d2/file3
28207         touch $DIR/$tdir/d2/file4
28208         touch $DIR/$tdir/d2/file5
28209
28210         wait
28211         at_max_set $amc client
28212         at_max_set $amo mds1
28213
28214         # LU-12838 - verify the ptlrpc thread watchdog is not always throttled
28215         do_facet mds1 "dmesg | grep 'Dumping the stack trace for debugging'" ||
28216                 error "Watchdog is always throttled"
28217 }
28218 run_test 422 "kill a process with RPC in progress"
28219
28220 stat_test() {
28221     df -h $MOUNT &
28222     df -h $MOUNT &
28223     df -h $MOUNT &
28224     df -h $MOUNT &
28225     df -h $MOUNT &
28226     df -h $MOUNT &
28227 }
28228
28229 test_423() {
28230     local _stats
28231     # ensure statfs cache is expired
28232     sleep 2;
28233
28234     _stats=$(stat_test | grep $MOUNT | sort -u | wc -l)
28235     [[ ${_stats} -ne 1 ]] && error "statfs wrong"
28236
28237     return 0
28238 }
28239 run_test 423 "statfs should return a right data"
28240
28241 test_424() {
28242 #define OBD_FAIL_PTLRPC_BULK_REPLY_ATTACH      0x522 | CFS_FAIL_ONCE
28243         $LCTL set_param fail_loc=0x80000522
28244         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
28245         rm -f $DIR/$tfile
28246 }
28247 run_test 424 "simulate ENOMEM in ptl_send_rpc bulk reply ME attach"
28248
28249 test_425() {
28250         test_mkdir -c -1 $DIR/$tdir
28251         $LFS setstripe -c -1 $DIR/$tdir
28252
28253         lru_resize_disable "" 100
28254         stack_trap "lru_resize_enable" EXIT
28255
28256         sleep 5
28257
28258         for i in $(seq $((MDSCOUNT * 125))); do
28259                 local t=$DIR/$tdir/$tfile_$i
28260
28261                 dd if=/dev/zero of=$t bs=4K count=1 > /dev/null 2>&1 ||
28262                         error_noexit "Create file $t"
28263         done
28264         stack_trap "rm -rf $DIR/$tdir" EXIT
28265
28266         for oscparam in $($LCTL list_param ldlm.namespaces.*osc-[-0-9a-f]*); do
28267                 local lru_size=$($LCTL get_param -n $oscparam.lru_size)
28268                 local lock_count=$($LCTL get_param -n $oscparam.lock_count)
28269
28270                 [ $lock_count -le $lru_size ] ||
28271                         error "osc lock count $lock_count > lru size $lru_size"
28272         done
28273
28274         for mdcparam in $($LCTL list_param ldlm.namespaces.*mdc-*); do
28275                 local lru_size=$($LCTL get_param -n $mdcparam.lru_size)
28276                 local lock_count=$($LCTL get_param -n $mdcparam.lock_count)
28277
28278                 [ $lock_count -le $lru_size ] ||
28279                         error "mdc lock count $lock_count > lru size $lru_size"
28280         done
28281 }
28282 run_test 425 "lock count should not exceed lru size"
28283
28284 test_426() {
28285         splice-test -r $DIR/$tfile
28286         splice-test -rd $DIR/$tfile
28287         splice-test $DIR/$tfile
28288         splice-test -d $DIR/$tfile
28289 }
28290 run_test 426 "splice test on Lustre"
28291
28292 test_427() {
28293         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
28294         (( $MDS1_VERSION >= $(version_code 2.12.4) )) ||
28295                 skip "Need MDS version at least 2.12.4"
28296         local log
28297
28298         mkdir $DIR/$tdir
28299         mkdir $DIR/$tdir/1
28300         mkdir $DIR/$tdir/2
28301         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/1/dir
28302         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/2/dir2
28303
28304         $LFS getdirstripe $DIR/$tdir/1/dir
28305
28306         #first setfattr for creating updatelog
28307         setfattr -n user.attr0 -v "some text" $DIR/$tdir/1/dir
28308
28309 #define OBD_FAIL_OUT_OBJECT_MISS        0x1708
28310         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param fail_loc=0x80001708
28311         setfattr -n user.attr1 -v "some text" $DIR/$tdir/1/dir &
28312         setfattr -n user.attr2 -v "another attr"  $DIR/$tdir/2/dir2 &
28313
28314         sleep 2
28315         fail mds2
28316         wait_recovery_complete mds2 $((2*TIMEOUT))
28317
28318         log=$(do_facet mds1 dmesg | tac | sed "/${TESTNAME//_/ }/,$ d")
28319         echo $log | grep "get update log failed" &&
28320                 error "update log corruption is detected" || true
28321 }
28322 run_test 427 "Failed DNE2 update request shouldn't corrupt updatelog"
28323
28324 test_428() {
28325         [ $PARALLEL == "yes" ] && skip "skip parallel run"
28326         local cache_limit=$CACHE_MAX
28327
28328         stack_trap "$LCTL set_param -n llite.*.max_cached_mb=$cache_limit"
28329         $LCTL set_param -n llite.*.max_cached_mb=64
28330
28331         mkdir $DIR/$tdir
28332         $LFS setstripe -c 1 $DIR/$tdir
28333         eval touch $DIR/$tdir/$tfile.{1..$OSTCOUNT}
28334         stack_trap "rm -f $DIR/$tdir/$tfile.*"
28335         #test write
28336         for f in $(seq 4); do
28337                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$f bs=128M count=1 &
28338         done
28339         wait
28340
28341         cancel_lru_locks osc
28342         # Test read
28343         for f in $(seq 4); do
28344                 dd if=$DIR/$tdir/$tfile.$f of=/dev/null bs=128M count=1 &
28345         done
28346         wait
28347 }
28348 run_test 428 "large block size IO should not hang"
28349
28350 test_429() { # LU-7915 / LU-10948
28351         local ll_opencache_threshold_count="llite.*.opencache_threshold_count"
28352         local testfile=$DIR/$tfile
28353         local mdc_rpcstats="mdc.$FSNAME-MDT0000-*.stats"
28354         local new_flag=1
28355         local first_rpc
28356         local second_rpc
28357         local third_rpc
28358
28359         $LCTL get_param $ll_opencache_threshold_count ||
28360                 skip "client does not have opencache parameter"
28361
28362         set_opencache $new_flag
28363         stack_trap "restore_opencache"
28364         [ $($LCTL get_param -n $ll_opencache_threshold_count) == $new_flag ] ||
28365                 error "enable opencache failed"
28366         touch $testfile
28367         # drop MDC DLM locks
28368         cancel_lru_locks mdc
28369         # clear MDC RPC stats counters
28370         $LCTL set_param $mdc_rpcstats=clear
28371
28372         # According to the current implementation, we need to run 3 times
28373         # open & close file to verify if opencache is enabled correctly.
28374         # 1st, RPCs are sent for lookup/open and open handle is released on
28375         #      close finally.
28376         # 2nd, RPC is sent for open, MDS_OPEN_LOCK is fetched automatically,
28377         #      so open handle won't be released thereafter.
28378         # 3rd, No RPC is sent out.
28379         $MULTIOP $testfile oc || error "multiop failed"
28380         first_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
28381         echo "1st: $first_rpc RPCs in flight"
28382
28383         $MULTIOP $testfile oc || error "multiop failed"
28384         second_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
28385         echo "2nd: $second_rpc RPCs in flight"
28386
28387         $MULTIOP $testfile oc || error "multiop failed"
28388         third_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
28389         echo "3rd: $third_rpc RPCs in flight"
28390
28391         #verify no MDC RPC is sent
28392         [[ $second_rpc == $third_rpc ]] || error "MDC RPC is still sent"
28393 }
28394 run_test 429 "verify if opencache flag on client side does work"
28395
28396 lseek_test_430() {
28397         local offset
28398         local file=$1
28399
28400         # data at [200K, 400K)
28401         dd if=/dev/urandom of=$file bs=256K count=1 seek=1 ||
28402                 error "256K->512K dd fails"
28403         # data at [2M, 3M)
28404         dd if=/dev/urandom of=$file bs=1M count=1 seek=2 ||
28405                 error "2M->3M dd fails"
28406         # data at [4M, 5M)
28407         dd if=/dev/urandom of=$file bs=1M count=1 seek=4 ||
28408                 error "4M->5M dd fails"
28409         echo "Data at 256K...512K, 2M...3M and 4M...5M"
28410         # start at first component hole #1
28411         printf "Seeking hole from 1000 ... "
28412         offset=$(lseek_test -l 1000 $file)
28413         echo $offset
28414         [[ $offset == 1000 ]] || error "offset $offset != 1000"
28415         printf "Seeking data from 1000 ... "
28416         offset=$(lseek_test -d 1000 $file)
28417         echo $offset
28418         [[ $offset == 262144 ]] || error "offset $offset != 262144"
28419
28420         # start at first component data block
28421         printf "Seeking hole from 300000 ... "
28422         offset=$(lseek_test -l 300000 $file)
28423         echo $offset
28424         [[ $offset == 524288 ]] || error "offset $offset != 524288"
28425         printf "Seeking data from 300000 ... "
28426         offset=$(lseek_test -d 300000 $file)
28427         echo $offset
28428         [[ $offset == 300000 ]] || error "offset $offset != 300000"
28429
28430         # start at the first component but beyond end of object size
28431         printf "Seeking hole from 1000000 ... "
28432         offset=$(lseek_test -l 1000000 $file)
28433         echo $offset
28434         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
28435         printf "Seeking data from 1000000 ... "
28436         offset=$(lseek_test -d 1000000 $file)
28437         echo $offset
28438         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
28439
28440         # start at second component stripe 2 (empty file)
28441         printf "Seeking hole from 1500000 ... "
28442         offset=$(lseek_test -l 1500000 $file)
28443         echo $offset
28444         [[ $offset == 1500000 ]] || error "offset $offset != 1500000"
28445         printf "Seeking data from 1500000 ... "
28446         offset=$(lseek_test -d 1500000 $file)
28447         echo $offset
28448         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
28449
28450         # start at second component stripe 1 (all data)
28451         printf "Seeking hole from 3000000 ... "
28452         offset=$(lseek_test -l 3000000 $file)
28453         echo $offset
28454         [[ $offset == 3145728 ]] || error "offset $offset != 3145728"
28455         printf "Seeking data from 3000000 ... "
28456         offset=$(lseek_test -d 3000000 $file)
28457         echo $offset
28458         [[ $offset == 3000000 ]] || error "offset $offset != 3000000"
28459
28460         dd if=/dev/urandom of=$file bs=640K count=1 seek=1 ||
28461                 error "2nd dd fails"
28462         echo "Add data block at 640K...1280K"
28463
28464         # start at before new data block, in hole
28465         printf "Seeking hole from 600000 ... "
28466         offset=$(lseek_test -l 600000 $file)
28467         echo $offset
28468         [[ $offset == 600000 ]] || error "offset $offset != 600000"
28469         printf "Seeking data from 600000 ... "
28470         offset=$(lseek_test -d 600000 $file)
28471         echo $offset
28472         [[ $offset == 655360 ]] || error "offset $offset != 655360"
28473
28474         # start at the first component new data block
28475         printf "Seeking hole from 1000000 ... "
28476         offset=$(lseek_test -l 1000000 $file)
28477         echo $offset
28478         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
28479         printf "Seeking data from 1000000 ... "
28480         offset=$(lseek_test -d 1000000 $file)
28481         echo $offset
28482         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
28483
28484         # start at second component stripe 2, new data
28485         printf "Seeking hole from 1200000 ... "
28486         offset=$(lseek_test -l 1200000 $file)
28487         echo $offset
28488         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
28489         printf "Seeking data from 1200000 ... "
28490         offset=$(lseek_test -d 1200000 $file)
28491         echo $offset
28492         [[ $offset == 1200000 ]] || error "offset $offset != 1200000"
28493
28494         # start beyond file end
28495         printf "Using offset > filesize ... "
28496         lseek_test -l 4000000 $file && error "lseek should fail"
28497         printf "Using offset > filesize ... "
28498         lseek_test -d 4000000 $file && error "lseek should fail"
28499
28500         printf "Done\n\n"
28501 }
28502
28503 test_430a() {
28504         $LCTL get_param mdc.*.import | grep -q 'connect_flags:.*seek' ||
28505                 skip "MDT does not support SEEK_HOLE"
28506
28507         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
28508                 skip "OST does not support SEEK_HOLE"
28509
28510         local file=$DIR/$tdir/$tfile
28511
28512         mkdir -p $DIR/$tdir
28513
28514         $LFS setstripe -E 1M -L mdt -E eof -c2 $file
28515         # OST stripe #1 will have continuous data at [1M, 3M)
28516         # OST stripe #2 is empty
28517         echo "Component #1: 1M DoM, component #2: EOF, 2 stripes 1M"
28518         lseek_test_430 $file
28519         rm $file
28520         $LFS setstripe -E 1M -c2 -S 64K -E 10M -c2 -S 1M $file
28521         echo "Component #1: 1M, 2 stripes 64K, component #2: EOF, 2 stripes 1M"
28522         lseek_test_430 $file
28523         rm $file
28524         $LFS setstripe -c2 -S 512K $file
28525         echo "Two stripes, stripe size 512K"
28526         lseek_test_430 $file
28527         rm $file
28528         # FLR with stale mirror
28529         $LFS setstripe -N -E 512K -c1 -S 64K -E eof -c2 -S 512K \
28530                        -N -c2 -S 1M $file
28531         echo "Mirrored file:"
28532         echo "Component #1: 512K, stripe 64K, component #2: EOF, 2 stripes 512K"
28533         echo "Plain 2 stripes 1M"
28534         lseek_test_430 $file
28535         rm $file
28536 }
28537 run_test 430a "lseek: SEEK_DATA/SEEK_HOLE basic functionality"
28538
28539 test_430b() {
28540         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
28541                 skip "OST does not support SEEK_HOLE"
28542
28543         local offset
28544         local file=$DIR/$tdir/$tfile
28545
28546         mkdir -p $DIR/$tdir
28547         # Empty layout lseek should fail
28548         $MCREATE $file
28549         # seek from 0
28550         printf "Seeking hole from 0 ... "
28551         lseek_test -l 0 $file && error "lseek should fail"
28552         printf "Seeking data from 0 ... "
28553         lseek_test -d 0 $file && error "lseek should fail"
28554         rm $file
28555
28556         # 1M-hole file
28557         $LFS setstripe -E 1M -c2 -E eof $file
28558         $TRUNCATE $file 1048576
28559         printf "Seeking hole from 1000000 ... "
28560         offset=$(lseek_test -l 1000000 $file)
28561         echo $offset
28562         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
28563         printf "Seeking data from 1000000 ... "
28564         lseek_test -d 1000000 $file && error "lseek should fail"
28565         rm $file
28566
28567         # full component followed by non-inited one
28568         $LFS setstripe -E 1M -c2 -E eof $file
28569         dd if=/dev/urandom of=$file bs=1M count=1
28570         printf "Seeking hole from 1000000 ... "
28571         offset=$(lseek_test -l 1000000 $file)
28572         echo $offset
28573         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
28574         printf "Seeking hole from 1048576 ... "
28575         lseek_test -l 1048576 $file && error "lseek should fail"
28576         # init second component and truncate back
28577         echo "123" >> $file
28578         $TRUNCATE $file 1048576
28579         printf "Seeking hole from 1000000 ... "
28580         offset=$(lseek_test -l 1000000 $file)
28581         echo $offset
28582         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
28583         printf "Seeking hole from 1048576 ... "
28584         lseek_test -l 1048576 $file && error "lseek should fail"
28585         # boundary checks for big values
28586         dd if=/dev/urandom of=$file.10g bs=1 count=1 seek=10G
28587         offset=$(lseek_test -d 0 $file.10g)
28588         [[ $offset == 10737418240 ]] || error "offset $offset != 10737418240"
28589         dd if=/dev/urandom of=$file.100g bs=1 count=1 seek=100G
28590         offset=$(lseek_test -d 0 $file.100g)
28591         [[ $offset == 107374182400 ]] || error "offset $offset != 107374182400"
28592         return 0
28593 }
28594 run_test 430b "lseek: SEEK_DATA/SEEK_HOLE special cases"
28595
28596 test_430c() {
28597         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
28598                 skip "OST does not support SEEK_HOLE"
28599
28600         local file=$DIR/$tdir/$tfile
28601         local start
28602
28603         mkdir -p $DIR/$tdir
28604         stack_trap "rm -f $file $file.tmp"
28605         dd if=/dev/urandom of=$file bs=1k count=1 seek=5M || error "dd failed"
28606
28607         # cp version 8.33+ prefers lseek over fiemap
28608         local ver=$(cp --version | awk '{ print $4; exit; }')
28609
28610         echo "cp $ver installed"
28611         if (( $(version_code $ver) >= $(version_code 8.33) )); then
28612                 start=$SECONDS
28613                 time cp -v $file $file.tmp || error "cp $file failed"
28614                 (( SECONDS - start < 5 )) || {
28615                         strace cp $file $file.tmp |&
28616                                 grep -E "open|read|seek|FIEMAP" |
28617                                 grep -A 100 $file
28618                         error "cp: too long runtime $((SECONDS - start))"
28619                 }
28620         else
28621                 echo "cp test skipped due to $ver < 8.33"
28622         fi
28623
28624         # tar version 1.29+ supports SEEK_HOLE/DATA
28625         ver=$(tar --version | awk '{ print $4; exit; }')
28626         echo "tar $ver installed"
28627         if (( $(version_code $ver) >= $(version_code 1.29) )); then
28628                 start=$SECONDS
28629                 time tar cvf $file.tmp --sparse $file || error "tar $file error"
28630                 (( SECONDS - start < 5 )) || {
28631                         strace tar cf $file.tmp --sparse $file |&
28632                                 grep -E "open|read|seek|FIEMAP" |
28633                                 grep -A 100 $file
28634                         error "tar: too long runtime $((SECONDS - start))"
28635                 }
28636         else
28637                 echo "tar test skipped due to $ver < 1.29"
28638         fi
28639 }
28640 run_test 430c "lseek: external tools check"
28641
28642 test_431() { # LU-14187
28643         local file=$DIR/$tdir/$tfile
28644
28645         mkdir -p $DIR/$tdir
28646         $LFS setstripe -c 1 -i 0 $file || error "lfs setstripe failed"
28647         dd if=/dev/urandom of=$file bs=4k count=1
28648         dd if=/dev/urandom of=$file bs=4k count=1 seek=10 conv=notrunc
28649         dd if=/dev/urandom of=$file bs=4k count=1 seek=12 conv=notrunc
28650         #define OBD_FAIL_OST_RESTART_IO 0x251
28651         do_facet ost1 "$LCTL set_param fail_loc=0x251"
28652         $LFS setstripe -c 1 -i 0 $file.0 || error "lfs setstripe failed"
28653         cp $file $file.0
28654         cancel_lru_locks
28655         sync_all_data
28656         echo 3 > /proc/sys/vm/drop_caches
28657         diff  $file $file.0 || error "data diff"
28658 }
28659 run_test 431 "Restart transaction for IO"
28660
28661 cleanup_test_432() {
28662         do_facet mgs $LCTL nodemap_activate 0
28663         wait_nm_sync active
28664 }
28665
28666 test_432() {
28667         local tmpdir=$TMP/dir432
28668
28669         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
28670                 skip "Need MDS version at least 2.14.52"
28671
28672         stack_trap cleanup_test_432 EXIT
28673         mkdir $DIR/$tdir
28674         mkdir $tmpdir
28675
28676         do_facet mgs $LCTL nodemap_activate 1
28677         wait_nm_sync active
28678         do_facet mgs $LCTL nodemap_modify --name default \
28679                 --property admin --value 1
28680         do_facet mgs $LCTL nodemap_modify --name default \
28681                 --property trusted --value 1
28682         cancel_lru_locks mdc
28683         wait_nm_sync default admin_nodemap
28684         wait_nm_sync default trusted_nodemap
28685
28686         if [ $(mv $tmpdir $DIR/$tdir/ 2>&1 |
28687                grep -ci "Operation not permitted") -ne 0 ]; then
28688                 error "mv $tmpdir $DIR/$tdir/ hits 'Operation not permitted'"
28689         fi
28690 }
28691 run_test 432 "mv dir from outside Lustre"
28692
28693 test_433() {
28694         [ $PARALLEL == "yes" ] && skip "skip parallel run"
28695
28696         [[ -n "$($LCTL list_param llite.*.inode_cache 2>/dev/null)" ]] ||
28697                 skip "inode cache not supported"
28698
28699         $LCTL set_param llite.*.inode_cache=0
28700         stack_trap "$LCTL set_param llite.*.inode_cache=1"
28701
28702         local count=256
28703         local before
28704         local after
28705
28706         cancel_lru_locks mdc
28707         test_mkdir $DIR/$tdir || error "mkdir $tdir"
28708         createmany -m $DIR/$tdir/f $count
28709         createmany -d $DIR/$tdir/d $count
28710         ls -l $DIR/$tdir > /dev/null
28711         stack_trap "rm -rf $DIR/$tdir"
28712
28713         before=$(num_objects)
28714         cancel_lru_locks mdc
28715         after=$(num_objects)
28716
28717         # sometimes even @before is less than 2 * count
28718         while (( before - after < count )); do
28719                 sleep 1
28720                 after=$(num_objects)
28721                 wait=$((wait + 1))
28722                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
28723                 if (( wait > 60 )); then
28724                         error "inode slab grew from $before to $after"
28725                 fi
28726         done
28727
28728         echo "lustre_inode_cache $before objs before lock cancel, $after after"
28729 }
28730 run_test 433 "ldlm lock cancel releases dentries and inodes"
28731
28732 test_434() {
28733         local file
28734         local getxattr_count
28735         local mdc_stat_param="mdc.$FSNAME-MDT0000*.md_stats"
28736         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
28737
28738         [[ $(getenforce) == "Disabled" ]] ||
28739                 skip "lsm selinux module have to be disabled for this test"
28740
28741         test_mkdir -i 0 -c1 $DIR/$tdir/ ||
28742                 error "fail to create $DIR/$tdir/ on MDT0000"
28743
28744         touch $DIR/$tdir/$tfile-{001..100}
28745
28746         # disable the xattr cache
28747         save_lustre_params client "llite.*.xattr_cache" > $p
28748         lctl set_param llite.*.xattr_cache=0
28749         stack_trap "restore_lustre_params < $p; rm -f $p" EXIT
28750
28751         # clear clients mdc stats
28752         clear_stats $mdc_stat_param ||
28753                 error "fail to clear stats on mdc MDT0000"
28754
28755         for file in $DIR/$tdir/$tfile-{001..100}; do
28756                 getfattr -n security.selinux $file |&
28757                         grep -q "Operation not supported" ||
28758                         error "getxattr on security.selinux should return EOPNOTSUPP"
28759         done
28760
28761         getxattr_count=$(calc_stats $mdc_stat_param "getxattr")
28762         (( getxattr_count < 100 )) ||
28763                 error "client sent $getxattr_count getxattr RPCs to the MDS"
28764 }
28765 run_test 434 "Client should not send RPCs for security.selinux with SElinux disabled"
28766
28767 test_440() {
28768         if [[ -f $LUSTRE/scripts/bash-completion/lustre ]]; then
28769                 source $LUSTRE/scripts/bash-completion/lustre
28770         elif [[ -f /usr/share/bash-completion/completions/lustre ]]; then
28771                 source /usr/share/bash-completion/completions/lustre
28772         else
28773                 skip "bash completion scripts not found"
28774         fi
28775
28776         local lctl_completions
28777         local lfs_completions
28778
28779         lctl_completions=$(_lustre_cmds lctl)
28780         if [[ ! $lctl_completions =~ "get_param" ]]; then
28781                 error "lctl bash completion failed"
28782         fi
28783
28784         lfs_completions=$(_lustre_cmds lfs)
28785         if [[ ! $lfs_completions =~ "setstripe" ]]; then
28786                 error "lfs bash completion failed"
28787         fi
28788 }
28789 run_test 440 "bash completion for lfs, lctl"
28790
28791 prep_801() {
28792         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
28793         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
28794                 skip "Need server version at least 2.9.55"
28795
28796         start_full_debug_logging
28797 }
28798
28799 post_801() {
28800         stop_full_debug_logging
28801 }
28802
28803 barrier_stat() {
28804         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
28805                 local st=$(do_facet mgs $LCTL barrier_stat $FSNAME |
28806                            awk '/The barrier for/ { print $7 }')
28807                 echo $st
28808         else
28809                 local st=$(do_facet mgs $LCTL barrier_stat -s $FSNAME)
28810                 echo \'$st\'
28811         fi
28812 }
28813
28814 barrier_expired() {
28815         local expired
28816
28817         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
28818                 expired=$(do_facet mgs $LCTL barrier_stat $FSNAME |
28819                           awk '/will be expired/ { print $7 }')
28820         else
28821                 expired=$(do_facet mgs $LCTL barrier_stat -t $FSNAME)
28822         fi
28823
28824         echo $expired
28825 }
28826
28827 test_801a() {
28828         prep_801
28829
28830         echo "Start barrier_freeze at: $(date)"
28831         #define OBD_FAIL_BARRIER_DELAY          0x2202
28832         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
28833         # Do not reduce barrier time - See LU-11873
28834         do_facet mgs $LCTL barrier_freeze $FSNAME 20 &
28835
28836         sleep 2
28837         local b_status=$(barrier_stat)
28838         echo "Got barrier status at: $(date)"
28839         [ "$b_status" = "'freezing_p1'" ] ||
28840                 error "(1) unexpected barrier status $b_status"
28841
28842         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
28843         wait
28844         b_status=$(barrier_stat)
28845         [ "$b_status" = "'frozen'" ] ||
28846                 error "(2) unexpected barrier status $b_status"
28847
28848         local expired=$(barrier_expired)
28849         echo "sleep $((expired + 3)) seconds, then the barrier will be expired"
28850         sleep $((expired + 3))
28851
28852         b_status=$(barrier_stat)
28853         [ "$b_status" = "'expired'" ] ||
28854                 error "(3) unexpected barrier status $b_status"
28855
28856         # Do not reduce barrier time - See LU-11873
28857         do_facet mgs $LCTL barrier_freeze $FSNAME 20 ||
28858                 error "(4) fail to freeze barrier"
28859
28860         b_status=$(barrier_stat)
28861         [ "$b_status" = "'frozen'" ] ||
28862                 error "(5) unexpected barrier status $b_status"
28863
28864         echo "Start barrier_thaw at: $(date)"
28865         #define OBD_FAIL_BARRIER_DELAY          0x2202
28866         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
28867         do_facet mgs $LCTL barrier_thaw $FSNAME &
28868
28869         sleep 2
28870         b_status=$(barrier_stat)
28871         echo "Got barrier status at: $(date)"
28872         [ "$b_status" = "'thawing'" ] ||
28873                 error "(6) unexpected barrier status $b_status"
28874
28875         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
28876         wait
28877         b_status=$(barrier_stat)
28878         [ "$b_status" = "'thawed'" ] ||
28879                 error "(7) unexpected barrier status $b_status"
28880
28881         #define OBD_FAIL_BARRIER_FAILURE        0x2203
28882         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2203
28883         do_facet mgs $LCTL barrier_freeze $FSNAME
28884
28885         b_status=$(barrier_stat)
28886         [ "$b_status" = "'failed'" ] ||
28887                 error "(8) unexpected barrier status $b_status"
28888
28889         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
28890         do_facet mgs $LCTL barrier_thaw $FSNAME
28891
28892         post_801
28893 }
28894 run_test 801a "write barrier user interfaces and stat machine"
28895
28896 test_801b() {
28897         prep_801
28898
28899         mkdir $DIR/$tdir || error "(1) fail to mkdir"
28900         createmany -d $DIR/$tdir/d 6 || error "(2) fail to mkdir"
28901         touch $DIR/$tdir/d2/f10 || error "(3) fail to touch"
28902         touch $DIR/$tdir/d3/f11 || error "(4) fail to touch"
28903         touch $DIR/$tdir/d4/f12 || error "(5) fail to touch"
28904
28905         cancel_lru_locks mdc
28906
28907         # 180 seconds should be long enough
28908         do_facet mgs $LCTL barrier_freeze $FSNAME 180
28909
28910         local b_status=$(barrier_stat)
28911         [ "$b_status" = "'frozen'" ] ||
28912                 error "(6) unexpected barrier status $b_status"
28913
28914         mkdir $DIR/$tdir/d0/d10 &
28915         mkdir_pid=$!
28916
28917         touch $DIR/$tdir/d1/f13 &
28918         touch_pid=$!
28919
28920         ln $DIR/$tdir/d2/f10 $DIR/$tdir/d2/f14 &
28921         ln_pid=$!
28922
28923         mv $DIR/$tdir/d3/f11 $DIR/$tdir/d3/f15 &
28924         mv_pid=$!
28925
28926         rm -f $DIR/$tdir/d4/f12 &
28927         rm_pid=$!
28928
28929         stat $DIR/$tdir/d5 || error "(7) stat should succeed"
28930
28931         # To guarantee taht the 'stat' is not blocked
28932         b_status=$(barrier_stat)
28933         [ "$b_status" = "'frozen'" ] ||
28934                 error "(8) unexpected barrier status $b_status"
28935
28936         # let above commands to run at background
28937         sleep 5
28938
28939         ps -p $mkdir_pid || error "(9) mkdir should be blocked"
28940         ps -p $touch_pid || error "(10) touch should be blocked"
28941         ps -p $ln_pid || error "(11) link should be blocked"
28942         ps -p $mv_pid || error "(12) rename should be blocked"
28943         ps -p $rm_pid || error "(13) unlink should be blocked"
28944
28945         b_status=$(barrier_stat)
28946         [ "$b_status" = "'frozen'" ] ||
28947                 error "(14) unexpected barrier status $b_status"
28948
28949         do_facet mgs $LCTL barrier_thaw $FSNAME
28950         b_status=$(barrier_stat)
28951         [ "$b_status" = "'thawed'" ] ||
28952                 error "(15) unexpected barrier status $b_status"
28953
28954         wait $mkdir_pid || error "(16) mkdir should succeed"
28955         wait $touch_pid || error "(17) touch should succeed"
28956         wait $ln_pid || error "(18) link should succeed"
28957         wait $mv_pid || error "(19) rename should succeed"
28958         wait $rm_pid || error "(20) unlink should succeed"
28959
28960         post_801
28961 }
28962 run_test 801b "modification will be blocked by write barrier"
28963
28964 test_801c() {
28965         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
28966
28967         prep_801
28968
28969         stop mds2 || error "(1) Fail to stop mds2"
28970
28971         do_facet mgs $LCTL barrier_freeze $FSNAME 30
28972
28973         local b_status=$(barrier_stat)
28974         [ "$b_status" = "'expired'" ] || [ "$b_status" = "'failed'" ] || {
28975                 do_facet mgs $LCTL barrier_thaw $FSNAME
28976                 error "(2) unexpected barrier status $b_status"
28977         }
28978
28979         do_facet mgs $LCTL barrier_rescan $FSNAME ||
28980                 error "(3) Fail to rescan barrier bitmap"
28981
28982         # Do not reduce barrier time - See LU-11873
28983         do_facet mgs $LCTL barrier_freeze $FSNAME 20
28984
28985         b_status=$(barrier_stat)
28986         [ "$b_status" = "'frozen'" ] ||
28987                 error "(4) unexpected barrier status $b_status"
28988
28989         do_facet mgs $LCTL barrier_thaw $FSNAME
28990         b_status=$(barrier_stat)
28991         [ "$b_status" = "'thawed'" ] ||
28992                 error "(5) unexpected barrier status $b_status"
28993
28994         local devname=$(mdsdevname 2)
28995
28996         start mds2 $devname $MDS_MOUNT_OPTS || error "(6) Fail to start mds2"
28997
28998         do_facet mgs $LCTL barrier_rescan $FSNAME ||
28999                 error "(7) Fail to rescan barrier bitmap"
29000
29001         post_801
29002 }
29003 run_test 801c "rescan barrier bitmap"
29004
29005 test_802b() {
29006         [ $PARALLEL == "yes" ] && skip "skip parallel run"
29007         remote_mds_nodsh && skip "remote MDS with nodsh"
29008
29009         do_facet $SINGLEMDS $LCTL get_param mdt.*.readonly ||
29010                 skip "readonly option not available"
29011
29012         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "(1) fail to mkdir"
29013
29014         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
29015                 error "(2) Fail to copy"
29016
29017         # write back all cached data before setting MDT to readonly
29018         cancel_lru_locks
29019         sync_all_data
29020
29021         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=1
29022         stack_trap "do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0" EXIT
29023
29024         echo "Modify should be refused"
29025         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
29026
29027         echo "Read should be allowed"
29028         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
29029                 error "(7) Read should succeed under ro mode"
29030
29031         # disable readonly
29032         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0
29033 }
29034 run_test 802b "be able to set MDTs to readonly"
29035
29036 test_803a() {
29037         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
29038         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
29039                 skip "MDS needs to be newer than 2.10.54"
29040
29041         mkdir_on_mdt0 $DIR/$tdir
29042         # Create some objects on all MDTs to trigger related logs objects
29043         for idx in $(seq $MDSCOUNT); do
29044                 $LFS mkdir -c $MDSCOUNT -i $((idx % $MDSCOUNT)) \
29045                         $DIR/$tdir/dir${idx} ||
29046                         error "Fail to create $DIR/$tdir/dir${idx}"
29047         done
29048
29049         wait_delete_completed # ensure old test cleanups are finished
29050         sleep 3
29051         echo "before create:"
29052         $LFS df -i $MOUNT
29053         local before_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
29054
29055         for i in {1..10}; do
29056                 $LFS mkdir -c 1 -i 1 $DIR/$tdir/foo$i ||
29057                         error "Fail to create $DIR/$tdir/foo$i"
29058         done
29059
29060         # sync ZFS-on-MDS to refresh statfs data
29061         wait_zfs_commit mds1
29062         sleep 3
29063         echo "after create:"
29064         $LFS df -i $MOUNT
29065         local after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
29066
29067         # allow for an llog to be cleaned up during the test
29068         [ $after_used -ge $((before_used + 10 - 1)) ] ||
29069                 error "before ($before_used) + 10 > after ($after_used)"
29070
29071         for i in {1..10}; do
29072                 rm -rf $DIR/$tdir/foo$i ||
29073                         error "Fail to remove $DIR/$tdir/foo$i"
29074         done
29075
29076         # sync ZFS-on-MDS to refresh statfs data
29077         wait_zfs_commit mds1
29078         wait_delete_completed
29079         sleep 3 # avoid MDT return cached statfs
29080         echo "after unlink:"
29081         $LFS df -i $MOUNT
29082         after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
29083
29084         # allow for an llog to be created during the test
29085         [ $after_used -le $((before_used + 1)) ] ||
29086                 error "after ($after_used) > before ($before_used) + 1"
29087 }
29088 run_test 803a "verify agent object for remote object"
29089
29090 test_803b() {
29091         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
29092         [ $MDS1_VERSION -lt $(version_code 2.13.56) ] &&
29093                 skip "MDS needs to be newer than 2.13.56"
29094         [ $PARALLEL == "yes" ] && skip "skip parallel run"
29095
29096         for i in $(seq 0 $((MDSCOUNT - 1))); do
29097                 $LFS mkdir -i $i $DIR/$tdir.$i || error "mkdir $tdir.$i"
29098         done
29099
29100         local before=0
29101         local after=0
29102
29103         local tmp
29104
29105         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
29106         for i in $(seq 0 $((MDSCOUNT - 1))); do
29107                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
29108                         awk '/getattr/ { print $2 }')
29109                 before=$((before + tmp))
29110         done
29111         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
29112         for i in $(seq 0 $((MDSCOUNT - 1))); do
29113                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
29114                         awk '/getattr/ { print $2 }')
29115                 after=$((after + tmp))
29116         done
29117
29118         [ $before -eq $after ] || error "getattr count $before != $after"
29119 }
29120 run_test 803b "remote object can getattr from cache"
29121
29122 test_804() {
29123         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
29124         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
29125                 skip "MDS needs to be newer than 2.10.54"
29126         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
29127
29128         mkdir -p $DIR/$tdir
29129         $LFS mkdir -c 1 -i 1 $DIR/$tdir/dir0 ||
29130                 error "Fail to create $DIR/$tdir/dir0"
29131
29132         local fid=$($LFS path2fid $DIR/$tdir/dir0)
29133         local dev=$(mdsdevname 2)
29134
29135         do_facet mds2 "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
29136                 grep ${fid} || error "NOT found agent entry for dir0"
29137
29138         $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir/dir1 ||
29139                 error "Fail to create $DIR/$tdir/dir1"
29140
29141         touch $DIR/$tdir/dir1/foo0 ||
29142                 error "Fail to create $DIR/$tdir/dir1/foo0"
29143         fid=$($LFS path2fid $DIR/$tdir/dir1/foo0)
29144         local rc=0
29145
29146         for idx in $(seq $MDSCOUNT); do
29147                 dev=$(mdsdevname $idx)
29148                 do_facet mds${idx} \
29149                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
29150                         grep ${fid} && rc=$idx
29151         done
29152
29153         mv $DIR/$tdir/dir1/foo0 $DIR/$tdir/dir1/foo1 ||
29154                 error "Fail to rename foo0 to foo1"
29155         if [ $rc -eq 0 ]; then
29156                 for idx in $(seq $MDSCOUNT); do
29157                         dev=$(mdsdevname $idx)
29158                         do_facet mds${idx} \
29159                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
29160                         grep ${fid} && rc=$idx
29161                 done
29162         fi
29163
29164         mv $DIR/$tdir/dir1/foo1 $DIR/$tdir/dir1/foo2 ||
29165                 error "Fail to rename foo1 to foo2"
29166         if [ $rc -eq 0 ]; then
29167                 for idx in $(seq $MDSCOUNT); do
29168                         dev=$(mdsdevname $idx)
29169                         do_facet mds${idx} \
29170                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
29171                         grep ${fid} && rc=$idx
29172                 done
29173         fi
29174
29175         [ $rc -ne 0 ] || error "NOT found agent entry for foo"
29176
29177         ln $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir0/guard ||
29178                 error "Fail to link to $DIR/$tdir/dir1/foo2"
29179         mv $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir1/foo0 ||
29180                 error "Fail to rename foo2 to foo0"
29181         unlink $DIR/$tdir/dir1/foo0 ||
29182                 error "Fail to unlink $DIR/$tdir/dir1/foo0"
29183         rm -rf $DIR/$tdir/dir0 ||
29184                 error "Fail to rm $DIR/$tdir/dir0"
29185
29186         for idx in $(seq $MDSCOUNT); do
29187                 rc=0
29188
29189                 stop mds${idx}
29190                 dev=$(mdsdevname $idx)
29191                 run_e2fsck $(facet_active_host mds$idx) $dev -n ||
29192                         rc=$?
29193                 start mds${idx} $dev $MDS_MOUNT_OPTS ||
29194                         error "mount mds$idx failed"
29195                 df $MOUNT > /dev/null 2>&1
29196
29197                 # e2fsck should not return error
29198                 [ $rc -eq 0 ] ||
29199                         error "e2fsck detected error on MDT${idx}: rc=$rc"
29200         done
29201 }
29202 run_test 804 "verify agent entry for remote entry"
29203
29204 cleanup_805() {
29205         do_facet $SINGLEMDS zfs set quota=$old $fsset
29206         unlinkmany $DIR/$tdir/f- 1000000
29207         trap 0
29208 }
29209
29210 test_805() {
29211         local zfs_version=$(do_facet mds1 cat /sys/module/zfs/version)
29212         [ "$mds1_FSTYPE" != "zfs" ] && skip "ZFS specific test"
29213         [ $(version_code $zfs_version) -lt $(version_code 0.7.2) ] &&
29214                 skip "netfree not implemented before 0.7"
29215         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
29216                 skip "Need MDS version at least 2.10.57"
29217
29218         local fsset
29219         local freekb
29220         local usedkb
29221         local old
29222         local quota
29223         local pref="osd-zfs.$FSNAME-MDT0000."
29224
29225         # limit available space on MDS dataset to meet nospace issue
29226         # quickly. then ZFS 0.7.2 can use reserved space if asked
29227         # properly (using netfree flag in osd_declare_destroy()
29228         fsset=$(do_facet $SINGLEMDS lctl get_param -n $pref.mntdev)
29229         old=$(do_facet $SINGLEMDS zfs get -H quota $fsset | \
29230                 gawk '{print $3}')
29231         freekb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytesfree)
29232         usedkb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytestotal)
29233         let "usedkb=usedkb-freekb"
29234         let "freekb=freekb/2"
29235         if let "freekb > 5000"; then
29236                 let "freekb=5000"
29237         fi
29238         do_facet $SINGLEMDS zfs set quota=$(((usedkb+freekb)*1024)) $fsset
29239         trap cleanup_805 EXIT
29240         mkdir_on_mdt0 $DIR/$tdir
29241         $LFS setstripe -E 1M -c2 -E 4M -c2 -E -1 -c2 $DIR/$tdir ||
29242                 error "Can't set PFL layout"
29243         createmany -m $DIR/$tdir/f- 1000000 && error "ENOSPC wasn't met"
29244         rm -rf $DIR/$tdir || error "not able to remove"
29245         do_facet $SINGLEMDS zfs set quota=$old $fsset
29246         trap 0
29247 }
29248 run_test 805 "ZFS can remove from full fs"
29249
29250 # Size-on-MDS test
29251 check_lsom_data()
29252 {
29253         local file=$1
29254         local expect=$(stat -c %s $file)
29255
29256         check_lsom_size $1 $expect
29257
29258         local blocks=$($LFS getsom -b $file)
29259         expect=$(stat -c %b $file)
29260         [[ $blocks == $expect ]] ||
29261                 error "$file expected blocks: $expect, got: $blocks"
29262 }
29263
29264 check_lsom_size()
29265 {
29266         local size
29267         local expect=$2
29268
29269         cancel_lru_locks mdc
29270
29271         size=$($LFS getsom -s $1)
29272         [[ $size == $expect ]] ||
29273                 error "$file expected size: $expect, got: $size"
29274 }
29275
29276 test_806() {
29277         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
29278                 skip "Need MDS version at least 2.11.52"
29279
29280         local bs=1048576
29281
29282         $LFS setstripe -c-1 $DIR/$tfile || error "setstripe $tfile failed"
29283
29284         disable_opencache
29285         stack_trap "restore_opencache"
29286
29287         # single-threaded write
29288         echo "Test SOM for single-threaded write"
29289         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 ||
29290                 error "write $tfile failed"
29291         check_lsom_size $DIR/$tfile $bs
29292
29293         local num=32
29294         local size=$(($num * $bs))
29295         local offset=0
29296         local i
29297
29298         echo "Test SOM for single client multi-threaded($num) write"
29299         $TRUNCATE $DIR/$tfile 0
29300         for ((i = 0; i < $num; i++)); do
29301                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
29302                 local pids[$i]=$!
29303                 offset=$((offset + $bs))
29304         done
29305         for (( i=0; i < $num; i++ )); do
29306                 wait ${pids[$i]}
29307         done
29308         check_lsom_size $DIR/$tfile $size
29309
29310         $TRUNCATE $DIR/$tfile 0
29311         for ((i = 0; i < $num; i++)); do
29312                 offset=$((offset - $bs))
29313                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
29314                 local pids[$i]=$!
29315         done
29316         for (( i=0; i < $num; i++ )); do
29317                 wait ${pids[$i]}
29318         done
29319         check_lsom_size $DIR/$tfile $size
29320
29321         # multi-client writes
29322         num=$(get_node_count ${CLIENTS//,/ })
29323         size=$(($num * $bs))
29324         offset=0
29325         i=0
29326
29327         echo "Test SOM for multi-client ($num) writes"
29328         $TRUNCATE $DIR/$tfile 0
29329         for client in ${CLIENTS//,/ }; do
29330                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
29331                 local pids[$i]=$!
29332                 i=$((i + 1))
29333                 offset=$((offset + $bs))
29334         done
29335         for (( i=0; i < $num; i++ )); do
29336                 wait ${pids[$i]}
29337         done
29338         check_lsom_size $DIR/$tfile $offset
29339
29340         i=0
29341         $TRUNCATE $DIR/$tfile 0
29342         for client in ${CLIENTS//,/ }; do
29343                 offset=$((offset - $bs))
29344                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
29345                 local pids[$i]=$!
29346                 i=$((i + 1))
29347         done
29348         for (( i=0; i < $num; i++ )); do
29349                 wait ${pids[$i]}
29350         done
29351         check_lsom_size $DIR/$tfile $size
29352
29353         # verify SOM blocks count
29354         echo "Verify SOM block count"
29355         $TRUNCATE $DIR/$tfile 0
29356         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w$((bs))YSc ||
29357                 error "failed to write file $tfile with fdatasync and fstat"
29358         check_lsom_data $DIR/$tfile
29359
29360         $TRUNCATE $DIR/$tfile 0
29361         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w$((bs * 2))Yc ||
29362                 error "failed to write file $tfile with fdatasync"
29363         check_lsom_data $DIR/$tfile
29364
29365         $TRUNCATE $DIR/$tfile 0
29366         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:O_SYNC:w$((bs * 3))c ||
29367                 error "failed to write file $tfile with sync IO"
29368         check_lsom_data $DIR/$tfile
29369
29370         # verify truncate
29371         echo "Test SOM for truncate"
29372         # use ftruncate to sync blocks on close request
29373         $MULTIOP $DIR/$tfile oO_WRONLY:T16384c
29374         check_lsom_size $DIR/$tfile 16384
29375         check_lsom_data $DIR/$tfile
29376
29377         $TRUNCATE $DIR/$tfile 1234
29378         check_lsom_size $DIR/$tfile 1234
29379         # sync blocks on the MDT
29380         $MULTIOP $DIR/$tfile oc
29381         check_lsom_data $DIR/$tfile
29382 }
29383 run_test 806 "Verify Lazy Size on MDS"
29384
29385 test_807() {
29386         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
29387         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
29388                 skip "Need MDS version at least 2.11.52"
29389
29390         # Registration step
29391         changelog_register || error "changelog_register failed"
29392         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
29393         changelog_users $SINGLEMDS | grep -q $cl_user ||
29394                 error "User $cl_user not found in changelog_users"
29395
29396         rm -rf $DIR/$tdir || error "rm $tdir failed"
29397         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
29398         touch $DIR/$tdir/trunc || error "touch $tdir/trunc failed"
29399         $TRUNCATE $DIR/$tdir/trunc 1024 || error "truncate $tdir/trunc failed"
29400         $TRUNCATE $DIR/$tdir/trunc 1048576 ||
29401                 error "truncate $tdir/trunc failed"
29402
29403         local bs=1048576
29404         echo "Test SOM for single-threaded write with fsync"
29405         dd if=/dev/zero of=$DIR/$tdir/single_dd bs=$bs count=1 ||
29406                 error "write $tfile failed"
29407         sync;sync;sync
29408
29409         # multi-client wirtes
29410         local num=$(get_node_count ${CLIENTS//,/ })
29411         local offset=0
29412         local i=0
29413
29414         echo "Test SOM for multi-client ($num) writes"
29415         touch $DIR/$tfile || error "touch $tfile failed"
29416         $TRUNCATE $DIR/$tfile 0
29417         for client in ${CLIENTS//,/ }; do
29418                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
29419                 local pids[$i]=$!
29420                 i=$((i + 1))
29421                 offset=$((offset + $bs))
29422         done
29423         for (( i=0; i < $num; i++ )); do
29424                 wait ${pids[$i]}
29425         done
29426
29427         do_rpc_nodes "$CLIENTS" cancel_lru_locks osc
29428         do_nodes "$CLIENTS" "sync ; sleep 5 ; sync"
29429         $LSOM_SYNC -u $cl_user -m $FSNAME-MDT0000 $MOUNT
29430         check_lsom_data $DIR/$tdir/trunc
29431         check_lsom_data $DIR/$tdir/single_dd
29432         check_lsom_data $DIR/$tfile
29433
29434         rm -rf $DIR/$tdir
29435         # Deregistration step
29436         changelog_deregister || error "changelog_deregister failed"
29437 }
29438 run_test 807 "verify LSOM syncing tool"
29439
29440 check_som_nologged()
29441 {
29442         local lines=$($LFS changelog $FSNAME-MDT0000 |
29443                 grep 'x=trusted.som' | wc -l)
29444         [ $lines -ne 0 ] && error "trusted.som xattr is logged in Changelogs"
29445 }
29446
29447 test_808() {
29448         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
29449                 skip "Need MDS version at least 2.11.55"
29450
29451         # Registration step
29452         changelog_register || error "changelog_register failed"
29453
29454         touch $DIR/$tfile || error "touch $tfile failed"
29455         check_som_nologged
29456
29457         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=1 ||
29458                 error "write $tfile failed"
29459         check_som_nologged
29460
29461         $TRUNCATE $DIR/$tfile 1234
29462         check_som_nologged
29463
29464         $TRUNCATE $DIR/$tfile 1048576
29465         check_som_nologged
29466
29467         # Deregistration step
29468         changelog_deregister || error "changelog_deregister failed"
29469 }
29470 run_test 808 "Check trusted.som xattr not logged in Changelogs"
29471
29472 check_som_nodata()
29473 {
29474         $LFS getsom $1
29475         [[ $? -eq 61 ]] || error "DoM-only file $1 has SOM xattr"
29476 }
29477
29478 test_809() {
29479         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
29480                 skip "Need MDS version at least 2.11.56"
29481
29482         $LFS setstripe -E 1M -L mdt $DIR/$tfile ||
29483                 error "failed to create DoM-only file $DIR/$tfile"
29484         touch $DIR/$tfile || error "touch $tfile failed"
29485         check_som_nodata $DIR/$tfile
29486
29487         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 ||
29488                 error "write $tfile failed"
29489         check_som_nodata $DIR/$tfile
29490
29491         $TRUNCATE $DIR/$tfile 1234
29492         check_som_nodata $DIR/$tfile
29493
29494         $TRUNCATE $DIR/$tfile 4097
29495         check_som_nodata $DIR/$file
29496 }
29497 run_test 809 "Verify no SOM xattr store for DoM-only files"
29498
29499 test_810() {
29500         [ $PARALLEL == "yes" ] && skip "skip parallel run"
29501         $GSS && skip_env "could not run with gss"
29502         [[ $OST1_VERSION -gt $(version_code 2.12.58) ]] ||
29503                 skip "OST < 2.12.58 doesn't align checksum"
29504
29505         set_checksums 1
29506         stack_trap "set_checksums $ORIG_CSUM" EXIT
29507         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
29508
29509         local csum
29510         local before
29511         local after
29512         for csum in $CKSUM_TYPES; do
29513                 #define OBD_FAIL_OSC_NO_GRANT   0x411
29514                 $LCTL set_param osc.*.checksum_type=$csum fail_loc=0x411
29515                 for i in "10240 0" "10000 0" "4000 1" "500 1"; do
29516                         eval set -- $i
29517                         dd if=/dev/urandom of=$DIR/$tfile bs=$1 count=2 seek=$2
29518                         before=$(md5sum $DIR/$tfile)
29519                         $LCTL set_param ldlm.namespaces.*osc*.lru_size=clear
29520                         after=$(md5sum $DIR/$tfile)
29521                         [ "$before" == "$after" ] ||
29522                                 error "$csum: $before != $after bs=$1 seek=$2"
29523                 done
29524         done
29525 }
29526 run_test 810 "partial page writes on ZFS (LU-11663)"
29527
29528 test_812a() {
29529         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
29530                 skip "OST < 2.12.51 doesn't support this fail_loc"
29531
29532         $LFS setstripe -c 1 -i 0 $DIR/$tfile
29533         # ensure ost1 is connected
29534         stat $DIR/$tfile >/dev/null || error "can't stat"
29535         wait_osc_import_state client ost1 FULL
29536         # no locks, no reqs to let the connection idle
29537         cancel_lru_locks osc
29538
29539         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
29540 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
29541         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
29542         wait_osc_import_state client ost1 CONNECTING
29543         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
29544
29545         stat $DIR/$tfile >/dev/null || error "can't stat file"
29546 }
29547 run_test 812a "do not drop reqs generated when imp is going to idle (LU-11951)"
29548
29549 test_812b() { # LU-12378
29550         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
29551                 skip "OST < 2.12.51 doesn't support this fail_loc"
29552
29553         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "setstripe failed"
29554         # ensure ost1 is connected
29555         stat $DIR/$tfile >/dev/null || error "can't stat"
29556         wait_osc_import_state client ost1 FULL
29557         # no locks, no reqs to let the connection idle
29558         cancel_lru_locks osc
29559
29560         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
29561 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
29562         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
29563         wait_osc_import_state client ost1 CONNECTING
29564         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
29565
29566         $LFS quota -u 0 $DIR/ || error "lfs quota should succeed"
29567         wait_osc_import_state client ost1 IDLE
29568 }
29569 run_test 812b "do not drop no resend request for idle connect"
29570
29571 test_812c() {
29572         local old
29573
29574         old=$($LCTL get_param -n osc.*.idle_timeout | head -n 1)
29575
29576         $LFS setstripe -c 1 -o 0 $DIR/$tfile
29577         $LFS getstripe $DIR/$tfile
29578         $LCTL set_param osc.*.idle_timeout=10
29579         stack_trap "$LCTL set_param osc.*.idle_timeout=$old" EXIT
29580         # ensure ost1 is connected
29581         stat $DIR/$tfile >/dev/null || error "can't stat"
29582         wait_osc_import_state client ost1 FULL
29583         # no locks, no reqs to let the connection idle
29584         cancel_lru_locks osc
29585
29586 #define OBD_FAIL_PTLRPC_IDLE_RACE        0x533
29587         $LCTL set_param fail_loc=0x80000533
29588         sleep 15
29589         dd if=/dev/zero of=$DIR/$tfile count=1 conv=sync || error "dd failed"
29590 }
29591 run_test 812c "idle import vs lock enqueue race"
29592
29593 test_813() {
29594         local file_heat_sav=$($LCTL get_param -n llite.*.file_heat 2>/dev/null)
29595         [ -z "$file_heat_sav" ] && skip "no file heat support"
29596
29597         local readsample
29598         local writesample
29599         local readbyte
29600         local writebyte
29601         local readsample1
29602         local writesample1
29603         local readbyte1
29604         local writebyte1
29605
29606         local period_second=$($LCTL get_param -n llite.*.heat_period_second)
29607         local decay_pct=$($LCTL get_param -n llite.*.heat_decay_percentage)
29608
29609         $LCTL set_param -n llite.*.file_heat=1
29610         echo "Turn on file heat"
29611         echo "Period second: $period_second, Decay percentage: $decay_pct"
29612
29613         echo "QQQQ" > $DIR/$tfile
29614         echo "QQQQ" > $DIR/$tfile
29615         echo "QQQQ" > $DIR/$tfile
29616         cat $DIR/$tfile > /dev/null
29617         cat $DIR/$tfile > /dev/null
29618         cat $DIR/$tfile > /dev/null
29619         cat $DIR/$tfile > /dev/null
29620
29621         local out=$($LFS heat_get $DIR/$tfile)
29622
29623         $LFS heat_get $DIR/$tfile
29624         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
29625         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
29626         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
29627         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
29628
29629         [ $readsample -le 4 ] || error "read sample ($readsample) is wrong"
29630         [ $writesample -le 3 ] || error "write sample ($writesample) is wrong"
29631         [ $readbyte -le 20 ] || error "read bytes ($readbyte) is wrong"
29632         [ $writebyte -le 15 ] || error "write bytes ($writebyte) is wrong"
29633
29634         sleep $((period_second + 3))
29635         echo "Sleep $((period_second + 3)) seconds..."
29636         # The recursion formula to calculate the heat of the file f is as
29637         # follow:
29638         # Hi+1(f) = (1-P)*Hi(f)+ P*Ci
29639         # Where Hi is the heat value in the period between time points i*I and
29640         # (i+1)*I; Ci is the access count in the period; the symbol P refers
29641         # to the weight of Ci.
29642         out=$($LFS heat_get $DIR/$tfile)
29643         $LFS heat_get $DIR/$tfile
29644         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
29645         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
29646         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
29647         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
29648
29649         [ $(bc <<< "$readsample <= 4 * $decay_pct / 100") -eq 1 ] ||
29650                 error "read sample ($readsample) is wrong"
29651         [ $(bc <<< "$writesample <= 3 * $decay_pct / 100") -eq 1 ] ||
29652                 error "write sample ($writesample) is wrong"
29653         [ $(bc <<< "$readbyte <= 20 * $decay_pct / 100") -eq 1 ] ||
29654                 error "read bytes ($readbyte) is wrong"
29655         [ $(bc <<< "$writebyte <= 15 * $decay_pct / 100") -eq 1 ] ||
29656                 error "write bytes ($writebyte) is wrong"
29657
29658         echo "QQQQ" > $DIR/$tfile
29659         echo "QQQQ" > $DIR/$tfile
29660         echo "QQQQ" > $DIR/$tfile
29661         cat $DIR/$tfile > /dev/null
29662         cat $DIR/$tfile > /dev/null
29663         cat $DIR/$tfile > /dev/null
29664         cat $DIR/$tfile > /dev/null
29665
29666         sleep $((period_second + 3))
29667         echo "Sleep $((period_second + 3)) seconds..."
29668
29669         out=$($LFS heat_get $DIR/$tfile)
29670         $LFS heat_get $DIR/$tfile
29671         readsample1=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
29672         writesample1=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
29673         readbyte1=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
29674         writebyte1=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
29675
29676         [ $(bc <<< "$readsample1 <= ($readsample * (100 - $decay_pct) + \
29677                 4 * $decay_pct) / 100") -eq 1 ] ||
29678                 error "read sample ($readsample1) is wrong"
29679         [ $(bc <<< "$writesample1 <= ($writesample * (100 - $decay_pct) + \
29680                 3 * $decay_pct) / 100") -eq 1 ] ||
29681                 error "write sample ($writesample1) is wrong"
29682         [ $(bc <<< "$readbyte1 <= ($readbyte * (100 - $decay_pct) + \
29683                 20 * $decay_pct) / 100") -eq 1 ] ||
29684                 error "read bytes ($readbyte1) is wrong"
29685         [ $(bc <<< "$writebyte1 <= ($writebyte * (100 - $decay_pct) + \
29686                 15 * $decay_pct) / 100") -eq 1 ] ||
29687                 error "write bytes ($writebyte1) is wrong"
29688
29689         echo "Turn off file heat for the file $DIR/$tfile"
29690         $LFS heat_set -o $DIR/$tfile
29691
29692         echo "QQQQ" > $DIR/$tfile
29693         echo "QQQQ" > $DIR/$tfile
29694         echo "QQQQ" > $DIR/$tfile
29695         cat $DIR/$tfile > /dev/null
29696         cat $DIR/$tfile > /dev/null
29697         cat $DIR/$tfile > /dev/null
29698         cat $DIR/$tfile > /dev/null
29699
29700         out=$($LFS heat_get $DIR/$tfile)
29701         $LFS heat_get $DIR/$tfile
29702         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
29703         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
29704         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
29705         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
29706
29707         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
29708         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
29709         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
29710         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
29711
29712         echo "Trun on file heat for the file $DIR/$tfile"
29713         $LFS heat_set -O $DIR/$tfile
29714
29715         echo "QQQQ" > $DIR/$tfile
29716         echo "QQQQ" > $DIR/$tfile
29717         echo "QQQQ" > $DIR/$tfile
29718         cat $DIR/$tfile > /dev/null
29719         cat $DIR/$tfile > /dev/null
29720         cat $DIR/$tfile > /dev/null
29721         cat $DIR/$tfile > /dev/null
29722
29723         out=$($LFS heat_get $DIR/$tfile)
29724         $LFS heat_get $DIR/$tfile
29725         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
29726         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
29727         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
29728         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
29729
29730         [ $readsample -gt 0 ] || error "read sample ($readsample) is wrong"
29731         [ $writesample -gt 0 ] || error "write sample ($writesample) is wrong"
29732         [ $readbyte -gt 0 ] || error "read bytes ($readbyte) is wrong"
29733         [ $writebyte -gt 0 ] || error "write bytes ($writebyte) is wrong"
29734
29735         $LFS heat_set -c $DIR/$tfile
29736         $LCTL set_param -n llite.*.file_heat=0
29737         echo "Turn off file heat support for the Lustre filesystem"
29738
29739         echo "QQQQ" > $DIR/$tfile
29740         echo "QQQQ" > $DIR/$tfile
29741         echo "QQQQ" > $DIR/$tfile
29742         cat $DIR/$tfile > /dev/null
29743         cat $DIR/$tfile > /dev/null
29744         cat $DIR/$tfile > /dev/null
29745         cat $DIR/$tfile > /dev/null
29746
29747         out=$($LFS heat_get $DIR/$tfile)
29748         $LFS heat_get $DIR/$tfile
29749         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
29750         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
29751         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
29752         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
29753
29754         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
29755         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
29756         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
29757         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
29758
29759         $LCTL set_param -n llite.*.file_heat=$file_heat_sav
29760         rm -f $DIR/$tfile
29761 }
29762 run_test 813 "File heat verfication"
29763
29764 test_814()
29765 {
29766         dd of=$DIR/$tfile seek=128 bs=1k < /dev/null
29767         echo -n y >> $DIR/$tfile
29768         cp --sparse=always $DIR/$tfile $DIR/${tfile}.cp || error "copy failed"
29769         diff $DIR/$tfile $DIR/${tfile}.cp || error "files should be same"
29770 }
29771 run_test 814 "sparse cp works as expected (LU-12361)"
29772
29773 test_815()
29774 {
29775         writeme -b 100 $DIR/$tfile || error "write 100 bytes failed"
29776         writeme -b 0 $DIR/$tfile || error "write 0 byte failed"
29777 }
29778 run_test 815 "zero byte tiny write doesn't hang (LU-12382)"
29779
29780 test_816() {
29781         local ost1_imp=$(get_osc_import_name client ost1)
29782         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
29783                          cut -d'.' -f2)
29784
29785         $LFS setstripe -c 1 -i 0 $DIR/$tfile
29786         # ensure ost1 is connected
29787
29788         stat $DIR/$tfile >/dev/null || error "can't stat"
29789         wait_osc_import_state client ost1 FULL
29790         # no locks, no reqs to let the connection idle
29791         cancel_lru_locks osc
29792         lru_resize_disable osc
29793         local before
29794         local now
29795         before=$($LCTL get_param -n \
29796                  ldlm.namespaces.$imp_name.lru_size)
29797
29798         wait_osc_import_state client ost1 IDLE
29799         dd if=/dev/null of=$DIR/$tfile bs=1k count=1 conv=sync
29800         now=$($LCTL get_param -n \
29801               ldlm.namespaces.$imp_name.lru_size)
29802         [ $before == $now ] || error "lru_size changed $before != $now"
29803 }
29804 run_test 816 "do not reset lru_resize on idle reconnect"
29805
29806 cleanup_817() {
29807         umount $tmpdir
29808         exportfs -u localhost:$DIR/nfsexp
29809         rm -rf $DIR/nfsexp
29810 }
29811
29812 test_817() {
29813         systemctl restart nfs-server.service || skip "failed to restart nfsd"
29814
29815         mkdir -p $DIR/nfsexp
29816         exportfs -orw,no_root_squash localhost:$DIR/nfsexp ||
29817                 error "failed to export nfs"
29818
29819         tmpdir=$(mktemp -d /tmp/nfs-XXXXXX)
29820         stack_trap cleanup_817 EXIT
29821
29822         mount -t nfs -orw localhost:$DIR/nfsexp $tmpdir ||
29823                 error "failed to mount nfs to $tmpdir"
29824
29825         cp /bin/true $tmpdir
29826         $DIR/nfsexp/true || error "failed to execute 'true' command"
29827 }
29828 run_test 817 "nfsd won't cache write lock for exec file"
29829
29830 test_818() {
29831         test_mkdir -i0 -c1 $DIR/$tdir
29832         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
29833         $LFS setstripe -c1 -i1 $DIR/$tdir/$tfile
29834         stop $SINGLEMDS
29835
29836         # restore osp-syn threads
29837         stack_trap "fail $SINGLEMDS"
29838
29839         #define OBD_FAIL_OSP_CANT_PROCESS_LLOG          0x2105
29840         do_facet $SINGLEMDS lctl set_param fail_loc=0x80002105
29841         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
29842                 error "start $SINGLEMDS failed"
29843         rm -rf $DIR/$tdir
29844
29845         local testid=$(echo $TESTNAME | tr '_' ' ')
29846
29847         do_facet mds1 dmesg | tac | sed "/$testid/,$ d" |
29848                 grep "run LFSCK" || error "run LFSCK is not suggested"
29849 }
29850 run_test 818 "unlink with failed llog"
29851
29852 test_819a() {
29853         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
29854         cancel_lru_locks osc
29855         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
29856         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
29857         dd if=$DIR/$tfile of=/dev/null bs=1M count=1
29858         rm -f $TDIR/$tfile
29859 }
29860 run_test 819a "too big niobuf in read"
29861
29862 test_819b() {
29863         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
29864         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
29865         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
29866         cancel_lru_locks osc
29867         sleep 1
29868         rm -f $TDIR/$tfile
29869 }
29870 run_test 819b "too big niobuf in write"
29871
29872
29873 function test_820_start_ost() {
29874         sleep 5
29875
29876         for num in $(seq $OSTCOUNT); do
29877                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS
29878         done
29879 }
29880
29881 test_820() {
29882         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
29883
29884         mkdir $DIR/$tdir
29885         umount_client $MOUNT || error "umount failed"
29886         for num in $(seq $OSTCOUNT); do
29887                 stop ost$num
29888         done
29889
29890         # mount client with no active OSTs
29891         # so that the client can't initialize max LOV EA size
29892         # from OSC notifications
29893         mount_client $MOUNT || error "mount failed"
29894         # delay OST starting to keep this 0 max EA size for a while
29895         test_820_start_ost &
29896
29897         # create a directory on MDS2
29898         test_mkdir -i 1 -c1 $DIR/$tdir/mds2 ||
29899                 error "Failed to create directory"
29900         # open intent should update default EA size
29901         # see mdc_update_max_ea_from_body()
29902         # notice this is the very first RPC to MDS2
29903         out=$(cp /etc/services $DIR/$tdir/mds2 2>&1)
29904         ret=$?
29905         echo $out
29906         # With SSK, this situation can lead to -EPERM being returned.
29907         # In that case, simply retry.
29908         if [ $ret -ne 0 ] && $SHARED_KEY; then
29909                 if echo "$out" | grep -q "not permitted"; then
29910                         cp /etc/services $DIR/$tdir/mds2
29911                         ret=$?
29912                 fi
29913         fi
29914         [ $ret -eq 0 ] || error "Failed to copy files to mds$n"
29915 }
29916 run_test 820 "update max EA from open intent"
29917
29918 test_823() {
29919         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
29920         local OST_MAX_PRECREATE=20000
29921
29922         (( $MDS1_VERSION >= $(version_code 2.14.56) )) ||
29923                 skip "Need MDS version at least 2.14.56"
29924
29925         save_lustre_params mds1 \
29926                 "osp.$FSNAME-OST*-osc-MDT0000.max_create_count" > $p
29927         do_facet $SINGLEMDS "$LCTL set_param -n \
29928                 osp.$FSNAME-OST*MDT0000.max_create_count=0"
29929         do_facet $SINGLEMDS "$LCTL set_param -n \
29930                 osp.$FSNAME-OST0000*MDT0000.max_create_count=$OST_MAX_PRECREATE"
29931
29932         stack_trap "restore_lustre_params < $p; rm $p"
29933
29934         do_facet $SINGLEMDS "$LCTL set_param -n \
29935                 osp.$FSNAME-OST*-osc-MDT*.create_count=100200"
29936
29937         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
29938                       osp.$FSNAME-OST0000*MDT0000.create_count")
29939         local max=$(do_facet $SINGLEMDS "$LCTL get_param -n \
29940                     osp.$FSNAME-OST0000*MDT0000.max_create_count")
29941         local expect_count=$(((($max/2)/256) * 256))
29942
29943         log "setting create_count to 100200:"
29944         log " -result- count: $count with max: $max, expecting: $expect_count"
29945
29946         [[ $count -eq expect_count ]] ||
29947                 error "Create count not set to max precreate."
29948 }
29949 run_test 823 "Setting create_count > OST_MAX_PRECREATE is lowered to maximum"
29950
29951 test_831() {
29952         [[ $MDS1_VERSION -lt $(version_code 2.14.56) ]] &&
29953                 skip "Need MDS version 2.14.56"
29954
29955         local sync_changes=$(do_facet $SINGLEMDS \
29956                 $LCTL get_param -n osp.$FSNAME-OST0000-osc-MDT0000.sync_changes)
29957
29958         [ "$sync_changes" -gt 100 ] &&
29959                 skip "Sync changes $sync_changes > 100 already"
29960
29961         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
29962
29963         $LFS mkdir -i 0 $DIR/$tdir
29964         $LFS setstripe -c 1 -i 0 $DIR/$tdir
29965
29966         save_lustre_params mds1 \
29967                 "osp.$FSNAME-OST*-osc-MDT0000.max_sync_changes" > $p
29968         save_lustre_params mds1 \
29969                 "osp.$FSNAME-OST*-osc-MDT0000.max_rpcs_in_progress" >> $p
29970
29971         do_facet mds1 "$LCTL set_param -n \
29972                 osp.$FSNAME-OST*-osc-MDT0000.max_sync_changes=100 \
29973                 osp.$FSNAME-OST*-osc-MDT0000.max_rpcs_in_progress=128"
29974         stack_trap "restore_lustre_params < $p" EXIT
29975
29976         createmany -o $DIR/$tdir/f- 1000
29977         unlinkmany $DIR/$tdir/f- 1000 &
29978         local UNLINK_PID=$!
29979
29980         while sleep 1; do
29981                 sync_changes=$(do_facet mds1 \
29982                 $LCTL get_param -n osp.$FSNAME-OST0000-osc-MDT0000.sync_changes)
29983                 # the check in the code is racy, fail the test
29984                 # if the value above the limit by 10.
29985                 [ $sync_changes -gt 110 ] && {
29986                         kill -2 $UNLINK_PID
29987                         wait
29988                         error "osp changes throttling failed, $sync_changes>110"
29989                 }
29990                 kill -0 $UNLINK_PID 2> /dev/null || break
29991         done
29992         wait
29993 }
29994 run_test 831 "throttling unlink/setattr queuing on OSP"
29995
29996 test_832() {
29997         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
29998         (( $MDS1_VERSION >= $(version_code 2.15.52) )) ||
29999                 skip "Need MDS version 2.15.52+"
30000         is_rmentry_supported || skip "rm_entry not supported"
30001
30002         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
30003         mkdir $DIR/$tdir/local_dir || error "mkdir local_dir failed"
30004         mkdir_on_mdt -i 1 $DIR/$tdir/remote_dir ||
30005                 error "mkdir remote_dir failed"
30006         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/striped_dir ||
30007                 error "mkdir striped_dir failed"
30008         touch $DIR/$tdir/file || error "touch file failed"
30009         $LFS rm_entry $DIR/$tdir/* || error "lfs rm_entry $tdir/* failed"
30010         [ -z "$(ls -A $DIR/$tdir)" ] || error "$tdir not empty"
30011 }
30012 run_test 832 "lfs rm_entry"
30013
30014 test_833() {
30015         local file=$DIR/$tfile
30016
30017         stack_trap "rm -f $file" EXIT
30018         dd if=/dev/zero of=$file bs=1M count=50 || error "Write $file failed"
30019
30020         local wpid
30021         local rpid
30022         local rpid2
30023
30024         # Buffered I/O write
30025         (
30026                 while [ ! -e $DIR/sanity.833.lck ]; do
30027                         dd if=/dev/zero of=$file bs=1M count=50 conv=notrunc ||
30028                                 error "failed to write $file"
30029                         sleep 0.$((RANDOM % 4 + 1))
30030                 done
30031         )&
30032         wpid=$!
30033
30034         # Buffered I/O read
30035         (
30036                 while [ ! -e $DIR/sanity.833.lck ]; do
30037                         dd if=$file of=/dev/null bs=1M count=50 ||
30038                                 error "failed to read $file"
30039                         sleep 0.$((RANDOM % 4 + 1))
30040                 done
30041         )&
30042         rpid=$!
30043
30044         # Direct I/O read
30045         (
30046                 while [ ! -e $DIR/sanity.833.lck ]; do
30047                         dd if=$file of=/dev/null bs=1M count=50 iflag=direct ||
30048                                 error "failed to read $file in direct I/O mode"
30049                         sleep 0.$((RANDOM % 4 + 1))
30050                 done
30051         )&
30052         rpid2=$!
30053
30054         sleep 30
30055         touch $DIR/sanity.833.lck
30056         wait $wpid || error "$?: buffered write failed"
30057         wait $rpid || error "$?: buffered read failed"
30058         wait $rpid2 || error "$?: direct read failed"
30059 }
30060 run_test 833 "Mixed buffered/direct read and write should not return -EIO"
30061
30062 #
30063 # tests that do cleanup/setup should be run at the end
30064 #
30065
30066 test_900() {
30067         [ $PARALLEL == "yes" ] && skip "skip parallel run"
30068         local ls
30069
30070         #define OBD_FAIL_MGC_PAUSE_PROCESS_LOG   0x903
30071         $LCTL set_param fail_loc=0x903
30072
30073         cancel_lru_locks MGC
30074
30075         FAIL_ON_ERROR=true cleanup
30076         FAIL_ON_ERROR=true setup
30077 }
30078 run_test 900 "umount should not race with any mgc requeue thread"
30079
30080 # LUS-6253/LU-11185
30081 test_901() {
30082         local old
30083         local count
30084         local oldc
30085         local newc
30086         local olds
30087         local news
30088         [ $PARALLEL == "yes" ] && skip "skip parallel run"
30089
30090         # some get_param have a bug to handle dot in param name
30091         cancel_lru_locks MGC
30092         old=$(mount -t lustre | wc -l)
30093         # 1 config+sptlrpc
30094         # 2 params
30095         # 3 nodemap
30096         # 4 IR
30097         old=$((old * 4))
30098         oldc=0
30099         count=0
30100         while [ $old -ne $oldc ]; do
30101                 oldc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
30102                 sleep 1
30103                 ((count++))
30104                 if [ $count -ge $TIMEOUT ]; then
30105                         error "too large timeout"
30106                 fi
30107         done
30108         umount_client $MOUNT || error "umount failed"
30109         mount_client $MOUNT || error "mount failed"
30110         cancel_lru_locks MGC
30111         newc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
30112
30113         [ $oldc -lt $newc ] && error "mgc lock leak ($oldc != $newc)"
30114
30115         return 0
30116 }
30117 run_test 901 "don't leak a mgc lock on client umount"
30118
30119 # LU-13377
30120 test_902() {
30121         [ $CLIENT_VERSION -lt $(version_code 2.13.52) ] &&
30122                 skip "client does not have LU-13377 fix"
30123         #define OBD_FAIL_LLITE_SHORT_COMMIT 0x1415
30124         $LCTL set_param fail_loc=0x1415
30125         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
30126         cancel_lru_locks osc
30127         rm -f $DIR/$tfile
30128 }
30129 run_test 902 "test short write doesn't hang lustre"
30130
30131 # LU-14711
30132 test_903() {
30133         $LFS setstripe -i 0 -c 1 $DIR/$tfile $DIR/${tfile}-2
30134         echo "blah" > $DIR/${tfile}-2
30135         dd if=/dev/zero of=$DIR/$tfile bs=1M count=6 conv=fsync
30136         #define OBD_FAIL_OSC_SLOW_PAGE_EVICT 0x417
30137         $LCTL set_param fail_loc=0x417 fail_val=20
30138
30139         mv $DIR/${tfile}-2 $DIR/$tfile # Destroys the big object
30140         sleep 1 # To start the destroy
30141         wait_destroy_complete 150 || error "Destroy taking too long"
30142         cat $DIR/$tfile > /dev/null || error "Evicted"
30143 }
30144 run_test 903 "Test long page discard does not cause evictions"
30145
30146 test_904() {
30147         [ "$mds1_FSTYPE" == "ldiskfs" ] || skip "ldiskfs only test"
30148         do_facet mds1 $DEBUGFS -R features $(mdsdevname 1) |
30149                 grep -q project || skip "skip project quota not supported"
30150
30151         local testfile="$DIR/$tdir/$tfile"
30152         local xattr="trusted.projid"
30153         local projid
30154         local mdts=$(comma_list $(mdts_nodes))
30155         local saved=$(do_facet mds1 $LCTL get_param -n \
30156                 osd-ldiskfs.*MDT0000.enable_projid_xattr)
30157
30158         do_nodes $mdts $LCTL set_param osd-ldiskfs.*MDT*.enable_projid_xattr=0
30159         stack_trap "do_nodes $mdts $LCTL set_param \
30160                 osd-ldiskfs.*MDT*.enable_projid_xattr=$saved"
30161
30162         mkdir -p $DIR/$tdir
30163         touch $testfile
30164         #hide projid xattr on server
30165         $LFS project -p 1 $testfile ||
30166                 error "set $testfile project id failed"
30167         getfattr -m - $testfile | grep $xattr &&
30168                 error "do not show trusted.projid when disabled on server"
30169         do_nodes $mdts $LCTL set_param osd-ldiskfs.*MDT*.enable_projid_xattr=1
30170         #should be hidden when projid is 0
30171         $LFS project -p 0 $testfile ||
30172                 error "set $testfile project id failed"
30173         getfattr -m - $testfile | grep $xattr &&
30174                 error "do not show trusted.projid with project ID 0"
30175
30176         #still can getxattr explicitly
30177         projid=$(getfattr -n $xattr $testfile |
30178                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
30179         [ $projid == "0" ] ||
30180                 error "projid expected 0 not $projid"
30181
30182         #set the projid via setxattr
30183         setfattr -n $xattr -v "1000" $testfile ||
30184                 error "setattr failed with $?"
30185         projid=($($LFS project $testfile))
30186         [ ${projid[0]} == "1000" ] ||
30187                 error "projid expected 1000 not $projid"
30188
30189         #check the new projid via getxattr
30190         $LFS project -p 1001 $testfile ||
30191                 error "set $testfile project id failed"
30192         getfattr -m - $testfile | grep $xattr ||
30193                 error "should show trusted.projid when project ID != 0"
30194         projid=$(getfattr -n $xattr $testfile |
30195                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
30196         [ $projid == "1001" ] ||
30197                 error "projid expected 1001 not $projid"
30198
30199         #try to set invalid projid
30200         setfattr -n $xattr -v "4294967295" $testfile &&
30201                 error "set invalid projid should fail"
30202
30203         #remove the xattr means setting projid to 0
30204         setfattr -x $xattr $testfile ||
30205                 error "setfattr failed with $?"
30206         projid=($($LFS project $testfile))
30207         [ ${projid[0]} == "0" ] ||
30208                 error "projid expected 0 not $projid"
30209
30210         #should be hidden when parent has inherit flag and same projid
30211         $LFS project -srp 1002 $DIR/$tdir ||
30212                 error "set $tdir project id failed"
30213         getfattr -m - $testfile | grep $xattr &&
30214                 error "do not show trusted.projid with inherit flag"
30215
30216         #still can getxattr explicitly
30217         projid=$(getfattr -n $xattr $testfile |
30218                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
30219         [ $projid == "1002" ] ||
30220                 error "projid expected 1002 not $projid"
30221 }
30222 run_test 904 "virtual project ID xattr"
30223
30224 # LU-8582
30225 test_905() {
30226         (( $OST1_VERSION >= $(version_code 2.8.54) )) ||
30227                 skip "lustre < 2.8.54 does not support ladvise"
30228
30229         remote_ost_nodsh && skip "remote OST with nodsh"
30230         $LFS setstripe -c -1 -i 0 $DIR/$tfile || error "setstripe failed"
30231
30232         $LFS ladvise -a willread $DIR/$tfile || error "ladvise does not work"
30233
30234         #define OBD_FAIL_OST_OPCODE 0x253
30235         # OST_LADVISE = 21
30236         do_facet ost1 "$LCTL set_param fail_val=21 fail_loc=0x0253"
30237         $LFS ladvise -a willread $DIR/$tfile &&
30238                 error "unexpected success of ladvise with fault injection"
30239         $LFS ladvise -a willread $DIR/$tfile |&
30240                 grep -q "Operation not supported"
30241         (( $? == 0 )) || error "unexpected stderr of ladvise with fault injection"
30242 }
30243 run_test 905 "bad or new opcode should not stuck client"
30244
30245 test_906() {
30246         grep -q io_uring_setup /proc/kallsyms ||
30247                 skip "Client OS does not support io_uring I/O engine"
30248         io_uring_probe || skip "kernel does not support io_uring fully"
30249         which fio || skip_env "no fio installed"
30250         fio --enghelp | grep -q io_uring ||
30251                 skip_env "fio does not support io_uring I/O engine"
30252
30253         local file=$DIR/$tfile
30254         local ioengine="io_uring"
30255         local numjobs=2
30256         local size=50M
30257
30258         fio --name=seqwrite --ioengine=$ioengine        \
30259                 --bs=$PAGE_SIZE --direct=1 --numjobs=$numjobs   \
30260                 --iodepth=64 --size=$size --filename=$file --rw=write ||
30261                 error "fio seqwrite $file failed"
30262
30263         fio --name=seqread --ioengine=$ioengine \
30264                 --bs=$PAGE_SIZE --direct=1 --numjobs=$numjobs   \
30265                 --iodepth=64 --size=$size --filename=$file --rw=read ||
30266                 error "fio seqread $file failed"
30267
30268         rm -f $file || error "rm -f $file failed"
30269 }
30270 run_test 906 "Simple test for io_uring I/O engine via fio"
30271
30272 complete_test $SECONDS
30273 [ -f $EXT2_DEV ] && rm $EXT2_DEV || true
30274 check_and_cleanup_lustre
30275 if [ "$I_MOUNTED" != "yes" ]; then
30276         lctl set_param debug="$OLDDEBUG" 2> /dev/null || true
30277 fi
30278 exit_status