Whamcloud - gitweb
LU-16756 kernel: RHEL 9.2 server support
[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_27Ch() {
2606         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2607                 skip "server does not support overstriping"
2608         (( $MDS1_VERSION >= $(version_code 2.15.55.102) )) ||
2609                 skip "need MDS >= 2.12.55.102 for mdt_dump_lmm fix"
2610
2611         stack_trap "rm -f $DIR/$tfile"
2612         # start_full_debug_logging
2613         $LFS setstripe -S 64K -C -1 $DIR/$tfile || error "create $tfile failed"
2614         $LFS getstripe -c $DIR/$tfile || error "getstripe $tfile failed"
2615         cancel_lru_locks
2616         $LFS getstripe -c $DIR/$tfile || error "getstripe failed after clear"
2617
2618         test_mkdir $DIR/$tdir
2619         stack_trap "rm -rf $DIR/$tdir/$tfile"
2620         $LFS setstripe -S 64K -C -1 $DIR/$tdir || error "mkdir $tdir failed"
2621         $LFS getstripe -y $DIR/$tdir || error "getstripe $tdir failed"
2622         touch $DIR/$tdir/$tfile || error "create $tdir/$tfile failed"
2623         cancel_lru_locks
2624         $LFS getstripe -c $DIR/$tdir/$tfile ||
2625                 error "getstripe $tdir/$tfile failed"
2626         #stop_full_debug_logging
2627 }
2628 run_test 27Ch "overstriping with -C -1 in mdt_dump_lmm"
2629
2630 test_27D() {
2631         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2632         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2633         remote_mds_nodsh && skip "remote MDS with nodsh"
2634
2635         local POOL=${POOL:-testpool}
2636         local first_ost=0
2637         local last_ost=$(($OSTCOUNT - 1))
2638         local ost_step=1
2639         local ost_list=$(seq $first_ost $ost_step $last_ost)
2640         local ost_range="$first_ost $last_ost $ost_step"
2641
2642         test_mkdir $DIR/$tdir
2643         pool_add $POOL || error "pool_add failed"
2644         pool_add_targets $POOL $ost_range || error "pool_add_targets failed"
2645
2646         local skip27D
2647         [ $MDS1_VERSION -lt $(version_code 2.8.55) ] &&
2648                 skip27D+="-s 29"
2649         [ $MDS1_VERSION -lt $(version_code 2.9.55) ] ||
2650                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2651                         skip27D+=" -s 30,31"
2652         [[ ! $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ||
2653           $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2654                 skip27D+=" -s 32,33"
2655         [[ $MDS_VERSION -lt $(version_code $SEL_VER) ]] &&
2656                 skip27D+=" -s 34"
2657         llapi_layout_test -d$DIR/$tdir -p$POOL -o$OSTCOUNT $skip27D ||
2658                 error "llapi_layout_test failed"
2659
2660         destroy_test_pools || error "destroy test pools failed"
2661 }
2662 run_test 27D "validate llapi_layout API"
2663
2664 # Verify that default_easize is increased from its initial value after
2665 # accessing a widely striped file.
2666 test_27E() {
2667         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2668         [ $CLIENT_VERSION -lt $(version_code 2.5.57) ] &&
2669                 skip "client does not have LU-3338 fix"
2670
2671         # 72 bytes is the minimum space required to store striping
2672         # information for a file striped across one OST:
2673         # (sizeof(struct lov_user_md_v3) +
2674         #  sizeof(struct lov_user_ost_data_v1))
2675         local min_easize=72
2676         $LCTL set_param -n llite.*.default_easize $min_easize ||
2677                 error "lctl set_param failed"
2678         local easize=$($LCTL get_param -n llite.*.default_easize)
2679
2680         [ $easize -eq $min_easize ] ||
2681                 error "failed to set default_easize"
2682
2683         $LFS setstripe -c $OSTCOUNT $DIR/$tfile ||
2684                 error "setstripe failed"
2685         # In order to ensure stat() call actually talks to MDS we need to
2686         # do something drastic to this file to shake off all lock, e.g.
2687         # rename it (kills lookup lock forcing cache cleaning)
2688         mv $DIR/$tfile $DIR/${tfile}-1
2689         ls -l $DIR/${tfile}-1
2690         rm $DIR/${tfile}-1
2691
2692         easize=$($LCTL get_param -n llite.*.default_easize)
2693
2694         [ $easize -gt $min_easize ] ||
2695                 error "default_easize not updated"
2696 }
2697 run_test 27E "check that default extended attribute size properly increases"
2698
2699 test_27F() { # LU-5346/LU-7975
2700         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2701         [[ $OSTCOUNT -lt 2 ]] && skip "needs >= 2 OSTs"
2702         [[ $MDS1_VERSION -lt $(version_code 2.8.51) ]] &&
2703                 skip "Need MDS version at least 2.8.51"
2704         remote_ost_nodsh && skip "remote OST with nodsh"
2705
2706         test_mkdir $DIR/$tdir
2707         rm -f $DIR/$tdir/f0
2708         $LFS setstripe -c 2 $DIR/$tdir
2709
2710         # stop all OSTs to reproduce situation for LU-7975 ticket
2711         for num in $(seq $OSTCOUNT); do
2712                 stop ost$num
2713         done
2714
2715         # open/create f0 with O_LOV_DELAY_CREATE
2716         # truncate f0 to a non-0 size
2717         # close
2718         multiop $DIR/$tdir/f0 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T1050000c
2719
2720         $CHECKSTAT -s 1050000 $DIR/$tdir/f0 || error "checkstat failed"
2721         # open/write it again to force delayed layout creation
2722         cat /etc/hosts > $DIR/$tdir/f0 &
2723         catpid=$!
2724
2725         # restart OSTs
2726         for num in $(seq $OSTCOUNT); do
2727                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS ||
2728                         error "ost$num failed to start"
2729         done
2730
2731         wait $catpid || error "cat failed"
2732
2733         cmp /etc/hosts $DIR/$tdir/f0 || error "cmp failed"
2734         [[ $($LFS getstripe -c $DIR/$tdir/f0) == 2 ]] ||
2735                 error "wrong stripecount"
2736
2737 }
2738 run_test 27F "Client resend delayed layout creation with non-zero size"
2739
2740 test_27G() { #LU-10629
2741         [ $MDS1_VERSION -lt $(version_code 2.11.51) ] &&
2742                 skip "Need MDS version at least 2.11.51"
2743         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2744         remote_mds_nodsh && skip "remote MDS with nodsh"
2745         local POOL=${POOL:-testpool}
2746         local ostrange="0 0 1"
2747
2748         test_mkdir $DIR/$tdir
2749         touch $DIR/$tdir/$tfile.nopool
2750         pool_add $POOL || error "pool_add failed"
2751         pool_add_targets $POOL $ostrange || error "pool_add_targets failed"
2752         $LFS setstripe -p $POOL $DIR/$tdir
2753
2754         local pool=$($LFS getstripe -p $DIR/$tdir)
2755
2756         [ "$pool" = "$POOL" ] || error "Striping failed got '$pool' not '$POOL'"
2757         touch $DIR/$tdir/$tfile.default
2758         $LFS setstripe -E 1M --pool $POOL -c 1 -E eof -c 1 $DIR/$tdir/$tfile.pfl
2759         $LFS find $DIR/$tdir -type f --pool $POOL
2760         local found=$($LFS find $DIR/$tdir -type f --pool $POOL | wc -l)
2761         [[ "$found" == "2" ]] ||
2762                 error "found $found != 2 files in '$DIR/$tdir' in '$POOL'"
2763
2764         $LFS setstripe -d $DIR/$tdir
2765
2766         pool=$($LFS getstripe -p -d $DIR/$tdir)
2767
2768         [[ "$pool" != "$POOL" ]] || error "$DIR/$tdir is still '$pool'"
2769 }
2770 run_test 27G "Clear OST pool from stripe"
2771
2772 test_27H() {
2773         [[ $MDS1_VERSION -le $(version_code 2.11.54) ]] &&
2774                 skip "Need MDS version newer than 2.11.54"
2775         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
2776         test_mkdir $DIR/$tdir
2777         $LFS setstripe -o 0 -o 2 $DIR/$tdir || error "setstripe failed"
2778         touch $DIR/$tdir/$tfile
2779         $LFS getstripe -c $DIR/$tdir/$tfile
2780         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
2781                 error "two-stripe file doesn't have two stripes"
2782
2783         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
2784         $LFS getstripe -y $DIR/$tdir/$tfile
2785         (( $($LFS getstripe -y $DIR/$tdir/$tfile |
2786              egrep -c "l_ost_idx: [02]$") == "2" )) ||
2787                 error "expected l_ost_idx: [02]$ not matched"
2788
2789         # make sure ost list has been cleared
2790         local stripesize=$($LFS getstripe -S $DIR/$tdir)
2791         $LFS setstripe -S $((stripesize * 4)) -i 1 \
2792                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
2793         touch $DIR/$tdir/f3
2794         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
2795 }
2796 run_test 27H "Set specific OSTs stripe"
2797
2798 test_27I() {
2799         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2800         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2801         [[ $MDS1_VERSION -gt $(version_code 2.12.52) ]] ||
2802                 skip "Need MDS version newer than 2.12.52"
2803         local pool=$TESTNAME
2804         local ostrange="1 1 1"
2805
2806         save_layout_restore_at_exit $MOUNT
2807         $LFS setstripe -c 2 -i 0 $MOUNT
2808         pool_add $pool || error "pool_add failed"
2809         pool_add_targets $pool $ostrange ||
2810                 error "pool_add_targets failed"
2811         test_mkdir $DIR/$tdir
2812         $LFS setstripe -p $pool $DIR/$tdir
2813         $MULTIOP $DIR/$tdir/$tfile Oc || error "multiop failed"
2814         $LFS getstripe $DIR/$tdir/$tfile
2815 }
2816 run_test 27I "check that root dir striping does not break parent dir one"
2817
2818 test_27J() {
2819         [[ $MDS1_VERSION -le $(version_code 2.12.51) ]] &&
2820                 skip "Need MDS version newer than 2.12.51"
2821
2822         test_mkdir $DIR/$tdir
2823         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2824         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2825
2826         # create foreign file (raw way)
2827         ! $LFS setstripe --flags 0xda08 $DIR/$tdir/$tfile ||
2828                 error "creating $tfile w/ hex flags w/o --foreign should fail"
2829
2830         ! $LFS setstripe --foreign --flags foo \
2831                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tfile ||
2832                         error "creating $tfile with '--flags foo' should fail"
2833
2834         ! $LFS setstripe --foreign --flags 0xffffffff \
2835                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tfile ||
2836                         error "creating $tfile w/ 0xffffffff flags should fail"
2837
2838         create_foreign_file -f $DIR/$tdir/$tfile -x "${uuid1}@${uuid2}" \
2839                 -t 1 -F 0xda08 || error "create_foreign_file failed"
2840
2841         # verify foreign file (raw way)
2842         parse_foreign_file -f $DIR/$tdir/$tfile |
2843                 grep "lov_foreign_magic: 0x0BD70BD0" ||
2844                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign magic"
2845         parse_foreign_file -f $DIR/$tdir/$tfile | grep "lov_xattr_size: 89" ||
2846                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2847         parse_foreign_file -f $DIR/$tdir/$tfile |
2848                 grep "lov_foreign_size: 73" ||
2849                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2850         parse_foreign_file -f $DIR/$tdir/$tfile |
2851                 grep "lov_foreign_type: 1" ||
2852                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign type"
2853         parse_foreign_file -f $DIR/$tdir/$tfile |
2854                 grep "lov_foreign_flags: 0x0000DA08" ||
2855                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign flags"
2856         local lov=$(parse_foreign_file -f $DIR/$tdir/$tfile |
2857                 grep "lov_foreign_value: 0x" |
2858                 sed -e 's/lov_foreign_value: 0x//')
2859         local lov2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160)
2860         [[ $lov = ${lov2// /} ]] ||
2861                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign value"
2862
2863         # create foreign file (lfs + API)
2864         $LFS setstripe --foreign=none --flags 0xda08 \
2865                 -x "${uuid1}@${uuid2}" $DIR/$tdir/${tfile}2 ||
2866                 error "$DIR/$tdir/${tfile}2: create failed"
2867
2868         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2869                 grep "lfm_magic:.*0x0BD70BD0" ||
2870                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign magic"
2871         # lfm_length is LOV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2872         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_length:.*73" ||
2873                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign size"
2874         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_type:.*none" ||
2875                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign type"
2876         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2877                 grep "lfm_flags:.*0x0000DA08" ||
2878                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign flags"
2879         $LFS getstripe $DIR/$tdir/${tfile}2 |
2880                 grep "lfm_value:.*${uuid1}@${uuid2}" ||
2881                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign value"
2882
2883         # modify striping should fail
2884         $LFS setstripe -c 2 $DIR/$tdir/$tfile &&
2885                 error "$DIR/$tdir/$tfile: setstripe should fail"
2886         $LFS setstripe -c 2 $DIR/$tdir/${tfile}2 &&
2887                 error "$DIR/$tdir/${tfile}2: setstripe should fail"
2888
2889         # R/W should fail
2890         cat $DIR/$tdir/$tfile && error "$DIR/$tdir/$tfile: read should fail"
2891         cat $DIR/$tdir/${tfile}2 &&
2892                 error "$DIR/$tdir/${tfile}2: read should fail"
2893         cat /etc/passwd > $DIR/$tdir/$tfile &&
2894                 error "$DIR/$tdir/$tfile: write should fail"
2895         cat /etc/passwd > $DIR/$tdir/${tfile}2 &&
2896                 error "$DIR/$tdir/${tfile}2: write should fail"
2897
2898         # chmod should work
2899         chmod 222 $DIR/$tdir/$tfile ||
2900                 error "$DIR/$tdir/$tfile: chmod failed"
2901         chmod 222 $DIR/$tdir/${tfile}2 ||
2902                 error "$DIR/$tdir/${tfile}2: chmod failed"
2903
2904         # chown should work
2905         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tfile ||
2906                 error "$DIR/$tdir/$tfile: chown failed"
2907         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tfile}2 ||
2908                 error "$DIR/$tdir/${tfile}2: chown failed"
2909
2910         # rename should work
2911         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}.new ||
2912                 error "$DIR/$tdir/$tfile: rename of foreign file has failed"
2913         mv $DIR/$tdir/${tfile}2 $DIR/$tdir/${tfile}2.new ||
2914                 error "$DIR/$tdir/${tfile}2: rename of foreign file has failed"
2915
2916         #remove foreign file
2917         rm $DIR/$tdir/${tfile}.new ||
2918                 error "$DIR/$tdir/${tfile}.new: remove of foreign file has failed"
2919         rm $DIR/$tdir/${tfile}2.new ||
2920                 error "$DIR/$tdir/${tfile}2.new: remove of foreign file has failed"
2921 }
2922 run_test 27J "basic ops on file with foreign LOV"
2923
2924 test_27K() {
2925         [[ $MDS1_VERSION -le $(version_code 2.12.49) ]] &&
2926                 skip "Need MDS version newer than 2.12.49"
2927
2928         test_mkdir $DIR/$tdir
2929         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2930         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2931
2932         # create foreign dir (raw way)
2933         ! $LFS setdirstripe --flags 0xda08 $DIR/$tdir/$tdir ||
2934                 error "creating $tdir w/ hex flags w/o --foreign should fail"
2935
2936         ! $LFS setdirstripe --foreign --flags foo \
2937                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tdir ||
2938                         error "creating $tdir with '--flags foo' should fail"
2939
2940         ! $LFS setdirstripe --foreign --flags 0xffffffff \
2941                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tdir ||
2942                         error "creating $tdir w/ 0xffffffff flags should fail"
2943
2944         create_foreign_dir -d $DIR/$tdir/$tdir -x "${uuid1}@${uuid2}" -t 1 ||
2945                 error "create_foreign_dir FAILED"
2946
2947         # verify foreign dir (raw way)
2948         parse_foreign_dir -d $DIR/$tdir/$tdir |
2949                 grep "lmv_foreign_magic:.*0xcd50cd0" ||
2950                 error "$DIR/$tdir/$tfile: invalid LMV EA magic"
2951         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_xattr_size:.*89$" ||
2952                 error "$DIR/$tdir/$tdir: invalid LMV EA size"
2953         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_foreign_type: 1$" ||
2954                 error "$DIR/$tdir/$tdir: invalid LMV EA type"
2955         parse_foreign_dir -d $DIR/$tdir/$tdir |
2956                 grep "lmv_foreign_flags: 55813$" ||
2957                 error "$DIR/$tdir/$tdir: invalid LMV EA flags"
2958         local lmv=$(parse_foreign_dir -d $DIR/$tdir/$tdir |
2959                 grep "lmv_foreign_value: 0x" |
2960                 sed 's/lmv_foreign_value: 0x//')
2961         local lmv2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160 |
2962                 sed 's/ //g')
2963         [[ $lmv == $lmv2 ]] || error "$DIR/$tdir/$tdir: invalid LMV EA value"
2964
2965         # create foreign dir (lfs + API)
2966         $LFS mkdir --foreign=none --xattr="${uuid1}@${uuid2}" --flags=0xda05 \
2967                 $DIR/$tdir/${tdir}2 ||
2968                 error "$DIR/$tdir/${tdir}2: create failed"
2969
2970         $LFS getdirstripe -v $DIR/$tdir/${tdir}2
2971
2972         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2973                 grep "lfm_magic:.*0x0CD50CD0" ||
2974                 error "$DIR/$tdir/${tdir}2: invalid LMV EA magic"
2975         # lfm_length is LMV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2976         # - sizeof(lfm_type) - sizeof(lfm_flags)
2977         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_length:.*73" ||
2978                 error "$DIR/$tdir/${tdir}2: invalid LMV EA size"
2979         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_type:.*none" ||
2980                 error "$DIR/$tdir/${tdir}2: invalid LMV EA type"
2981         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2982                 grep "lfm_flags:.*0x0000DA05" ||
2983                 error "$DIR/$tdir/${tdir}2: invalid LMV EA flags"
2984         $LFS getdirstripe $DIR/$tdir/${tdir}2 |
2985                 grep "lfm_value.*${uuid1}@${uuid2}" ||
2986                 error "$DIR/$tdir/${tdir}2: invalid LMV EA value"
2987
2988         # file create in dir should fail
2989         touch $DIR/$tdir/$tdir/$tfile && error "$DIR/$tdir: file create should fail"
2990         touch $DIR/$tdir/${tdir}2/$tfile &&
2991                 error "$DIR/${tdir}2: file create should fail"
2992
2993         # chmod should work
2994         chmod 777 $DIR/$tdir/$tdir ||
2995                 error "$DIR/$tdir: chmod failed"
2996         chmod 777 $DIR/$tdir/${tdir}2 ||
2997                 error "$DIR/${tdir}2: chmod failed"
2998
2999         # chown should work
3000         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tdir ||
3001                 error "$DIR/$tdir: chown failed"
3002         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tdir}2 ||
3003                 error "$DIR/${tdir}2: chown failed"
3004
3005         # rename should work
3006         mv $DIR/$tdir/$tdir $DIR/$tdir/${tdir}.new ||
3007                 error "$DIR/$tdir/$tdir: rename of foreign dir has failed"
3008         mv $DIR/$tdir/${tdir}2 $DIR/$tdir/${tdir}2.new ||
3009                 error "$DIR/$tdir/${tdir}2: rename of foreign dir has failed"
3010
3011         #remove foreign dir
3012         rmdir $DIR/$tdir/${tdir}.new ||
3013                 error "$DIR/$tdir/${tdir}.new: remove of foreign dir has failed"
3014         rmdir $DIR/$tdir/${tdir}2.new ||
3015                 error "$DIR/$tdir/${tdir}2.new: remove of foreign dir has failed"
3016 }
3017 run_test 27K "basic ops on dir with foreign LMV"
3018
3019 test_27L() {
3020         remote_mds_nodsh && skip "remote MDS with nodsh"
3021
3022         local POOL=${POOL:-$TESTNAME}
3023
3024         pool_add $POOL || error "pool_add failed"
3025
3026         lfs pool_list $MOUNT | grep -Fx "${FSNAME}.${POOL}" ||
3027                  error "pool_list does not contain ${FSNAME}.${POOL}:" \
3028                        "$(lfs pool_list $MOUNT | grep -F "${POOL}")"
3029 }
3030 run_test 27L "lfs pool_list gives correct pool name"
3031
3032 test_27M() {
3033         [[ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.12.57) ]] &&
3034                 skip "Need MDS version >= than 2.12.57"
3035         remote_mds_nodsh && skip "remote MDS with nodsh"
3036         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
3037
3038         # Set default striping on directory
3039         local setcount=4
3040         local stripe_opt
3041         local mdts=$(comma_list $(mdts_nodes))
3042
3043         # if we run against a 2.12 server which lacks overstring support
3044         # then the connect_flag will not report overstriping, even if client
3045         # is 2.14+
3046         if [[ $($LCTL get_param mdc.*.connect_flags) =~ overstriping ]]; then
3047                 stripe_opt="-C $setcount"
3048         elif (( $OSTCOUNT >= $setcount )); then
3049                 stripe_opt="-c $setcount"
3050         else
3051                 skip "server does not support overstriping"
3052         fi
3053
3054         test_mkdir $DIR/$tdir
3055
3056         # Validate existing append_* params and ensure restore
3057         local pool=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_pool)
3058         [[ "$pool" == "" ]] || error "expected append_pool == '', got '$pool'"
3059         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_pool=none"
3060
3061         local orig_count=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_stripe_count)
3062         ((orig_count == 1)) || error "expected append_stripe_count == 1, got $orig_count"
3063         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=1"
3064
3065         $LFS setstripe $stripe_opt $DIR/$tdir
3066
3067         echo 1 > $DIR/$tdir/${tfile}.1
3068         local count=$($LFS getstripe -c $DIR/$tdir/${tfile}.1)
3069         [ $count -eq $setcount ] ||
3070                 error "(1) stripe count $count, should be $setcount"
3071
3072         local appendcount=$orig_count
3073         echo 1 >> $DIR/$tdir/${tfile}.2_append
3074         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.2_append)
3075         [ $count -eq $appendcount ] ||
3076                 error "(2)stripe count $count, should be $appendcount for append"
3077
3078         # Disable O_APPEND striping, verify it works
3079         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
3080
3081         # Should now get the default striping, which is 4
3082         setcount=4
3083         echo 1 >> $DIR/$tdir/${tfile}.3_append
3084         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.3_append)
3085         [ $count -eq $setcount ] ||
3086                 error "(3) stripe count $count, should be $setcount"
3087
3088         # Try changing the stripe count for append files
3089         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=2
3090
3091         # Append striping is now 2 (directory default is still 4)
3092         appendcount=2
3093         echo 1 >> $DIR/$tdir/${tfile}.4_append
3094         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.4_append)
3095         [ $count -eq $appendcount ] ||
3096                 error "(4) stripe count $count, should be $appendcount for append"
3097
3098         # Test append stripe count of -1
3099         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=-1
3100         appendcount=$OSTCOUNT
3101         echo 1 >> $DIR/$tdir/${tfile}.5
3102         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.5)
3103         [ $count -eq $appendcount ] ||
3104                 error "(5) stripe count $count, should be $appendcount for append"
3105
3106         # Set append striping back to default of 1
3107         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=1
3108
3109         # Try a new default striping, PFL + DOM
3110         $LFS setstripe -L mdt -E 1M -E -1 -c 2 $DIR/$tdir
3111
3112         # Create normal DOM file, DOM returns stripe count == 0
3113         setcount=0
3114         touch $DIR/$tdir/${tfile}.6
3115         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.6)
3116         [ $count -eq $setcount ] ||
3117                 error "(6) stripe count $count, should be $setcount"
3118
3119         # Show
3120         appendcount=1
3121         echo 1 >> $DIR/$tdir/${tfile}.7_append
3122         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.7_append)
3123         [ $count -eq $appendcount ] ||
3124                 error "(7) stripe count $count, should be $appendcount for append"
3125
3126         # Clean up DOM layout
3127         $LFS setstripe -d $DIR/$tdir
3128
3129         save_layout_restore_at_exit $MOUNT
3130         # Now test that append striping works when layout is from root
3131         $LFS setstripe -c 2 $MOUNT
3132         # Make a special directory for this
3133         mkdir $DIR/${tdir}/${tdir}.2
3134
3135         # Verify for normal file
3136         setcount=2
3137         echo 1 > $DIR/${tdir}/${tdir}.2/${tfile}.8
3138         count=$($LFS getstripe -c $DIR/$tdir/${tdir}.2/${tfile}.8)
3139         [ $count -eq $setcount ] ||
3140                 error "(8) stripe count $count, should be $setcount"
3141
3142         appendcount=1
3143         echo 1 >> $DIR/${tdir}/${tdir}.2/${tfile}.9_append
3144         count=$($LFS getstripe -c $DIR/${tdir}/${tdir}.2/${tfile}.9_append)
3145         [ $count -eq $appendcount ] ||
3146                 error "(9) stripe count $count, should be $appendcount for append"
3147
3148         # Now test O_APPEND striping with pools
3149         pool_add $TESTNAME || error "pool creation failed"
3150         pool_add_targets $TESTNAME 0 1 || error "Pool add targets failed"
3151         do_nodes $mdts $LCTL set_param mdd.*.append_pool="$TESTNAME"
3152
3153         echo 1 >> $DIR/$tdir/${tfile}.10_append
3154
3155         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.10_append)
3156         [ "$pool" = "$TESTNAME" ] || error "(10) incorrect pool: $pool"
3157
3158         # Check that count is still correct
3159         appendcount=1
3160         echo 1 >> $DIR/$tdir/${tfile}.11_append
3161         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.11_append)
3162         [ $count -eq $appendcount ] ||
3163                 error "(11) stripe count $count, should be $appendcount for append"
3164
3165         # Disable O_APPEND stripe count, verify pool works separately
3166         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
3167
3168         echo 1 >> $DIR/$tdir/${tfile}.12_append
3169
3170         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.12_append)
3171         [ "$pool" = "$TESTNAME" ] || error "(12) incorrect pool: $pool"
3172
3173         # Remove pool setting, verify it's not applied
3174         do_nodes $mdts $LCTL set_param mdd.*.append_pool='none'
3175
3176         echo 1 >> $DIR/$tdir/${tfile}.13_append
3177
3178         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.13_append)
3179         [ "$pool" = "" ] || error "(13) pool found: $pool"
3180 }
3181 run_test 27M "test O_APPEND striping"
3182
3183 test_27N() {
3184         combined_mgs_mds && skip "needs separate MGS/MDT"
3185
3186         pool_add $TESTNAME || error "pool_add failed"
3187         do_facet mgs "$LCTL pool_list $FSNAME" |
3188                 grep -Fx "${FSNAME}.${TESTNAME}" ||
3189                 error "lctl pool_list on MGS failed"
3190 }
3191 run_test 27N "lctl pool_list on separate MGS gives correct pool name"
3192
3193 clean_foreign_symlink() {
3194         trap 0
3195         lctl set_param llite/$FSNAME-*/foreign_symlink_enable=0
3196         for i in $DIR/$tdir/* ; do
3197                 $LFS unlink_foreign $i || true
3198         done
3199 }
3200
3201 test_27O() {
3202         [[ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.12.51) ]] &&
3203                 skip "Need MDS version newer than 2.12.51"
3204
3205         test_mkdir $DIR/$tdir
3206         local uuid1=$(cat /proc/sys/kernel/random/uuid)
3207         local uuid2=$(cat /proc/sys/kernel/random/uuid)
3208
3209         trap clean_foreign_symlink EXIT
3210
3211         # enable foreign_symlink behaviour
3212         $LCTL set_param llite/$FSNAME-*/foreign_symlink_enable=1
3213
3214         # foreign symlink LOV format is a partial path by default
3215
3216         # create foreign file (lfs + API)
3217         $LFS setstripe --foreign=symlink --flags 0xda05 \
3218                 -x "${uuid1}/${uuid2}" --mode 0600 $DIR/$tdir/${tfile} ||
3219                 error "$DIR/$tdir/${tfile}: create failed"
3220
3221         $LFS getstripe -v $DIR/$tdir/${tfile} |
3222                 grep "lfm_magic:.*0x0BD70BD0" ||
3223                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign magic"
3224         $LFS getstripe -v $DIR/$tdir/${tfile} | grep "lfm_type:.*symlink" ||
3225                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign type"
3226         $LFS getstripe -v $DIR/$tdir/${tfile} |
3227                 grep "lfm_flags:.*0x0000DA05" ||
3228                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign flags"
3229         $LFS getstripe $DIR/$tdir/${tfile} |
3230                 grep "lfm_value:.*${uuid1}/${uuid2}" ||
3231                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign value"
3232
3233         # modify striping should fail
3234         $LFS setstripe -c 2 $DIR/$tdir/$tfile &&
3235                 error "$DIR/$tdir/$tfile: setstripe should fail"
3236
3237         # R/W should fail ("/{foreign_symlink_prefix}/${uuid1}/" missing)
3238         cat $DIR/$tdir/$tfile && error "$DIR/$tdir/$tfile: read should fail"
3239         cat /etc/passwd > $DIR/$tdir/$tfile &&
3240                 error "$DIR/$tdir/$tfile: write should fail"
3241
3242         # rename should succeed
3243         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}.new ||
3244                 error "$DIR/$tdir/$tfile: rename has failed"
3245
3246         #remove foreign_symlink file should fail
3247         rm $DIR/$tdir/${tfile}.new &&
3248                 error "$DIR/$tdir/${tfile}.new: remove of foreign_symlink file should fail"
3249
3250         #test fake symlink
3251         mkdir /tmp/${uuid1} ||
3252                 error "/tmp/${uuid1}: mkdir has failed"
3253         echo FOOFOO > /tmp/${uuid1}/${uuid2} ||
3254                 error "/tmp/${uuid1}/${uuid2}: echo has failed"
3255         $LCTL set_param llite/$FSNAME-*/foreign_symlink_prefix=/tmp/
3256         $CHECKSTAT -t link -l /tmp/${uuid1}/${uuid2} $DIR/$tdir/${tfile}.new ||
3257                 error "$DIR/$tdir/${tfile}.new: not seen as a symlink"
3258         #read should succeed now
3259         cat $DIR/$tdir/${tfile}.new | grep FOOFOO ||
3260                 error "$DIR/$tdir/${tfile}.new: symlink resolution has failed"
3261         #write should succeed now
3262         cat /etc/passwd > $DIR/$tdir/${tfile}.new ||
3263                 error "$DIR/$tdir/${tfile}.new: write should succeed"
3264         diff /etc/passwd $DIR/$tdir/${tfile}.new ||
3265                 error "$DIR/$tdir/${tfile}.new: diff has failed"
3266         diff /etc/passwd /tmp/${uuid1}/${uuid2} ||
3267                 error "/tmp/${uuid1}/${uuid2}: diff has failed"
3268
3269         #check that getstripe still works
3270         $LFS getstripe $DIR/$tdir/${tfile}.new ||
3271                 error "$DIR/$tdir/${tfile}.new: getstripe should still work with foreign_symlink enabled"
3272
3273         # chmod should still succeed
3274         chmod 644 $DIR/$tdir/${tfile}.new ||
3275                 error "$DIR/$tdir/${tfile}.new: chmod has failed"
3276
3277         # chown should still succeed
3278         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tfile}.new ||
3279                 error "$DIR/$tdir/${tfile}.new: chown has failed"
3280
3281         # rename should still succeed
3282         mv $DIR/$tdir/${tfile}.new $DIR/$tdir/${tfile} ||
3283                 error "$DIR/$tdir/${tfile}.new: rename has failed"
3284
3285         #remove foreign_symlink file should still fail
3286         rm $DIR/$tdir/${tfile} &&
3287                 error "$DIR/$tdir/${tfile}: remove of foreign_symlink file should fail"
3288
3289         #use special ioctl() to unlink foreign_symlink file
3290         $LFS unlink_foreign $DIR/$tdir/${tfile} ||
3291                 error "$DIR/$tdir/$tfile: unlink/ioctl failed"
3292
3293 }
3294 run_test 27O "basic ops on foreign file of symlink type"
3295
3296 test_27P() {
3297         [[ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.12.49) ]] &&
3298                 skip "Need MDS version newer than 2.12.49"
3299
3300         test_mkdir $DIR/$tdir
3301         local uuid1=$(cat /proc/sys/kernel/random/uuid)
3302         local uuid2=$(cat /proc/sys/kernel/random/uuid)
3303
3304         trap clean_foreign_symlink EXIT
3305
3306         # enable foreign_symlink behaviour
3307         $LCTL set_param llite/$FSNAME-*/foreign_symlink_enable=1
3308
3309         # foreign symlink LMV format is a partial path by default
3310
3311         # create foreign dir (lfs + API)
3312         $LFS mkdir --foreign=symlink --xattr="${uuid1}/${uuid2}" \
3313                 --flags=0xda05 --mode 0750 $DIR/$tdir/${tdir} ||
3314                 error "$DIR/$tdir/${tdir}: create failed"
3315
3316         $LFS getdirstripe -v $DIR/$tdir/${tdir}
3317
3318         $LFS getdirstripe -v $DIR/$tdir/${tdir} |
3319                 grep "lfm_magic:.*0x0CD50CD0" ||
3320                 error "$DIR/$tdir/${tdir}: invalid LMV EA magic"
3321         $LFS getdirstripe -v $DIR/$tdir/${tdir} | grep "lfm_type:.*symlink" ||
3322                 error "$DIR/$tdir/${tdir}: invalid LMV EA type"
3323         $LFS getdirstripe -v $DIR/$tdir/${tdir} |
3324                 grep "lfm_flags:.*0x0000DA05" ||
3325                 error "$DIR/$tdir/${tdir}: invalid LMV EA flags"
3326         $LFS getdirstripe $DIR/$tdir/${tdir} |
3327                 grep "lfm_value.*${uuid1}/${uuid2}" ||
3328                 error "$DIR/$tdir/${tdir}: invalid LMV EA value"
3329
3330         # file create in dir should fail
3331         # ("/{foreign_symlink_prefix}/${uuid1}/${uuid2}/" missing)
3332         touch $DIR/$tdir/$tdir/$tfile && error "$DIR/$tdir: file create should fail"
3333
3334         # rename should succeed
3335         mv $DIR/$tdir/$tdir $DIR/$tdir/${tdir}.new ||
3336                 error "$DIR/$tdir/$tdir: rename of foreign_symlink dir has failed"
3337
3338         #remove foreign_symlink dir should fail
3339         rmdir $DIR/$tdir/${tdir}.new &&
3340                 error "$DIR/$tdir/${tdir}.new: remove of foreign_symlink dir should fail"
3341
3342         #test fake symlink
3343         mkdir -p /tmp/${uuid1}/${uuid2} ||
3344                 error "/tmp/${uuid1}/${uuid2}: mkdir has failed"
3345         echo FOOFOO > /tmp/${uuid1}/${uuid2}/foo ||
3346                 error "/tmp/${uuid1}/${uuid2}/foo: echo has failed"
3347         $LCTL set_param llite/$FSNAME-*/foreign_symlink_prefix=/tmp/
3348         $CHECKSTAT -t link -l /tmp/${uuid1}/${uuid2} $DIR/$tdir/${tdir}.new ||
3349                 error "$DIR/$tdir/${tdir}.new: not seen as a symlink"
3350         cat $DIR/$tdir/${tdir}.new/foo | grep FOOFOO ||
3351                 error "$DIR/$tdir/${tdir}.new: symlink resolution has failed"
3352
3353         #check that getstripe fails now that foreign_symlink enabled
3354         $LFS getdirstripe $DIR/$tdir/${tdir}.new ||
3355                 error "$DIR/$tdir/${tdir}.new: getdirstripe should still work with foreign_symlink enabled"
3356
3357         # file create in dir should work now
3358         cp /etc/passwd $DIR/$tdir/${tdir}.new/$tfile ||
3359                 error "$DIR/$tdir/${tdir}.new/$tfile: file create should fail"
3360         diff /etc/passwd $DIR/$tdir/${tdir}.new/$tfile ||
3361                 error "$DIR/$tdir/${tdir}.new/$tfile: diff has failed"
3362         diff /etc/passwd /tmp/${uuid1}/${uuid2}/$tfile ||
3363                 error "/tmp/${uuid1}/${uuid2}/$tfile: diff has failed"
3364
3365         # chmod should still succeed
3366         chmod 755 $DIR/$tdir/${tdir}.new ||
3367                 error "$DIR/$tdir/${tdir}.new: chmod has failed"
3368
3369         # chown should still succeed
3370         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tdir}.new ||
3371                 error "$DIR/$tdir/${tdir}.new: chown has failed"
3372
3373         # rename should still succeed
3374         mv $DIR/$tdir/${tdir}.new $DIR/$tdir/${tdir} ||
3375                 error "$DIR/$tdir/${tdir}.new: rename of foreign_symlink dir has failed"
3376
3377         #remove foreign_symlink dir should still fail
3378         rmdir $DIR/$tdir/${tdir} &&
3379                 error "$DIR/$tdir/${tdir}: remove of foreign_symlink dir should fail"
3380
3381         #use special ioctl() to unlink foreign_symlink file
3382         $LFS unlink_foreign $DIR/$tdir/${tdir} ||
3383                 error "$DIR/$tdir/$tdir: unlink/ioctl failed"
3384
3385         #created file should still exist
3386         [[ -f /tmp/${uuid1}/${uuid2}/$tfile ]] ||
3387                 error "/tmp/${uuid1}/${uuid2}/$tfile has been removed"
3388         diff /etc/passwd /tmp/${uuid1}/${uuid2}/$tfile ||
3389                 error "/tmp/${uuid1}/${uuid2}/$tfile: diff has failed"
3390 }
3391 run_test 27P "basic ops on foreign dir of foreign_symlink type"
3392
3393 test_27Q() {
3394         rm -f $TMP/$tfile $TMP/$tfile.loop $TMP/$tfile.none $TMP/$tfile.broken
3395         stack_trap "rm -f $TMP/$tfile*"
3396
3397         test_mkdir $DIR/$tdir-1
3398         test_mkdir $DIR/$tdir-2
3399
3400         echo 'It is what it is' > $DIR/$tdir-1/$tfile
3401         lov_getstripe_old $DIR/$tdir-1/$tfile || error "$DIR/$tdir-1/$tfile: rc = $?"
3402
3403         ln -s $DIR/$tdir-1/$tfile $DIR/$tdir-2/$tfile
3404         lov_getstripe_old $DIR/$tdir-2/$tfile || error "$DIR/$tdir-2/$tfile: rc = $?"
3405
3406         ln -s $DIR/$tdir-1/$tfile $TMP/$tfile
3407         lov_getstripe_old $TMP/$tfile || error "$TMP/$tfile: rc = $?"
3408
3409         # Create some bad symlinks and ensure that we don't loop
3410         # forever or something. These should return ELOOP (40) and
3411         # ENOENT (2) but I don't want to test for that because there's
3412         # always some weirdo architecture that needs to ruin
3413         # everything by defining these error numbers differently.
3414
3415         ln -s $TMP/$tfile.loop $TMP/$tfile.loop
3416         lov_getstripe_old $TMP/$tfile.loop && error "$TMP/$tfile.loop: rc = $?"
3417
3418         ln -s $TMP/$tfile.none $TMP/$tfile.broken
3419         lov_getstripe_old $TMP/$tfile.broken && error "$TMP/$tfile.broken: rc = $?"
3420
3421         return 0
3422 }
3423 run_test 27Q "llapi_file_get_stripe() works on symlinks"
3424
3425 test_27R() {
3426         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
3427                 skip "need MDS 2.14.55 or later"
3428         (( $OSTCOUNT >= 2 )) || skip_env "needs at least 2 OSTs"
3429
3430         local testdir="$DIR/$tdir"
3431         test_mkdir -p $testdir
3432         stack_trap "rm -rf $testdir"
3433         $LFS setstripe -c -1 $testdir || error "setstripe failed"
3434
3435         local f1="$testdir/f1"
3436         touch $f1 || error "failed to touch $f1"
3437         local count=$($LFS getstripe -c $f1)
3438         (( $count == $OSTCOUNT )) || error "wrong stripe count"
3439
3440         do_facet $SINGLEMDS $LCTL set_param lod.*.max_stripecount=-1
3441         (( $? == 34 )) || error "setting max_stripecount to -1 should fail and return ERANGE"
3442
3443         local maxcount=$(($OSTCOUNT - 1))
3444         local mdts=$(comma_list $(mdts_nodes))
3445         do_nodes $mdts $LCTL set_param lod.*.max_stripecount=$maxcount
3446         stack_trap "do_nodes $mdts $LCTL set_param lod.*.max_stripecount=0"
3447
3448         local f2="$testdir/f2"
3449         touch $f2 || error "failed to touch $f2"
3450         local count=$($LFS getstripe -c $f2)
3451         (( $count == $maxcount )) || error "wrong stripe count"
3452 }
3453 run_test 27R "test max_stripecount limitation when stripe count is set to -1"
3454
3455 test_27T() {
3456         [ $(facet_host client) == $(facet_host ost1) ] &&
3457                 skip "need ost1 and client on different nodes"
3458
3459 #define OBD_FAIL_OSC_NO_GRANT            0x411
3460         $LCTL set_param fail_loc=0x20000411 fail_val=1
3461 #define OBD_FAIL_OST_ENOSPC              0x215
3462         do_facet ost1 "$LCTL set_param fail_loc=0x80000215"
3463         $LFS setstripe -i 0 -c 1 $DIR/$tfile
3464         $MULTIOP $DIR/$tfile oO_WRONLY:P$((4 * 1024 * 1024 + 10 * 4096))c ||
3465                 error "multiop failed"
3466 }
3467 run_test 27T "no eio on close on partial write due to enosp"
3468
3469 test_27U() {
3470         local dir=$DIR/$tdir
3471         local file=$dir/$tfile
3472         local append_pool=${TESTNAME}-append
3473         local normal_pool=${TESTNAME}-normal
3474         local pool
3475         local stripe_count
3476         local stripe_count2
3477         local mdts=$(comma_list $(mdts_nodes))
3478
3479         (( $MDS1_VERSION >= $(version_code 2.15.51) )) ||
3480                 skip "Need MDS version at least 2.15.51 for append pool feature"
3481
3482         # Validate existing append_* params and ensure restore
3483         pool=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_pool)
3484         [[ "$pool" == "" ]] || error "expected append_pool == '', got '$pool'"
3485         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_pool=none"
3486
3487         stripe_count=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_stripe_count)
3488         ((stripe_count == 1)) || error "expected append_stripe_count != 0, got $stripe_count"
3489         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=$stripe_count"
3490
3491         pool_add $append_pool || error "pool creation failed"
3492         pool_add_targets $append_pool 0 1 || error "Pool add targets failed"
3493
3494         pool_add $normal_pool || error "pool creation failed"
3495         pool_add_targets $normal_pool 0 1 || error "Pool add targets failed"
3496
3497         test_mkdir $dir
3498         $LFS setstripe -E 1M -c 1 -p $normal_pool -E 2M -c 2 -p $normal_pool -E eof -c -1 $dir
3499
3500         echo XXX >> $file.1
3501         $LFS getstripe $file.1
3502
3503         pool=$($LFS getstripe -p $file.1)
3504         [[ "$pool" == "$normal_pool" ]] || error "got pool '$pool', expected '$normal_pool'"
3505
3506         stripe_count2=$($LFS getstripe -c $file.1)
3507         ((stripe_count2 == stripe_count)) ||
3508                 error "got stripe_count '$stripe_count2', expected '$stripe_count'"
3509
3510         do_nodes $mdts $LCTL set_param mdd.*.append_pool=$append_pool
3511
3512         echo XXX >> $file.2
3513         $LFS getstripe $file.2
3514
3515         pool=$($LFS getstripe -p $file.2)
3516         [[ "$pool" == "$append_pool" ]] || error "got pool '$pool', expected '$append_pool'"
3517
3518         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=2
3519
3520         echo XXX >> $file.3
3521         $LFS getstripe $file.3
3522
3523         stripe_count2=$($LFS getstripe -c $file.3)
3524         ((stripe_count2 == 2)) || error "got stripe_count '$stripe_count2', expected 2"
3525 }
3526 run_test 27U "append pool and stripe count work with composite default layout"
3527
3528 # createtest also checks that device nodes are created and
3529 # then visible correctly (#2091)
3530 test_28() { # bug 2091
3531         test_mkdir $DIR/d28
3532         $CREATETEST $DIR/d28/ct || error "createtest failed"
3533 }
3534 run_test 28 "create/mknod/mkdir with bad file types ============"
3535
3536 test_29() {
3537         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3538
3539         [ $MDS1_VERSION -ge $(version_code 2.14.51) ] && {
3540                 disable_opencache
3541                 stack_trap "restore_opencache"
3542         }
3543
3544         sync; sleep 1; sync # flush out any dirty pages from previous tests
3545         cancel_lru_locks
3546         test_mkdir $DIR/d29
3547         touch $DIR/d29/foo
3548         log 'first d29'
3549         ls -l $DIR/d29
3550
3551         declare -i LOCKCOUNTORIG=0
3552         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
3553                 let LOCKCOUNTORIG=$LOCKCOUNTORIG+$lock_count
3554         done
3555         [ $LOCKCOUNTORIG -eq 0 ] && error "No mdc lock count" && return 1
3556
3557         declare -i LOCKUNUSEDCOUNTORIG=0
3558         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3559                 let LOCKUNUSEDCOUNTORIG=$LOCKUNUSEDCOUNTORIG+$unused_count
3560         done
3561
3562         log 'second d29'
3563         ls -l $DIR/d29
3564         log 'done'
3565
3566         declare -i LOCKCOUNTCURRENT=0
3567         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
3568                 let LOCKCOUNTCURRENT=$LOCKCOUNTCURRENT+$lock_count
3569         done
3570
3571         declare -i LOCKUNUSEDCOUNTCURRENT=0
3572         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3573                 let LOCKUNUSEDCOUNTCURRENT=$LOCKUNUSEDCOUNTCURRENT+$unused_count
3574         done
3575
3576         if [[ $LOCKCOUNTCURRENT -gt $LOCKCOUNTORIG ]]; then
3577                 $LCTL set_param -n ldlm.dump_namespaces ""
3578                 error "CURRENT: $LOCKCOUNTCURRENT > $LOCKCOUNTORIG"
3579                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3580                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3581                 return 2
3582         fi
3583         if [[ $LOCKUNUSEDCOUNTCURRENT -gt $LOCKUNUSEDCOUNTORIG ]]; then
3584                 error "UNUSED: $LOCKUNUSEDCOUNTCURRENT > $LOCKUNUSEDCOUNTORIG"
3585                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3586                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3587                 return 3
3588         fi
3589 }
3590 run_test 29 "IT_GETATTR regression  ============================"
3591
3592 test_30a() { # was test_30
3593         cp $(which ls) $DIR || cp /bin/ls $DIR
3594         $DIR/ls / || error "Can't execute binary from lustre"
3595         rm $DIR/ls
3596 }
3597 run_test 30a "execute binary from Lustre (execve) =============="
3598
3599 test_30b() {
3600         cp `which ls` $DIR || cp /bin/ls $DIR
3601         chmod go+rx $DIR/ls
3602         $RUNAS $DIR/ls / || error "Can't execute binary from lustre as non-root"
3603         rm $DIR/ls
3604 }
3605 run_test 30b "execute binary from Lustre as non-root ==========="
3606
3607 test_30c() { # b=22376
3608         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3609
3610         cp $(which ls) $DIR || cp /bin/ls $DIR
3611         chmod a-rw $DIR/ls
3612         cancel_lru_locks mdc
3613         cancel_lru_locks osc
3614         $RUNAS $DIR/ls / || error "Can't execute binary from lustre"
3615         rm -f $DIR/ls
3616 }
3617 run_test 30c "execute binary from Lustre without read perms ===="
3618
3619 test_30d() {
3620         cp $(which dd) $DIR || error "failed to copy dd to $DIR/dd"
3621
3622         for i in {1..10}; do
3623                 $DIR/dd bs=1M count=128 if=/dev/zero of=$DIR/$tfile &
3624                 local PID=$!
3625                 sleep 1
3626                 $LCTL set_param ldlm.namespaces.*MDT*.lru_size=clear
3627                 wait $PID || error "executing dd from Lustre failed"
3628                 rm -f $DIR/$tfile
3629         done
3630
3631         rm -f $DIR/dd
3632 }
3633 run_test 30d "execute binary from Lustre while clear locks"
3634
3635 test_31a() {
3636         $OPENUNLINK $DIR/f31 $DIR/f31 || error "openunlink failed"
3637         $CHECKSTAT -a $DIR/f31 || error "$DIR/f31 exists"
3638 }
3639 run_test 31a "open-unlink file =================================="
3640
3641 test_31b() {
3642         touch $DIR/f31 || error "touch $DIR/f31 failed"
3643         ln $DIR/f31 $DIR/f31b || error "ln failed"
3644         $MULTIOP $DIR/f31b Ouc || error "multiop failed"
3645         $CHECKSTAT -t file $DIR/f31 || error "$DIR/f31 not file type"
3646 }
3647 run_test 31b "unlink file with multiple links while open ======="
3648
3649 test_31c() {
3650         touch $DIR/f31 || error "touch $DIR/f31 failed"
3651         ln $DIR/f31 $DIR/f31c || error "ln failed"
3652         multiop_bg_pause $DIR/f31 O_uc ||
3653                 error "multiop_bg_pause for $DIR/f31 failed"
3654         MULTIPID=$!
3655         $MULTIOP $DIR/f31c Ouc
3656         kill -USR1 $MULTIPID
3657         wait $MULTIPID
3658 }
3659 run_test 31c "open-unlink file with multiple links ============="
3660
3661 test_31d() {
3662         opendirunlink $DIR/d31d $DIR/d31d || error "opendirunlink failed"
3663         $CHECKSTAT -a $DIR/d31d || error "$DIR/d31d exists"
3664 }
3665 run_test 31d "remove of open directory ========================="
3666
3667 test_31e() { # bug 2904
3668         openfilleddirunlink $DIR/d31e || error "openfilleddirunlink failed"
3669 }
3670 run_test 31e "remove of open non-empty directory ==============="
3671
3672 test_31f() { # bug 4554
3673         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3674
3675         set -vx
3676         test_mkdir $DIR/d31f
3677         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3678         cp /etc/hosts $DIR/d31f
3679         ls -l $DIR/d31f
3680         $LFS getstripe $DIR/d31f/hosts
3681         multiop_bg_pause $DIR/d31f D_c || return 1
3682         MULTIPID=$!
3683
3684         rm -rv $DIR/d31f || error "first of $DIR/d31f"
3685         test_mkdir $DIR/d31f
3686         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3687         cp /etc/hosts $DIR/d31f
3688         ls -l $DIR/d31f
3689         $LFS getstripe $DIR/d31f/hosts
3690         multiop_bg_pause $DIR/d31f D_c || return 1
3691         MULTIPID2=$!
3692
3693         kill -USR1 $MULTIPID || error "first opendir $MULTIPID not running"
3694         wait $MULTIPID || error "first opendir $MULTIPID failed"
3695
3696         sleep 6
3697
3698         kill -USR1 $MULTIPID2 || error "second opendir $MULTIPID not running"
3699         wait $MULTIPID2 || error "second opendir $MULTIPID2 failed"
3700         set +vx
3701 }
3702 run_test 31f "remove of open directory with open-unlink file ==="
3703
3704 test_31g() {
3705         echo "-- cross directory link --"
3706         test_mkdir -c1 $DIR/${tdir}ga
3707         test_mkdir -c1 $DIR/${tdir}gb
3708         touch $DIR/${tdir}ga/f
3709         ln $DIR/${tdir}ga/f $DIR/${tdir}gb/g
3710         $CHECKSTAT -t file $DIR/${tdir}ga/f || error "source"
3711         [ `stat -c%h $DIR/${tdir}ga/f` == '2' ] || error "source nlink"
3712         $CHECKSTAT -t file $DIR/${tdir}gb/g || error "target"
3713         [ `stat -c%h $DIR/${tdir}gb/g` == '2' ] || error "target nlink"
3714 }
3715 run_test 31g "cross directory link==============="
3716
3717 test_31h() {
3718         echo "-- cross directory link --"
3719         test_mkdir -c1 $DIR/${tdir}
3720         test_mkdir -c1 $DIR/${tdir}/dir
3721         touch $DIR/${tdir}/f
3722         ln $DIR/${tdir}/f $DIR/${tdir}/dir/g
3723         $CHECKSTAT -t file $DIR/${tdir}/f || error "source"
3724         [ `stat -c%h $DIR/${tdir}/f` == '2' ] || error "source nlink"
3725         $CHECKSTAT -t file $DIR/${tdir}/dir/g || error "target"
3726         [ `stat -c%h $DIR/${tdir}/dir/g` == '2' ] || error "target nlink"
3727 }
3728 run_test 31h "cross directory link under child==============="
3729
3730 test_31i() {
3731         echo "-- cross directory link --"
3732         test_mkdir -c1 $DIR/$tdir
3733         test_mkdir -c1 $DIR/$tdir/dir
3734         touch $DIR/$tdir/dir/f
3735         ln $DIR/$tdir/dir/f $DIR/$tdir/g
3736         $CHECKSTAT -t file $DIR/$tdir/dir/f || error "source"
3737         [ `stat -c%h $DIR/$tdir/dir/f` == '2' ] || error "source nlink"
3738         $CHECKSTAT -t file $DIR/$tdir/g || error "target"
3739         [ `stat -c%h $DIR/$tdir/g` == '2' ] || error "target nlink"
3740 }
3741 run_test 31i "cross directory link under parent==============="
3742
3743 test_31j() {
3744         test_mkdir -c1 -p $DIR/$tdir
3745         test_mkdir -c1 -p $DIR/$tdir/dir1
3746         ln $DIR/$tdir/dir1 $DIR/$tdir/dir2 && error "ln for dir"
3747         link $DIR/$tdir/dir1 $DIR/$tdir/dir3 && error "link for dir"
3748         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir4 && error "mlink for dir"
3749         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir1 && error "mlink to the same dir"
3750         return 0
3751 }
3752 run_test 31j "link for directory==============="
3753
3754 test_31k() {
3755         test_mkdir -c1 -p $DIR/$tdir
3756         touch $DIR/$tdir/s
3757         touch $DIR/$tdir/exist
3758         mlink $DIR/$tdir/s $DIR/$tdir/t || error "mlink"
3759         mlink $DIR/$tdir/s $DIR/$tdir/exist && error "mlink to exist file"
3760         mlink $DIR/$tdir/s $DIR/$tdir/s && error "mlink to the same file"
3761         mlink $DIR/$tdir/s $DIR/$tdir && error "mlink to parent dir"
3762         mlink $DIR/$tdir $DIR/$tdir/s && error "mlink parent dir to target"
3763         mlink $DIR/$tdir/not-exist $DIR/$tdir/foo && error "mlink non-existing to new"
3764         mlink $DIR/$tdir/not-exist $DIR/$tdir/s && error "mlink non-existing to exist"
3765         return 0
3766 }
3767 run_test 31k "link to file: the same, non-existing, dir==============="
3768
3769 test_31l() {
3770         local ln_ver=$(ln --version | awk '/coreutils/ { print $4 }')
3771
3772         (( $(version_code $ln_ver) < $(version_code 8.31) )) ||
3773         (( $(version_code $(uname -r)) >= $(version_code 5.18) )) ||
3774                 skip "need coreutils < 8.31 or kernel >= 5.18 for ln"
3775
3776         touch $DIR/$tfile || error "create failed"
3777         mkdir $DIR/$tdir || error "mkdir failed"
3778         ln $DIR/$tfile $DIR/$tdir/ || error "ln to '$tdir/' failed"
3779 }
3780 run_test 31l "link to file: target dir has trailing slash"
3781
3782 test_31m() {
3783         mkdir $DIR/d31m
3784         touch $DIR/d31m/s
3785         mkdir $DIR/d31m2
3786         touch $DIR/d31m2/exist
3787         mlink $DIR/d31m/s $DIR/d31m2/t || error "mlink"
3788         mlink $DIR/d31m/s $DIR/d31m2/exist && error "mlink to exist file"
3789         mlink $DIR/d31m/s $DIR/d31m2 && error "mlink to parent dir"
3790         mlink $DIR/d31m2 $DIR/d31m/s && error "mlink parent dir to target"
3791         mlink $DIR/d31m/not-exist $DIR/d31m2/foo && error "mlink non-existing to new"
3792         mlink $DIR/d31m/not-exist $DIR/d31m2/s && error "mlink non-existing to exist"
3793         return 0
3794 }
3795 run_test 31m "link to file: the same, non-existing, dir==============="
3796
3797 test_31n() {
3798         touch $DIR/$tfile || error "cannot create '$DIR/$tfile'"
3799         nlink=$(stat --format=%h $DIR/$tfile)
3800         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3801         local fd=$(free_fd)
3802         local cmd="exec $fd<$DIR/$tfile"
3803         eval $cmd
3804         cmd="exec $fd<&-"
3805         trap "eval $cmd" EXIT
3806         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3807         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3808         rm $DIR/$tfile || error "cannot remove '$DIR/$tfile'"
3809         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3810         [ ${nlink:--1} -eq 0 ] || error "nlink is $nlink, expected 0"
3811         eval $cmd
3812 }
3813 run_test 31n "check link count of unlinked file"
3814
3815 link_one() {
3816         local tempfile=$(mktemp $1_XXXXXX)
3817         mlink $tempfile $1 2> /dev/null &&
3818                 echo "$BASHPID: link $tempfile to $1 succeeded"
3819         munlink $tempfile
3820 }
3821
3822 test_31o() { # LU-2901
3823         test_mkdir $DIR/$tdir
3824         for LOOP in $(seq 100); do
3825                 rm -f $DIR/$tdir/$tfile*
3826                 for THREAD in $(seq 8); do
3827                         link_one $DIR/$tdir/$tfile.$LOOP &
3828                 done
3829                 wait
3830                 local LINKS=$(ls -1 $DIR/$tdir | grep -c $tfile.$LOOP)
3831                 [[ $LINKS -gt 1 ]] && ls $DIR/$tdir &&
3832                         error "$LINKS duplicate links to $tfile.$LOOP" &&
3833                         break || true
3834         done
3835 }
3836 run_test 31o "duplicate hard links with same filename"
3837
3838 test_31p() {
3839         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3840
3841         test_mkdir $DIR/$tdir
3842         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3843         $LFS setdirstripe -D -c2 -H all_char $DIR/$tdir/striped_dir
3844
3845         opendirunlink $DIR/$tdir/striped_dir/test1 ||
3846                 error "open unlink test1 failed"
3847         opendirunlink $DIR/$tdir/striped_dir/test2 ||
3848                 error "open unlink test2 failed"
3849
3850         $CHECKSTAT -a $DIR/$tdir/striped_dir/test1 ||
3851                 error "test1 still exists"
3852         $CHECKSTAT -a $DIR/$tdir/striped_dir/test2 ||
3853                 error "test2 still exists"
3854 }
3855 run_test 31p "remove of open striped directory"
3856
3857 test_31q() {
3858         [ $MDSCOUNT -lt 3 ] && skip_env "needs >= 3 MDTs"
3859
3860         $LFS mkdir -i 3,1 $DIR/$tdir || error "mkdir failed"
3861         index=$($LFS getdirstripe -i $DIR/$tdir)
3862         [ $index -eq 3 ] || error "first stripe index $index != 3"
3863         index=$($LFS getdirstripe $DIR/$tdir | tail -1 | awk '{print $1}')
3864         [ $index -eq 1 ] || error "second stripe index $index != 1"
3865
3866         # when "-c <stripe_count>" is set, the number of MDTs specified after
3867         # "-i" should equal to the stripe count
3868         $LFS mkdir -i 3,1 -c 3 $DIR/$tdir.2 && error "mkdir should fail" || true
3869 }
3870 run_test 31q "create striped directory on specific MDTs"
3871
3872 #LU-14949
3873 test_31r() {
3874         touch $DIR/$tfile.target
3875         touch $DIR/$tfile.source
3876
3877         #OBD_FAIL_LLITE_OPEN_DELAY 0x1419
3878         $LCTL set_param fail_loc=0x1419 fail_val=3
3879         cat $DIR/$tfile.target &
3880         CATPID=$!
3881
3882         # Guarantee open is waiting before we get here
3883         sleep 1
3884         mv $DIR/$tfile.source $DIR/$tfile.target
3885
3886         wait $CATPID
3887         RC=$?
3888         if [[ $RC -ne 0 ]]; then
3889                 error "open with cat failed, rc=$RC"
3890         fi
3891 }
3892 run_test 31r "open-rename(replace) race"
3893
3894 cleanup_test32_mount() {
3895         local rc=0
3896         trap 0
3897         local loopdev=$(losetup -a | grep $EXT2_DEV | sed -ne 's/:.*$//p')
3898         $UMOUNT $DIR/$tdir/ext2-mountpoint || rc=$?
3899         losetup -d $loopdev || true
3900         rm -rf $DIR/$tdir
3901         return $rc
3902 }
3903
3904 test_32a() {
3905         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3906
3907         echo "== more mountpoints and symlinks ================="
3908         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3909         trap cleanup_test32_mount EXIT
3910         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3911         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3912                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3913         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/.. ||
3914                 error "$DIR/$tdir/ext2-mountpoint/.. not dir type"
3915         cleanup_test32_mount
3916 }
3917 run_test 32a "stat d32a/ext2-mountpoint/.. ====================="
3918
3919 test_32b() {
3920         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3921
3922         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3923         trap cleanup_test32_mount EXIT
3924         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3925         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3926                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3927         ls -al $DIR/$tdir/ext2-mountpoint/.. ||
3928                 error "Can't list $DIR/$tdir/ext2-mountpoint/.."
3929         cleanup_test32_mount
3930 }
3931 run_test 32b "open d32b/ext2-mountpoint/.. ====================="
3932
3933 test_32c() {
3934         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3935
3936         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3937         trap cleanup_test32_mount EXIT
3938         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3939         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3940                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3941         test_mkdir -p $DIR/$tdir/d2/test_dir
3942         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3943                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_dir not dir type"
3944         cleanup_test32_mount
3945 }
3946 run_test 32c "stat d32c/ext2-mountpoint/../d2/test_dir ========="
3947
3948 test_32d() {
3949         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3950
3951         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3952         trap cleanup_test32_mount EXIT
3953         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3954         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3955                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3956         test_mkdir -p $DIR/$tdir/d2/test_dir
3957         ls -al $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3958                 error "Can't list $DIR/$tdir/ext2-mountpoint/../d2/test_dir"
3959         cleanup_test32_mount
3960 }
3961 run_test 32d "open d32d/ext2-mountpoint/../d2/test_dir"
3962
3963 test_32e() {
3964         rm -fr $DIR/$tdir
3965         test_mkdir -p $DIR/$tdir/tmp
3966         local tmp_dir=$DIR/$tdir/tmp
3967         ln -s $DIR/$tdir $tmp_dir/symlink11
3968         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3969         $CHECKSTAT -t link $DIR/$tdir/tmp/symlink11 || error "symlink11 bad"
3970         $CHECKSTAT -t link $DIR/$tdir/symlink01 || error "symlink01 bad"
3971 }
3972 run_test 32e "stat d32e/symlink->tmp/symlink->lustre-subdir"
3973
3974 test_32f() {
3975         rm -fr $DIR/$tdir
3976         test_mkdir -p $DIR/$tdir/tmp
3977         local tmp_dir=$DIR/$tdir/tmp
3978         ln -s $DIR/$tdir $tmp_dir/symlink11
3979         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3980         ls $DIR/$tdir/tmp/symlink11  || error "symlink11 bad"
3981         ls $DIR/$tdir/symlink01 || error "symlink01 bad"
3982 }
3983 run_test 32f "open d32f/symlink->tmp/symlink->lustre-subdir"
3984
3985 test_32g() {
3986         local tmp_dir=$DIR/$tdir/tmp
3987         test_mkdir -p $tmp_dir
3988         test_mkdir $DIR/${tdir}2
3989         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3990         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3991         $CHECKSTAT -t link $tmp_dir/symlink12 || error "symlink12 not a link"
3992         $CHECKSTAT -t link $DIR/$tdir/symlink02 || error "symlink02 not a link"
3993         $CHECKSTAT -t dir -f $tmp_dir/symlink12 || error "symlink12 not a dir"
3994         $CHECKSTAT -t dir -f $DIR/$tdir/symlink02 || error "symlink12 not a dir"
3995 }
3996 run_test 32g "stat d32g/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3997
3998 test_32h() {
3999         rm -fr $DIR/$tdir $DIR/${tdir}2
4000         tmp_dir=$DIR/$tdir/tmp
4001         test_mkdir -p $tmp_dir
4002         test_mkdir $DIR/${tdir}2
4003         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
4004         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
4005         ls $tmp_dir/symlink12 || error "listing symlink12"
4006         ls $DIR/$tdir/symlink02  || error "listing symlink02"
4007 }
4008 run_test 32h "open d32h/symlink->tmp/symlink->lustre-subdir/${tdir}2"
4009
4010 test_32i() {
4011         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4012
4013         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
4014         trap cleanup_test32_mount EXIT
4015         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4016         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4017                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4018         touch $DIR/$tdir/test_file
4019         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../test_file ||
4020                 error "$DIR/$tdir/ext2-mountpoint/../test_file not file type"
4021         cleanup_test32_mount
4022 }
4023 run_test 32i "stat d32i/ext2-mountpoint/../test_file ==========="
4024
4025 test_32j() {
4026         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4027
4028         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
4029         trap cleanup_test32_mount EXIT
4030         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4031         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4032                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4033         touch $DIR/$tdir/test_file
4034         cat $DIR/$tdir/ext2-mountpoint/../test_file ||
4035                 error "Can't open $DIR/$tdir/ext2-mountpoint/../test_file"
4036         cleanup_test32_mount
4037 }
4038 run_test 32j "open d32j/ext2-mountpoint/../test_file ==========="
4039
4040 test_32k() {
4041         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4042
4043         rm -fr $DIR/$tdir
4044         trap cleanup_test32_mount EXIT
4045         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4046         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4047                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4048         test_mkdir -p $DIR/$tdir/d2
4049         touch $DIR/$tdir/d2/test_file || error "touch failed"
4050         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
4051                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_file not file type"
4052         cleanup_test32_mount
4053 }
4054 run_test 32k "stat d32k/ext2-mountpoint/../d2/test_file ========"
4055
4056 test_32l() {
4057         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4058
4059         rm -fr $DIR/$tdir
4060         trap cleanup_test32_mount EXIT
4061         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4062         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4063                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4064         test_mkdir -p $DIR/$tdir/d2
4065         touch $DIR/$tdir/d2/test_file || error "touch failed"
4066         cat  $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
4067                 error "Can't open $DIR/$tdir/ext2-mountpoint/../d2/test_file"
4068         cleanup_test32_mount
4069 }
4070 run_test 32l "open d32l/ext2-mountpoint/../d2/test_file ========"
4071
4072 test_32m() {
4073         rm -fr $DIR/d32m
4074         test_mkdir -p $DIR/d32m/tmp
4075         TMP_DIR=$DIR/d32m/tmp
4076         ln -s $DIR $TMP_DIR/symlink11
4077         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
4078         $CHECKSTAT -t link $DIR/d32m/tmp/symlink11 ||
4079                 error "symlink11 not a link"
4080         $CHECKSTAT -t link $DIR/d32m/symlink01 ||
4081                 error "symlink01 not a link"
4082 }
4083 run_test 32m "stat d32m/symlink->tmp/symlink->lustre-root ======"
4084
4085 test_32n() {
4086         rm -fr $DIR/d32n
4087         test_mkdir -p $DIR/d32n/tmp
4088         TMP_DIR=$DIR/d32n/tmp
4089         ln -s $DIR $TMP_DIR/symlink11
4090         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
4091         ls -l $DIR/d32n/tmp/symlink11  || error "listing symlink11"
4092         ls -l $DIR/d32n/symlink01 || error "listing symlink01"
4093 }
4094 run_test 32n "open d32n/symlink->tmp/symlink->lustre-root ======"
4095
4096 test_32o() {
4097         touch $DIR/$tfile
4098         test_mkdir -p $DIR/d32o/tmp
4099         TMP_DIR=$DIR/d32o/tmp
4100         ln -s $DIR/$tfile $TMP_DIR/symlink12
4101         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
4102         $CHECKSTAT -t link $DIR/d32o/tmp/symlink12 ||
4103                 error "symlink12 not a link"
4104         $CHECKSTAT -t link $DIR/d32o/symlink02 || error "symlink02 not a link"
4105         $CHECKSTAT -t file -f $DIR/d32o/tmp/symlink12 ||
4106                 error "$DIR/d32o/tmp/symlink12 not file type"
4107         $CHECKSTAT -t file -f $DIR/d32o/symlink02 ||
4108                 error "$DIR/d32o/symlink02 not file type"
4109 }
4110 run_test 32o "stat d32o/symlink->tmp/symlink->lustre-root/$tfile"
4111
4112 test_32p() {
4113         log 32p_1
4114         rm -fr $DIR/d32p
4115         log 32p_2
4116         rm -f $DIR/$tfile
4117         log 32p_3
4118         touch $DIR/$tfile
4119         log 32p_4
4120         test_mkdir -p $DIR/d32p/tmp
4121         log 32p_5
4122         TMP_DIR=$DIR/d32p/tmp
4123         log 32p_6
4124         ln -s $DIR/$tfile $TMP_DIR/symlink12
4125         log 32p_7
4126         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
4127         log 32p_8
4128         cat $DIR/d32p/tmp/symlink12 ||
4129                 error "Can't open $DIR/d32p/tmp/symlink12"
4130         log 32p_9
4131         cat $DIR/d32p/symlink02 || error "Can't open $DIR/d32p/symlink02"
4132         log 32p_10
4133 }
4134 run_test 32p "open d32p/symlink->tmp/symlink->lustre-root/$tfile"
4135
4136 test_32q() {
4137         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4138
4139         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
4140         trap cleanup_test32_mount EXIT
4141         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4142         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
4143         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4144                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4145         ls $DIR/$tdir/ext2-mountpoint | grep "\<under_the_mount\>" && error
4146         cleanup_test32_mount
4147 }
4148 run_test 32q "stat follows mountpoints in Lustre (should return error)"
4149
4150 test_32r() {
4151         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4152
4153         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
4154         trap cleanup_test32_mount EXIT
4155         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4156         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
4157         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4158                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4159         ls $DIR/$tdir/ext2-mountpoint | grep -q under_the_mount && error || true
4160         cleanup_test32_mount
4161 }
4162 run_test 32r "opendir follows mountpoints in Lustre (should return error)"
4163
4164 test_33aa() {
4165         rm -f $DIR/$tfile
4166         touch $DIR/$tfile
4167         chmod 444 $DIR/$tfile
4168         chown $RUNAS_ID $DIR/$tfile
4169         log 33_1
4170         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
4171         log 33_2
4172 }
4173 run_test 33aa "write file with mode 444 (should return error)"
4174
4175 test_33a() {
4176         rm -fr $DIR/$tdir
4177         test_mkdir $DIR/$tdir
4178         chown $RUNAS_ID $DIR/$tdir
4179         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile ||
4180                 error "$RUNAS create $tdir/$tfile failed"
4181         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile &&
4182                 error "open RDWR" || true
4183 }
4184 run_test 33a "test open file(mode=0444) with O_RDWR (should return error)"
4185
4186 test_33b() {
4187         rm -fr $DIR/$tdir
4188         test_mkdir $DIR/$tdir
4189         chown $RUNAS_ID $DIR/$tdir
4190         $RUNAS $OPENFILE -f 1286739555 $DIR/$tdir/$tfile || true
4191 }
4192 run_test 33b "test open file with malformed flags (No panic)"
4193
4194 test_33c() {
4195         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4196         remote_ost_nodsh && skip "remote OST with nodsh"
4197
4198         local ostnum
4199         local ostname
4200         local write_bytes
4201         local all_zeros
4202
4203         all_zeros=true
4204         test_mkdir $DIR/$tdir
4205         # Read: 0, Write: 4, create/destroy: 2/0, stat: 1, punch: 0
4206
4207         sync
4208         for ostnum in $(seq $OSTCOUNT); do
4209                 # test-framework's OST numbering is one-based, while Lustre's
4210                 # is zero-based
4211                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4212                 # check if at least some write_bytes stats are counted
4213                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
4214                               obdfilter.$ostname.stats |
4215                               awk '/^write_bytes/ {print $7}' )
4216                 echo "baseline_write_bytes@ost$ostnum/$ostname=$write_bytes"
4217                 if (( ${write_bytes:-0} > 0 )); then
4218                         all_zeros=false
4219                         break
4220                 fi
4221         done
4222
4223         $all_zeros || return 0
4224
4225         # Write four bytes
4226         echo foo > $DIR/$tdir/bar
4227         # Really write them
4228         sync
4229
4230         # Total up write_bytes after writing.  We'd better find non-zeros.
4231         for ostnum in $(seq $OSTCOUNT); do
4232                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4233                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
4234                               obdfilter/$ostname/stats |
4235                               awk '/^write_bytes/ {print $7}' )
4236                 echo "write_bytes@ost$ostnum/$ostname=$write_bytes"
4237                 if (( ${write_bytes:-0} > 0 )); then
4238                         all_zeros=false
4239                         break
4240                 fi
4241         done
4242
4243         if $all_zeros; then
4244                 for ostnum in $(seq $OSTCOUNT); do
4245                         ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4246                         echo "Check write_bytes is in obdfilter.*.stats:"
4247                         do_facet ost$ostnum lctl get_param -n \
4248                                 obdfilter.$ostname.stats
4249                 done
4250                 error "OST not keeping write_bytes stats (b=22312)"
4251         fi
4252 }
4253 run_test 33c "test write_bytes stats"
4254
4255 test_33d() {
4256         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
4257         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4258
4259         local MDTIDX=1
4260         local remote_dir=$DIR/$tdir/remote_dir
4261
4262         test_mkdir $DIR/$tdir
4263         $LFS mkdir -i $MDTIDX $remote_dir ||
4264                 error "create remote directory failed"
4265
4266         touch $remote_dir/$tfile
4267         chmod 444 $remote_dir/$tfile
4268         chown $RUNAS_ID $remote_dir/$tfile
4269
4270         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
4271
4272         chown $RUNAS_ID $remote_dir
4273         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 ||
4274                                         error "create" || true
4275         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 &&
4276                                     error "open RDWR" || true
4277         $RUNAS $OPENFILE -f 1286739555 $remote_dir/f33 || true
4278 }
4279 run_test 33d "openfile with 444 modes and malformed flags under remote dir"
4280
4281 test_33e() {
4282         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4283
4284         mkdir $DIR/$tdir
4285
4286         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4287         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4288         mkdir $DIR/$tdir/local_dir
4289
4290         local s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4291         local s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4292         local l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4293
4294         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4295                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode"
4296
4297         rmdir $DIR/$tdir/* || error "rmdir failed"
4298
4299         umask 777
4300         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4301         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4302         mkdir $DIR/$tdir/local_dir
4303
4304         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4305         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4306         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4307
4308         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4309                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 777"
4310
4311         rmdir $DIR/$tdir/* || error "rmdir(umask 777) failed"
4312
4313         umask 000
4314         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4315         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4316         mkdir $DIR/$tdir/local_dir
4317
4318         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4319         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4320         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4321
4322         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4323                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 0"
4324 }
4325 run_test 33e "mkdir and striped directory should have same mode"
4326
4327 cleanup_33f() {
4328         trap 0
4329         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=0
4330 }
4331
4332 test_33f() {
4333         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4334         remote_mds_nodsh && skip "remote MDS with nodsh"
4335
4336         mkdir $DIR/$tdir
4337         chmod go+rwx $DIR/$tdir
4338         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=-1
4339         trap cleanup_33f EXIT
4340
4341         $RUNAS lfs mkdir -i 0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
4342                 error "cannot create striped directory"
4343
4344         $RUNAS touch $DIR/$tdir/striped_dir/{0..16} ||
4345                 error "cannot create files in striped directory"
4346
4347         $RUNAS rm $DIR/$tdir/striped_dir/{0..16} ||
4348                 error "cannot remove files in striped directory"
4349
4350         $RUNAS rmdir $DIR/$tdir/striped_dir ||
4351                 error "cannot remove striped directory"
4352
4353         cleanup_33f
4354 }
4355 run_test 33f "nonroot user can create, access, and remove a striped directory"
4356
4357 test_33g() {
4358         mkdir -p $DIR/$tdir/dir2
4359
4360         local err=$($RUNAS mkdir $DIR/$tdir/dir2 2>&1)
4361         echo $err
4362         [[ $err =~ "exists" ]] || error "Not exists error"
4363 }
4364 run_test 33g "nonroot user create already existing root created file"
4365
4366 sub_33h() {
4367         local hash_type=$1
4368         local count=250
4369
4370         test_mkdir -c $MDSCOUNT -H $hash_type $DIR/$tdir ||
4371                 error "lfs mkdir -H $hash_type $tdir failed"
4372         touch $DIR/$tdir/$tfile || error "touch $tfile failed"
4373
4374         local index=$($LFS getstripe -m $DIR/$tdir/$tfile)
4375         local index2
4376         local fname
4377
4378         for fname in $DIR/$tdir/$tfile.bak \
4379                      $DIR/$tdir/$tfile.SAV \
4380                      $DIR/$tdir/$tfile.orig \
4381                      $DIR/$tdir/$tfile~; do
4382                 touch $fname || error "touch $fname failed"
4383                 index2=$($LFS getstripe -m $fname)
4384                 (( $index == $index2 )) ||
4385                         error "$fname MDT index mismatch $index != $index2"
4386         done
4387
4388         local failed=0
4389         local patterns=(".$tfile.XXXXXX" "$tfile.XXXXXXXX")
4390         local pattern
4391
4392         for pattern in ${patterns[*]}; do
4393                 echo "pattern $pattern"
4394                 fname=$DIR/$tdir/$pattern
4395                 for (( i = 0; i < $count; i++ )); do
4396                         fname=$(mktemp $DIR/$tdir/$pattern) ||
4397                                 error "mktemp $DIR/$tdir/$pattern failed"
4398                         index2=$($LFS getstripe -m $fname)
4399                         (( $index == $index2 )) && continue
4400
4401                         failed=$((failed + 1))
4402                         echo "$fname MDT index mismatch $index != $index2"
4403                 done
4404         done
4405
4406         echo "$failed/$count MDT index mismatches, expect ~2-4"
4407         (( failed < 10 )) || error "MDT index mismatch $failed/$count times"
4408
4409         local same=0
4410         local expect
4411
4412         # verify that "crush" is still broken with all files on same MDT,
4413         # crush2 should have about 1/MDSCOUNT files on each MDT, with margin
4414         [[ "$hash_type" == "crush" ]] && expect=$count ||
4415                 expect=$((count / MDSCOUNT))
4416
4417         # crush2 doesn't put all-numeric suffixes on the same MDT,
4418         # filename like $tfile.12345678 should *not* be considered temp
4419         for pattern in ${patterns[*]}; do
4420                 local base=${pattern%%X*}
4421                 local suff=${pattern#$base}
4422
4423                 echo "pattern $pattern"
4424                 for (( i = 0; i < $count; i++ )); do
4425                         fname=$DIR/$tdir/$base$((${suff//X/1} + i))
4426                         touch $fname || error "touch $fname failed"
4427                         index2=$($LFS getstripe -m $fname)
4428                         (( $index != $index2 )) && continue
4429
4430                         same=$((same + 1))
4431                 done
4432         done
4433
4434         # the number of "bad" hashes is random, as it depends on the random
4435         # filenames generated by "mktemp".  Allow some margin in the results.
4436         echo "$((same/${#patterns[*]}))/$count matches, expect ~$expect for $1"
4437         (( same / ${#patterns[*]} <= expect * 9 / 7 &&
4438            same / ${#patterns[*]} > expect * 5 / 7 )) ||
4439                 error "MDT index match $((same / ${#patterns[*]}))/$count times"
4440         same=0
4441
4442         # crush2 doesn't put suffixes with special characters on the same MDT
4443         # filename like $tfile.txt.1234 should *not* be considered temp
4444         for pattern in ${patterns[*]}; do
4445                 local base=${pattern%%X*}
4446                 local suff=${pattern#$base}
4447
4448                 pattern=$base...${suff/XXX}
4449                 echo "pattern=$pattern"
4450                 for (( i = 0; i < $count; i++ )); do
4451                         fname=$(mktemp $DIR/$tdir/$pattern) ||
4452                                 error "touch $fname failed"
4453                         index2=$($LFS getstripe -m $fname)
4454                         (( $index != $index2 )) && continue
4455
4456                         same=$((same + 1))
4457                 done
4458         done
4459
4460         # the number of "bad" hashes is random, as it depends on the random
4461         # filenames generated by "mktemp".  Allow some margin in the results.
4462         echo "$((same/${#patterns[*]}))/$count matches, expect ~$expect for $1"
4463         (( same / ${#patterns[*]} <= expect * 9 / 7 &&
4464            same / ${#patterns[*]} > expect * 5 / 7 )) ||
4465                 error "MDT index match $((same / ${#patterns[*]}))/$count times"
4466 }
4467
4468 test_33h() {
4469         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
4470         (( $MDS1_VERSION >= $(version_code 2.13.50) )) ||
4471                 skip "Need MDS version at least 2.13.50"
4472
4473         sub_33h crush
4474 }
4475 run_test 33h "temp file is located on the same MDT as target (crush)"
4476
4477 test_33hh() {
4478         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
4479         echo "MDS1_VERSION=$MDS1_VERSION version_code=$(version_code 2.15.0)"
4480         (( $MDS1_VERSION > $(version_code 2.15.0) )) ||
4481                 skip "Need MDS version at least 2.15.0 for crush2"
4482
4483         sub_33h crush2
4484 }
4485 run_test 33hh "temp file is located on the same MDT as target (crush2)"
4486
4487 test_33i()
4488 {
4489         (( MDSCOUNT < 2 )) && skip "needs >= 2 MDTs"
4490
4491         local FNAME=$(str_repeat 'f' 250)
4492
4493         test_mkdir -i 0 -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
4494         createmany -o $DIR/$tdir/$FNAME 1000 || error "createmany failed"
4495
4496         local count
4497         local total
4498
4499         count=$($LFS getstripe -m $DIR/$tdir/* | grep -cw 1)
4500
4501         local MDC=$(lctl dl | awk '/MDT0001-mdc-[^M]/ { print $4 }')
4502
4503         lctl --device %$MDC deactivate
4504         stack_trap "lctl --device %$MDC activate"
4505         ls $DIR/$tdir > /dev/null && error "ls should return an error"
4506         total=$(\ls -l $DIR/$tdir | wc -l)
4507         # "ls -l" will list total in the first line
4508         total=$((total - 1))
4509         (( total + count == 1000 )) ||
4510                 error "ls list $total files, $count files on MDT1"
4511 }
4512 run_test 33i "striped directory can be accessed when one MDT is down"
4513
4514 test_33j() {
4515         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
4516
4517         mkdir -p $DIR/$tdir/
4518
4519         $LFS setdirstripe -D -i0,1 $DIR/$tdir/striped_dir_a &&
4520                 error "setdirstripe -D -i0,1 incorrectly succeeded"
4521
4522         $LFS setdirstripe -D -i0,1 -c1 $DIR/$tdir/striped_dir_b &&
4523                 error "setdirstripe -D -i0,1 -c1 incorrectly succeeded"
4524
4525         $LFS setdirstripe -D -i0,1 -c3 $DIR/$tdir/striped_dir_c &&
4526                 error "setdirstripe -D -i0,1 -c3 incorrectly succeeded"
4527
4528         $LFS setdirstripe -i0,1 $DIR/$tdir/striped_dir_e ||
4529                 error "-D was not specified, but still failed"
4530 }
4531 run_test 33j "lfs setdirstripe -D -i x,y,x should fail"
4532
4533 TEST_34_SIZE=${TEST_34_SIZE:-2000000000000}
4534 test_34a() {
4535         rm -f $DIR/f34
4536         $MCREATE $DIR/f34 || error "mcreate failed"
4537         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4538                 error "getstripe failed"
4539         $TRUNCATE $DIR/f34 $TEST_34_SIZE || error "truncate failed"
4540         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4541                 error "getstripe failed"
4542         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4543                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4544 }
4545 run_test 34a "truncate file that has not been opened ==========="
4546
4547 test_34b() {
4548         [ ! -f $DIR/f34 ] && test_34a
4549         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4550                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4551         $OPENFILE -f O_RDONLY $DIR/f34
4552         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4553                 error "getstripe failed"
4554         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4555                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4556 }
4557 run_test 34b "O_RDONLY opening file doesn't create objects ====="
4558
4559 test_34c() {
4560         [ ! -f $DIR/f34 ] && test_34a
4561         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4562                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4563         $OPENFILE -f O_RDWR $DIR/f34
4564         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" &&
4565                 error "$LFS getstripe failed"
4566         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4567                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4568 }
4569 run_test 34c "O_RDWR opening file-with-size works =============="
4570
4571 test_34d() {
4572         [ ! -f $DIR/f34 ] && test_34a
4573         dd if=/dev/zero of=$DIR/f34 conv=notrunc bs=4k count=1 ||
4574                 error "dd failed"
4575         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4576                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4577         rm $DIR/f34
4578 }
4579 run_test 34d "write to sparse file ============================="
4580
4581 test_34e() {
4582         rm -f $DIR/f34e
4583         $MCREATE $DIR/f34e || error "mcreate failed"
4584         $TRUNCATE $DIR/f34e 1000 || error "truncate failed"
4585         $CHECKSTAT -s 1000 $DIR/f34e ||
4586                 error "Size of $DIR/f34e not equal to 1000 bytes"
4587         $OPENFILE -f O_RDWR $DIR/f34e
4588         $CHECKSTAT -s 1000 $DIR/f34e ||
4589                 error "Size of $DIR/f34e not equal to 1000 bytes"
4590 }
4591 run_test 34e "create objects, some with size and some without =="
4592
4593 test_34f() { # bug 6242, 6243
4594         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4595
4596         SIZE34F=48000
4597         rm -f $DIR/f34f
4598         $MCREATE $DIR/f34f || error "mcreate failed"
4599         $TRUNCATE $DIR/f34f $SIZE34F || error "truncating $DIR/f3f to $SIZE34F"
4600         dd if=$DIR/f34f of=$TMP/f34f
4601         $CHECKSTAT -s $SIZE34F $TMP/f34f || error "$TMP/f34f not $SIZE34F bytes"
4602         dd if=/dev/zero of=$TMP/f34fzero bs=$SIZE34F count=1
4603         cmp $DIR/f34f $TMP/f34fzero || error "$DIR/f34f not all zero"
4604         cmp $TMP/f34f $TMP/f34fzero || error "$TMP/f34f not all zero"
4605         rm $TMP/f34f $TMP/f34fzero $DIR/f34f
4606 }
4607 run_test 34f "read from a file with no objects until EOF ======="
4608
4609 test_34g() {
4610         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4611
4612         dd if=/dev/zero of=$DIR/$tfile bs=1 count=100 seek=$TEST_34_SIZE ||
4613                 error "dd failed"
4614         $TRUNCATE $DIR/$tfile $((TEST_34_SIZE / 2))|| error "truncate failed"
4615         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
4616                 error "Size of $DIR/$tfile not equal to $((TEST_34_SIZE / 2))"
4617         cancel_lru_locks osc
4618         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
4619                 error "wrong size after lock cancel"
4620
4621         $TRUNCATE $DIR/$tfile $TEST_34_SIZE || error "truncate failed"
4622         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
4623                 error "expanding truncate failed"
4624         cancel_lru_locks osc
4625         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
4626                 error "wrong expanded size after lock cancel"
4627 }
4628 run_test 34g "truncate long file ==============================="
4629
4630 test_34h() {
4631         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4632
4633         local gid=10
4634         local sz=1000
4635
4636         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 || error "dd failed"
4637         sync # Flush the cache so that multiop below does not block on cache
4638              # flush when getting the group lock
4639         $MULTIOP $DIR/$tfile OG${gid}T${sz}g${gid}c &
4640         MULTIPID=$!
4641
4642         # Since just timed wait is not good enough, let's do a sync write
4643         # that way we are sure enough time for a roundtrip + processing
4644         # passed + 2 seconds of extra margin.
4645         dd if=/dev/zero of=$DIR/${tfile}-1 bs=$PAGE_SIZE oflag=direct count=1
4646         rm $DIR/${tfile}-1
4647         sleep 2
4648
4649         if [[ `ps h -o comm -p $MULTIPID` == "multiop" ]]; then
4650                 error "Multiop blocked on ftruncate, pid=$MULTIPID"
4651                 kill -9 $MULTIPID
4652         fi
4653         wait $MULTIPID
4654         local nsz=`stat -c %s $DIR/$tfile`
4655         [[ $nsz == $sz ]] || error "New size wrong $nsz != $sz"
4656 }
4657 run_test 34h "ftruncate file under grouplock should not block"
4658
4659 test_35a() {
4660         cp /bin/sh $DIR/f35a
4661         chmod 444 $DIR/f35a
4662         chown $RUNAS_ID $DIR/f35a
4663         $RUNAS $DIR/f35a && error || true
4664         rm $DIR/f35a
4665 }
4666 run_test 35a "exec file with mode 444 (should return and not leak)"
4667
4668 test_36a() {
4669         rm -f $DIR/f36
4670         utime $DIR/f36 || error "utime failed for MDS"
4671 }
4672 run_test 36a "MDS utime check (mknod, utime)"
4673
4674 test_36b() {
4675         echo "" > $DIR/f36
4676         utime $DIR/f36 || error "utime failed for OST"
4677 }
4678 run_test 36b "OST utime check (open, utime)"
4679
4680 test_36c() {
4681         rm -f $DIR/d36/f36
4682         test_mkdir $DIR/d36
4683         chown $RUNAS_ID $DIR/d36
4684         $RUNAS utime $DIR/d36/f36 || error "utime failed for MDS as non-root"
4685 }
4686 run_test 36c "non-root MDS utime check (mknod, utime)"
4687
4688 test_36d() {
4689         [ ! -d $DIR/d36 ] && test_36c
4690         echo "" > $DIR/d36/f36
4691         $RUNAS utime $DIR/d36/f36 || error "utime failed for OST as non-root"
4692 }
4693 run_test 36d "non-root OST utime check (open, utime)"
4694
4695 test_36e() {
4696         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID -- skipping"
4697
4698         test_mkdir $DIR/$tdir
4699         touch $DIR/$tdir/$tfile
4700         $RUNAS utime $DIR/$tdir/$tfile &&
4701                 error "utime worked, expected failure" || true
4702 }
4703 run_test 36e "utime on non-owned file (should return error)"
4704
4705 subr_36fh() {
4706         local fl="$1"
4707         local LANG_SAVE=$LANG
4708         local LC_LANG_SAVE=$LC_LANG
4709         export LANG=C LC_LANG=C # for date language
4710
4711         DATESTR="Dec 20  2000"
4712         test_mkdir $DIR/$tdir
4713         lctl set_param fail_loc=$fl
4714         date; date +%s
4715         cp /etc/hosts $DIR/$tdir/$tfile
4716         sync & # write RPC generated with "current" inode timestamp, but delayed
4717         sleep 1
4718         touch --date="$DATESTR" $DIR/$tdir/$tfile # setattr timestamp in past
4719         LS_BEFORE="`ls -l $DIR/$tdir/$tfile`" # old timestamp from client cache
4720         cancel_lru_locks $OSC
4721         LS_AFTER="`ls -l $DIR/$tdir/$tfile`"  # timestamp from OST object
4722         date; date +%s
4723         [ "$LS_BEFORE" != "$LS_AFTER" ] && \
4724                 echo "BEFORE: $LS_BEFORE" && \
4725                 echo "AFTER : $LS_AFTER" && \
4726                 echo "WANT  : $DATESTR" && \
4727                 error "$DIR/$tdir/$tfile timestamps changed" || true
4728
4729         export LANG=$LANG_SAVE LC_LANG=$LC_LANG_SAVE
4730 }
4731
4732 test_36f() {
4733         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4734
4735         #define OBD_FAIL_OST_BRW_PAUSE_BULK 0x214
4736         subr_36fh "0x80000214"
4737 }
4738 run_test 36f "utime on file racing with OST BRW write =========="
4739
4740 test_36g() {
4741         remote_ost_nodsh && skip "remote OST with nodsh"
4742         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4743         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
4744                 skip "Need MDS version at least 2.12.51"
4745
4746         local fmd_max_age
4747         local fmd
4748         local facet="ost1"
4749         local tgt="obdfilter"
4750
4751         [[ $OSC == "mdc" ]] && tgt="mdt" && facet="mds1"
4752
4753         test_mkdir $DIR/$tdir
4754         fmd_max_age=$(do_facet $facet \
4755                 "lctl get_param -n $tgt.*.tgt_fmd_seconds 2> /dev/null | \
4756                 head -n 1")
4757
4758         echo "FMD max age: ${fmd_max_age}s"
4759         touch $DIR/$tdir/$tfile
4760         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4761                 gawk '{cnt=cnt+$1}  END{print cnt}')
4762         echo "FMD before: $fmd"
4763         [[ $fmd == 0 ]] &&
4764                 error "FMD wasn't create by touch"
4765         sleep $((fmd_max_age + 12))
4766         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4767                 gawk '{cnt=cnt+$1}  END{print cnt}')
4768         echo "FMD after: $fmd"
4769         [[ $fmd == 0 ]] ||
4770                 error "FMD wasn't expired by ping"
4771 }
4772 run_test 36g "FMD cache expiry ====================="
4773
4774 test_36h() {
4775         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4776
4777         #define OBD_FAIL_OST_BRW_PAUSE_BULK2 0x227
4778         subr_36fh "0x80000227"
4779 }
4780 run_test 36h "utime on file racing with OST BRW write =========="
4781
4782 test_36i() {
4783         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4784
4785         test_mkdir $DIR/$tdir
4786         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir
4787
4788         local mtime=$(stat -c%Y $DIR/$tdir/striped_dir)
4789         local new_mtime=$((mtime + 200))
4790
4791         #change Modify time of striped dir
4792         touch -m -d @$new_mtime $DIR/$tdir/striped_dir ||
4793                         error "change mtime failed"
4794
4795         local got=$(stat -c%Y $DIR/$tdir/striped_dir)
4796
4797         [ "$new_mtime" = "$got" ] || error "expect $new_mtime got $got"
4798 }
4799 run_test 36i "change mtime on striped directory"
4800
4801 # test_37 - duplicate with tests 32q 32r
4802
4803 test_38() {
4804         local file=$DIR/$tfile
4805         touch $file
4806         openfile -f O_DIRECTORY $file
4807         local RC=$?
4808         local ENOTDIR=20
4809         [ $RC -eq 0 ] && error "opened file $file with O_DIRECTORY" || true
4810         [ $RC -eq $ENOTDIR ] || error "error $RC should be ENOTDIR ($ENOTDIR)"
4811 }
4812 run_test 38 "open a regular file with O_DIRECTORY should return -ENOTDIR ==="
4813
4814 test_39a() { # was test_39
4815         touch $DIR/$tfile
4816         touch $DIR/${tfile}2
4817 #       ls -l  $DIR/$tfile $DIR/${tfile}2
4818 #       ls -lu  $DIR/$tfile $DIR/${tfile}2
4819 #       ls -lc  $DIR/$tfile $DIR/${tfile}2
4820         sleep 2
4821         $OPENFILE -f O_CREAT:O_TRUNC:O_WRONLY $DIR/${tfile}2
4822         if [ ! $DIR/${tfile}2 -nt $DIR/$tfile ]; then
4823                 echo "mtime"
4824                 ls -l --full-time $DIR/$tfile $DIR/${tfile}2
4825                 echo "atime"
4826                 ls -lu --full-time $DIR/$tfile $DIR/${tfile}2
4827                 echo "ctime"
4828                 ls -lc --full-time $DIR/$tfile $DIR/${tfile}2
4829                 error "O_TRUNC didn't change timestamps"
4830         fi
4831 }
4832 run_test 39a "mtime changed on create"
4833
4834 test_39b() {
4835         test_mkdir -c1 $DIR/$tdir
4836         cp -p /etc/passwd $DIR/$tdir/fopen
4837         cp -p /etc/passwd $DIR/$tdir/flink
4838         cp -p /etc/passwd $DIR/$tdir/funlink
4839         cp -p /etc/passwd $DIR/$tdir/frename
4840         ln $DIR/$tdir/funlink $DIR/$tdir/funlink2
4841
4842         sleep 1
4843         echo "aaaaaa" >> $DIR/$tdir/fopen
4844         echo "aaaaaa" >> $DIR/$tdir/flink
4845         echo "aaaaaa" >> $DIR/$tdir/funlink
4846         echo "aaaaaa" >> $DIR/$tdir/frename
4847
4848         local open_new=`stat -c %Y $DIR/$tdir/fopen`
4849         local link_new=`stat -c %Y $DIR/$tdir/flink`
4850         local unlink_new=`stat -c %Y $DIR/$tdir/funlink`
4851         local rename_new=`stat -c %Y $DIR/$tdir/frename`
4852
4853         cat $DIR/$tdir/fopen > /dev/null
4854         ln $DIR/$tdir/flink $DIR/$tdir/flink2
4855         rm -f $DIR/$tdir/funlink2
4856         mv -f $DIR/$tdir/frename $DIR/$tdir/frename2
4857
4858         for (( i=0; i < 2; i++ )) ; do
4859                 local open_new2=`stat -c %Y $DIR/$tdir/fopen`
4860                 local link_new2=`stat -c %Y $DIR/$tdir/flink`
4861                 local unlink_new2=`stat -c %Y $DIR/$tdir/funlink`
4862                 local rename_new2=`stat -c %Y $DIR/$tdir/frename2`
4863
4864                 [ $open_new2 -eq $open_new ] || error "open file reverses mtime"
4865                 [ $link_new2 -eq $link_new ] || error "link file reverses mtime"
4866                 [ $unlink_new2 -eq $unlink_new ] || error "unlink file reverses mtime"
4867                 [ $rename_new2 -eq $rename_new ] || error "rename file reverses mtime"
4868
4869                 cancel_lru_locks $OSC
4870                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4871         done
4872 }
4873 run_test 39b "mtime change on open, link, unlink, rename  ======"
4874
4875 # this should be set to past
4876 TEST_39_MTIME=`date -d "1 year ago" +%s`
4877
4878 # bug 11063
4879 test_39c() {
4880         touch $DIR1/$tfile
4881         sleep 2
4882         local mtime0=`stat -c %Y $DIR1/$tfile`
4883
4884         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4885         local mtime1=`stat -c %Y $DIR1/$tfile`
4886         [ "$mtime1" = $TEST_39_MTIME ] || \
4887                 error "mtime is not set to past: $mtime1, should be $TEST_39_MTIME"
4888
4889         local d1=`date +%s`
4890         echo hello >> $DIR1/$tfile
4891         local d2=`date +%s`
4892         local mtime2=`stat -c %Y $DIR1/$tfile`
4893         [ "$mtime2" -ge "$d1" ] && [ "$mtime2" -le "$d2" ] || \
4894                 error "mtime is not updated on write: $d1 <= $mtime2 <= $d2"
4895
4896         mv $DIR1/$tfile $DIR1/$tfile-1
4897
4898         for (( i=0; i < 2; i++ )) ; do
4899                 local mtime3=`stat -c %Y $DIR1/$tfile-1`
4900                 [ "$mtime2" = "$mtime3" ] || \
4901                         error "mtime ($mtime2) changed (to $mtime3) on rename"
4902
4903                 cancel_lru_locks $OSC
4904                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4905         done
4906 }
4907 run_test 39c "mtime change on rename ==========================="
4908
4909 # bug 21114
4910 test_39d() {
4911         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4912
4913         touch $DIR1/$tfile
4914         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4915
4916         for (( i=0; i < 2; i++ )) ; do
4917                 local mtime=`stat -c %Y $DIR1/$tfile`
4918                 [ $mtime = $TEST_39_MTIME ] || \
4919                         error "mtime($mtime) is not set to $TEST_39_MTIME"
4920
4921                 cancel_lru_locks $OSC
4922                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4923         done
4924 }
4925 run_test 39d "create, utime, stat =============================="
4926
4927 # bug 21114
4928 test_39e() {
4929         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4930
4931         touch $DIR1/$tfile
4932         local mtime1=`stat -c %Y $DIR1/$tfile`
4933
4934         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4935
4936         for (( i=0; i < 2; i++ )) ; do
4937                 local mtime2=`stat -c %Y $DIR1/$tfile`
4938                 [ $mtime2 = $TEST_39_MTIME ] || \
4939                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4940
4941                 cancel_lru_locks $OSC
4942                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4943         done
4944 }
4945 run_test 39e "create, stat, utime, stat ========================"
4946
4947 # bug 21114
4948 test_39f() {
4949         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4950
4951         touch $DIR1/$tfile
4952         mtime1=`stat -c %Y $DIR1/$tfile`
4953
4954         sleep 2
4955         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4956
4957         for (( i=0; i < 2; i++ )) ; do
4958                 local mtime2=`stat -c %Y $DIR1/$tfile`
4959                 [ $mtime2 = $TEST_39_MTIME ] || \
4960                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4961
4962                 cancel_lru_locks $OSC
4963                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4964         done
4965 }
4966 run_test 39f "create, stat, sleep, utime, stat ================="
4967
4968 # bug 11063
4969 test_39g() {
4970         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4971
4972         echo hello >> $DIR1/$tfile
4973         local mtime1=`stat -c %Y $DIR1/$tfile`
4974
4975         sleep 2
4976         chmod o+r $DIR1/$tfile
4977
4978         for (( i=0; i < 2; i++ )) ; do
4979                 local mtime2=`stat -c %Y $DIR1/$tfile`
4980                 [ "$mtime1" = "$mtime2" ] || \
4981                         error "lost mtime: $mtime2, should be $mtime1"
4982
4983                 cancel_lru_locks $OSC
4984                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4985         done
4986 }
4987 run_test 39g "write, chmod, stat ==============================="
4988
4989 # bug 11063
4990 test_39h() {
4991         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4992
4993         touch $DIR1/$tfile
4994         sleep 1
4995
4996         local d1=`date`
4997         echo hello >> $DIR1/$tfile
4998         local mtime1=`stat -c %Y $DIR1/$tfile`
4999
5000         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
5001         local d2=`date`
5002         if [ "$d1" != "$d2" ]; then
5003                 echo "write and touch not within one second"
5004         else
5005                 for (( i=0; i < 2; i++ )) ; do
5006                         local mtime2=`stat -c %Y $DIR1/$tfile`
5007                         [ "$mtime2" = $TEST_39_MTIME ] || \
5008                                 error "lost mtime: $mtime2, should be $TEST_39_MTIME"
5009
5010                         cancel_lru_locks $OSC
5011                         if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
5012                 done
5013         fi
5014 }
5015 run_test 39h "write, utime within one second, stat ============="
5016
5017 test_39i() {
5018         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5019
5020         touch $DIR1/$tfile
5021         sleep 1
5022
5023         echo hello >> $DIR1/$tfile
5024         local mtime1=`stat -c %Y $DIR1/$tfile`
5025
5026         mv $DIR1/$tfile $DIR1/$tfile-1
5027
5028         for (( i=0; i < 2; i++ )) ; do
5029                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
5030
5031                 [ "$mtime1" = "$mtime2" ] || \
5032                         error "lost mtime: $mtime2, should be $mtime1"
5033
5034                 cancel_lru_locks $OSC
5035                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
5036         done
5037 }
5038 run_test 39i "write, rename, stat =============================="
5039
5040 test_39j() {
5041         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5042
5043         start_full_debug_logging
5044         touch $DIR1/$tfile
5045         sleep 1
5046
5047         #define OBD_FAIL_OSC_DELAY_SETTIME       0x412
5048         lctl set_param fail_loc=0x80000412
5049         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c ||
5050                 error "multiop failed"
5051         local multipid=$!
5052         local mtime1=`stat -c %Y $DIR1/$tfile`
5053
5054         mv $DIR1/$tfile $DIR1/$tfile-1
5055
5056         kill -USR1 $multipid
5057         wait $multipid || error "multiop close failed"
5058
5059         for (( i=0; i < 2; i++ )) ; do
5060                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
5061                 [ "$mtime1" = "$mtime2" ] ||
5062                         error "mtime is lost on close: $mtime2, " \
5063                               "should be $mtime1"
5064
5065                 cancel_lru_locks
5066                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
5067         done
5068         lctl set_param fail_loc=0
5069         stop_full_debug_logging
5070 }
5071 run_test 39j "write, rename, close, stat ======================="
5072
5073 test_39k() {
5074         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5075
5076         touch $DIR1/$tfile
5077         sleep 1
5078
5079         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c || error "multiop failed"
5080         local multipid=$!
5081         local mtime1=`stat -c %Y $DIR1/$tfile`
5082
5083         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
5084
5085         kill -USR1 $multipid
5086         wait $multipid || error "multiop close failed"
5087
5088         for (( i=0; i < 2; i++ )) ; do
5089                 local mtime2=`stat -c %Y $DIR1/$tfile`
5090
5091                 [ "$mtime2" = $TEST_39_MTIME ] || \
5092                         error "mtime is lost on close: $mtime2, should be $TEST_39_MTIME"
5093
5094                 cancel_lru_locks
5095                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
5096         done
5097 }
5098 run_test 39k "write, utime, close, stat ========================"
5099
5100 # this should be set to future
5101 TEST_39_ATIME=`date -d "1 year" +%s`
5102
5103 test_39l() {
5104         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5105         remote_mds_nodsh && skip "remote MDS with nodsh"
5106
5107         local atime_diff=$(do_facet $SINGLEMDS \
5108                                 lctl get_param -n mdd.*MDT0000*.atime_diff)
5109         rm -rf $DIR/$tdir
5110         mkdir_on_mdt0 $DIR/$tdir
5111
5112         # test setting directory atime to future
5113         touch -a -d @$TEST_39_ATIME $DIR/$tdir
5114         local atime=$(stat -c %X $DIR/$tdir)
5115         [ "$atime" = $TEST_39_ATIME ] ||
5116                 error "atime is not set to future: $atime, $TEST_39_ATIME"
5117
5118         # test setting directory atime from future to now
5119         local now=$(date +%s)
5120         touch -a -d @$now $DIR/$tdir
5121
5122         atime=$(stat -c %X $DIR/$tdir)
5123         [ "$atime" -eq "$now"  ] ||
5124                 error "atime is not updated from future: $atime, $now"
5125
5126         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=2
5127         sleep 3
5128
5129         # test setting directory atime when now > dir atime + atime_diff
5130         local d1=$(date +%s)
5131         ls $DIR/$tdir
5132         local d2=$(date +%s)
5133         cancel_lru_locks mdc
5134         atime=$(stat -c %X $DIR/$tdir)
5135         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
5136                 error "atime is not updated  : $atime, should be $d2"
5137
5138         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=60
5139         sleep 3
5140
5141         # test not setting directory atime when now < dir atime + atime_diff
5142         ls $DIR/$tdir
5143         cancel_lru_locks mdc
5144         atime=$(stat -c %X $DIR/$tdir)
5145         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
5146                 error "atime is updated to $atime, should remain $d1<atime<$d2"
5147
5148         do_facet $SINGLEMDS \
5149                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
5150 }
5151 run_test 39l "directory atime update ==========================="
5152
5153 test_39m() {
5154         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5155
5156         touch $DIR1/$tfile
5157         sleep 2
5158         local far_past_mtime=$(date -d "May 29 1953" +%s)
5159         local far_past_atime=$(date -d "Dec 17 1903" +%s)
5160
5161         touch -m -d @$far_past_mtime $DIR1/$tfile
5162         touch -a -d @$far_past_atime $DIR1/$tfile
5163
5164         for (( i=0; i < 2; i++ )) ; do
5165                 local timestamps=$(stat -c "%X %Y" $DIR1/$tfile)
5166                 [ "$timestamps" = "$far_past_atime $far_past_mtime" ] || \
5167                         error "atime or mtime set incorrectly"
5168
5169                 cancel_lru_locks $OSC
5170                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
5171         done
5172 }
5173 run_test 39m "test atime and mtime before 1970"
5174
5175 test_39n() { # LU-3832
5176         remote_mds_nodsh && skip "remote MDS with nodsh"
5177
5178         local atime_diff=$(do_facet $SINGLEMDS \
5179                 lctl get_param -n mdd.*MDT0000*.atime_diff)
5180         local atime0
5181         local atime1
5182         local atime2
5183
5184         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=1
5185
5186         rm -rf $DIR/$tfile
5187         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 status=noxfer
5188         atime0=$(stat -c %X $DIR/$tfile)
5189
5190         sleep 5
5191         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
5192         atime1=$(stat -c %X $DIR/$tfile)
5193
5194         sleep 5
5195         cancel_lru_locks mdc
5196         cancel_lru_locks osc
5197         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
5198         atime2=$(stat -c %X $DIR/$tfile)
5199
5200         do_facet $SINGLEMDS \
5201                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
5202
5203         [ "$atime0" -eq "$atime1" ] || error "atime0 $atime0 != atime1 $atime1"
5204         [ "$atime1" -eq "$atime2" ] || error "atime0 $atime0 != atime1 $atime1"
5205 }
5206 run_test 39n "check that O_NOATIME is honored"
5207
5208 test_39o() {
5209         TESTDIR=$DIR/$tdir/$tfile
5210         [ -e $TESTDIR ] && rm -rf $TESTDIR
5211         mkdir -p $TESTDIR
5212         cd $TESTDIR
5213         links1=2
5214         ls
5215         mkdir a b
5216         ls
5217         links2=$(stat -c %h .)
5218         [ $(($links1 + 2)) != $links2 ] &&
5219                 error "wrong links count $(($links1 + 2)) != $links2"
5220         rmdir b
5221         links3=$(stat -c %h .)
5222         [ $(($links1 + 1)) != $links3 ] &&
5223                 error "wrong links count $links1 != $links3"
5224         return 0
5225 }
5226 run_test 39o "directory cached attributes updated after create"
5227
5228 test_39p() {
5229         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
5230
5231         local MDTIDX=1
5232         TESTDIR=$DIR/$tdir/$tdir
5233         [ -e $TESTDIR ] && rm -rf $TESTDIR
5234         test_mkdir -p $TESTDIR
5235         cd $TESTDIR
5236         links1=2
5237         ls
5238         test_mkdir -i $MDTIDX $TESTDIR/remote_dir1
5239         test_mkdir -i $MDTIDX $TESTDIR/remote_dir2
5240         ls
5241         links2=$(stat -c %h .)
5242         [ $(($links1 + 2)) != $links2 ] &&
5243                 error "wrong links count $(($links1 + 2)) != $links2"
5244         rmdir remote_dir2
5245         links3=$(stat -c %h .)
5246         [ $(($links1 + 1)) != $links3 ] &&
5247                 error "wrong links count $links1 != $links3"
5248         return 0
5249 }
5250 run_test 39p "remote directory cached attributes updated after create ========"
5251
5252 test_39r() {
5253         [ $OST1_VERSION -ge $(version_code 2.13.52) ] ||
5254                 skip "no atime update on old OST"
5255         if [ "$ost1_FSTYPE" != ldiskfs ]; then
5256                 skip_env "ldiskfs only test"
5257         fi
5258
5259         local saved_adiff
5260         saved_adiff=$(do_facet ost1 \
5261                 lctl get_param -n obdfilter.*OST0000.atime_diff)
5262         stack_trap "do_facet ost1 \
5263                 lctl set_param obdfilter.*.atime_diff=$saved_adiff"
5264
5265         do_facet ost1 "lctl set_param obdfilter.*.atime_diff=5"
5266
5267         $LFS setstripe -i 0 $DIR/$tfile
5268         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 ||
5269                 error "can't write initial file"
5270         cancel_lru_locks osc
5271
5272         # exceed atime_diff and access file
5273         sleep 10
5274         dd if=$DIR/$tfile of=/dev/null bs=4k count=1 ||
5275                 error "can't udpate atime"
5276
5277         local atime_cli=$(stat -c %X $DIR/$tfile)
5278         echo "client atime: $atime_cli"
5279         # allow atime update to be written to device
5280         do_facet ost1 "$LCTL set_param -n osd*.*OST*.force_sync 1"
5281         sleep 5
5282
5283         local ostdev=$(ostdevname 1)
5284         local fid=($($LFS getstripe $DIR/$tfile | grep 0x))
5285         local seq=${fid[3]#0x}
5286         local oid=${fid[1]}
5287         local oid_hex
5288
5289         if [ $seq == 0 ]; then
5290                 oid_hex=${fid[1]}
5291         else
5292                 oid_hex=${fid[2]#0x}
5293         fi
5294         local objpath="O/$seq/d$(($oid % 32))/$oid_hex"
5295         local cmd="debugfs -c -R \\\"stat $objpath\\\" $ostdev"
5296
5297         echo "OST atime: $(do_facet ost1 "$cmd" |& grep atime)"
5298         local atime_ost=$(do_facet ost1 "$cmd" |&
5299                           awk -F'[: ]' '/atime:/ { print $4 }')
5300         (( atime_cli == atime_ost )) ||
5301                 error "atime on client $atime_cli != ost $atime_ost"
5302 }
5303 run_test 39r "lazy atime update on OST"
5304
5305 test_39q() { # LU-8041
5306         local testdir=$DIR/$tdir
5307         mkdir -p $testdir
5308         multiop_bg_pause $testdir D_c || error "multiop failed"
5309         local multipid=$!
5310         cancel_lru_locks mdc
5311         kill -USR1 $multipid
5312         local atime=$(stat -c %X $testdir)
5313         [ "$atime" -ne 0 ] || error "atime is zero"
5314 }
5315 run_test 39q "close won't zero out atime"
5316
5317 test_39s() {
5318         local atime0
5319         local atime1
5320         local atime2
5321         local atime3
5322         local atime4
5323
5324         umount_client $MOUNT
5325         mount_client $MOUNT relatime
5326
5327         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 status=noxfer conv=fsync
5328         atime0=$(stat -c %X $DIR/$tfile)
5329
5330         # First read updates atime
5331         sleep 1
5332         cat $DIR/$tfile >/dev/null
5333         atime1=$(stat -c %X $DIR/$tfile) # (atime = atime0 + 1)
5334
5335         # Next reads do not update atime
5336         sleep 1
5337         cat $DIR/$tfile >/dev/null
5338         atime2=$(stat -c %X $DIR/$tfile) # (atime = atime0 + 1)
5339
5340         # If mtime is greater than atime, atime is updated
5341         sleep 1
5342         touch -m $DIR/$tfile # (mtime = now)
5343         sleep 1
5344         cat $DIR/$tfile >/dev/null # (atime is updated because atime < mtime)
5345         atime3=$(stat -c %X $DIR/$tfile) # (atime = mtime = atime0 + 3)
5346
5347         # Next reads do not update atime
5348         sleep 1
5349         cat $DIR/$tfile >/dev/null
5350         atime4=$(stat -c %X $DIR/$tfile)
5351
5352         # Remount the client to clear 'relatime' option
5353         remount_client $MOUNT
5354
5355         (( atime0 < atime1 )) ||
5356                 error "atime $atime0 should be smaller than $atime1"
5357         (( atime1 == atime2 )) ||
5358                 error "atime $atime1 was updated to $atime2"
5359         (( atime1 < atime3 )) || error "atime1 $atime1 != atime3 $atime3"
5360         (( atime3 == atime4 )) || error "atime3 $atime3 != atime4 $atime4"
5361 }
5362 run_test 39s "relatime is supported"
5363
5364 test_40() {
5365         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
5366         $RUNAS $OPENFILE -f O_WRONLY:O_TRUNC $DIR/$tfile &&
5367                 error "openfile O_WRONLY:O_TRUNC $tfile failed"
5368         $CHECKSTAT -t file -s 4096 $DIR/$tfile ||
5369                 error "$tfile is not 4096 bytes in size"
5370 }
5371 run_test 40 "failed open(O_TRUNC) doesn't truncate ============="
5372
5373 test_41() {
5374         # bug 1553
5375         small_write $DIR/f41 18
5376 }
5377 run_test 41 "test small file write + fstat ====================="
5378
5379 count_ost_writes() {
5380         lctl get_param -n ${OSC}.*.stats |
5381                 awk -vwrites=0 '/ost_write/ { writes += $2 } \
5382                         END { printf("%0.0f", writes) }'
5383 }
5384
5385 # decent default
5386 WRITEBACK_SAVE=500
5387 DIRTY_RATIO_SAVE=40
5388 MAX_DIRTY_RATIO=50
5389 BG_DIRTY_RATIO_SAVE=10
5390 MAX_BG_DIRTY_RATIO=25
5391
5392 start_writeback() {
5393         trap 0
5394         # in 2.6, restore /proc/sys/vm/dirty_writeback_centisecs,
5395         # dirty_ratio, dirty_background_ratio
5396         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
5397                 sysctl -w vm.dirty_writeback_centisecs=$WRITEBACK_SAVE
5398                 sysctl -w vm.dirty_background_ratio=$BG_DIRTY_RATIO_SAVE
5399                 sysctl -w vm.dirty_ratio=$DIRTY_RATIO_SAVE
5400         else
5401                 # if file not here, we are a 2.4 kernel
5402                 kill -CONT `pidof kupdated`
5403         fi
5404 }
5405
5406 stop_writeback() {
5407         # setup the trap first, so someone cannot exit the test at the
5408         # exact wrong time and mess up a machine
5409         trap start_writeback EXIT
5410         # in 2.6, save and 0 /proc/sys/vm/dirty_writeback_centisecs
5411         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
5412                 WRITEBACK_SAVE=`sysctl -n vm.dirty_writeback_centisecs`
5413                 sysctl -w vm.dirty_writeback_centisecs=0
5414                 sysctl -w vm.dirty_writeback_centisecs=0
5415                 # save and increase /proc/sys/vm/dirty_ratio
5416                 DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_ratio`
5417                 sysctl -w vm.dirty_ratio=$MAX_DIRTY_RATIO
5418                 # save and increase /proc/sys/vm/dirty_background_ratio
5419                 BG_DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_background_ratio`
5420                 sysctl -w vm.dirty_background_ratio=$MAX_BG_DIRTY_RATIO
5421         else
5422                 # if file not here, we are a 2.4 kernel
5423                 kill -STOP `pidof kupdated`
5424         fi
5425 }
5426
5427 # ensure that all stripes have some grant before we test client-side cache
5428 setup_test42() {
5429         for i in `seq -f $DIR/f42-%g 1 $OSTCOUNT`; do
5430                 dd if=/dev/zero of=$i bs=4k count=1
5431                 rm $i
5432         done
5433 }
5434
5435 # Tests 42* verify that our behaviour is correct WRT caching, file closure,
5436 # file truncation, and file removal.
5437 test_42a() {
5438         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5439
5440         setup_test42
5441         cancel_lru_locks $OSC
5442         stop_writeback
5443         sync; sleep 1; sync # just to be safe
5444         BEFOREWRITES=`count_ost_writes`
5445         lctl get_param -n osc.*[oO][sS][cC][_-]*.cur_grant_bytes | grep "[0-9]"
5446         dd if=/dev/zero of=$DIR/f42a bs=1024 count=100
5447         AFTERWRITES=`count_ost_writes`
5448         [ $BEFOREWRITES -eq $AFTERWRITES ] || \
5449                 error "$BEFOREWRITES < $AFTERWRITES"
5450         start_writeback
5451 }
5452 run_test 42a "ensure that we don't flush on close"
5453
5454 test_42b() {
5455         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5456
5457         setup_test42
5458         cancel_lru_locks $OSC
5459         stop_writeback
5460         sync
5461         dd if=/dev/zero of=$DIR/f42b bs=1024 count=100
5462         BEFOREWRITES=$(count_ost_writes)
5463         $MUNLINK $DIR/f42b || error "$MUNLINK $DIR/f42b: $?"
5464         AFTERWRITES=$(count_ost_writes)
5465         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
5466                 error "$BEFOREWRITES < $AFTERWRITES on unlink"
5467         fi
5468         BEFOREWRITES=$(count_ost_writes)
5469         sync || error "sync: $?"
5470         AFTERWRITES=$(count_ost_writes)
5471         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
5472                 error "$BEFOREWRITES < $AFTERWRITES on sync"
5473         fi
5474         dmesg | grep 'error from obd_brw_async' && error 'error writing back'
5475         start_writeback
5476         return 0
5477 }
5478 run_test 42b "test destroy of file with cached dirty data ======"
5479
5480 # if these tests just want to test the effect of truncation,
5481 # they have to be very careful.  consider:
5482 # - the first open gets a {0,EOF}PR lock
5483 # - the first write conflicts and gets a {0, count-1}PW
5484 # - the rest of the writes are under {count,EOF}PW
5485 # - the open for truncate tries to match a {0,EOF}PR
5486 #   for the filesize and cancels the PWs.
5487 # any number of fixes (don't get {0,EOF} on open, match
5488 # composite locks, do smarter file size management) fix
5489 # this, but for now we want these tests to verify that
5490 # the cancellation with truncate intent works, so we
5491 # start the file with a full-file pw lock to match against
5492 # until the truncate.
5493 trunc_test() {
5494         test=$1
5495         file=$DIR/$test
5496         offset=$2
5497         cancel_lru_locks $OSC
5498         stop_writeback
5499         # prime the file with 0,EOF PW to match
5500         touch $file
5501         $TRUNCATE $file 0
5502         sync; sync
5503         # now the real test..
5504         dd if=/dev/zero of=$file bs=1024 count=100
5505         BEFOREWRITES=`count_ost_writes`
5506         $TRUNCATE $file $offset
5507         cancel_lru_locks $OSC
5508         AFTERWRITES=`count_ost_writes`
5509         start_writeback
5510 }
5511
5512 test_42c() {
5513         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5514
5515         trunc_test 42c 1024
5516         [ $BEFOREWRITES -eq $AFTERWRITES ] &&
5517                 error "beforewrites $BEFOREWRITES == afterwrites $AFTERWRITES on truncate"
5518         rm $file
5519 }
5520 run_test 42c "test partial truncate of file with cached dirty data"
5521
5522 test_42d() {
5523         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5524
5525         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
5526         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
5527         $LCTL set_param debug=+cache
5528
5529         trunc_test 42d 0
5530         [ $BEFOREWRITES -eq $AFTERWRITES ] ||
5531                 error "beforewrites $BEFOREWRITES != afterwrites $AFTERWRITES on truncate"
5532         rm $file
5533 }
5534 run_test 42d "test complete truncate of file with cached dirty data"
5535
5536 test_42e() { # bug22074
5537         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5538
5539         local TDIR=$DIR/${tdir}e
5540         local pages=16 # hardcoded 16 pages, don't change it.
5541         local files=$((OSTCOUNT * 500)) # hopefully 500 files on each OST
5542         local proc_osc0="osc.${FSNAME}-OST0000-osc-[^MDT]*"
5543         local max_dirty_mb
5544         local warmup_files
5545
5546         test_mkdir $DIR/${tdir}e
5547         $LFS setstripe -c 1 $TDIR
5548         createmany -o $TDIR/f $files
5549
5550         max_dirty_mb=$($LCTL get_param -n $proc_osc0/max_dirty_mb)
5551
5552         # we assume that with $OSTCOUNT files, at least one of them will
5553         # be allocated on OST0.
5554         warmup_files=$((OSTCOUNT * max_dirty_mb))
5555         createmany -o $TDIR/w $warmup_files
5556
5557         # write a large amount of data into one file and sync, to get good
5558         # avail_grant number from OST.
5559         for ((i=0; i<$warmup_files; i++)); do
5560                 idx=$($LFS getstripe -i $TDIR/w$i)
5561                 [ $idx -ne 0 ] && continue
5562                 dd if=/dev/zero of=$TDIR/w$i bs="$max_dirty_mb"M count=1
5563                 break
5564         done
5565         [[ $i -gt $warmup_files ]] && error "OST0 is still cold"
5566         sync
5567         $LCTL get_param $proc_osc0/cur_dirty_bytes
5568         $LCTL get_param $proc_osc0/cur_grant_bytes
5569
5570         # create as much dirty pages as we can while not to trigger the actual
5571         # RPCs directly. but depends on the env, VFS may trigger flush during this
5572         # period, hopefully we are good.
5573         for ((i=0; i<$warmup_files; i++)); do
5574                 idx=$($LFS getstripe -i $TDIR/w$i)
5575                 [ $idx -ne 0 ] && continue
5576                 dd if=/dev/zero of=$TDIR/w$i bs=1M count=1 2>/dev/null
5577         done
5578         $LCTL get_param $proc_osc0/cur_dirty_bytes
5579         $LCTL get_param $proc_osc0/cur_grant_bytes
5580
5581         # perform the real test
5582         $LCTL set_param $proc_osc0/rpc_stats 0
5583         for ((;i<$files; i++)); do
5584                 [ $($LFS getstripe -i $TDIR/f$i) -eq 0 ] || continue
5585                 dd if=/dev/zero of=$TDIR/f$i bs=$PAGE_SIZE count=$pages 2>/dev/null
5586         done
5587         sync
5588         $LCTL get_param $proc_osc0/rpc_stats
5589
5590         local percent=0
5591         local have_ppr=false
5592         $LCTL get_param $proc_osc0/rpc_stats |
5593                 while read PPR RRPC RPCT RCUM BAR WRPC WPCT WCUM; do
5594                         # skip lines until we are at the RPC histogram data
5595                         [ "$PPR" == "pages" ] && have_ppr=true && continue
5596                         $have_ppr || continue
5597
5598                         # we only want the percent stat for < 16 pages
5599                         [[ $(echo $PPR | tr -d ':') -ge $pages ]] && break
5600
5601                         percent=$((percent + WPCT))
5602                         if [[ $percent -gt 15 ]]; then
5603                                 error "less than 16-pages write RPCs" \
5604                                       "$percent% > 15%"
5605                                 break
5606                         fi
5607                 done
5608         rm -rf $TDIR
5609 }
5610 run_test 42e "verify sub-RPC writes are not done synchronously"
5611
5612 test_43A() { # was test_43
5613         test_mkdir $DIR/$tdir
5614         cp -p /bin/ls $DIR/$tdir/$tfile
5615         $MULTIOP $DIR/$tdir/$tfile Ow_c &
5616         pid=$!
5617         # give multiop a chance to open
5618         sleep 1
5619
5620         $DIR/$tdir/$tfile && error "execute $DIR/$tdir/$tfile succeeded" || true
5621         kill -USR1 $pid
5622         # Wait for multiop to exit
5623         wait $pid
5624 }
5625 run_test 43A "execution of file opened for write should return -ETXTBSY"
5626
5627 test_43a() {
5628         test_mkdir $DIR/$tdir
5629         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
5630         $DIR/$tdir/sleep 60 &
5631         SLEEP_PID=$!
5632         # Make sure exec of $tdir/sleep wins race with truncate
5633         sleep 1
5634         $MULTIOP $DIR/$tdir/sleep Oc && error "expected error, got success"
5635         kill $SLEEP_PID
5636 }
5637 run_test 43a "open(RDWR) of file being executed should return -ETXTBSY"
5638
5639 test_43b() {
5640         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5641
5642         test_mkdir $DIR/$tdir
5643         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
5644         $DIR/$tdir/sleep 60 &
5645         SLEEP_PID=$!
5646         # Make sure exec of $tdir/sleep wins race with truncate
5647         sleep 1
5648         $TRUNCATE $DIR/$tdir/sleep 0 && error "expected error, got success"
5649         kill $SLEEP_PID
5650 }
5651 run_test 43b "truncate of file being executed should return -ETXTBSY"
5652
5653 test_43c() {
5654         local testdir="$DIR/$tdir"
5655         test_mkdir $testdir
5656         cp $SHELL $testdir/
5657         ( cd $(dirname $SHELL) && md5sum $(basename $SHELL) ) |
5658                 ( cd $testdir && md5sum -c )
5659 }
5660 run_test 43c "md5sum of copy into lustre"
5661
5662 test_44A() { # was test_44
5663         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5664
5665         dd if=/dev/zero of=$DIR/f1 bs=4k count=1 seek=1023
5666         dd if=$DIR/f1 bs=4k count=1 > /dev/null
5667 }
5668 run_test 44A "zero length read from a sparse stripe"
5669
5670 test_44a() {
5671         local nstripe=$($LFS getstripe -c -d $DIR)
5672         [ -z "$nstripe" ] && skip "can't get stripe info"
5673         [[ $nstripe -gt $OSTCOUNT ]] &&
5674                 skip "Wrong default stripe_count: $nstripe OSTCOUNT: $OSTCOUNT"
5675
5676         local stride=$($LFS getstripe -S -d $DIR)
5677         if [[ $nstripe -eq 0 || $nstripe -eq -1 ]]; then
5678                 nstripe=$($LFS df $DIR | grep OST: | wc -l)
5679         fi
5680
5681         OFFSETS="0 $((stride/2)) $((stride-1))"
5682         for offset in $OFFSETS; do
5683                 for i in $(seq 0 $((nstripe-1))); do
5684                         local GLOBALOFFSETS=""
5685                         # size in Bytes
5686                         local size=$((((i + 2 * $nstripe )*$stride + $offset)))
5687                         local myfn=$DIR/d44a-$size
5688                         echo "--------writing $myfn at $size"
5689                         ll_sparseness_write $myfn $size ||
5690                                 error "ll_sparseness_write"
5691                         GLOBALOFFSETS="$GLOBALOFFSETS $size"
5692                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
5693                                 error "ll_sparseness_verify $GLOBALOFFSETS"
5694
5695                         for j in $(seq 0 $((nstripe-1))); do
5696                                 # size in Bytes
5697                                 size=$((((j + $nstripe )*$stride + $offset)))
5698                                 ll_sparseness_write $myfn $size ||
5699                                         error "ll_sparseness_write"
5700                                 GLOBALOFFSETS="$GLOBALOFFSETS $size"
5701                         done
5702                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
5703                                 error "ll_sparseness_verify $GLOBALOFFSETS"
5704                         rm -f $myfn
5705                 done
5706         done
5707 }
5708 run_test 44a "test sparse pwrite ==============================="
5709
5710 dirty_osc_total() {
5711         tot=0
5712         for d in `lctl get_param -n ${OSC}.*.cur_dirty_bytes`; do
5713                 tot=$(($tot + $d))
5714         done
5715         echo $tot
5716 }
5717 do_dirty_record() {
5718         before=`dirty_osc_total`
5719         echo executing "\"$*\""
5720         eval $*
5721         after=`dirty_osc_total`
5722         echo before $before, after $after
5723 }
5724 test_45() {
5725         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5726
5727         f="$DIR/f45"
5728         # Obtain grants from OST if it supports it
5729         echo blah > ${f}_grant
5730         stop_writeback
5731         sync
5732         do_dirty_record "echo blah > $f"
5733         [[ $before -eq $after ]] && error "write wasn't cached"
5734         do_dirty_record "> $f"
5735         [[ $before -gt $after ]] || error "truncate didn't lower dirty count"
5736         do_dirty_record "echo blah > $f"
5737         [[ $before -eq $after ]] && error "write wasn't cached"
5738         do_dirty_record "sync"
5739         [[ $before -gt $after ]] || error "writeback didn't lower dirty count"
5740         do_dirty_record "echo blah > $f"
5741         [[ $before -eq $after ]] && error "write wasn't cached"
5742         do_dirty_record "cancel_lru_locks osc"
5743         [[ $before -gt $after ]] ||
5744                 error "lock cancellation didn't lower dirty count"
5745         start_writeback
5746 }
5747 run_test 45 "osc io page accounting ============================"
5748
5749 # in a 2 stripe file (lov.sh), page 1023 maps to page 511 in its object.  this
5750 # test tickles a bug where re-dirtying a page was failing to be mapped to the
5751 # objects offset and an assert hit when an rpc was built with 1023's mapped
5752 # offset 511 and 511's raw 511 offset. it also found general redirtying bugs.
5753 test_46() {
5754         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5755
5756         f="$DIR/f46"
5757         stop_writeback
5758         sync
5759         dd if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5760         sync
5761         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=1023 count=1
5762         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5763         sync
5764         start_writeback
5765 }
5766 run_test 46 "dirtying a previously written page ================"
5767
5768 # test_47 is removed "Device nodes check" is moved to test_28
5769
5770 test_48a() { # bug 2399
5771         [ "$mds1_FSTYPE" = "zfs" ] &&
5772         [ $MDS1_VERSION -lt $(version_code 2.3.63) ] &&
5773                 skip "MDS prior to 2.3.63 handle ZFS dir .. incorrectly"
5774
5775         test_mkdir $DIR/$tdir
5776         cd $DIR/$tdir
5777         mv $DIR/$tdir $DIR/$tdir.new || error "move directory failed"
5778         test_mkdir $DIR/$tdir
5779         touch foo || error "'touch foo' failed after recreating cwd"
5780         test_mkdir bar
5781         touch .foo || error "'touch .foo' failed after recreating cwd"
5782         test_mkdir .bar
5783         ls . > /dev/null || error "'ls .' failed after recreating cwd"
5784         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5785         cd . || error "'cd .' failed after recreating cwd"
5786         mkdir . && error "'mkdir .' worked after recreating cwd"
5787         rmdir . && error "'rmdir .' worked after recreating cwd"
5788         ln -s . baz || error "'ln -s .' failed after recreating cwd"
5789         cd .. || error "'cd ..' failed after recreating cwd"
5790 }
5791 run_test 48a "Access renamed working dir (should return errors)="
5792
5793 test_48b() { # bug 2399
5794         rm -rf $DIR/$tdir
5795         test_mkdir $DIR/$tdir
5796         cd $DIR/$tdir
5797         rmdir $DIR/$tdir || error "remove cwd $DIR/$tdir failed"
5798         touch foo && error "'touch foo' worked after removing cwd"
5799         mkdir foo && error "'mkdir foo' worked after removing cwd"
5800         touch .foo && error "'touch .foo' worked after removing cwd"
5801         mkdir .foo && error "'mkdir .foo' worked after removing cwd"
5802         ls . > /dev/null && error "'ls .' worked after removing cwd"
5803         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5804         mkdir . && error "'mkdir .' worked after removing cwd"
5805         rmdir . && error "'rmdir .' worked after removing cwd"
5806         ln -s . foo && error "'ln -s .' worked after removing cwd"
5807         cd .. || echo "'cd ..' failed after removing cwd `pwd`"  #bug 3517
5808 }
5809 run_test 48b "Access removed working dir (should return errors)="
5810
5811 test_48c() { # bug 2350
5812         #lctl set_param debug=-1
5813         #set -vx
5814         rm -rf $DIR/$tdir
5815         test_mkdir -p $DIR/$tdir/dir
5816         cd $DIR/$tdir/dir
5817         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5818         $TRACE touch foo && error "touch foo worked after removing cwd"
5819         $TRACE mkdir foo && error "'mkdir foo' worked after removing cwd"
5820         touch .foo && error "touch .foo worked after removing cwd"
5821         mkdir .foo && error "mkdir .foo worked after removing cwd"
5822         $TRACE ls . && error "'ls .' worked after removing cwd"
5823         $TRACE ls .. || error "'ls ..' failed after removing cwd"
5824         $TRACE mkdir . && error "'mkdir .' worked after removing cwd"
5825         $TRACE rmdir . && error "'rmdir .' worked after removing cwd"
5826         $TRACE ln -s . foo && error "'ln -s .' worked after removing cwd"
5827         $TRACE cd .. || echo "'cd ..' failed after removing cwd `pwd`" #bug 3415
5828 }
5829 run_test 48c "Access removed working subdir (should return errors)"
5830
5831 test_48d() { # bug 2350
5832         #lctl set_param debug=-1
5833         #set -vx
5834         rm -rf $DIR/$tdir
5835         test_mkdir -p $DIR/$tdir/dir
5836         cd $DIR/$tdir/dir
5837         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5838         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5839         $TRACE touch foo && error "'touch foo' worked after removing parent"
5840         $TRACE mkdir foo && error "mkdir foo worked after removing parent"
5841         touch .foo && error "'touch .foo' worked after removing parent"
5842         mkdir .foo && error "mkdir .foo worked after removing parent"
5843         $TRACE ls . && error "'ls .' worked after removing parent"
5844         $TRACE ls .. && error "'ls ..' worked after removing parent"
5845         $TRACE mkdir . && error "'mkdir .' worked after removing parent"
5846         $TRACE rmdir . && error "'rmdir .' worked after removing parent"
5847         $TRACE ln -s . foo && error "'ln -s .' worked after removing parent"
5848         true
5849 }
5850 run_test 48d "Access removed parent subdir (should return errors)"
5851
5852 test_48e() { # bug 4134
5853         #lctl set_param debug=-1
5854         #set -vx
5855         rm -rf $DIR/$tdir
5856         test_mkdir -p $DIR/$tdir/dir
5857         cd $DIR/$tdir/dir
5858         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5859         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5860         $TRACE touch $DIR/$tdir || error "'touch $DIR/$tdir' failed"
5861         $TRACE chmod +x $DIR/$tdir || error "'chmod +x $DIR/$tdir' failed"
5862         # On a buggy kernel addition of "touch foo" after cd .. will
5863         # produce kernel oops in lookup_hash_it
5864         touch ../foo && error "'cd ..' worked after recreate parent"
5865         cd $DIR
5866         $TRACE rm $DIR/$tdir || error "rm '$DIR/$tdir' failed"
5867 }
5868 run_test 48e "Access to recreated parent subdir (should return errors)"
5869
5870 test_48f() {
5871         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
5872                 skip "need MDS >= 2.13.55"
5873         [[ $MDSCOUNT -ge 2 ]] || skip "needs >= 2 MDTs"
5874         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] ||
5875                 skip "needs different host for mdt1 mdt2"
5876         [[ $(facet_fstype mds1) == ldiskfs ]] || skip "ldiskfs only"
5877
5878         $LFS mkdir -i0 $DIR/$tdir
5879         $LFS mkdir -i 1 $DIR/$tdir/sub1 $DIR/$tdir/sub2 $DIR/$tdir/sub3
5880
5881         for d in sub1 sub2 sub3; do
5882                 #define OBD_FAIL_OSD_REF_DEL    0x19c
5883                 do_facet mds1 $LCTL set_param fail_loc=0x8000019c
5884                 rm -rf $DIR/$tdir/$d && error "rm $d should fail"
5885         done
5886
5887         rm -d --interactive=never $DIR/$tdir || error "rm $tdir fail"
5888 }
5889 run_test 48f "non-zero nlink dir unlink won't LBUG()"
5890
5891 test_49() { # LU-1030
5892         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5893         remote_ost_nodsh && skip "remote OST with nodsh"
5894
5895         # get ost1 size - $FSNAME-OST0000
5896         ost1_size=$(do_facet ost1 $LFS df | grep ${ost1_svc} |
5897                 awk '{ print $4 }')
5898         # write 800M at maximum
5899         [[ $ost1_size -lt 2 ]] && ost1_size=2
5900         [[ $ost1_size -gt 819200 ]] && ost1_size=819200
5901
5902         $LFS setstripe -c 1 -i 0 $DIR/$tfile
5903         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((ost1_size >> 2)) &
5904         local dd_pid=$!
5905
5906         # change max_pages_per_rpc while writing the file
5907         local osc1_mppc=osc.$(get_osc_import_name client ost1).max_pages_per_rpc
5908         local orig_mppc=$($LCTL get_param -n $osc1_mppc)
5909         # loop until dd process exits
5910         while ps ax -opid | grep -wq $dd_pid; do
5911                 $LCTL set_param $osc1_mppc=$((RANDOM % 256 + 1))
5912                 sleep $((RANDOM % 5 + 1))
5913         done
5914         # restore original max_pages_per_rpc
5915         $LCTL set_param $osc1_mppc=$orig_mppc
5916         rm $DIR/$tfile || error "rm $DIR/$tfile failed"
5917 }
5918 run_test 49 "Change max_pages_per_rpc won't break osc extent"
5919
5920 test_50() {
5921         # bug 1485
5922         test_mkdir $DIR/$tdir
5923         cd $DIR/$tdir
5924         ls /proc/$$/cwd || error "ls /proc/$$/cwd failed"
5925 }
5926 run_test 50 "special situations: /proc symlinks  ==============="
5927
5928 test_51a() {    # was test_51
5929         # bug 1516 - create an empty entry right after ".." then split dir
5930         test_mkdir -c1 $DIR/$tdir
5931         touch $DIR/$tdir/foo
5932         $MCREATE $DIR/$tdir/bar
5933         rm $DIR/$tdir/foo
5934         createmany -m $DIR/$tdir/longfile 201
5935         FNUM=202
5936         while [[ $(ls -sd $DIR/$tdir | awk '{ print $1 }') -eq 4 ]]; do
5937                 $MCREATE $DIR/$tdir/longfile$FNUM
5938                 FNUM=$(($FNUM + 1))
5939                 echo -n "+"
5940         done
5941         echo
5942         ls -l $DIR/$tdir > /dev/null || error "ls -l $DIR/$tdir failed"
5943 }
5944 run_test 51a "special situations: split htree with empty entry =="
5945
5946 cleanup_print_lfs_df () {
5947         trap 0
5948         $LFS df
5949         $LFS df -i
5950 }
5951
5952 test_51b() {
5953         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5954
5955         local dir=$DIR/$tdir
5956         local nrdirs=$((65536 + 100))
5957
5958         # cleanup the directory
5959         rm -fr $dir
5960
5961         mkdir_on_mdt -i $((RANDOM % MDSCOUNT)) $dir
5962
5963         $LFS df
5964         $LFS df -i
5965         local mdtidx=$(printf "%04x" $($LFS getstripe -m $dir))
5966         local numfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.filesfree)
5967         [[ $numfree -lt $nrdirs ]] &&
5968                 skip "not enough free inodes ($numfree) on MDT$mdtidx"
5969
5970         # need to check free space for the directories as well
5971         local blkfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.kbytesavail)
5972         numfree=$(( blkfree / $(fs_inode_ksize) ))
5973         [[ $numfree -lt $nrdirs ]] && skip "not enough blocks ($numfree)"
5974
5975         trap cleanup_print_lfs_df EXIT
5976
5977         # create files
5978         createmany -d $dir/d $nrdirs || {
5979                 unlinkmany $dir/d $nrdirs
5980                 error "failed to create $nrdirs subdirs in MDT$mdtidx:$dir"
5981         }
5982
5983         # really created :
5984         nrdirs=$(ls -U $dir | wc -l)
5985
5986         # unlink all but 100 subdirectories, then check it still works
5987         local left=100
5988         local delete=$((nrdirs - left))
5989
5990         $LFS df
5991         $LFS df -i
5992
5993         # for ldiskfs the nlink count should be 1, but this is OSD specific
5994         # and so this is listed for informational purposes only
5995         echo "nlink before: $(stat -c %h $dir), created before: $nrdirs"
5996         unlinkmany -d $dir/d $delete ||
5997                 error "unlink of first $delete subdirs failed"
5998
5999         echo "nlink between: $(stat -c %h $dir)"
6000         local found=$(ls -U $dir | wc -l)
6001         [ $found -ne $left ] &&
6002                 error "can't find subdirs: found only $found, expected $left"
6003
6004         unlinkmany -d $dir/d $delete $left ||
6005                 error "unlink of second $left subdirs failed"
6006         # regardless of whether the backing filesystem tracks nlink accurately
6007         # or not, the nlink count shouldn't be more than "." and ".." here
6008         local after=$(stat -c %h $dir)
6009         [[ $after -gt 2 ]] && error "nlink after: $after > 2" ||
6010                 echo "nlink after: $after"
6011
6012         cleanup_print_lfs_df
6013 }
6014 run_test 51b "exceed 64k subdirectory nlink limit on create, verify unlink"
6015
6016 test_51d_sub() {
6017         local stripecount=$1
6018         local nfiles=$2
6019
6020         log "create files with stripecount=$stripecount"
6021         $LFS setstripe -C $stripecount $DIR/$tdir
6022         createmany -o $DIR/$tdir/t- $nfiles
6023         $LFS getstripe $DIR/$tdir > $TMP/$tfile
6024         for ((n = 0; n < $OSTCOUNT; n++)); do
6025                 objs[$n]=$(awk -vobjs=0 '($1 == '$n') { objs += 1 } \
6026                            END { printf("%0.0f", objs) }' $TMP/$tfile)
6027                 objs0[$n]=$(grep -A 1 idx $TMP/$tfile | awk -vobjs=0 \
6028                             '($1 == '$n') { objs += 1 } \
6029                             END { printf("%0.0f", objs) }')
6030                 log "OST$n has ${objs[$n]} objects, ${objs0[$n]} are index 0"
6031         done
6032         unlinkmany $DIR/$tdir/t- $nfiles
6033         rm  -f $TMP/$tfile
6034
6035         local nlast
6036         local min=4
6037         local max=6 # allow variance of (1 - $min/$max) = 33% by default
6038
6039         # For some combinations of stripecount and OSTCOUNT current code
6040         # is not ideal, and allocates 50% fewer *first* objects to some OSTs
6041         # than others. Rather than skipping this test entirely, check that
6042         # and keep testing to ensure imbalance does not get worse. LU-15282
6043         (( (OSTCOUNT == 6 && stripecount == 4) ||
6044            (OSTCOUNT == 10 && (stripecount == 4 || stripecount == 8)) ||
6045            (OSTCOUNT == 12 && (stripecount == 8 || stripecount == 9)))) && max=9
6046         for ((nlast=0, n = 1; n < $OSTCOUNT; nlast=n,n++)); do
6047                 (( ${objs[$n]} > ${objs[$nlast]} * 4 / 5 )) ||
6048                         { $LFS df && $LFS df -i &&
6049                         error "stripecount=$stripecount: " \
6050                               "OST $n has fewer objects vs. OST $nlast " \
6051                               "(${objs[$n]} < ${objs[$nlast]} x 4/5)"; }
6052                 (( ${objs[$n]} < ${objs[$nlast]} * 5 / 4 )) ||
6053                         { $LFS df && $LFS df -i &&
6054                         error "stripecount=$stripecount: " \
6055                               "OST $n has more objects vs. OST $nlast " \
6056                               "(${objs[$n]} > ${objs[$nlast]} x 5/4)"; }
6057
6058                 (( ${objs0[$n]} > ${objs0[$nlast]} * $min / $max )) ||
6059                         { $LFS df && $LFS df -i &&
6060                         error "stripecount=$stripecount: " \
6061                               "OST $n has fewer #0 objects vs. OST $nlast " \
6062                               "(${objs0[$n]} < ${objs0[$nlast]} x $min/$max)"; }
6063                 (( ${objs0[$n]} < ${objs0[$nlast]} * $max / $min )) ||
6064                         { $LFS df && $LFS df -i &&
6065                         error "stripecount=$stripecount: " \
6066                               "OST $n has more #0 objects vs. OST $nlast " \
6067                               "(${objs0[$n]} > ${objs0[$nlast]} x $max/$min)"; }
6068         done
6069 }
6070
6071 test_51d() {
6072         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6073         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
6074
6075         local stripecount
6076         local per_ost=100
6077         local nfiles=$((per_ost * OSTCOUNT))
6078         local mdts=$(comma_list $(mdts_nodes))
6079         local param="osp.*.create_count"
6080         local qos_old=$(do_facet mds1 \
6081                 "$LCTL get_param -n lod.$FSNAME-*.qos_threshold_rr" | head -n 1)
6082
6083         do_nodes $mdts \
6084                 "$LCTL set_param lod.$FSNAME-*.qos_threshold_rr=100"
6085         stack_trap "do_nodes $mdts \
6086                 '$LCTL set_param lod.$FSNAME-*.qos_threshold_rr=${qos_old%%%}'"
6087
6088         test_mkdir $DIR/$tdir
6089         local dirstripes=$(lfs getdirstripe -c $DIR/$tdir)
6090         (( dirstripes > 0 )) || dirstripes=1
6091
6092         # Ensure enough OST objects precreated for tests to pass without
6093         # running out of objects.  This is an LOV r-r OST algorithm test,
6094         # not an OST object precreation test.
6095         local old=$(do_facet mds1 "$LCTL get_param -n $param" | head -n 1)
6096         (( old >= nfiles )) ||
6097         {
6098                 local create_count=$((nfiles * OSTCOUNT / dirstripes))
6099
6100                 do_nodes $mdts "$LCTL set_param $param=$create_count"
6101                 stack_trap "do_nodes $mdts $LCTL set_param $param=$old"
6102
6103                 # trigger precreation from all MDTs for all OSTs
6104                 for ((i = 0; i < $MDSCOUNT * 2; i++ )); do
6105                         $LFS setstripe -c -1 $DIR/$tdir/wide.$i
6106                 done
6107         }
6108
6109         for ((stripecount = 3; stripecount <= $OSTCOUNT; stripecount++)); do
6110                 sleep 8  # allow object precreation to catch up
6111                 test_51d_sub $stripecount $nfiles
6112         done
6113 }
6114 run_test 51d "check LOV round-robin OST object distribution"
6115
6116 test_51e() {
6117         if [ "$mds1_FSTYPE" != ldiskfs ]; then
6118                 skip_env "ldiskfs only test"
6119         fi
6120
6121         test_mkdir -c1 $DIR/$tdir
6122         test_mkdir -c1 $DIR/$tdir/d0
6123
6124         touch $DIR/$tdir/d0/foo
6125         createmany -l $DIR/$tdir/d0/foo $DIR/$tdir/d0/f- 65001 &&
6126                 error "file exceed 65000 nlink limit!"
6127         unlinkmany $DIR/$tdir/d0/f- 65001
6128         return 0
6129 }
6130 run_test 51e "check file nlink limit"
6131
6132 test_51f() {
6133         test_mkdir $DIR/$tdir
6134
6135         local max=100000
6136         local ulimit_old=$(ulimit -n)
6137         local spare=20 # number of spare fd's for scripts/libraries, etc.
6138         local mdt=$($LFS getstripe -m $DIR/$tdir)
6139         local numfree=$($LFS df -i $DIR/$tdir | awk '/MDT:'$mdt'/ { print $4 }')
6140
6141         echo "MDT$mdt numfree=$numfree, max=$max"
6142         [[ $numfree -gt $max ]] && numfree=$max || numfree=$((numfree * 7 / 8))
6143         if [ $((numfree + spare)) -gt $ulimit_old ]; then
6144                 while ! ulimit -n $((numfree + spare)); do
6145                         numfree=$((numfree * 3 / 4))
6146                 done
6147                 echo "changed ulimit from $ulimit_old to $((numfree + spare))"
6148         else
6149                 echo "left ulimit at $ulimit_old"
6150         fi
6151
6152         createmany -o -k -t 120 $DIR/$tdir/f $numfree || {
6153                 unlinkmany $DIR/$tdir/f $numfree
6154                 error "create+open $numfree files in $DIR/$tdir failed"
6155         }
6156         ulimit -n $ulimit_old
6157
6158         # if createmany exits at 120s there will be fewer than $numfree files
6159         unlinkmany $DIR/$tdir/f $numfree || true
6160 }
6161 run_test 51f "check many open files limit"
6162
6163 test_52a() {
6164         [ -f $DIR/$tdir/foo ] && chattr -a $DIR/$tdir/foo
6165         test_mkdir $DIR/$tdir
6166         touch $DIR/$tdir/foo
6167         chattr +a $DIR/$tdir/foo || error "chattr +a failed"
6168         echo bar >> $DIR/$tdir/foo || error "append bar failed"
6169         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
6170         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
6171         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
6172                                         error "link worked"
6173         echo foo >> $DIR/$tdir/foo || error "append foo failed"
6174         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
6175         lsattr $DIR/$tdir/foo | egrep -q "^-+a[-e]+ $DIR/$tdir/foo" ||
6176                                                      error "lsattr"
6177         chattr -a $DIR/$tdir/foo || error "chattr -a failed"
6178         cp -r $DIR/$tdir $TMP/
6179         rm -fr $DIR/$tdir $TMP/$tdir || error "cleanup rm failed"
6180 }
6181 run_test 52a "append-only flag test (should return errors)"
6182
6183 test_52b() {
6184         [ -f $DIR/$tdir/foo ] && chattr -i $DIR/$tdir/foo
6185         test_mkdir $DIR/$tdir
6186         touch $DIR/$tdir/foo
6187         chattr +i $DIR/$tdir/foo || error "chattr +i failed"
6188         cat test > $DIR/$tdir/foo && error "cat test worked"
6189         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
6190         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
6191         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
6192                                         error "link worked"
6193         echo foo >> $DIR/$tdir/foo && error "echo worked"
6194         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
6195         [ -f $DIR/$tdir/foo ] || error "$tdir/foo is not a file"
6196         [ -f $DIR/$tdir/foo_ren ] && error "$tdir/foo_ren is not a file"
6197         lsattr $DIR/$tdir/foo | egrep -q "^-+i[-e]+ $DIR/$tdir/foo" ||
6198                                                         error "lsattr"
6199         chattr -i $DIR/$tdir/foo || error "chattr failed"
6200
6201         rm -fr $DIR/$tdir || error "unable to remove $DIR/$tdir"
6202 }
6203 run_test 52b "immutable flag test (should return errors) ======="
6204
6205 test_53() {
6206         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6207         remote_mds_nodsh && skip "remote MDS with nodsh"
6208         remote_ost_nodsh && skip "remote OST with nodsh"
6209
6210         local param
6211         local param_seq
6212         local ostname
6213         local mds_last
6214         local mds_last_seq
6215         local ost_last
6216         local ost_last_seq
6217         local ost_last_id
6218         local ostnum
6219         local node
6220         local found=false
6221         local support_last_seq=true
6222
6223         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
6224                 support_last_seq=false
6225
6226         # only test MDT0000
6227         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS)
6228         local value
6229         for value in $(do_facet $SINGLEMDS \
6230                        $LCTL get_param osp.$mdtosc.prealloc_last_id) ; do
6231                 param=$(echo ${value[0]} | cut -d "=" -f1)
6232                 ostname=$(echo $param | cut -d "." -f2 | cut -d - -f 1-2)
6233
6234                 if $support_last_seq; then
6235                         param_seq=$(echo $param |
6236                                 sed -e s/prealloc_last_id/prealloc_last_seq/g)
6237                         mds_last_seq=$(do_facet $SINGLEMDS \
6238                                        $LCTL get_param -n $param_seq)
6239                 fi
6240                 mds_last=$(do_facet $SINGLEMDS $LCTL get_param -n $param)
6241
6242                 ostnum=$(index_from_ostuuid ${ostname}_UUID)
6243                 node=$(facet_active_host ost$((ostnum+1)))
6244                 param="obdfilter.$ostname.last_id"
6245                 for ost_last in $(do_node $node $LCTL get_param -n $param) ; do
6246                         echo "$ostname.last_id=$ost_last; MDS.last_id=$mds_last"
6247                         ost_last_id=$ost_last
6248
6249                         if $support_last_seq; then
6250                                 ost_last_id=$(echo $ost_last |
6251                                               awk -F':' '{print $2}' |
6252                                               sed -e "s/^0x//g")
6253                                 ost_last_seq=$(echo $ost_last |
6254                                                awk -F':' '{print $1}')
6255                                 [[ $ost_last_seq = $mds_last_seq ]] || continue
6256                         fi
6257
6258                         if [[ $ost_last_id != $mds_last ]]; then
6259                                 error "$ost_last_id != $mds_last"
6260                         else
6261                                 found=true
6262                                 break
6263                         fi
6264                 done
6265         done
6266         $found || error "can not match last_seq/last_id for $mdtosc"
6267         return 0
6268 }
6269 run_test 53 "verify that MDS and OSTs agree on pre-creation ===="
6270
6271 test_54a() {
6272         LANG=C perl -MSocket -e ';' || skip "no Socket perl module installed"
6273
6274         LANG=C $SOCKETSERVER $DIR/socket ||
6275                 error "$SOCKETSERVER $DIR/socket failed: $?"
6276         LANG=C $SOCKETCLIENT $DIR/socket ||
6277                 error "$SOCKETCLIENT $DIR/socket failed: $?"
6278         $MUNLINK $DIR/socket || error "$MUNLINK $DIR/socket failed: $?"
6279 }
6280 run_test 54a "unix domain socket test =========================="
6281
6282 test_54b() {
6283         f="$DIR/f54b"
6284         mknod $f c 1 3
6285         chmod 0666 $f
6286         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1
6287 }
6288 run_test 54b "char device works in lustre ======================"
6289
6290 find_loop_dev() {
6291         [ -b /dev/loop/0 ] && LOOPBASE=/dev/loop/
6292         [ -b /dev/loop0 ] && LOOPBASE=/dev/loop
6293         [ -z "$LOOPBASE" ] && echo "/dev/loop/0 and /dev/loop0 gone?" && return
6294
6295         for i in $(seq 3 7); do
6296                 losetup $LOOPBASE$i > /dev/null 2>&1 && continue
6297                 LOOPDEV=$LOOPBASE$i
6298                 LOOPNUM=$i
6299                 break
6300         done
6301 }
6302
6303 cleanup_54c() {
6304         local rc=0
6305         loopdev="$DIR/loop54c"
6306
6307         trap 0
6308         $UMOUNT $DIR/$tdir || rc=$?
6309         losetup -d $loopdev || true
6310         losetup -d $LOOPDEV || true
6311         rm -rf $loopdev $DIR/$tfile $DIR/$tdir
6312         return $rc
6313 }
6314
6315 test_54c() {
6316         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6317
6318         loopdev="$DIR/loop54c"
6319
6320         find_loop_dev
6321         [ -z "$LOOPNUM" ] && skip_env "couldn't find empty loop device"
6322         trap cleanup_54c EXIT
6323         mknod $loopdev b 7 $LOOPNUM
6324         echo "make a loop file system with $DIR/$tfile on $loopdev ($LOOPNUM)."
6325         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE seek=1024 count=1 > /dev/null
6326         losetup $loopdev $DIR/$tfile ||
6327                 error "can't set up $loopdev for $DIR/$tfile"
6328         mkfs.ext2 $loopdev || error "mke2fs on $loopdev"
6329         test_mkdir $DIR/$tdir
6330         mount -t ext2 $loopdev $DIR/$tdir ||
6331                 error "error mounting $loopdev on $DIR/$tdir"
6332         dd if=/dev/zero of=$DIR/$tdir/tmp bs=$PAGE_SIZE count=30 ||
6333                 error "dd write"
6334         df $DIR/$tdir
6335         dd if=$DIR/$tdir/tmp of=/dev/zero bs=$PAGE_SIZE count=30 ||
6336                 error "dd read"
6337         cleanup_54c
6338 }
6339 run_test 54c "block device works in lustre ====================="
6340
6341 test_54d() {
6342         local pipe="$DIR/$tfile.pipe"
6343         local string="aaaaaa"
6344
6345         mknod $pipe p
6346         echo -n "$string" > $pipe &
6347         local result=$(cat $pipe)
6348         [[ "$result" == "$string" ]] || error "$result != $string"
6349 }
6350 run_test 54d "fifo device works in lustre ======================"
6351
6352 test_54e() {
6353         f="$DIR/f54e"
6354         string="aaaaaa"
6355         cp -aL /dev/console $f
6356         echo $string > $f || error "echo $string to $f failed"
6357 }
6358 run_test 54e "console/tty device works in lustre ======================"
6359
6360 test_56a() {
6361         local numfiles=3
6362         local numdirs=2
6363         local dir=$DIR/$tdir
6364
6365         rm -rf $dir
6366         test_mkdir -p $dir/dir
6367         for i in $(seq $numfiles); do
6368                 touch $dir/file$i
6369                 touch $dir/dir/file$i
6370         done
6371
6372         local numcomp=$($LFS getstripe --component-count $dir)
6373
6374         [[ $numcomp == 0 ]] && numcomp=1
6375
6376         # test lfs getstripe with --recursive
6377         local filenum=$($LFS getstripe -r $dir | egrep -c "obdidx|l_ost_idx")
6378
6379         [[ $filenum -eq $((numfiles * 2)) ]] ||
6380                 error "$LFS getstripe -r: found $filenum != $((numfiles * 2))"
6381         filenum=$($LFS getstripe $dir | egrep -c "obdidx|l_ost_idx")
6382         [[ $filenum -eq $numfiles ]] ||
6383                 error "$LFS getstripe $dir: found $filenum, not $numfiles"
6384         echo "$LFS getstripe showed obdidx or l_ost_idx"
6385
6386         # test lfs getstripe with file instead of dir
6387         filenum=$($LFS getstripe $dir/file1 | egrep -c "obdidx|l_ost_idx")
6388         [[ $filenum -eq 1 ]] ||
6389                 error "$LFS getstripe $dir/file1: found $filenum, not 1"
6390         echo "$LFS getstripe file1 passed"
6391
6392         #test lfs getstripe with --verbose
6393         filenum=$($LFS getstripe --verbose $dir | grep -c lmm_magic)
6394         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
6395                 error "$LFS getstripe --verbose $dir: "\
6396                       "got $filenum want $((numfiles * numcomp)) lmm_magic"
6397         [[ $($LFS getstripe $dir | grep -c lmm_magic) -eq 0 ]] ||
6398                 error "$LFS getstripe $dir: showed lmm_magic"
6399
6400         #test lfs getstripe with -v prints lmm_fid
6401         filenum=$($LFS getstripe -v $dir | grep -c lmm_fid)
6402         local countfids=$((numdirs + numfiles * numcomp))
6403         [[ $filenum -eq $countfids ]] ||
6404                 error "$LFS getstripe -v $dir: "\
6405                       "got $filenum want $countfids lmm_fid"
6406         [[ $($LFS getstripe $dir | grep -c lmm_fid) -eq 0 ]] ||
6407                 error "$LFS getstripe $dir: showed lmm_fid by default"
6408         echo "$LFS getstripe --verbose passed"
6409
6410         #check for FID information
6411         local fid1=$($LFS getstripe --fid $dir/file1)
6412         local fid2=$($LFS getstripe --verbose $dir/file1 |
6413                      awk '/lmm_fid: / { print $2; exit; }')
6414         local fid3=$($LFS path2fid $dir/file1)
6415
6416         [ "$fid1" != "$fid2" ] &&
6417                 error "getstripe --fid '$fid1' != getstripe --verbose '$fid2'"
6418         [ "$fid1" != "$fid3" ] &&
6419                 error "getstripe --fid '$fid1' != lfs path2fid '$fid3'"
6420         echo "$LFS getstripe --fid passed"
6421
6422         #test lfs getstripe with --obd
6423         $LFS getstripe --obd wrong_uuid $dir 2>&1 | grep -q "unknown obduuid" ||
6424                 error "$LFS getstripe --obd wrong_uuid: should return error"
6425
6426         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6427
6428         local ostidx=1
6429         local obduuid=$(ostuuid_from_index $ostidx)
6430         local found=$($LFS getstripe -r --obd $obduuid $dir |
6431                 grep 'lmm_stripe_offset:' | grep -c " $ostidx\$")
6432
6433         filenum=$($LFS getstripe -ir $dir | grep -c "^$ostidx\$")
6434         [[ $($LFS getstripe -id $dir) -ne $ostidx ]] ||
6435                 ((filenum--))
6436         [[ $($LFS getstripe -id $dir/dir) -ne $ostidx ]] ||
6437                 ((filenum--))
6438
6439         [[ $found -eq $filenum ]] ||
6440                 error "$LFS getstripe --obd: found $found expect $filenum"
6441         [[ $($LFS getstripe -r -v --obd $obduuid $dir |
6442                 sed '/^[         ]*'${ostidx}'[  ]/d' |
6443                 sed -n '/^[      ]*[0-9][0-9]*[  ]/p' | wc -l) -eq 0 ]] ||
6444                 error "$LFS getstripe --obd: should not show file on other obd"
6445         echo "$LFS getstripe --obd passed"
6446 }
6447 run_test 56a "check $LFS getstripe"
6448
6449 test_56b() {
6450         local dir=$DIR/$tdir
6451         local numdirs=3
6452
6453         test_mkdir $dir
6454         for i in $(seq $numdirs); do
6455                 test_mkdir $dir/dir$i
6456         done
6457
6458         # test lfs getdirstripe default mode is non-recursion, which is
6459         # different from lfs getstripe
6460         local dircnt=$($LFS getdirstripe $dir | grep -c lmv_stripe_count)
6461
6462         [[ $dircnt -eq 1 ]] ||
6463                 error "$LFS getdirstripe: found $dircnt, not 1"
6464         dircnt=$($LFS getdirstripe --recursive $dir |
6465                 grep -c lmv_stripe_count)
6466         [[ $dircnt -eq $((numdirs + 1)) ]] ||
6467                 error "$LFS getdirstripe -r: $dircnt, != $((numdirs + 1))"
6468 }
6469 run_test 56b "check $LFS getdirstripe"
6470
6471 test_56bb() {
6472         verify_yaml_available || skip_env "YAML verification not installed"
6473         local output_file=$DIR/$tfile.out
6474
6475         $LFS getdirstripe -v -D -y $DIR 1> $output_file
6476
6477         cat $output_file
6478         cat $output_file | verify_yaml || error "layout is not valid YAML"
6479 }
6480 run_test 56bb "check $LFS getdirstripe layout is YAML"
6481
6482 test_56c() {
6483         remote_ost_nodsh && skip "remote OST with nodsh"
6484
6485         local ost_idx=0
6486         local ost_name=$(ostname_from_index $ost_idx)
6487         local old_status=$(ost_dev_status $ost_idx)
6488         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
6489
6490         [[ -z "$old_status" ]] ||
6491                 skip_env "OST $ost_name is in $old_status status"
6492
6493         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=1
6494         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
6495                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=1
6496         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
6497                 save_lustre_params ost1 osd-*.$ost_name.nonrotational > $p
6498                 do_facet ost1 $LCTL set_param -n osd-*.$ost_name.nonrotational=1
6499         fi
6500
6501         [[ $($LFS df -v $MOUNT |& grep -c "inactive device") -eq 0 ]] ||
6502                 error "$LFS df -v showing inactive devices"
6503         sleep_maxage
6504
6505         local new_status=$(ost_dev_status $ost_idx $MOUNT -v)
6506
6507         [[ "$new_status" =~ "D" ]] ||
6508                 error "$ost_name status is '$new_status', missing 'D'"
6509         if [[ $OST1_VERSION -ge $(version_code 2.12.55) ]]; then
6510                 [[ "$new_status" =~ "N" ]] ||
6511                         error "$ost_name status is '$new_status', missing 'N'"
6512         fi
6513         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
6514                 [[ "$new_status" =~ "f" ]] ||
6515                         error "$ost_name status is '$new_status', missing 'f'"
6516         fi
6517
6518         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=0
6519         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
6520                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=0
6521         [[ -z "$p" ]] && restore_lustre_params < $p || true
6522         sleep_maxage
6523
6524         new_status=$(ost_dev_status $ost_idx)
6525         [[ ! "$new_status" =~ "D" && ! "$new_status" =~ "N" ]] ||
6526                 error "$ost_name status is '$new_status', has 'D' and/or 'N'"
6527         # can't check 'f' as devices may actually be on flash
6528 }
6529 run_test 56c "check 'lfs df' showing device status"
6530
6531 test_56d() {
6532         local mdts=$($LFS df -v $MOUNT | grep -c MDT)
6533         local osts=$($LFS df -v $MOUNT | grep -c OST)
6534
6535         $LFS df $MOUNT
6536
6537         (( mdts == MDSCOUNT )) ||
6538                 error "lfs df -v showed $mdts MDTs, not $MDSCOUNT"
6539         (( osts == OSTCOUNT )) ||
6540                 error "lfs df -v showed $osts OSTs, not $OSTCOUNT"
6541 }
6542 run_test 56d "'lfs df -v' prints only configured devices"
6543
6544 test_56e() {
6545         err_enoent=2 # No such file or directory
6546         err_eopnotsupp=95 # Operation not supported
6547
6548         enoent_mnt=/pmt1 # Invalid dentry. Path not present
6549         notsup_mnt=/tmp  # Valid dentry, but Not a lustreFS
6550
6551         # Check for handling of path not exists
6552         output=$($LFS df $enoent_mnt 2>&1)
6553         ret=$?
6554
6555         fs=$(echo $output | awk -F: '{print $2}' | awk '{print $3}' | tr -d \')
6556         [[ $fs = $enoent_mnt && $ret -eq $err_enoent ]] ||
6557                 error "expect failure $err_enoent, not $ret"
6558
6559         # Check for handling of non-Lustre FS
6560         output=$($LFS df $notsup_mnt)
6561         ret=$?
6562
6563         fs=$(echo $output | awk '{print $1}' | awk -F: '{print $2}')
6564         [[ $fs = $notsup_mnt && $ret -eq $err_eopnotsupp ]] ||
6565                 error "expect success $err_eopnotsupp, not $ret"
6566
6567         # Check for multiple LustreFS argument
6568         output=$($LFS df $MOUNT $MOUNT $MOUNT | grep -c "filesystem_summary:")
6569         ret=$?
6570
6571         [[ $output -eq 3 && $ret -eq 0 ]] ||
6572                 error "expect success 3, not $output, rc = $ret"
6573
6574         # Check for correct non-Lustre FS handling among multiple
6575         # LustreFS argument
6576         output=$($LFS df $MOUNT $notsup_mnt $MOUNT |
6577                 grep -c "filesystem_summary:"; exit ${PIPESTATUS[0]})
6578         ret=$?
6579
6580         [[ $output -eq 2 && $ret -eq $err_eopnotsupp ]] ||
6581                 error "expect success 2, not $output, rc = $ret"
6582 }
6583 run_test 56e "'lfs df' Handle non LustreFS & multiple LustreFS"
6584
6585 NUMFILES=3
6586 NUMDIRS=3
6587 setup_56() {
6588         local local_tdir="$1"
6589         local local_numfiles="$2"
6590         local local_numdirs="$3"
6591         local dir_params="$4"
6592         local dir_stripe_params="$5"
6593
6594         if [ ! -d "$local_tdir" ] ; then
6595                 test_mkdir -p $dir_stripe_params $local_tdir
6596                 [ "$dir_params" ] && $LFS setstripe $dir_params $local_tdir
6597                 for i in $(seq $local_numfiles) ; do
6598                         touch $local_tdir/file$i
6599                 done
6600                 for i in $(seq $local_numdirs) ; do
6601                         test_mkdir $dir_stripe_params $local_tdir/dir$i
6602                         for j in $(seq $local_numfiles) ; do
6603                                 touch $local_tdir/dir$i/file$j
6604                         done
6605                 done
6606         fi
6607 }
6608
6609 setup_56_special() {
6610         local local_tdir=$1
6611         local local_numfiles=$2
6612         local local_numdirs=$3
6613
6614         setup_56 $local_tdir $local_numfiles $local_numdirs
6615
6616         if [ ! -e "$local_tdir/loop${local_numfiles}b" ] ; then
6617                 for i in $(seq $local_numfiles) ; do
6618                         mknod $local_tdir/loop${i}b b 7 $i
6619                         mknod $local_tdir/null${i}c c 1 3
6620                         ln -s $local_tdir/file1 $local_tdir/link${i}
6621                 done
6622                 for i in $(seq $local_numdirs) ; do
6623                         mknod $local_tdir/dir$i/loop${i}b b 7 $i
6624                         mknod $local_tdir/dir$i/null${i}c c 1 3
6625                         ln -s $local_tdir/dir$i/file1 $local_tdir/dir$i/link${i}
6626                 done
6627         fi
6628 }
6629
6630 test_56g() {
6631         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6632         local expected=$(($NUMDIRS + 2))
6633
6634         setup_56 $dir $NUMFILES $NUMDIRS
6635
6636         # test lfs find with -name
6637         for i in $(seq $NUMFILES) ; do
6638                 local nums=$($LFS find -name "*$i" $dir | wc -l)
6639
6640                 [ $nums -eq $expected ] ||
6641                         error "lfs find -name '*$i' $dir wrong: "\
6642                               "found $nums, expected $expected"
6643         done
6644 }
6645 run_test 56g "check lfs find -name"
6646
6647 test_56h() {
6648         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6649         local expected=$(((NUMDIRS + 1) * (NUMFILES - 1) + NUMFILES))
6650
6651         setup_56 $dir $NUMFILES $NUMDIRS
6652
6653         # test lfs find with ! -name
6654         for i in $(seq $NUMFILES) ; do
6655                 local nums=$($LFS find ! -name "*$i" $dir | wc -l)
6656
6657                 [ $nums -eq $expected ] ||
6658                         error "lfs find ! -name '*$i' $dir wrong: "\
6659                               "found $nums, expected $expected"
6660         done
6661 }
6662 run_test 56h "check lfs find ! -name"
6663
6664 test_56i() {
6665         local dir=$DIR/$tdir
6666
6667         test_mkdir $dir
6668
6669         local cmd="$LFS find -ost $(ostuuid_from_index 0 $dir) $dir"
6670         local out=$($cmd)
6671
6672         [ -z "$out" ] || error "'$cmd' returned directory '$out'"
6673 }
6674 run_test 56i "check 'lfs find -ost UUID' skips directories"
6675
6676 test_56j() {
6677         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6678
6679         setup_56_special $dir $NUMFILES $NUMDIRS
6680
6681         local expected=$((NUMDIRS + 1))
6682         local cmd="$LFS find -type d $dir"
6683         local nums=$($cmd | wc -l)
6684
6685         [ $nums -eq $expected ] ||
6686                 error "'$cmd' wrong: found $nums, expected $expected"
6687 }
6688 run_test 56j "check lfs find -type d"
6689
6690 test_56k() {
6691         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6692
6693         setup_56_special $dir $NUMFILES $NUMDIRS
6694
6695         local expected=$(((NUMDIRS + 1) * NUMFILES))
6696         local cmd="$LFS find -type f $dir"
6697         local nums=$($cmd | wc -l)
6698
6699         [ $nums -eq $expected ] ||
6700                 error "'$cmd' wrong: found $nums, expected $expected"
6701 }
6702 run_test 56k "check lfs find -type f"
6703
6704 test_56l() {
6705         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6706
6707         setup_56_special $dir $NUMFILES $NUMDIRS
6708
6709         local expected=$((NUMDIRS + NUMFILES))
6710         local cmd="$LFS find -type b $dir"
6711         local nums=$($cmd | wc -l)
6712
6713         [ $nums -eq $expected ] ||
6714                 error "'$cmd' wrong: found $nums, expected $expected"
6715 }
6716 run_test 56l "check lfs find -type b"
6717
6718 test_56m() {
6719         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6720
6721         setup_56_special $dir $NUMFILES $NUMDIRS
6722
6723         local expected=$((NUMDIRS + NUMFILES))
6724         local cmd="$LFS find -type c $dir"
6725         local nums=$($cmd | wc -l)
6726         [ $nums -eq $expected ] ||
6727                 error "'$cmd' wrong: found $nums, expected $expected"
6728 }
6729 run_test 56m "check lfs find -type c"
6730
6731 test_56n() {
6732         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6733         setup_56_special $dir $NUMFILES $NUMDIRS
6734
6735         local expected=$((NUMDIRS + NUMFILES))
6736         local cmd="$LFS find -type l $dir"
6737         local nums=$($cmd | wc -l)
6738
6739         [ $nums -eq $expected ] ||
6740                 error "'$cmd' wrong: found $nums, expected $expected"
6741 }
6742 run_test 56n "check lfs find -type l"
6743
6744 test_56o() {
6745         local dir=$DIR/$tdir
6746
6747         setup_56 $dir $NUMFILES $NUMDIRS
6748         utime $dir/file1 > /dev/null || error "utime (1)"
6749         utime $dir/file2 > /dev/null || error "utime (2)"
6750         utime $dir/dir1 > /dev/null || error "utime (3)"
6751         utime $dir/dir2 > /dev/null || error "utime (4)"
6752         utime $dir/dir1/file1 > /dev/null || error "utime (5)"
6753         dd if=/dev/zero count=1 >> $dir/dir1/file1 && sync
6754
6755         local expected=4
6756         local nums=$($LFS find -mtime +0 $dir | wc -l)
6757
6758         [ $nums -eq $expected ] ||
6759                 error "lfs find -mtime +0 $dir: found $nums expect $expected"
6760
6761         expected=12
6762         cmd="$LFS find -mtime 0 $dir"
6763         nums=$($cmd | wc -l)
6764         [ $nums -eq $expected ] ||
6765                 error "'$cmd' wrong: found $nums, expected $expected"
6766 }
6767 run_test 56o "check lfs find -mtime for old files"
6768
6769 test_56ob() {
6770         local dir=$DIR/$tdir
6771         local expected=1
6772         local count=0
6773
6774         # just to make sure there is something that won't be found
6775         test_mkdir $dir
6776         touch $dir/$tfile.now
6777
6778         for age in year week day hour min; do
6779                 count=$((count + 1))
6780
6781                 touch $dir/$tfile-a.$age $dir/$tfile-m.$age
6782                 touch --date="$count $age ago" -a $dir/$tfile-a.$age
6783                 touch --date="$count $age ago" -m $dir/$tfile-m.$age
6784
6785                 local cmd="$LFS find $dir -mtime $count${age:0:1}"
6786                 local nums=$($cmd | wc -l)
6787                 [ $nums -eq $expected ] ||
6788                         error "'$cmd' wrong: found $nums, expected $expected"
6789
6790                 cmd="$LFS find $dir -atime $count${age:0:1}"
6791                 nums=$($cmd | wc -l)
6792                 [ $nums -eq $expected ] ||
6793                         error "'$cmd' wrong: found $nums, expected $expected"
6794         done
6795
6796         sleep 2
6797         cmd="$LFS find $dir -ctime +1s -type f"
6798         nums=$($cmd | wc -l)
6799         (( $nums == $count * 2 + 1)) ||
6800                 error "'$cmd' wrong: found $nums, expected $((count * 2 + 1))"
6801 }
6802 run_test 56ob "check lfs find -atime -mtime -ctime with units"
6803
6804 test_newerXY_base() {
6805         local x=$1
6806         local y=$2
6807         local dir=$DIR/$tdir
6808         local ref
6809         local negref
6810
6811         if [ $y == "t" ]; then
6812                 if [ $x == "b" ]; then
6813                         ref=\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\"
6814                 else
6815                         ref=\"$(date +"%Y-%m-%d %H:%M:%S")\"
6816                 fi
6817         else
6818                 ref=$DIR/$tfile.newer.$x$y
6819                 touch $ref || error "touch $ref failed"
6820         fi
6821
6822         echo "before = $ref"
6823         sleep 2
6824         setup_56 $dir $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6825         sleep 2
6826         if [ $y == "t" ]; then
6827                 if [ $x == "b" ]; then
6828                         negref=\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\"
6829                 else
6830                         negref=\"$(date +"%Y-%m-%d %H:%M:%S")\"
6831                 fi
6832         else
6833                 negref=$DIR/$tfile.negnewer.$x$y
6834                 touch $negref || error "touch $negref failed"
6835         fi
6836
6837         echo "after = $negref"
6838         local cmd="$LFS find $dir -newer$x$y $ref"
6839         local nums=$(eval $cmd | wc -l)
6840         local expected=$(((NUMFILES + 2) * NUMDIRS + 1))
6841
6842         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6843                 error "'$cmd' wrong: found $nums newer, expected $expected"  ; }
6844
6845         cmd="$LFS find $dir ! -newer$x$y $negref"
6846         nums=$(eval $cmd | wc -l)
6847         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6848                 error "'$cmd' wrong: found $nums older, expected $expected"  ; }
6849
6850         cmd="$LFS find $dir -newer$x$y $ref ! -newer$x$y $negref"
6851         nums=$(eval $cmd | wc -l)
6852         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6853                 error "'$cmd' wrong: found $nums between, expected $expected"; }
6854
6855         rm -rf $DIR/*
6856 }
6857
6858 test_56oc() {
6859         test_newerXY_base "a" "a"
6860         test_newerXY_base "a" "m"
6861         test_newerXY_base "a" "c"
6862         test_newerXY_base "m" "a"
6863         test_newerXY_base "m" "m"
6864         test_newerXY_base "m" "c"
6865         test_newerXY_base "c" "a"
6866         test_newerXY_base "c" "m"
6867         test_newerXY_base "c" "c"
6868
6869         test_newerXY_base "a" "t"
6870         test_newerXY_base "m" "t"
6871         test_newerXY_base "c" "t"
6872
6873         [[ $MDS1_VERSION -lt $(version_code 2.13.54) ||
6874            $CLIENT_VERSION -lt $(version_code 2.13.54) ]] &&
6875                 ! btime_supported && echo "btime unsupported" && return 0
6876
6877         test_newerXY_base "b" "b"
6878         test_newerXY_base "b" "t"
6879 }
6880 run_test 56oc "check lfs find -newerXY work"
6881
6882 btime_supported() {
6883         local dir=$DIR/$tdir
6884         local rc
6885
6886         mkdir -p $dir
6887         touch $dir/$tfile
6888         $LFS find $dir -btime -1d -type f
6889         rc=$?
6890         rm -rf $dir
6891         return $rc
6892 }
6893
6894 test_56od() {
6895         [ $MDS1_VERSION -lt $(version_code 2.13.53) ] &&
6896                 ! btime_supported && skip "btime unsupported on MDS"
6897
6898         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
6899                 ! btime_supported && skip "btime unsupported on clients"
6900
6901         local dir=$DIR/$tdir
6902         local ref=$DIR/$tfile.ref
6903         local negref=$DIR/$tfile.negref
6904
6905         mkdir $dir || error "mkdir $dir failed"
6906         touch $dir/$tfile.n1 || error "touch $dir/$tfile.n1 failed"
6907         touch $dir/$tfile.n2 || error "touch $dir/$tfile.n2 failed"
6908         mkdir $dir/$tdir.n1 || error "mkdir $dir/$tdir.n1 failed"
6909         mkdir $dir/$tdir.n2 || error "mkdir $dir/$tdir.n2 failed"
6910         touch $ref || error "touch $ref failed"
6911         # sleep 3 seconds at least
6912         sleep 3
6913
6914         local before=$(do_facet mds1 date +%s)
6915         local skew=$(($(date +%s) - before + 1))
6916
6917         if (( skew < 0 && skew > -5 )); then
6918                 sleep $((0 - skew + 1))
6919                 skew=0
6920         fi
6921
6922         # Set the dir stripe params to limit files all on MDT0,
6923         # otherwise we need to calc the max clock skew between
6924         # the client and MDTs.
6925         setup_56 $dir/d.btime $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6926         sleep 2
6927         touch $negref || error "touch $negref failed"
6928
6929         local cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type f"
6930         local nums=$($cmd | wc -l)
6931         local expected=$(((NUMFILES + 1) * NUMDIRS))
6932
6933         [ $nums -eq $expected ] ||
6934                 error "'$cmd' wrong: found $nums, expected $expected"
6935
6936         cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type d"
6937         nums=$($cmd | wc -l)
6938         expected=$((NUMFILES + 1))
6939         [ $nums -eq $expected ] ||
6940                 error "'$cmd' wrong: found $nums, expected $expected"
6941
6942         [ $skew -lt 0 ] && return
6943
6944         local after=$(do_facet mds1 date +%s)
6945         local age=$((after - before + 1 + skew))
6946
6947         cmd="$LFS find $dir -btime -${age}s -type f"
6948         nums=$($cmd | wc -l)
6949         expected=$(((NUMFILES + 1) * NUMDIRS))
6950
6951         echo "Clock skew between client and server: $skew, age:$age"
6952         [ $nums -eq $expected ] ||
6953                 error "'$cmd' wrong: found $nums, expected $expected"
6954
6955         expected=$(($NUMDIRS + 1))
6956         cmd="$LFS find $dir -btime -${age}s -type d"
6957         nums=$($cmd | wc -l)
6958         [ $nums -eq $expected ] ||
6959                 error "'$cmd' wrong: found $nums, expected $expected"
6960         rm -f $ref $negref || error "Failed to remove $ref $negref"
6961 }
6962 run_test 56od "check lfs find -btime with units"
6963
6964 test_56p() {
6965         [ $RUNAS_ID -eq $UID ] &&
6966                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6967
6968         local dir=$DIR/$tdir
6969
6970         setup_56 $dir $NUMFILES $NUMDIRS
6971         chown $RUNAS_ID $dir/file* || error "chown $DIR/${tdir}g/file$i failed"
6972
6973         local expected=$NUMFILES
6974         local cmd="$LFS find -uid $RUNAS_ID $dir"
6975         local nums=$($cmd | wc -l)
6976
6977         [ $nums -eq $expected ] ||
6978                 error "'$cmd' wrong: found $nums, expected $expected"
6979
6980         expected=$(((NUMFILES + 1) * NUMDIRS + 1))
6981         cmd="$LFS find ! -uid $RUNAS_ID $dir"
6982         nums=$($cmd | wc -l)
6983         [ $nums -eq $expected ] ||
6984                 error "'$cmd' wrong: found $nums, expected $expected"
6985 }
6986 run_test 56p "check lfs find -uid and ! -uid"
6987
6988 test_56q() {
6989         [ $RUNAS_ID -eq $UID ] &&
6990                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6991
6992         local dir=$DIR/$tdir
6993
6994         setup_56 $dir $NUMFILES $NUMDIRS
6995         chgrp $RUNAS_GID $dir/file* || error "chown $dir/file$i failed"
6996
6997         local expected=$NUMFILES
6998         local cmd="$LFS find -gid $RUNAS_GID $dir"
6999         local nums=$($cmd | wc -l)
7000
7001         [ $nums -eq $expected ] ||
7002                 error "'$cmd' wrong: found $nums, expected $expected"
7003
7004         expected=$(( ($NUMFILES+1) * $NUMDIRS + 1))
7005         cmd="$LFS find ! -gid $RUNAS_GID $dir"
7006         nums=$($cmd | wc -l)
7007         [ $nums -eq $expected ] ||
7008                 error "'$cmd' wrong: found $nums, expected $expected"
7009 }
7010 run_test 56q "check lfs find -gid and ! -gid"
7011
7012 test_56r() {
7013         local dir=$DIR/$tdir
7014
7015         setup_56 $dir $NUMFILES $NUMDIRS
7016
7017         local expected=12
7018         local cmd="$LFS find -size 0 -type f -lazy $dir"
7019         local nums=$($cmd | wc -l)
7020
7021         [ $nums -eq $expected ] ||
7022                 error "'$cmd' wrong: found $nums, expected $expected"
7023         cmd="$LFS find -size 0 -type f $dir"
7024         nums=$($cmd | wc -l)
7025         [ $nums -eq $expected ] ||
7026                 error "'$cmd' wrong: found $nums, expected $expected"
7027
7028         expected=0
7029         cmd="$LFS find ! -size 0 -type f -lazy $dir"
7030         nums=$($cmd | wc -l)
7031         [ $nums -eq $expected ] ||
7032                 error "'$cmd' wrong: found $nums, expected $expected"
7033         cmd="$LFS find ! -size 0 -type f $dir"
7034         nums=$($cmd | wc -l)
7035         [ $nums -eq $expected ] ||
7036                 error "'$cmd' wrong: found $nums, expected $expected"
7037
7038         echo "test" > $dir/$tfile
7039         echo "test2" > $dir/$tfile.2 && sync
7040         expected=1
7041         cmd="$LFS find -size 5 -type f -lazy $dir"
7042         nums=$($cmd | wc -l)
7043         [ $nums -eq $expected ] ||
7044                 error "'$cmd' wrong: found $nums, expected $expected"
7045         cmd="$LFS find -size 5 -type f $dir"
7046         nums=$($cmd | wc -l)
7047         [ $nums -eq $expected ] ||
7048                 error "'$cmd' wrong: found $nums, expected $expected"
7049
7050         expected=1
7051         cmd="$LFS find -size +5 -type f -lazy $dir"
7052         nums=$($cmd | wc -l)
7053         [ $nums -eq $expected ] ||
7054                 error "'$cmd' wrong: found $nums, expected $expected"
7055         cmd="$LFS find -size +5 -type f $dir"
7056         nums=$($cmd | wc -l)
7057         [ $nums -eq $expected ] ||
7058                 error "'$cmd' wrong: found $nums, expected $expected"
7059
7060         expected=2
7061         cmd="$LFS find -size +0 -type f -lazy $dir"
7062         nums=$($cmd | wc -l)
7063         [ $nums -eq $expected ] ||
7064                 error "'$cmd' wrong: found $nums, expected $expected"
7065         cmd="$LFS find -size +0 -type f $dir"
7066         nums=$($cmd | wc -l)
7067         [ $nums -eq $expected ] ||
7068                 error "'$cmd' wrong: found $nums, expected $expected"
7069
7070         expected=2
7071         cmd="$LFS find ! -size -5 -type f -lazy $dir"
7072         nums=$($cmd | wc -l)
7073         [ $nums -eq $expected ] ||
7074                 error "'$cmd' wrong: found $nums, expected $expected"
7075         cmd="$LFS find ! -size -5 -type f $dir"
7076         nums=$($cmd | wc -l)
7077         [ $nums -eq $expected ] ||
7078                 error "'$cmd' wrong: found $nums, expected $expected"
7079
7080         expected=12
7081         cmd="$LFS find -size -5 -type f -lazy $dir"
7082         nums=$($cmd | wc -l)
7083         [ $nums -eq $expected ] ||
7084                 error "'$cmd' wrong: found $nums, expected $expected"
7085         cmd="$LFS find -size -5 -type f $dir"
7086         nums=$($cmd | wc -l)
7087         [ $nums -eq $expected ] ||
7088                 error "'$cmd' wrong: found $nums, expected $expected"
7089 }
7090 run_test 56r "check lfs find -size works"
7091
7092 test_56ra_sub() {
7093         local expected=$1
7094         local glimpses=$2
7095         local cmd="$3"
7096
7097         cancel_lru_locks $OSC
7098
7099         local rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
7100         local nums=$($cmd | wc -l)
7101
7102         [ $nums -eq $expected ] ||
7103                 error "'$cmd' wrong: found $nums, expected $expected"
7104
7105         local rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
7106
7107         if (( rpcs_before + glimpses != rpcs_after )); then
7108                 echo "Before: $rpcs_before After: $rpcs_after $NUMFILES"
7109                 $LCTL get_param osc.*.stats | grep ldlm_glimpse_enqueue
7110
7111                 if [[ $glimpses == 0 ]]; then
7112                         error "'$cmd' should not send glimpse RPCs to OST"
7113                 else
7114                         error "'$cmd' should send $glimpses glimpse RPCs to OST"
7115                 fi
7116         fi
7117 }
7118
7119 test_56ra() {
7120         [[ $MDS1_VERSION -gt $(version_code 2.12.58) ]] ||
7121                 skip "MDS < 2.12.58 doesn't return LSOM data"
7122         local dir=$DIR/$tdir
7123         local old_agl=$($LCTL get_param -n llite.*.statahead_agl)
7124
7125         [[ $OSC == "mdc" ]] && skip "statahead not needed for DoM files"
7126
7127         # statahead_agl may cause extra glimpse which confuses results. LU-13017
7128         $LCTL set_param -n llite.*.statahead_agl=0
7129         stack_trap "$LCTL set_param -n llite.*.statahead_agl=$old_agl"
7130
7131         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
7132         # open and close all files to ensure LSOM is updated
7133         cancel_lru_locks $OSC
7134         find $dir -type f | xargs cat > /dev/null
7135
7136         #   expect_found  glimpse_rpcs  command_to_run
7137         test_56ra_sub 12  0 "$LFS find -size 0 -type f -lazy $dir"
7138         test_56ra_sub 12 12 "$LFS find -size 0 -type f $dir"
7139         test_56ra_sub  0  0 "$LFS find ! -size 0 -type f -lazy $dir"
7140         test_56ra_sub  0 12 "$LFS find ! -size 0 -type f $dir"
7141
7142         echo "test" > $dir/$tfile
7143         echo "test2" > $dir/$tfile.2 && sync
7144         cancel_lru_locks $OSC
7145         cat $dir/$tfile $dir/$tfile.2 > /dev/null
7146
7147         test_56ra_sub  1  0 "$LFS find -size 5 -type f -lazy $dir"
7148         test_56ra_sub  1 14 "$LFS find -size 5 -type f $dir"
7149         test_56ra_sub  1  0 "$LFS find -size +5 -type f -lazy $dir"
7150         test_56ra_sub  1 14 "$LFS find -size +5 -type f $dir"
7151
7152         test_56ra_sub  2  0 "$LFS find -size +0 -type f -lazy $dir"
7153         test_56ra_sub  2 14 "$LFS find -size +0 -type f $dir"
7154         test_56ra_sub  2  0 "$LFS find ! -size -5 -type f -lazy $dir"
7155         test_56ra_sub  2 14 "$LFS find ! -size -5 -type f $dir"
7156         test_56ra_sub 12  0 "$LFS find -size -5 -type f -lazy $dir"
7157         test_56ra_sub 12 14 "$LFS find -size -5 -type f $dir"
7158 }
7159 run_test 56ra "check lfs find -size -lazy works for data on OSTs"
7160
7161 test_56rb() {
7162         local dir=$DIR/$tdir
7163         local tmp=$TMP/$tfile.log
7164         local mdt_idx;
7165
7166         test_mkdir -p $dir || error "failed to mkdir $dir"
7167         $LFS setstripe -c 1 -i 0 $dir/$tfile ||
7168                 error "failed to setstripe $dir/$tfile"
7169         mdt_idx=$($LFS getdirstripe -i $dir)
7170         dd if=/dev/zero of=$dir/$tfile bs=1M count=1
7171
7172         stack_trap "rm -f $tmp" EXIT
7173         $LFS find --size +100K --ost 0 $dir |& tee $tmp
7174         ! grep -q obd_uuid $tmp ||
7175                 error "failed to find --size +100K --ost 0 $dir"
7176         $LFS find --size +100K --mdt $mdt_idx $dir |& tee $tmp
7177         ! grep -q obd_uuid $tmp ||
7178                 error "failed to find --size +100K --mdt $mdt_idx $dir"
7179 }
7180 run_test 56rb "check lfs find --size --ost/--mdt works"
7181
7182 test_56rc() {
7183         (( MDSCOUNT >= 2 )) || skip "needs at least 2 MDTs"
7184         local dir=$DIR/$tdir
7185         local found
7186
7187         test_mkdir -c 2 -H all_char $dir || error "failed to mkdir $dir"
7188         $LFS mkdir -c 2 --mdt-hash all_char $dir/$tdir-all{1..10}
7189         (( $MDSCOUNT > 2 )) &&
7190                 $LFS mkdir -c 3 --mdt-hash fnv_1a_64 $dir/$tdir-fnv{1..10}
7191         mkdir $dir/$tdir-{1..10}
7192         touch $dir/$tfile-{1..10}
7193
7194         found=$($LFS find $dir --mdt-count 2 | wc -l)
7195         expect=11
7196         (( $found == $expect )) || error "found $found 2-stripe, expect $expect"
7197
7198         found=$($LFS find $dir -T +1 | wc -l)
7199         (( $MDSCOUNT > 2 )) && expect=$((expect + 10))
7200         (( $found == $expect )) || error "found $found 2+stripe, expect $expect"
7201
7202         found=$($LFS find $dir --mdt-hash all_char | wc -l)
7203         expect=11
7204         (( $found == $expect )) || error "found $found all_char, expect $expect"
7205
7206         found=$($LFS find $dir --mdt-hash fnv_1a_64 | wc -l)
7207         (( $MDSCOUNT > 2 )) && expect=10 || expect=0
7208         (( $found == $expect )) || error "found $found all_char, expect $expect"
7209 }
7210 run_test 56rc "check lfs find --mdt-count/--mdt-hash works"
7211
7212 test_56s() { # LU-611 #LU-9369
7213         [[ $OSTCOUNT -lt 2 ]] && skip_env "need at least 2 OSTs"
7214
7215         local dir=$DIR/$tdir
7216         local onestripe=$(((NUMDIRS + 1) * NUMFILES))
7217
7218         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
7219         for i in $(seq $NUMDIRS); do
7220                 $LFS setstripe -c $((OSTCOUNT + 1)) $dir/dir$i/$tfile
7221         done
7222
7223         local expected=$NUMDIRS
7224         local cmd="$LFS find -c $OSTCOUNT $dir"
7225         local nums=$($cmd | wc -l)
7226
7227         [ $nums -eq $expected ] || {
7228                 $LFS getstripe -R $dir
7229                 error "'$cmd' wrong: found $nums, expected $expected"
7230         }
7231
7232         expected=$((NUMDIRS + onestripe))
7233         cmd="$LFS find -stripe-count +0 -type f $dir"
7234         nums=$($cmd | wc -l)
7235         [ $nums -eq $expected ] || {
7236                 $LFS getstripe -R $dir
7237                 error "'$cmd' wrong: found $nums, expected $expected"
7238         }
7239
7240         expected=$onestripe
7241         cmd="$LFS find -stripe-count 1 -type f $dir"
7242         nums=$($cmd | wc -l)
7243         [ $nums -eq $expected ] || {
7244                 $LFS getstripe -R $dir
7245                 error "'$cmd' wrong: found $nums, expected $expected"
7246         }
7247
7248         cmd="$LFS find -stripe-count -2 -type f $dir"
7249         nums=$($cmd | wc -l)
7250         [ $nums -eq $expected ] || {
7251                 $LFS getstripe -R $dir
7252                 error "'$cmd' wrong: found $nums, expected $expected"
7253         }
7254
7255         expected=0
7256         cmd="$LFS find -stripe-count $((OSTCOUNT + 1)) -type f $dir"
7257         nums=$($cmd | wc -l)
7258         [ $nums -eq $expected ] || {
7259                 $LFS getstripe -R $dir
7260                 error "'$cmd' wrong: found $nums, expected $expected"
7261         }
7262 }
7263 run_test 56s "check lfs find -stripe-count works"
7264
7265 test_56t() { # LU-611 #LU-9369
7266         local dir=$DIR/$tdir
7267
7268         setup_56 $dir 0 $NUMDIRS
7269         for i in $(seq $NUMDIRS); do
7270                 $LFS setstripe -S 8M $dir/dir$i/$tfile
7271         done
7272
7273         local expected=$NUMDIRS
7274         local cmd="$LFS find -S 8M $dir"
7275         local nums=$($cmd | wc -l)
7276
7277         [ $nums -eq $expected ] || {
7278                 $LFS getstripe -R $dir
7279                 error "'$cmd' wrong: found $nums, expected $expected"
7280         }
7281         rm -rf $dir
7282
7283         setup_56 $dir $NUMFILES $NUMDIRS "--stripe-size 512k"
7284
7285         $LFS setstripe -S 256k $dir/$tfile.{0,1,2,3}
7286
7287         expected=$(((NUMDIRS + 1) * NUMFILES))
7288         cmd="$LFS find -stripe-size 512k -type f $dir"
7289         nums=$($cmd | wc -l)
7290         [ $nums -eq $expected ] ||
7291                 error "'$cmd' wrong: found $nums, expected $expected"
7292
7293         cmd="$LFS find -stripe-size +320k -type f $dir"
7294         nums=$($cmd | wc -l)
7295         [ $nums -eq $expected ] ||
7296                 error "'$cmd' wrong: found $nums, expected $expected"
7297
7298         expected=$(((NUMDIRS + 1) * NUMFILES + 4))
7299         cmd="$LFS find -stripe-size +200k -type f $dir"
7300         nums=$($cmd | wc -l)
7301         [ $nums -eq $expected ] ||
7302                 error "'$cmd' wrong: found $nums, expected $expected"
7303
7304         cmd="$LFS find -stripe-size -640k -type f $dir"
7305         nums=$($cmd | wc -l)
7306         [ $nums -eq $expected ] ||
7307                 error "'$cmd' wrong: found $nums, expected $expected"
7308
7309         expected=4
7310         cmd="$LFS find -stripe-size 256k -type f $dir"
7311         nums=$($cmd | wc -l)
7312         [ $nums -eq $expected ] ||
7313                 error "'$cmd' wrong: found $nums, expected $expected"
7314
7315         cmd="$LFS find -stripe-size -320k -type f $dir"
7316         nums=$($cmd | wc -l)
7317         [ $nums -eq $expected ] ||
7318                 error "'$cmd' wrong: found $nums, expected $expected"
7319
7320         expected=0
7321         cmd="$LFS find -stripe-size 1024k -type f $dir"
7322         nums=$($cmd | wc -l)
7323         [ $nums -eq $expected ] ||
7324                 error "'$cmd' wrong: found $nums, expected $expected"
7325 }
7326 run_test 56t "check lfs find -stripe-size works"
7327
7328 test_56u() { # LU-611
7329         local dir=$DIR/$tdir
7330
7331         setup_56 $dir $NUMFILES $NUMDIRS "-i 0 -c 1"
7332
7333         if [[ $OSTCOUNT -gt 1 ]]; then
7334                 $LFS setstripe -i 1 -c 1 $dir/$tfile.{0,1,2,3}
7335                 onestripe=4
7336         else
7337                 onestripe=0
7338         fi
7339
7340         local expected=$(((NUMDIRS + 1) * NUMFILES))
7341         local cmd="$LFS find -stripe-index 0 -type f $dir"
7342         local nums=$($cmd | wc -l)
7343
7344         [ $nums -eq $expected ] ||
7345                 error "'$cmd' wrong: found $nums, expected $expected"
7346
7347         expected=$onestripe
7348         cmd="$LFS find -stripe-index 1 -type f $dir"
7349         nums=$($cmd | wc -l)
7350         [ $nums -eq $expected ] ||
7351                 error "'$cmd' wrong: found $nums, expected $expected"
7352
7353         cmd="$LFS find ! -stripe-index 0 -type f $dir"
7354         nums=$($cmd | wc -l)
7355         [ $nums -eq $expected ] ||
7356                 error "'$cmd' wrong: found $nums, expected $expected"
7357
7358         expected=0
7359         # This should produce an error and not return any files
7360         cmd="$LFS find -stripe-index $OSTCOUNT -type f $dir"
7361         nums=$($cmd 2>/dev/null | wc -l)
7362         [ $nums -eq $expected ] ||
7363                 error "'$cmd' wrong: found $nums, expected $expected"
7364
7365         if [[ $OSTCOUNT -gt 1 ]]; then
7366                 expected=$(((NUMDIRS + 1) * NUMFILES + onestripe))
7367                 cmd="$LFS find -stripe-index 0,1 -type f $dir"
7368                 nums=$($cmd | wc -l)
7369                 [ $nums -eq $expected ] ||
7370                         error "'$cmd' wrong: found $nums, expected $expected"
7371         fi
7372 }
7373 run_test 56u "check lfs find -stripe-index works"
7374
7375 test_56v() {
7376         local mdt_idx=0
7377         local dir=$DIR/$tdir
7378
7379         setup_56 $dir $NUMFILES $NUMDIRS
7380
7381         UUID=$(mdtuuid_from_index $mdt_idx $dir)
7382         [ -z "$UUID" ] && error "mdtuuid_from_index cannot find MDT $mdt_idx"
7383
7384         for file in $($LFS find -m $UUID $dir); do
7385                 file_midx=$($LFS getstripe -m $file)
7386                 [ $file_midx -eq $mdt_idx ] ||
7387                         error "lfs find -m $UUID != getstripe -m $file_midx"
7388         done
7389 }
7390 run_test 56v "check 'lfs find -m match with lfs getstripe -m'"
7391
7392 test_56wa() {
7393         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
7394         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7395
7396         local dir=$DIR/$tdir
7397
7398         setup_56 $dir $NUMFILES $NUMDIRS "-c $OSTCOUNT" "-c1"
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         $LFS setstripe $layout_yaml $f_yaml ||
8026                 error "cannot setstripe $f_yaml with layout $layout_yaml"
8027         $LFS getstripe --yaml $f_yaml > $yamlfile
8028         $LFS setstripe $layout_copy $f_copy ||
8029                 error "cannot setstripe $f_copy with layout $layout_copy"
8030         touch $f_mgrt
8031         dd if=/dev/zero of=$f_mgrt bs=1M count=4
8032
8033         # 1. test option --yaml
8034         $LFS_MIGRATE -y --yaml $yamlfile $f_mgrt ||
8035                 error "cannot migrate $f_mgrt with --yaml $yamlfile"
8036         layout_before=$(get_layout_param $f_yaml)
8037         layout_after=$(get_layout_param $f_mgrt)
8038         [ "$layout_after" == "$layout_before" ] ||
8039                 error "lfs_migrate --yaml: $layout_after != $layout_before"
8040
8041         # 2. test option --copy
8042         $LFS_MIGRATE -y --copy $f_copy $f_mgrt ||
8043                 error "cannot migrate $f_mgrt with --copy $f_copy"
8044         layout_before=$(SKIP_INDEX=yes get_layout_param $f_copy)
8045         layout_after=$(SKIP_INDEX=yes get_layout_param $f_mgrt)
8046         [ "$layout_after" == "$layout_before" ] ||
8047                 error "lfs_migrate --copy: $layout_after != $layout_before"
8048 }
8049 run_test 56xd "check lfs_migrate --yaml and --copy support"
8050
8051 test_56xe() {
8052         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8053
8054         local dir=$DIR/$tdir
8055         local f_comp=$dir/$tfile
8056         local layout="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
8057         local layout_before=""
8058         local layout_after=""
8059
8060         test_mkdir "$dir" || error "cannot create dir $dir"
8061         $LFS setstripe $layout $f_comp ||
8062                 error "cannot setstripe $f_comp with layout $layout"
8063         layout_before=$(SKIP_INDEX=yes get_layout_param $f_comp)
8064         dd if=/dev/zero of=$f_comp bs=1M count=4
8065
8066         # 1. migrate a comp layout file by lfs_migrate
8067         $LFS_MIGRATE -y $f_comp || error "cannot migrate $f_comp by lfs_migrate"
8068         layout_after=$(SKIP_INDEX=yes get_layout_param $f_comp)
8069         [ "$layout_before" == "$layout_after" ] ||
8070                 error "lfs_migrate: $layout_before != $layout_after"
8071
8072         # 2. migrate a comp layout file by lfs migrate
8073         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
8074         layout_after=$(SKIP_INDEX=yes get_layout_param $f_comp)
8075         [ "$layout_before" == "$layout_after" ] ||
8076                 error "lfs migrate: $layout_before != $layout_after"
8077 }
8078 run_test 56xe "migrate a composite layout file"
8079
8080 test_56xf() {
8081         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
8082
8083         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
8084                 skip "Need server version at least 2.13.53"
8085
8086         local dir=$DIR/$tdir
8087         local f_comp=$dir/$tfile
8088         local layout="-E 1M -c1 -E -1 -c2"
8089         local fid_before=""
8090         local fid_after=""
8091
8092         test_mkdir "$dir" || error "cannot create dir $dir"
8093         $LFS setstripe $layout $f_comp ||
8094                 error "cannot setstripe $f_comp with layout $layout"
8095         fid_before=$($LFS getstripe --fid $f_comp)
8096         dd if=/dev/zero of=$f_comp bs=1M count=4
8097
8098         # 1. migrate a comp layout file to a comp layout
8099         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
8100         fid_after=$($LFS getstripe --fid $f_comp)
8101         [ "$fid_before" == "$fid_after" ] ||
8102                 error "comp-to-comp migrate: $fid_before != $fid_after"
8103
8104         # 2. migrate a comp layout file to a plain layout
8105         $LFS migrate -c2 $f_comp ||
8106                 error "cannot migrate $f_comp by lfs migrate"
8107         fid_after=$($LFS getstripe --fid $f_comp)
8108         [ "$fid_before" == "$fid_after" ] ||
8109                 error "comp-to-plain migrate: $fid_before != $fid_after"
8110
8111         # 3. migrate a plain layout file to a comp layout
8112         $LFS migrate $layout $f_comp ||
8113                 error "cannot migrate $f_comp by lfs migrate"
8114         fid_after=$($LFS getstripe --fid $f_comp)
8115         [ "$fid_before" == "$fid_after" ] ||
8116                 error "plain-to-comp migrate: $fid_before != $fid_after"
8117 }
8118 run_test 56xf "FID is not lost during migration of a composite layout file"
8119
8120 check_file_ost_range() {
8121         local file="$1"
8122         shift
8123         local range="$*"
8124         local -a file_range
8125         local idx
8126
8127         file_range=($($LFS getstripe -y "$file" |
8128                 awk '/l_ost_idx:/ { print $NF }'))
8129
8130         if [[ "${#file_range[@]}" = 0 ]]; then
8131                 echo "No osts found for $file"
8132                 return 1
8133         fi
8134
8135         for idx in "${file_range[@]}"; do
8136                 [[ " $range " =~ " $idx " ]] ||
8137                         return 1
8138         done
8139
8140         return 0
8141 }
8142
8143 sub_test_56xg() {
8144         local stripe_opt="$1"
8145         local pool="$2"
8146         shift 2
8147         local pool_ostidx="$(seq $* | tr '\n' ' ')"
8148
8149         $LFS migrate $stripe_opt -p $pool $DIR/$tfile ||
8150                 error "Fail to migrate $tfile on $pool"
8151         [[ "$($LFS getstripe -p $DIR/$tfile)" = "$pool" ]] ||
8152                 error "$tfile is not in pool $pool"
8153         check_file_ost_range "$DIR/$tfile" $pool_ostidx ||
8154                 error "$tfile osts mismatch with pool $pool (osts $pool_ostidx)"
8155 }
8156
8157 test_56xg() {
8158         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
8159         [[ $OSTCOUNT -ge 2 ]] || skip "needs >= 2 OSTs"
8160         [[ $MDS1_VERSION -gt $(version_code 2.14.52) ]] ||
8161                 skip "Need MDS version newer than 2.14.52"
8162
8163         local -a pool_names=("${TESTNAME}_0" "${TESTNAME}_1" "${TESTNAME}_2")
8164         local -a pool_ranges=("0 0" "1 1" "0 1")
8165
8166         # init pools
8167         for i in "${!pool_names[@]}"; do
8168                 pool_add ${pool_names[$i]} ||
8169                         error "pool_add failed (pool: ${pool_names[$i]})"
8170                 pool_add_targets ${pool_names[$i]} ${pool_ranges[$i]} ||
8171                         error "pool_add_targets failed (pool: ${pool_names[$i]})"
8172         done
8173
8174         # init the file to migrate
8175         $LFS setstripe -c1 -i1 $DIR/$tfile ||
8176                 error "Unable to create $tfile on OST1"
8177         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=4 status=none ||
8178                 error "Unable to write on $tfile"
8179
8180         echo "1. migrate $tfile on pool ${pool_names[0]}"
8181         sub_test_56xg "-c-1" "${pool_names[0]}" ${pool_ranges[0]}
8182
8183         echo "2. migrate $tfile on pool ${pool_names[2]}"
8184         sub_test_56xg "-c-1 -S2M" "${pool_names[2]}" ${pool_ranges[2]}
8185
8186         echo "3. migrate $tfile on pool ${pool_names[1]}"
8187         sub_test_56xg "-n -c-1" "${pool_names[1]}" ${pool_ranges[1]}
8188
8189         echo "4. migrate $tfile on pool ${pool_names[2]} with default stripe parameters"
8190         sub_test_56xg "" "${pool_names[2]}" ${pool_ranges[2]}
8191         echo
8192
8193         # Clean pools
8194         destroy_test_pools ||
8195                 error "pool_destroy failed"
8196 }
8197 run_test 56xg "lfs migrate pool support"
8198
8199 test_56xh() {
8200         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
8201
8202         local size_mb=25
8203         local file1=$DIR/$tfile
8204         local tmp1=$TMP/$tfile.tmp
8205
8206         $LFS setstripe -c 2 $file1
8207
8208         stack_trap "rm -f $file1 $tmp1"
8209         dd if=/dev/urandom of=$tmp1 bs=1M count=$size_mb ||
8210                         error "error creating $tmp1"
8211         ls -lsh $tmp1
8212         cp $tmp1 $file1
8213
8214         local start=$SECONDS
8215
8216         $LFS migrate --stats --stats-interval=1 -W 1M -c 1 $file1 ||
8217                 error "migrate failed rc = $?"
8218
8219         local elapsed=$((SECONDS - start))
8220
8221         # with 1MB/s, elapsed should equal size_mb
8222         (( elapsed >= size_mb * 95 / 100 )) ||
8223                 error "'lfs migrate -W' too fast ($elapsed < 0.95 * $size_mb)?"
8224
8225         (( elapsed <= size_mb * 120 / 100 )) ||
8226                 error_not_in_vm "'lfs migrate -W' slow ($elapsed > 1.2 * $size_mb)"
8227
8228         (( elapsed <= size_mb * 350 / 100 )) ||
8229                 error "'lfs migrate -W' too slow in VM ($elapsed > 3.5 * $size_mb)"
8230
8231         stripe=$($LFS getstripe -c $file1)
8232         (( $stripe == 1 )) || error "stripe of $file1 is $stripe != 1"
8233         cmp $file1 $tmp1 || error "content mismatch $file1 differs from $tmp1"
8234
8235         # Clean up file (since it is multiple MB)
8236         rm -f $file1 $tmp1
8237 }
8238 run_test 56xh "lfs migrate bandwidth limitation support"
8239
8240 test_56xi() {
8241         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
8242         verify_yaml_available || skip_env "YAML verification not installed"
8243
8244         local size_mb=5
8245         local file1=$DIR/$tfile.1
8246         local file2=$DIR/$tfile.2
8247         local file3=$DIR/$tfile.3
8248         local output_file=$DIR/$tfile.out
8249         local tmp1=$TMP/$tfile.tmp
8250
8251         $LFS setstripe -c 2 $file1
8252         $LFS setstripe -c 2 $file2
8253         $LFS setstripe -c 2 $file3
8254
8255         stack_trap "rm -f $file1 $file2 $file3 $tmp1 $output_file"
8256         dd if=/dev/urandom of=$tmp1 bs=1M count=$size_mb ||
8257                         error "error creating $tmp1"
8258         ls -lsh $tmp1
8259         cp $tmp1 $file1
8260         cp $tmp1 $file2
8261         cp $tmp1 $file3
8262
8263         $LFS migrate --stats --stats-interval=1 \
8264                 -c 1 $file1 $file2 $file3 1> $output_file ||
8265                 error "migrate failed rc = $?"
8266
8267         cat $output_file
8268         cat $output_file | verify_yaml || error "rename_stats is not valid YAML"
8269
8270         # Clean up file (since it is multiple MB)
8271         rm -f $file1 $file2 $file3 $tmp1 $output_file
8272 }
8273 run_test 56xi "lfs migrate stats support"
8274
8275 test_56xj() { # LU-16571 "lfs migrate -b" can cause thread starvation on OSS
8276         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
8277
8278         local file=$DIR/$tfile
8279         local linkdir=$DIR/$tdir
8280
8281         test_mkdir $linkdir || error "fail to create $linkdir"
8282         $LFS setstripe -i 0 -c 1 -S1M $file
8283         dd if=/dev/urandom of=$file bs=1M count=10 ||
8284                 error "fail to create $file"
8285
8286         # Create file links
8287         local cpts
8288         local threads_max
8289         local nlinks
8290
8291         thread_max=$(do_facet ost1 "$LCTL get_param -n ost.OSS.ost.threads_max")
8292         cpts=$(do_facet ost1 "$LCTL get_param -n cpu_partition_table | wc -l")
8293         (( nlinks = thread_max * 3 / 2 / cpts))
8294
8295         echo "create $nlinks hard links of $file"
8296         createmany -l $file $linkdir/link $nlinks
8297
8298         # Parallel migrates (should not block)
8299         local i
8300         for ((i = 0; i < nlinks; i++)); do
8301                 echo $linkdir/link$i
8302         done | xargs -n1 -P $nlinks $LFS migrate -c2
8303
8304         local stripe_count
8305         stripe_count=$($LFS getstripe -c $file) ||
8306                 error "fail to get stripe count on $file"
8307
8308         ((stripe_count == 2)) ||
8309                 error "fail to migrate $file (stripe_count = $stripe_count)"
8310 }
8311 run_test 56xj "lfs migrate -b should not cause starvation of threads on OSS"
8312
8313 test_56y() {
8314         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
8315                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
8316
8317         local res=""
8318         local dir=$DIR/$tdir
8319         local f1=$dir/file1
8320         local f2=$dir/file2
8321
8322         test_mkdir -p $dir || error "creating dir $dir"
8323         touch $f1 || error "creating std file $f1"
8324         $MULTIOP $f2 H2c || error "creating released file $f2"
8325
8326         # a directory can be raid0, so ask only for files
8327         res=$($LFS find $dir -L raid0 -type f | wc -l)
8328         [[ $res == 2 ]] || error "search raid0: found $res files != 2"
8329
8330         res=$($LFS find $dir \! -L raid0 -type f | wc -l)
8331         [[ $res == 0 ]] || error "search !raid0: found $res files != 0"
8332
8333         # only files can be released, so no need to force file search
8334         res=$($LFS find $dir -L released)
8335         [[ $res == $f2 ]] || error "search released: found $res != $f2"
8336
8337         res=$($LFS find $dir -type f \! -L released)
8338         [[ $res == $f1 ]] || error "search !released: found $res != $f1"
8339 }
8340 run_test 56y "lfs find -L raid0|released"
8341
8342 test_56z() { # LU-4824
8343         # This checks to make sure 'lfs find' continues after errors
8344         # There are two classes of errors that should be caught:
8345         # - If multiple paths are provided, all should be searched even if one
8346         #   errors out
8347         # - If errors are encountered during the search, it should not terminate
8348         #   early
8349         local dir=$DIR/$tdir
8350         local i
8351
8352         test_mkdir $dir
8353         for i in d{0..9}; do
8354                 test_mkdir $dir/$i
8355                 touch $dir/$i/$tfile
8356         done
8357         $LFS find $DIR/non_existent_dir $dir &&
8358                 error "$LFS find did not return an error"
8359         # Make a directory unsearchable. This should NOT be the last entry in
8360         # directory order.  Arbitrarily pick the 6th entry
8361         chmod 700 $($LFS find $dir -type d | sed '6!d')
8362
8363         $RUNAS $LFS find $DIR/non_existent $dir
8364         local count=$($RUNAS $LFS find $DIR/non_existent $dir | wc -l)
8365
8366         # The user should be able to see 10 directories and 9 files
8367         (( count == 19 )) ||
8368                 error "$LFS find found $count != 19 entries after error"
8369 }
8370 run_test 56z "lfs find should continue after an error"
8371
8372 test_56aa() { # LU-5937
8373         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
8374
8375         local dir=$DIR/$tdir
8376
8377         mkdir $dir
8378         $LFS setdirstripe -c$MDSCOUNT $dir/striped_dir
8379
8380         createmany -o $dir/striped_dir/${tfile}- 1024
8381         local dirs=$($LFS find --size +8k $dir/)
8382
8383         [ -n "$dirs" ] || error "lfs find --size wrong under striped dir"
8384 }
8385 run_test 56aa "lfs find --size under striped dir"
8386
8387 test_56ab() { # LU-10705
8388         test_mkdir $DIR/$tdir
8389         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=8k count=1 seek=2k
8390         dd if=/dev/zero of=$DIR/$tdir/$tfile.2 bs=4k count=1 seek=4k
8391         dd if=/dev/zero of=$DIR/$tdir/$tfile.3 bs=1M count=2 seek=16
8392         # Flush writes to ensure valid blocks.  Need to be more thorough for
8393         # ZFS, since blocks are not allocated/returned to client immediately.
8394         sync_all_data
8395         wait_zfs_commit ost1 2
8396         cancel_lru_locks osc
8397         ls -ls $DIR/$tdir
8398
8399         local files=$($LFS find --size +16M $DIR/$tdir | wc -l)
8400
8401         [[ $files == 3 ]] || error ">16M size files $files isn't 3 as expected"
8402
8403         files=$($LFS find --blocks +1M $DIR/$tdir | wc -l)
8404         [[ $files == 1 ]] || error ">1M blocks files $files isn't 1 as expected"
8405
8406         rm -f $DIR/$tdir/$tfile.[123]
8407 }
8408 run_test 56ab "lfs find --blocks"
8409
8410 # LU-11188
8411 test_56aca() {
8412         local dir="$DIR/$tdir"
8413         local perms=(001 002 003 004 005 006 007
8414                      010 020 030 040 050 060 070
8415                      100 200 300 400 500 600 700
8416                      111 222 333 444 555 666 777)
8417         local perm_minus=(8 8 4 8 4 4 2
8418                           8 8 4 8 4 4 2
8419                           8 8 4 8 4 4 2
8420                           4 4 2 4 2 2 1)
8421         local perm_slash=(8  8 12  8 12 12 14
8422                           8  8 12  8 12 12 14
8423                           8  8 12  8 12 12 14
8424                          16 16 24 16 24 24 28)
8425
8426         test_mkdir "$dir"
8427         for perm in ${perms[*]}; do
8428                 touch "$dir/$tfile.$perm"
8429                 chmod $perm "$dir/$tfile.$perm"
8430         done
8431
8432         for ((i = 0; i < ${#perms[*]}; i++)); do
8433                 local num=$($LFS find $dir -perm ${perms[i]} | wc -l)
8434                 (( $num == 1 )) ||
8435                         error "lfs find -perm ${perms[i]}:"\
8436                               "$num != 1"
8437
8438                 num=$($LFS find $dir -perm -${perms[i]} -type f| wc -l)
8439                 (( $num == ${perm_minus[i]} )) ||
8440                         error "lfs find -perm -${perms[i]}:"\
8441                               "$num != ${perm_minus[i]}"
8442
8443                 num=$($LFS find $dir -perm /${perms[i]} -type f| wc -l)
8444                 (( $num == ${perm_slash[i]} )) ||
8445                         error "lfs find -perm /${perms[i]}:"\
8446                               "$num != ${perm_slash[i]}"
8447         done
8448 }
8449 run_test 56aca "check lfs find -perm with octal representation"
8450
8451 test_56acb() {
8452         local dir=$DIR/$tdir
8453         # p is the permission of write and execute for user, group and other
8454         # without the umask. It is used to test +wx.
8455         local p=$(printf "%o" "$((0333 & ~$(umask)))")
8456         local perms=(1000 000 2000 4000 $p 644 111 110 100 004)
8457         local symbolic=(+t  a+t u+t g+t o+t
8458                         g+s u+s o+s +s o+sr
8459                         o=r,ug+o,u+w
8460                         u+ g+ o+ a+ ugo+
8461                         u- g- o- a- ugo-
8462                         u= g= o= a= ugo=
8463                         o=r,ug+o,u+w u=r,a+u,u+w
8464                         g=r,ugo=g,u+w u+x,+X +X
8465                         u+x,u+X u+X u+x,g+X o+r,+X
8466                         u+x,go+X +wx +rwx)
8467
8468         test_mkdir $dir
8469         for perm in ${perms[*]}; do
8470                 touch "$dir/$tfile.$perm"
8471                 chmod $perm "$dir/$tfile.$perm"
8472         done
8473
8474         for (( i = 0; i < ${#symbolic[*]}; i++ )); do
8475                 local num=$($LFS find $dir -perm ${symbolic[i]} | wc -l)
8476
8477                 (( $num == 1 )) ||
8478                         error "lfs find $dir -perm ${symbolic[i]}: $num != 1"
8479         done
8480 }
8481 run_test 56acb "check lfs find -perm with symbolic representation"
8482
8483 test_56acc() {
8484         local dir=$DIR/$tdir
8485         local tests="17777 787 789 abcd
8486                 ug=uu ug=a ug=gu uo=ou urw
8487                 u+xg+x a=r,u+x,"
8488
8489         test_mkdir $dir
8490         for err in $tests; do
8491                 if $LFS find $dir -perm $err 2>/dev/null; then
8492                         error "lfs find -perm $err: parsing should have failed"
8493                 fi
8494         done
8495 }
8496 run_test 56acc "check parsing error for lfs find -perm"
8497
8498 test_56ba() {
8499         [ $MDS1_VERSION -lt $(version_code 2.10.50) ] &&
8500                 skip "Need MDS version at least 2.10.50"
8501
8502         # Create composite files with one component
8503         local dir=$DIR/$tdir
8504
8505         setup_56 $dir/1Mfiles 5 1 "-S 1M --component-end 1M"
8506         # Create composite files with three components
8507         setup_56 $dir/2Mfiles 5 2 "-E 2M -S 1M -E 4M -E 6M"
8508         # Create non-composite files
8509         createmany -o $dir/${tfile}- 10
8510
8511         local nfiles=$($LFS find --component-end 1M --type f $dir | wc -l)
8512
8513         [[ $nfiles == 10 ]] ||
8514                 error "lfs find -E 1M found $nfiles != 10 files"
8515
8516         nfiles=$($LFS find ! -E 1M --type f $dir | wc -l)
8517         [[ $nfiles == 25 ]] ||
8518                 error "lfs find ! -E 1M found $nfiles != 25 files"
8519
8520         # All files have a component that starts at 0
8521         nfiles=$($LFS find --component-start 0 --type f $dir | wc -l)
8522         [[ $nfiles == 35 ]] ||
8523                 error "lfs find --component-start 0 - $nfiles != 35 files"
8524
8525         nfiles=$($LFS find --component-start 2M --type f $dir | wc -l)
8526         [[ $nfiles == 15 ]] ||
8527                 error "lfs find --component-start 2M - $nfiles != 15 files"
8528
8529         # All files created here have a componenet that does not starts at 2M
8530         nfiles=$($LFS find ! --component-start 2M --type f $dir | wc -l)
8531         [[ $nfiles == 35 ]] ||
8532                 error "lfs find ! --component-start 2M - $nfiles != 35 files"
8533
8534         # Find files with a specified number of components
8535         local nfiles=$($LFS find --component-count 3 --type f $dir | wc -l)
8536         [[ $nfiles == 15 ]] ||
8537                 error "lfs find --component-count 3 - $nfiles != 15 files"
8538
8539         # Remember non-composite files have a component count of zero
8540         local nfiles=$($LFS find --component-count 0 --type f $dir | wc -l)
8541         [[ $nfiles == 10 ]] ||
8542                 error "lfs find --component-count 0 - $nfiles != 10 files"
8543
8544         nfiles=$($LFS find ! --component-count 3 --type f $dir | wc -l)
8545         [[ $nfiles == 20 ]] ||
8546                 error "lfs find ! --component-count 3 - $nfiles != 20 files"
8547
8548         # All files have a flag called "init"
8549         local nfiles=$($LFS find --component-flags init --type f $dir | wc -l)
8550         [[ $nfiles == 35 ]] ||
8551                 error "lfs find --component-flags init - $nfiles != 35 files"
8552
8553         # Multi-component files will have a component not initialized
8554         local nfiles=$($LFS find ! --component-flags init --type f $dir | wc -l)
8555         [[ $nfiles == 15 ]] ||
8556                 error "lfs find !--component-flags init - $nfiles != 15 files"
8557
8558         rm -rf $dir
8559
8560 }
8561 run_test 56ba "test lfs find --component-end, -start, -count, and -flags"
8562
8563 test_56ca() {
8564         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
8565                 skip "Need MDS version at least 2.10.57"
8566
8567         local td=$DIR/$tdir
8568         local tf=$td/$tfile
8569         local dir
8570         local nfiles
8571         local cmd
8572         local i
8573         local j
8574
8575         # create mirrored directories and mirrored files
8576         mkdir $td || error "mkdir $td failed"
8577         $LFS mirror create -N3 $td || error "create mirrored dir $td failed"
8578         createmany -o $tf- 10 || error "create $tf- failed"
8579
8580         for i in $(seq 2); do
8581                 dir=$td/dir$i
8582                 mkdir $dir || error "mkdir $dir failed"
8583                 $LFS mirror create -N$((3 + i)) $dir ||
8584                         error "create mirrored dir $dir failed"
8585                 createmany -o $dir/$tfile- 10 ||
8586                         error "create $dir/$tfile- failed"
8587         done
8588
8589         # change the states of some mirrored files
8590         echo foo > $tf-6
8591         for i in $(seq 2); do
8592                 dir=$td/dir$i
8593                 for j in $(seq 4 9); do
8594                         echo foo > $dir/$tfile-$j
8595                 done
8596         done
8597
8598         # find mirrored files with specific mirror count
8599         cmd="$LFS find --mirror-count 3 --type f $td"
8600         nfiles=$($cmd | wc -l)
8601         [[ $nfiles = 10 ]] || error "$cmd: $nfiles != 10 files"
8602
8603         cmd="$LFS find ! --mirror-count 3 --type f $td"
8604         nfiles=$($cmd | wc -l)
8605         [[ $nfiles = 20 ]] || error "$cmd: $nfiles != 20 files"
8606
8607         cmd="$LFS find --mirror-count +2 --type f $td"
8608         nfiles=$($cmd | wc -l)
8609         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8610
8611         cmd="$LFS find --mirror-count -6 --type f $td"
8612         nfiles=$($cmd | wc -l)
8613         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8614
8615         # find mirrored files with specific file state
8616         cmd="$LFS find --maxdepth 1 --mirror-state=^ro --type f $td"
8617         [[ $($cmd) = $tf-6 ]] || error "$cmd: didn't return $tf-6"
8618
8619         cmd="$LFS find --mirror-state=ro --type f $td"
8620         nfiles=$($cmd | wc -l)
8621         [[ $nfiles = 17 ]] || error "$cmd: $nfiles != 17 files"
8622
8623         cmd="$LFS find ! --mirror-state=ro --type f $td"
8624         nfiles=$($cmd | wc -l)
8625         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
8626
8627         cmd="$LFS find --mirror-state=wp --type f $td"
8628         nfiles=$($cmd | wc -l)
8629         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
8630
8631         cmd="$LFS find ! --mirror-state=sp --type f $td"
8632         nfiles=$($cmd | wc -l)
8633         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8634 }
8635 run_test 56ca "check lfs find --mirror-count|-N and --mirror-state"
8636
8637 test_56da() { # LU-14179
8638         local path=$DIR/$tdir
8639
8640         test_mkdir $path
8641         cd $path
8642
8643         local longdir=$(str_repeat 'a' 255)
8644
8645         for i in {1..15}; do
8646                 path=$path/$longdir
8647                 test_mkdir $longdir
8648                 cd $longdir
8649         done
8650
8651         local len=${#path}
8652         local lastdir=$(str_repeat 'a' $((4096 - 1 - $len - 1)))
8653
8654         test_mkdir $lastdir
8655         cd $lastdir
8656         # PATH_MAX-1
8657         (( ${#PWD} == 4095 )) || error "bad PWD length ${#PWD}, expect 4095"
8658
8659         # NAME_MAX
8660         touch $(str_repeat 'f' 255)
8661
8662         $LFS find $DIR/$tdir --type d |& grep "lfs find: error" &&
8663                 error "lfs find reported an error"
8664
8665         rm -rf $DIR/$tdir
8666 }
8667 run_test 56da "test lfs find with long paths"
8668
8669 test_56ea() { #LU-10378
8670         local path=$DIR/$tdir
8671         local pool=$TESTNAME
8672
8673         # Create ost pool
8674         pool_add $pool || error "pool_add $pool failed"
8675         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
8676                 error "adding targets to $pool failed"
8677
8678         # Set default pool on directory before creating file
8679         mkdir $path || error "mkdir $path failed"
8680         $LFS setstripe -p $pool $path ||
8681                 error "set OST pool on $pool failed"
8682         touch $path/$tfile || error "touch $path/$tfile failed"
8683
8684         # Compare basic file attributes from -printf and stat
8685         local attr_printf=$($LFS find $path/$tfile -printf "%A@ %T@ %C@ %U %G %n")
8686         local attr_stat=$(stat -c "%X %Y %Z %u %g %h" $path/$tfile)
8687
8688         [[ "${attr_printf}" == "${attr_stat}" ]] ||
8689                 error "Attrs from lfs find and stat don't match"
8690
8691         # Compare Lustre attributes from lfs find and lfs getstripe
8692         local lattr_printf=$($LFS find $path/$tfile -printf "%Lc %LS %Li %Lp")
8693         local str_cnt=$($LFS getstripe --stripe-count $path/$tfile)
8694         local str_size=$($LFS getstripe --stripe-size $path/$tfile)
8695         local str_idx=$($LFS getstripe --stripe-index $path/$tfile)
8696         local fpool=$($LFS getstripe --pool $path/$tfile)
8697         local lattr_getstr="${str_cnt} ${str_size} ${str_idx} ${fpool}"
8698
8699         [[ "${lattr_printf}" == "${lattr_getstr}" ]] ||
8700                 error "Attrs from lfs find and lfs getstripe don't match"
8701
8702         # Verify behavior for unknown escape/format sequences
8703         local esc_printf=$($LFS find $path/$tfile -printf '\\ %% \Q %Q')
8704
8705         [[ "${esc_printf}" == '\ % \Q %Q' ]] ||
8706                 error "Escape/format codes don't match"
8707 }
8708 run_test 56ea "test lfs find -printf option"
8709
8710 test_56eb() {
8711         local dir=$DIR/$tdir
8712         local subdir_1=$dir/subdir_1
8713
8714         test_mkdir -p $subdir_1
8715         ln -s subdir_1 $dir/link_1
8716
8717         $LFS getstripe $dir | grep "^$dir/link_1$" -A1 ||
8718                 error "symlink is not followed"
8719
8720         $LFS getstripe --no-follow $dir |
8721                 grep "^$dir/link_1 has no stripe info$" ||
8722                 error "symlink should not have stripe info"
8723
8724         touch $dir/testfile
8725         ln -s testfile $dir/file_link_2
8726
8727         $LFS getstripe $dir | grep "^$dir/file_link_2$" -A1 ||
8728                 error "symlink is not followed"
8729
8730         $LFS getstripe --no-follow $dir |
8731                 grep "^$dir/file_link_2 has no stripe info$" ||
8732                 error "symlink should not have stripe info"
8733 }
8734 run_test 56eb "check lfs getstripe on symlink"
8735
8736 test_56ec() {
8737         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8738         local dir=$DIR/$tdir
8739         local srcfile=$dir/srcfile
8740         local srcyaml=$dir/srcyaml
8741         local destfile=$dir/destfile
8742
8743         test_mkdir -p $dir
8744
8745         $LFS setstripe -i 1 $srcfile
8746         $LFS getstripe --hex-idx --yaml $srcfile > $srcyaml
8747         # if the setstripe yaml parsing fails for any reason, the command can
8748         # randomly assign the correct OST index, leading to an erroneous
8749         # success. but the chance of false success is low enough that a
8750         # regression should still be quickly caught.
8751         $LFS setstripe --yaml=$srcyaml $destfile
8752
8753         local srcindex=$($LFS getstripe -i $srcfile)
8754         local destindex=$($LFS getstripe -i $destfile)
8755
8756         if [[ ! $srcindex -eq $destindex ]]; then
8757                 error "setstripe did not set OST index correctly"
8758         fi
8759 }
8760 run_test 56ec "check lfs getstripe,setstripe --hex --yaml"
8761
8762 test_56eda() {
8763         local dir=$DIR/$tdir
8764         local subdir=$dir/subdir
8765         local file1=$dir/$tfile
8766         local file2=$dir/$tfile\2
8767         local link=$dir/$tfile-link
8768         local nfiles
8769
8770         test_mkdir -p $dir
8771         $LFS setdirstripe -c1 $subdir
8772         touch $file1
8773         touch $file2
8774         ln $file2 $link
8775
8776         nfiles=$($LFS find --links 1 $dir | wc -l)
8777         (( $nfiles == 1 )) ||
8778                 error "lfs find --links expected 1 file, got $nfiles"
8779
8780         nfiles=$($LFS find --type f --links 2 $dir | wc -l)
8781         (( $nfiles == 2 )) ||
8782                 error "lfs find --links expected 2 files, got $nfiles"
8783
8784         nfiles=$($LFS find --type d --links 2 $dir | wc -l)
8785         (( $nfiles == 1 )) ||
8786                 error "lfs find --links expected 1 directory, got $nfiles"
8787 }
8788 run_test 56eda "check lfs find --links"
8789
8790 test_56edb() {
8791         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
8792
8793         local dir=$DIR/$tdir
8794         local stripedir=$dir/stripedir
8795         local nfiles
8796
8797         test_mkdir -p $dir
8798
8799         $LFS setdirstripe -c2 $stripedir
8800
8801         $LFS getdirstripe $stripedir
8802
8803         nfiles=$($LFS find --type d --links 2 $stripedir | wc -l)
8804         (( $nfiles == 1 )) ||
8805                 error "lfs find --links expected 1 directory, got $nfiles"
8806 }
8807 run_test 56edb "check lfs find --links for directory striped on multiple MDTs"
8808
8809 test_57a() {
8810         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8811         # note test will not do anything if MDS is not local
8812         if [ "$mds1_FSTYPE" != ldiskfs ]; then
8813                 skip_env "ldiskfs only test"
8814         fi
8815         remote_mds_nodsh && skip "remote MDS with nodsh"
8816
8817         local MNTDEV="osd*.*MDT*.mntdev"
8818         DEV=$(do_facet $SINGLEMDS lctl get_param -n $MNTDEV)
8819         [ -z "$DEV" ] && error "can't access $MNTDEV"
8820         for DEV in $(do_facet $SINGLEMDS lctl get_param -n $MNTDEV); do
8821                 do_facet $SINGLEMDS $DUMPE2FS -h $DEV > $TMP/t57a.dump ||
8822                         error "can't access $DEV"
8823                 DEVISIZE=$(awk '/Inode size:/ { print $3 }' $TMP/t57a.dump)
8824                 [[ $DEVISIZE -gt 128 ]] || error "inode size $DEVISIZE"
8825                 rm $TMP/t57a.dump
8826         done
8827 }
8828 run_test 57a "verify MDS filesystem created with large inodes =="
8829
8830 test_57b() {
8831         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8832         if [ "$mds1_FSTYPE" != ldiskfs ]; then
8833                 skip_env "ldiskfs only test"
8834         fi
8835         remote_mds_nodsh && skip "remote MDS with nodsh"
8836
8837         local dir=$DIR/$tdir
8838         local filecount=100
8839         local file1=$dir/f1
8840         local fileN=$dir/f$filecount
8841
8842         rm -rf $dir || error "removing $dir"
8843         test_mkdir -c1 $dir
8844         local mdtidx=$($LFS getstripe -m $dir)
8845         local mdtname=MDT$(printf %04x $mdtidx)
8846         local facet=mds$((mdtidx + 1))
8847
8848         echo "mcreating $filecount files"
8849         createmany -m $dir/f 1 $filecount || error "creating files in $dir"
8850
8851         # verify that files do not have EAs yet
8852         $LFS getstripe $file1 2>&1 | grep -q "no stripe" ||
8853                 error "$file1 has an EA"
8854         $LFS getstripe $fileN 2>&1 | grep -q "no stripe" ||
8855                 error "$fileN has an EA"
8856
8857         sync
8858         sleep 1
8859         df $dir  #make sure we get new statfs data
8860         local mdsfree=$(do_facet $facet \
8861                         lctl get_param -n osd*.*$mdtname.kbytesfree)
8862         local mdcfree=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
8863         local file
8864
8865         echo "opening files to create objects/EAs"
8866         for file in $(seq -f $dir/f%g 1 $filecount); do
8867                 $OPENFILE -f O_RDWR $file > /dev/null 2>&1 ||
8868                         error "opening $file"
8869         done
8870
8871         # verify that files have EAs now
8872         $LFS getstripe $file1 | grep -q "obdidx" || error "$file1 missing EA"
8873         $LFS getstripe $fileN | grep -q "obdidx" || error "$fileN missing EA"
8874
8875         sleep 1  #make sure we get new statfs data
8876         df $dir
8877         local mdsfree2=$(do_facet $facet \
8878                          lctl get_param -n osd*.*$mdtname.kbytesfree)
8879         local mdcfree2=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
8880
8881         if [[ $mdcfree2 -lt $((mdcfree - 16)) ]]; then
8882                 if [ "$mdsfree" != "$mdsfree2" ]; then
8883                         error "MDC before $mdcfree != after $mdcfree2"
8884                 else
8885                         echo "MDC before $mdcfree != after $mdcfree2"
8886                         echo "unable to confirm if MDS has large inodes"
8887                 fi
8888         fi
8889         rm -rf $dir
8890 }
8891 run_test 57b "default LOV EAs are stored inside large inodes ==="
8892
8893 test_58() {
8894         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8895         [ -z "$(which wiretest 2>/dev/null)" ] &&
8896                         skip_env "could not find wiretest"
8897
8898         wiretest
8899 }
8900 run_test 58 "verify cross-platform wire constants =============="
8901
8902 test_59() {
8903         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8904
8905         echo "touch 130 files"
8906         createmany -o $DIR/f59- 130
8907         echo "rm 130 files"
8908         unlinkmany $DIR/f59- 130
8909         sync
8910         # wait for commitment of removal
8911         wait_delete_completed
8912 }
8913 run_test 59 "verify cancellation of llog records async ========="
8914
8915 TEST60_HEAD="test_60 run $RANDOM"
8916 test_60a() {
8917         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8918         remote_mgs_nodsh && skip "remote MGS with nodsh"
8919         do_facet mgs "! which run-llog.sh &> /dev/null" &&
8920                 do_facet mgs "! ls run-llog.sh &> /dev/null" &&
8921                         skip_env "missing subtest run-llog.sh"
8922
8923         log "$TEST60_HEAD - from kernel mode"
8924         do_facet mgs "$LCTL dk > /dev/null"
8925         do_facet mgs "bash run-llog.sh" || error "run-llog.sh failed"
8926         do_facet mgs $LCTL dk > $TMP/$tfile
8927
8928         # LU-6388: test llog_reader
8929         local llog_reader=$(do_facet mgs "which llog_reader 2> /dev/null")
8930         llog_reader=${llog_reader:-$LUSTRE/utils/llog_reader}
8931         [ -z $(do_facet mgs ls -d $llog_reader 2> /dev/null) ] &&
8932                         skip_env "missing llog_reader"
8933         local fstype=$(facet_fstype mgs)
8934         [ $fstype != ldiskfs -a $fstype != zfs ] &&
8935                 skip_env "Only for ldiskfs or zfs type mgs"
8936
8937         local mntpt=$(facet_mntpt mgs)
8938         local mgsdev=$(mgsdevname 1)
8939         local fid_list
8940         local fid
8941         local rec_list
8942         local rec
8943         local rec_type
8944         local obj_file
8945         local path
8946         local seq
8947         local oid
8948         local pass=true
8949
8950         #get fid and record list
8951         fid_list=($(awk '/9_sub.*record/ { print $NF }' $TMP/$tfile |
8952                 tail -n 4))
8953         rec_list=($(awk '/9_sub.*record/ { print $((NF-3)) }' $TMP/$tfile |
8954                 tail -n 4))
8955         #remount mgs as ldiskfs or zfs type
8956         stop mgs || error "stop mgs failed"
8957         mount_fstype mgs || error "remount mgs failed"
8958         for ((i = 0; i < ${#fid_list[@]}; i++)); do
8959                 fid=${fid_list[i]}
8960                 rec=${rec_list[i]}
8961                 seq=$(echo $fid | awk -F ':' '{ print $1 }' | sed -e "s/^0x//g")
8962                 oid=$(echo $fid | awk -F ':' '{ print $2 }' | sed -e "s/^0x//g")
8963                 oid=$((16#$oid))
8964
8965                 case $fstype in
8966                         ldiskfs )
8967                                 obj_file=$mntpt/O/$seq/d$((oid%32))/$oid ;;
8968                         zfs )
8969                                 obj_file=$mntpt/oi.$(($((16#$seq))&127))/$fid ;;
8970                 esac
8971                 echo "obj_file is $obj_file"
8972                 do_facet mgs $llog_reader $obj_file
8973
8974                 rec_type=$(do_facet mgs $llog_reader $obj_file | grep "type=" |
8975                         awk '{ print $3 }' | sed -e "s/^type=//g")
8976                 if [ $rec_type != $rec ]; then
8977                         echo "FAILED test_60a wrong record type $rec_type," \
8978                               "should be $rec"
8979                         pass=false
8980                         break
8981                 fi
8982
8983                 #check obj path if record type is LLOG_LOGID_MAGIC
8984                 if [ "$rec" == "1064553b" ]; then
8985                         path=$(do_facet mgs $llog_reader $obj_file |
8986                                 grep "path=" | awk '{ print $NF }' |
8987                                 sed -e "s/^path=//g")
8988                         if [ $obj_file != $mntpt/$path ]; then
8989                                 echo "FAILED test_60a wrong obj path" \
8990                                       "$montpt/$path, should be $obj_file"
8991                                 pass=false
8992                                 break
8993                         fi
8994                 fi
8995         done
8996         rm -f $TMP/$tfile
8997         #restart mgs before "error", otherwise it will block the next test
8998         stop mgs || error "stop mgs failed"
8999         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
9000         $pass || error "test failed, see FAILED test_60a messages for specifics"
9001 }
9002 run_test 60a "llog_test run from kernel module and test llog_reader"
9003
9004 test_60b() { # bug 6411
9005         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9006
9007         dmesg > $DIR/$tfile
9008         LLOG_COUNT=$(do_facet mgs dmesg |
9009                      awk "/$TEST60_HEAD/ { marker = 1; from_marker = 0; }
9010                           /llog_[a-z]*.c:[0-9]/ {
9011                                 if (marker)
9012                                         from_marker++
9013                                 from_begin++
9014                           }
9015                           END {
9016                                 if (marker)
9017                                         print from_marker
9018                                 else
9019                                         print from_begin
9020                           }")
9021
9022         [[ $LLOG_COUNT -gt 120 ]] &&
9023                 error "CDEBUG_LIMIT not limiting messages ($LLOG_COUNT)" || true
9024 }
9025 run_test 60b "limit repeated messages from CERROR/CWARN"
9026
9027 test_60c() {
9028         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9029
9030         echo "create 5000 files"
9031         createmany -o $DIR/f60c- 5000
9032 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED  0x137
9033         lctl set_param fail_loc=0x80000137
9034         unlinkmany $DIR/f60c- 5000
9035         lctl set_param fail_loc=0
9036 }
9037 run_test 60c "unlink file when mds full"
9038
9039 test_60d() {
9040         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9041
9042         SAVEPRINTK=$(lctl get_param -n printk)
9043         # verify "lctl mark" is even working"
9044         MESSAGE="test message ID $RANDOM $$"
9045         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
9046         dmesg | grep -q "$MESSAGE" || error "didn't find debug marker in log"
9047
9048         lctl set_param printk=0 || error "set lnet.printk failed"
9049         lctl get_param -n printk | grep emerg || error "lnet.printk dropped emerg"
9050         MESSAGE="new test message ID $RANDOM $$"
9051         # Assume here that libcfs_debug_mark_buffer() uses D_WARNING
9052         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
9053         dmesg | grep -q "$MESSAGE" && error "D_WARNING wasn't masked" || true
9054
9055         lctl set_param -n printk="$SAVEPRINTK"
9056 }
9057 run_test 60d "test printk console message masking"
9058
9059 test_60e() {
9060         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9061         remote_mds_nodsh && skip "remote MDS with nodsh"
9062
9063         touch $DIR/$tfile
9064 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED2  0x15b
9065         do_facet mds1 lctl set_param fail_loc=0x15b
9066         rm $DIR/$tfile
9067 }
9068 run_test 60e "no space while new llog is being created"
9069
9070 test_60f() {
9071         local old_path=$($LCTL get_param -n debug_path)
9072
9073         stack_trap "$LCTL set_param debug_path=$old_path"
9074         stack_trap "rm -f $TMP/$tfile*"
9075         rm -f $TMP/$tfile* 2> /dev/null
9076         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
9077         $LCTL set_param debug_path=$TMP/$tfile fail_loc=0x8000050e
9078         test_mkdir $DIR/$tdir
9079         # retry in case the open is cached and not released
9080         for (( i = 0; i < 100 && $(ls $TMP/$tfile* | wc -l) == 0; i++ )); do
9081                 echo $i > $DIR/$tdir/$tfile.$i && cat $DIR/$tdir/$tfile.$i
9082                 sleep 0.1
9083         done
9084         ls $TMP/$tfile*
9085         (( $(ls $TMP/$tfile* | wc -l) > 0 )) || error "$TMP/$tfile not dumped"
9086 }
9087 run_test 60f "change debug_path works"
9088
9089 test_60g() {
9090         local pid
9091         local i
9092
9093         test_mkdir -c $MDSCOUNT $DIR/$tdir
9094
9095         (
9096                 local index=0
9097                 while true; do
9098                         $LFS setdirstripe -i $(($index % $MDSCOUNT)) \
9099                                 -c $MDSCOUNT $DIR/$tdir/subdir$index \
9100                                 2>/dev/null
9101                         mkdir $DIR/$tdir/subdir$index 2>/dev/null
9102                         rmdir $DIR/$tdir/subdir$index 2>/dev/null
9103                         index=$((index + 1))
9104                 done
9105         ) &
9106
9107         pid=$!
9108
9109         for i in {0..100}; do
9110                 # define OBD_FAIL_OSD_TXN_START    0x19a
9111                 local index=$((i % MDSCOUNT + 1))
9112
9113                 do_facet mds$index $LCTL set_param fail_loc=0x8000019a \
9114                         > /dev/null
9115                 sleep 0.01
9116         done
9117
9118         kill -9 $pid
9119
9120         for i in $(seq $MDSCOUNT); do
9121                 do_facet mds$i $LCTL set_param fail_loc=0 > /dev/null
9122         done
9123
9124         mkdir $DIR/$tdir/new || error "mkdir failed"
9125         rmdir $DIR/$tdir/new || error "rmdir failed"
9126
9127         do_facet mds1 $LCTL lfsck_start -M $(facet_svc mds1) -A -C \
9128                 -t namespace
9129         for i in $(seq $MDSCOUNT); do
9130                 wait_update_facet mds$i "$LCTL get_param -n \
9131                         mdd.$(facet_svc mds$i).lfsck_namespace |
9132                         awk '/^status/ { print \\\$2 }'" "completed"
9133         done
9134
9135         ls -R $DIR/$tdir
9136         rm -rf $DIR/$tdir || error "rmdir failed"
9137 }
9138 run_test 60g "transaction abort won't cause MDT hung"
9139
9140 test_60h() {
9141         [ $MDS1_VERSION -le $(version_code 2.12.52) ] &&
9142                 skip "Need MDS version at least 2.12.52"
9143         [ $MDSCOUNT -lt 2 ] && skip "Need at least 2 MDTs"
9144
9145         local f
9146
9147         #define OBD_FAIL_MDS_STRIPE_CREATE       0x188
9148         #define OBD_FAIL_MDS_STRIPE_FID          0x189
9149         for fail_loc in 0x80000188 0x80000189; do
9150                 do_facet mds1 "$LCTL set_param fail_loc=$fail_loc"
9151                 $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir-$fail_loc ||
9152                         error "mkdir $dir-$fail_loc failed"
9153                 for i in {0..10}; do
9154                         # create may fail on missing stripe
9155                         echo $i > $DIR/$tdir-$fail_loc/$i
9156                 done
9157                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
9158                         error "getdirstripe $tdir-$fail_loc failed"
9159                 $LFS migrate -m 1 $DIR/$tdir-$fail_loc ||
9160                         error "migrate $tdir-$fail_loc failed"
9161                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
9162                         error "getdirstripe $tdir-$fail_loc failed"
9163                 pushd $DIR/$tdir-$fail_loc
9164                 for f in *; do
9165                         echo $f | cmp $f - || error "$f data mismatch"
9166                 done
9167                 popd
9168                 rm -rf $DIR/$tdir-$fail_loc
9169         done
9170 }
9171 run_test 60h "striped directory with missing stripes can be accessed"
9172
9173 function t60i_load() {
9174         mkdir $DIR/$tdir
9175         #define OBD_FAIL_LLOG_PAUSE_AFTER_PAD               0x131c
9176         $LCTL set_param fail_loc=0x131c fail_val=1
9177         for ((i=0; i<5000; i++)); do
9178                 touch $DIR/$tdir/f$i
9179         done
9180 }
9181
9182 test_60i() {
9183         changelog_register || error "changelog_register failed"
9184         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
9185         changelog_users $SINGLEMDS | grep -q $cl_user ||
9186                 error "User $cl_user not found in changelog_users"
9187         changelog_chmask "ALL"
9188         t60i_load &
9189         local PID=$!
9190         for((i=0; i<100; i++)); do
9191                 changelog_dump >/dev/null ||
9192                         error "can't read changelog"
9193         done
9194         kill $PID
9195         wait $PID
9196         changelog_deregister || error "changelog_deregister failed"
9197         $LCTL set_param fail_loc=0
9198 }
9199 run_test 60i "llog: new record vs reader race"
9200
9201 test_60j() {
9202         (( $MDS1_VERSION >= $(version_code 2.15.50) )) ||
9203                 skip "need MDS version at least 2.15.50"
9204         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
9205         remote_mds_nodsh && skip "remote MDS with nodsh"
9206         [[ "$mds1_FSTYPE" == "ldiskfs" ]] || skip "ldiskfs only test"
9207
9208         changelog_users $SINGLEMDS | grep "^cl" &&
9209                 skip "active changelog user"
9210
9211         local llog_reader=$(do_facet $SINGLEMDS "which llog_reader 2> /dev/null")
9212
9213         [[ -z $(do_facet $SINGLEMDS ls -d $llog_reader 2> /dev/null) ]] &&
9214                 skip_env "missing llog_reader"
9215
9216         mkdir_on_mdt0 $DIR/$tdir
9217
9218         local f=$DIR/$tdir/$tfile
9219         local mdt_dev
9220         local tmpfile
9221         local plain
9222
9223         changelog_register || error "cannot register changelog user"
9224
9225         # set changelog_mask to ALL
9226         changelog_chmask "ALL"
9227         changelog_clear
9228
9229         createmany -o ${f}- 100 || error "createmany failed as $RUNAS_ID"
9230         unlinkmany ${f}- 100 || error "unlinkmany failed"
9231
9232         tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
9233         mdt_dev=$(facet_device $SINGLEMDS)
9234
9235         do_facet $SINGLEMDS sync
9236         plain=$(do_facet $SINGLEMDS "$DEBUGFS -c -R 'dump changelog_catalog \
9237                 $tmpfile' $mdt_dev; $llog_reader $tmpfile" |
9238                 awk '{match($0,"path=([^ ]+)",a)}END{print a[1]}')
9239
9240         stack_trap "do_facet $SINGLEMDS rm -f $tmpfile"
9241
9242         # if $tmpfile is not on EXT3 filesystem for some reason
9243         [[ ${plain:0:1} == 'O' ]] ||
9244                 skip "path $plain is not in 'O/1/d<n>/<n>' format"
9245
9246         size=$(do_facet $SINGLEMDS "$DEBUGFS -c -R 'dump $plain $tmpfile' \
9247                 $mdt_dev; stat -c %s $tmpfile")
9248         echo "Truncate llog from $size to $((size - size % 8192))"
9249         size=$((size - size % 8192))
9250         do_facet $SINGLEMDS $TRUNCATE $tmpfile $size
9251         errs=$(do_facet $SINGLEMDS "$llog_reader $tmpfile" |
9252                 grep -c 'in bitmap only')
9253         (( $errs > 0 )) || error "llog_reader didn't find lost records"
9254
9255         size=$((size - 9000))
9256         echo "Corrupt llog in the middle at $size"
9257         do_facet $SINGLEMDS dd if=/dev/urandom of=$tmpfile bs=1 seek=$size \
9258                 count=333 conv=notrunc
9259         errs=$(do_facet $SINGLEMDS "$llog_reader $tmpfile" |
9260                 grep -c 'next chunk')
9261         (( $errs > 0 )) || error "llog_reader didn't skip bad chunk"
9262 }
9263 run_test 60j "llog_reader reports corruptions"
9264
9265 test_61a() {
9266         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9267
9268         f="$DIR/f61"
9269         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1 || error "dd $f failed"
9270         cancel_lru_locks osc
9271         $MULTIOP $f OSMWUc || error "$MULTIOP $f failed"
9272         sync
9273 }
9274 run_test 61a "mmap() writes don't make sync hang ================"
9275
9276 test_61b() {
9277         mmap_mknod_test $DIR/$tfile || error "mmap_mknod_test failed"
9278 }
9279 run_test 61b "mmap() of unstriped file is successful"
9280
9281 # bug 2330 - insufficient obd_match error checking causes LBUG
9282 test_62() {
9283         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9284
9285         f="$DIR/f62"
9286         echo foo > $f
9287         cancel_lru_locks osc
9288         lctl set_param fail_loc=0x405
9289         cat $f && error "cat succeeded, expect -EIO"
9290         lctl set_param fail_loc=0
9291 }
9292 # This test is now irrelevant (as of bug 10718 inclusion), we no longer
9293 # match every page all of the time.
9294 #run_test 62 "verify obd_match failure doesn't LBUG (should -EIO)"
9295
9296 # bug 2319 - oig_wait() interrupted causes crash because of invalid waitq.
9297 # Though this test is irrelevant anymore, it helped to reveal some
9298 # other grant bugs (LU-4482), let's keep it.
9299 test_63a() {   # was test_63
9300         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9301
9302         MAX_DIRTY_MB=$(lctl get_param -n osc.*.max_dirty_mb | head -n 1)
9303
9304         for i in `seq 10` ; do
9305                 dd if=/dev/zero of=$DIR/f63 bs=8k &
9306                 sleep 5
9307                 kill $!
9308                 sleep 1
9309         done
9310
9311         rm -f $DIR/f63 || true
9312 }
9313 run_test 63a "Verify oig_wait interruption does not crash ======="
9314
9315 # bug 2248 - async write errors didn't return to application on sync
9316 # bug 3677 - async write errors left page locked
9317 test_63b() {
9318         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9319
9320         debugsave
9321         lctl set_param debug=-1
9322
9323         # ensure we have a grant to do async writes
9324         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1
9325         rm $DIR/$tfile
9326
9327         sync    # sync lest earlier test intercept the fail_loc
9328
9329         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
9330         lctl set_param fail_loc=0x80000406
9331         $MULTIOP $DIR/$tfile Owy && \
9332                 error "sync didn't return ENOMEM"
9333         sync; sleep 2; sync     # do a real sync this time to flush page
9334         lctl get_param -n llite.*.dump_page_cache | grep locked && \
9335                 error "locked page left in cache after async error" || true
9336         debugrestore
9337 }
9338 run_test 63b "async write errors should be returned to fsync ==="
9339
9340 test_64a () {
9341         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9342
9343         lfs df $DIR
9344         lctl get_param osc.*[oO][sS][cC][_-]*.cur* | grep "=[1-9]"
9345 }
9346 run_test 64a "verify filter grant calculations (in kernel) ====="
9347
9348 test_64b () {
9349         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9350
9351         bash oos.sh $MOUNT || error "oos.sh failed: $?"
9352 }
9353 run_test 64b "check out-of-space detection on client"
9354
9355 test_64c() {
9356         $LCTL set_param osc.*OST0000-osc-[^mM]*.cur_grant_bytes=0
9357 }
9358 run_test 64c "verify grant shrink"
9359
9360 import_param() {
9361         local tgt=$1
9362         local param=$2
9363
9364         $LCTL get_param osc.$tgt.import | awk "/$param/ { print \$2 }"
9365 }
9366
9367 # this does exactly what osc_request.c:osc_announce_cached() does in
9368 # order to calculate max amount of grants to ask from server
9369 want_grant() {
9370         local tgt=$1
9371
9372         local nrpages=$($LCTL get_param -n osc.$tgt.max_pages_per_rpc)
9373         local rpc_in_flight=$($LCTL get_param -n osc.$tgt.max_rpcs_in_flight)
9374
9375         ((rpc_in_flight++));
9376         nrpages=$((nrpages * rpc_in_flight))
9377
9378         local dirty_max_pages=$($LCTL get_param -n osc.$tgt.max_dirty_mb)
9379
9380         dirty_max_pages=$((dirty_max_pages * 1024 * 1024 / PAGE_SIZE))
9381
9382         [[ $dirty_max_pages -gt $nrpages ]] && nrpages=$dirty_max_pages
9383         local undirty=$((nrpages * PAGE_SIZE))
9384
9385         local max_extent_pages
9386         max_extent_pages=$(import_param $tgt grant_max_extent_size)
9387         max_extent_pages=$((max_extent_pages / PAGE_SIZE))
9388         local nrextents=$(((nrpages + max_extent_pages - 1) / max_extent_pages))
9389         local grant_extent_tax
9390         grant_extent_tax=$(import_param $tgt grant_extent_tax)
9391
9392         undirty=$((undirty + nrextents * grant_extent_tax))
9393
9394         echo $undirty
9395 }
9396
9397 # this is size of unit for grant allocation. It should be equal to
9398 # what tgt_grant.c:tgt_grant_chunk() calculates
9399 grant_chunk() {
9400         local tgt=$1
9401         local max_brw_size
9402         local grant_extent_tax
9403
9404         max_brw_size=$(import_param $tgt max_brw_size)
9405
9406         grant_extent_tax=$(import_param $tgt grant_extent_tax)
9407
9408         echo $(((max_brw_size + grant_extent_tax) * 2))
9409 }
9410
9411 test_64d() {
9412         [ $OST1_VERSION -ge $(version_code 2.10.56) ] ||
9413                 skip "OST < 2.10.55 doesn't limit grants enough"
9414
9415         local tgt=$($LCTL dl | awk '/OST0000-osc-[^mM]/ { print $4 }')
9416
9417         [[ "$($LCTL get_param osc.${tgt}.import)" =~ "grant_param" ]] ||
9418                 skip "no grant_param connect flag"
9419
9420         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
9421
9422         $LCTL set_param -n -n debug="$OLDDEBUG" || true
9423         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
9424
9425
9426         local max_cur_granted=$(($(want_grant $tgt) + $(grant_chunk $tgt)))
9427         stack_trap "rm -f $DIR/$tfile && wait_delete_completed" EXIT
9428
9429         $LFS setstripe $DIR/$tfile -i 0 -c 1
9430         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1000 &
9431         ddpid=$!
9432
9433         while kill -0 $ddpid; do
9434                 local cur_grant=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
9435
9436                 if [[ $cur_grant -gt $max_cur_granted ]]; then
9437                         kill $ddpid
9438                         error "cur_grant $cur_grant > $max_cur_granted"
9439                 fi
9440
9441                 sleep 1
9442         done
9443 }
9444 run_test 64d "check grant limit exceed"
9445
9446 check_grants() {
9447         local tgt=$1
9448         local expected=$2
9449         local msg=$3
9450         local cur_grants=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
9451
9452         ((cur_grants == expected)) ||
9453                 error "$msg: grants mismatch: $cur_grants, expected $expected"
9454 }
9455
9456 round_up_p2() {
9457         echo $((($1 + $2 - 1) & ~($2 - 1)))
9458 }
9459
9460 test_64e() {
9461         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9462         [ $OST1_VERSION -ge $(version_code 2.11.56) ] ||
9463                 skip "Need OSS version at least 2.11.56"
9464
9465         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
9466         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
9467         $LCTL set_param debug=+cache
9468
9469         # Remount client to reset grant
9470         remount_client $MOUNT || error "failed to remount client"
9471         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9472
9473         local init_grants=$(import_param $osc_tgt initial_grant)
9474
9475         check_grants $osc_tgt $init_grants "init grants"
9476
9477         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
9478         local max_brw_size=$(import_param $osc_tgt max_brw_size)
9479         local gbs=$(import_param $osc_tgt grant_block_size)
9480
9481         # write random number of bytes from max_brw_size / 4 to max_brw_size
9482         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
9483         # align for direct io
9484         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
9485         # round to grant consumption unit
9486         local wb_round_up=$(round_up_p2 $write_bytes gbs)
9487
9488         local grants=$((wb_round_up + extent_tax))
9489
9490         $LFS setstripe -c 1 -i 0 $DIR/$tfile  || error "lfs setstripe failed"
9491
9492         # define OBD_FAIL_TGT_NO_GRANT 0x725
9493         # make the server not grant more back
9494         do_facet ost1 $LCTL set_param fail_loc=0x725
9495         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct
9496
9497         do_facet ost1 $LCTL set_param fail_loc=0
9498
9499         check_grants $osc_tgt $((init_grants - grants)) "dio w/o grant alloc"
9500
9501         rm -f $DIR/$tfile || error "rm failed"
9502
9503         # Remount client to reset grant
9504         remount_client $MOUNT || error "failed to remount client"
9505         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9506
9507         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
9508
9509         # define OBD_FAIL_TGT_NO_GRANT 0x725
9510         # make the server not grant more back
9511         do_facet ost1 $LCTL set_param fail_loc=0x725
9512         $MULTIOP $DIR/$tfile "oO_WRONLY:w${write_bytes}yc"
9513         do_facet ost1 $LCTL set_param fail_loc=0
9514
9515         check_grants $osc_tgt $((init_grants - grants)) "buf io w/o grant alloc"
9516 }
9517 run_test 64e "check grant consumption (no grant allocation)"
9518
9519 test_64f() {
9520         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9521
9522         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
9523         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
9524         $LCTL set_param debug=+cache
9525
9526         # Remount client to reset grant
9527         remount_client $MOUNT || error "failed to remount client"
9528         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9529
9530         local init_grants=$(import_param $osc_tgt initial_grant)
9531         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
9532         local max_brw_size=$(import_param $osc_tgt max_brw_size)
9533         local gbs=$(import_param $osc_tgt grant_block_size)
9534         local chunk=$(grant_chunk $osc_tgt)
9535
9536         # write random number of bytes from max_brw_size / 4 to max_brw_size
9537         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
9538         # align for direct io
9539         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
9540         # round to grant consumption unit
9541         local wb_round_up=$(round_up_p2 $write_bytes gbs)
9542
9543         local grants=$((wb_round_up + extent_tax))
9544
9545         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
9546         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct ||
9547                 error "error writing to $DIR/$tfile"
9548
9549         check_grants $osc_tgt $((init_grants - grants + chunk)) \
9550                 "direct io with grant allocation"
9551
9552         rm -f $DIR/$tfile || error "rm failed"
9553
9554         # Remount client to reset grant
9555         remount_client $MOUNT || error "failed to remount client"
9556         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9557
9558         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
9559
9560         local cmd="oO_WRONLY:w${write_bytes}_yc"
9561
9562         $MULTIOP $DIR/$tfile $cmd &
9563         MULTIPID=$!
9564         sleep 1
9565
9566         check_grants $osc_tgt $((init_grants - grants)) \
9567                 "buffered io, not write rpc"
9568
9569         kill -USR1 $MULTIPID
9570         wait
9571
9572         check_grants $osc_tgt $((init_grants - grants + chunk)) \
9573                 "buffered io, one RPC"
9574 }
9575 run_test 64f "check grant consumption (with grant allocation)"
9576
9577 test_64g() {
9578         (( $MDS1_VERSION >= $(version_code 2.14.56) )) ||
9579                 skip "Need MDS version at least 2.14.56"
9580
9581         local mdts=$(comma_list $(mdts_nodes))
9582
9583         local old=$($LCTL get_param mdc.$FSNAME-*.grant_shrink_interval |
9584                         tr '\n' ' ')
9585         stack_trap "$LCTL set_param $old"
9586
9587         # generate dirty pages and increase dirty granted on MDT
9588         stack_trap "rm -f $DIR/$tfile-*"
9589         for (( i = 0; i < 10; i++)); do
9590                 $LFS setstripe -E 1M -L mdt $DIR/$tfile-$i ||
9591                         error "can't set stripe"
9592                 dd if=/dev/zero of=$DIR/$tfile-$i bs=128k count=1 ||
9593                         error "can't dd"
9594                 $LFS getstripe $DIR/$tfile-$i | grep -q pattern.*mdt || {
9595                         $LFS getstripe $DIR/$tfile-$i
9596                         error "not DoM file"
9597                 }
9598         done
9599
9600         # flush dirty pages
9601         sync
9602
9603         # wait until grant shrink reset grant dirty on MDTs
9604         for ((i = 0; i < 120; i++)); do
9605                 grant_dirty=$(do_nodes $mdts $LCTL get_param -n  mdt.*.tot_dirty |
9606                         awk '{sum=sum+$1} END {print sum}')
9607                 vm_dirty=$(awk '/Dirty:/{print $2}' /proc/meminfo)
9608                 echo "$grant_dirty grants, $vm_dirty pages"
9609                 (( grant_dirty + vm_dirty == 0 )) && break
9610                 (( i == 3 )) && sync &&
9611                         $LCTL set_param mdc.$FSNAME-*.grant_shrink_interval=5
9612                 sleep 1
9613         done
9614
9615         grant_dirty=$(do_nodes $mdts $LCTL get_param -n  mdt.*.tot_dirty |
9616                 awk '{sum=sum+$1} END {print sum}')
9617         (( grant_dirty == 0 )) || error "$grant_dirty on MDT"
9618 }
9619 run_test 64g "grant shrink on MDT"
9620
9621 test_64h() {
9622         (( $OST1_VERSION >= $(version_code 2.14.56) )) ||
9623                 skip "need OST at least 2.14.56 to avoid grant shrink on read"
9624
9625         local instance=$($LFS getname -i $DIR)
9626         local osc_tgt="$FSNAME-OST0000-osc-$instance"
9627         local num_exps=$(do_facet ost1 \
9628             $LCTL get_param -n obdfilter.*OST0000*.num_exports)
9629         local max_brw_size=$(import_param $osc_tgt max_brw_size)
9630         local avail=$($LCTL get_param -n osc.*OST0000-osc-$instance.kbytesavail)
9631         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
9632
9633         # 10MiB is for file to be written, max_brw_size * 16 *
9634         # num_exps is space reserve so that tgt_grant_shrink() decided
9635         # to not shrink
9636         local expect=$((max_brw_size * 16 * num_exps + 10 * 1048576))
9637         (( avail * 1024 < expect )) &&
9638                 skip "need $expect bytes on ost1, have $(( avail * 1024 )) only"
9639
9640         save_lustre_params client "osc.*OST0000*.grant_shrink" > $p
9641         save_lustre_params client "osc.*OST0000*.grant_shrink_interval" >> $p
9642         stack_trap "restore_lustre_params < $p; rm -f $save" EXIT
9643         $LCTL set_param osc.*OST0000*.grant_shrink=1
9644         $LCTL set_param osc.*OST0000*.grant_shrink_interval=10
9645
9646         $LFS setstripe -c 1 -i 0 $DIR/$tfile
9647         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 oflag=sync
9648
9649         # drop cache so that coming read would do rpc
9650         cancel_lru_locks osc
9651
9652         # shrink interval is set to 10, pause for 7 seconds so that
9653         # grant thread did not wake up yet but coming read entered
9654         # shrink mode for rpc (osc_should_shrink_grant())
9655         sleep 7
9656
9657         declare -a cur_grant_bytes
9658         declare -a tot_granted
9659         cur_grant_bytes[0]=$($LCTL get_param -n osc.*OST0000*.cur_grant_bytes)
9660         tot_granted[0]=$(do_facet ost1 \
9661             $LCTL get_param -n obdfilter.*OST0000*.tot_granted)
9662
9663         dd if=$DIR/$tfile bs=4K count=1 of=/dev/null
9664
9665         cur_grant_bytes[1]=$($LCTL get_param -n osc.*OST0000*.cur_grant_bytes)
9666         tot_granted[1]=$(do_facet ost1 \
9667             $LCTL get_param -n obdfilter.*OST0000*.tot_granted)
9668
9669         # grant change should be equal on both sides
9670         (( cur_grant_bytes[0] - cur_grant_bytes[1] ==
9671                 tot_granted[0] - tot_granted[1])) ||
9672                 error "grant change mismatch, "                                \
9673                         "server: ${tot_granted[0]} to ${tot_granted[1]}, "     \
9674                         "client: ${cur_grant_bytes[0]} to ${cur_grant_bytes[1]}"
9675 }
9676 run_test 64h "grant shrink on read"
9677
9678 test_64i() {
9679         (( $OST1_VERSION >= $(version_code 2.14.56) )) ||
9680                 skip "need OST at least 2.14.56 to avoid grant shrink on replay"
9681
9682         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9683         remote_ost_nodsh && skip "remote OSTs with nodsh"
9684
9685         $LFS setstripe -c 1 -i 0 $DIR/$tfile
9686
9687         dd if=/dev/zero of=$DIR/$tfile bs=1M count=64
9688
9689         # lustre-ffff9fc75e850800 /mnt/lustre -> ffff9fc75e850800
9690         local instance=$($LFS getname -i $DIR)
9691
9692         local osc_tgt="$FSNAME-OST0000-osc-$instance"
9693         local cgb=$($LCTL get_param -n osc.$osc_tgt.cur_grant_bytes)
9694
9695         # shrink grants and simulate rpc loss
9696         #define OBD_FAIL_PTLRPC_DROP_REQ_OPC     0x513
9697         do_facet ost1 "$LCTL set_param fail_loc=0x80000513 fail_val=17"
9698         $LCTL set_param osc.$osc_tgt.cur_grant_bytes=$((cgb/2))B
9699
9700         fail ost1
9701
9702         dd if=/dev/zero of=$DIR/$tfile oflag=append bs=1M count=8 conv=notrunc
9703
9704         local testid=$(echo $TESTNAME | tr '_' ' ')
9705
9706         do_facet ost1 dmesg | tac | sed "/$testid/,$ d" |
9707                 grep "GRANT, real grant" &&
9708                 error "client has more grants then it owns" || true
9709 }
9710 run_test 64i "shrink on reconnect"
9711
9712 # bug 1414 - set/get directories' stripe info
9713 test_65a() {
9714         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9715
9716         test_mkdir $DIR/$tdir
9717         touch $DIR/$tdir/f1
9718         $LVERIFY $DIR/$tdir $DIR/$tdir/f1 || error "lverify failed"
9719 }
9720 run_test 65a "directory with no stripe info"
9721
9722 test_65b() {
9723         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9724
9725         test_mkdir $DIR/$tdir
9726         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9727
9728         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
9729                                                 error "setstripe"
9730         touch $DIR/$tdir/f2
9731         $LVERIFY $DIR/$tdir $DIR/$tdir/f2 || error "lverify failed"
9732 }
9733 run_test 65b "directory setstripe -S stripe_size*2 -i 0 -c 1"
9734
9735 test_65c() {
9736         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9737         [ $OSTCOUNT -lt 2 ] && skip_env "need at least 2 OSTs"
9738
9739         test_mkdir $DIR/$tdir
9740         local stripesize=$($LFS getstripe -S $DIR/$tdir)
9741
9742         $LFS setstripe -S $((stripesize * 4)) -i 1 \
9743                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
9744         touch $DIR/$tdir/f3
9745         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
9746 }
9747 run_test 65c "directory setstripe -S stripe_size*4 -i 1 -c $((OSTCOUNT-1))"
9748
9749 test_65d() {
9750         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9751
9752         test_mkdir $DIR/$tdir
9753         local STRIPECOUNT=$($LFS getstripe -c $DIR/$tdir)
9754         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9755
9756         if [[ $STRIPECOUNT -le 0 ]]; then
9757                 sc=1
9758         elif [[ $STRIPECOUNT -gt $LOV_MAX_STRIPE_COUNT ]]; then
9759                 [[ $OSTCOUNT -gt $LOV_MAX_STRIPE_COUNT ]] &&
9760                         sc=$LOV_MAX_STRIPE_COUNT || sc=$(($OSTCOUNT - 1))
9761         else
9762                 sc=$(($STRIPECOUNT - 1))
9763         fi
9764         $LFS setstripe -S $STRIPESIZE -c $sc $DIR/$tdir || error "setstripe"
9765         touch $DIR/$tdir/f4 $DIR/$tdir/f5
9766         $LVERIFY $DIR/$tdir $DIR/$tdir/f4 $DIR/$tdir/f5 ||
9767                 error "lverify failed"
9768 }
9769 run_test 65d "directory setstripe -S stripe_size -c stripe_count"
9770
9771 test_65e() {
9772         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9773
9774         test_mkdir $DIR/$tdir
9775
9776         $LFS setstripe $DIR/$tdir || error "setstripe"
9777         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
9778                                         error "no stripe info failed"
9779         touch $DIR/$tdir/f6
9780         $LVERIFY $DIR/$tdir $DIR/$tdir/f6 || error "lverify failed"
9781 }
9782 run_test 65e "directory setstripe defaults"
9783
9784 test_65f() {
9785         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9786
9787         test_mkdir $DIR/${tdir}f
9788         $RUNAS $LFS setstripe $DIR/${tdir}f &&
9789                 error "setstripe succeeded" || true
9790 }
9791 run_test 65f "dir setstripe permission (should return error) ==="
9792
9793 test_65g() {
9794         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9795
9796         test_mkdir $DIR/$tdir
9797         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9798
9799         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
9800                 error "setstripe -S failed"
9801         $LFS setstripe -d $DIR/$tdir || error "setstripe -d failed"
9802         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
9803                 error "delete default stripe failed"
9804 }
9805 run_test 65g "directory setstripe -d"
9806
9807 test_65h() {
9808         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9809
9810         test_mkdir $DIR/$tdir
9811         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9812
9813         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
9814                 error "setstripe -S failed"
9815         test_mkdir $DIR/$tdir/dd1
9816         [ $($LFS getstripe -c $DIR/$tdir) = $($LFS getstripe -c $DIR/$tdir/dd1) ] ||
9817                 error "stripe info inherit failed"
9818 }
9819 run_test 65h "directory stripe info inherit ===================="
9820
9821 test_65i() {
9822         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9823
9824         save_layout_restore_at_exit $MOUNT
9825
9826         # bug6367: set non-default striping on root directory
9827         $LFS setstripe -S 65536 -c -1 $MOUNT || error "error setting stripe"
9828
9829         # bug12836: getstripe on -1 default directory striping
9830         $LFS getstripe $MOUNT || error "getstripe $MOUNT failed"
9831
9832         # bug12836: getstripe -v on -1 default directory striping
9833         $LFS getstripe -v $MOUNT || error "getstripe -v $MOUNT failed"
9834
9835         # bug12836: new find on -1 default directory striping
9836         $LFS find -mtime -1 $MOUNT > /dev/null || error "find $MOUNT failed"
9837 }
9838 run_test 65i "various tests to set root directory striping"
9839
9840 test_65j() { # bug6367
9841         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9842
9843         sync; sleep 1
9844
9845         # if we aren't already remounting for each test, do so for this test
9846         if [ "$I_MOUNTED" = "yes" ]; then
9847                 cleanup || error "failed to unmount"
9848                 setup
9849         fi
9850
9851         save_layout_restore_at_exit $MOUNT
9852
9853         $LFS setstripe -d $MOUNT || error "setstripe failed"
9854 }
9855 run_test 65j "set default striping on root directory (bug 6367)="
9856
9857 cleanup_65k() {
9858         rm -rf $DIR/$tdir
9859         wait_delete_completed
9860         do_facet $SINGLEMDS "lctl set_param -n \
9861                 osp.$ost*MDT0000.max_create_count=$max_count"
9862         do_facet $SINGLEMDS "lctl set_param -n \
9863                 osp.$ost*MDT0000.create_count=$count"
9864         do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
9865         echo $INACTIVE_OSC "is Activate"
9866
9867         wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
9868 }
9869
9870 test_65k() { # bug11679
9871         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9872         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9873         remote_mds_nodsh && skip "remote MDS with nodsh"
9874
9875         local disable_precreate=true
9876         [ $MDS1_VERSION -le $(version_code 2.8.54) ] &&
9877                 disable_precreate=false
9878
9879         echo "Check OST status: "
9880         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
9881                 awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
9882
9883         for OSC in $MDS_OSCS; do
9884                 echo $OSC "is active"
9885                 do_facet $SINGLEMDS lctl --device %$OSC activate
9886         done
9887
9888         for INACTIVE_OSC in $MDS_OSCS; do
9889                 local ost=$(osc_to_ost $INACTIVE_OSC)
9890                 local ostnum=$(do_facet $SINGLEMDS lctl get_param -n \
9891                                lov.*md*.target_obd |
9892                                awk -F: /$ost/'{ print $1 }' | head -n 1)
9893
9894                 mkdir -p $DIR/$tdir
9895                 $LFS setstripe -i $ostnum -c 1 $DIR/$tdir
9896                 createmany -o $DIR/$tdir/$tfile.$ostnum. 1000
9897
9898                 echo "Deactivate: " $INACTIVE_OSC
9899                 do_facet $SINGLEMDS lctl --device %$INACTIVE_OSC deactivate
9900
9901                 local count=$(do_facet $SINGLEMDS "lctl get_param -n \
9902                               osp.$ost*MDT0000.create_count")
9903                 local max_count=$(do_facet $SINGLEMDS "lctl get_param -n \
9904                                   osp.$ost*MDT0000.max_create_count")
9905                 $disable_precreate &&
9906                         do_facet $SINGLEMDS "lctl set_param -n \
9907                                 osp.$ost*MDT0000.max_create_count=0"
9908
9909                 for idx in $(seq 0 $((OSTCOUNT - 1))); do
9910                         [ -f $DIR/$tdir/$idx ] && continue
9911                         echo "$LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx"
9912                         $LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx ||
9913                                 { cleanup_65k;
9914                                   error "setstripe $idx should succeed"; }
9915                         rm -f $DIR/$tdir/$idx || error "rm $idx failed"
9916                 done
9917                 unlinkmany $DIR/$tdir/$tfile.$ostnum. 1000
9918                 rmdir $DIR/$tdir
9919
9920                 do_facet $SINGLEMDS "lctl set_param -n \
9921                         osp.$ost*MDT0000.max_create_count=$max_count"
9922                 do_facet $SINGLEMDS "lctl set_param -n \
9923                         osp.$ost*MDT0000.create_count=$count"
9924                 do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
9925                 echo $INACTIVE_OSC "is Activate"
9926
9927                 wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
9928         done
9929 }
9930 run_test 65k "validate manual striping works properly with deactivated OSCs"
9931
9932 test_65l() { # bug 12836
9933         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9934
9935         test_mkdir -p $DIR/$tdir/test_dir
9936         $LFS setstripe -c -1 $DIR/$tdir/test_dir
9937         $LFS find -mtime -1 $DIR/$tdir >/dev/null
9938 }
9939 run_test 65l "lfs find on -1 stripe dir ========================"
9940
9941 test_65m() {
9942         local layout=$(save_layout $MOUNT)
9943         $RUNAS $LFS setstripe -c 2 $MOUNT && {
9944                 restore_layout $MOUNT $layout
9945                 error "setstripe should fail by non-root users"
9946         }
9947         true
9948 }
9949 run_test 65m "normal user can't set filesystem default stripe"
9950
9951 test_65n() {
9952         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
9953         [[ $MDS1_VERSION -ge $(version_code 2.12.50) ]] ||
9954                 skip "Need MDS version at least 2.12.50"
9955         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
9956
9957         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
9958         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
9959         which setfattr > /dev/null 2>&1 || skip_env "no setfattr command"
9960
9961         save_layout_restore_at_exit $MOUNT
9962
9963         # new subdirectory under root directory should not inherit
9964         # the default layout from root
9965         local dir1=$MOUNT/$tdir-1
9966         mkdir $dir1 || error "mkdir $dir1 failed"
9967         ! getfattr -n trusted.lov $dir1 &> /dev/null ||
9968                 error "$dir1 shouldn't have LOV EA"
9969
9970         # delete the default layout on root directory
9971         $LFS setstripe -d $MOUNT || error "delete root default layout failed"
9972
9973         local dir2=$MOUNT/$tdir-2
9974         mkdir $dir2 || error "mkdir $dir2 failed"
9975         ! getfattr -n trusted.lov $dir2 &> /dev/null ||
9976                 error "$dir2 shouldn't have LOV EA"
9977
9978         # set a new striping pattern on root directory
9979         local def_stripe_size=$($LFS getstripe -S $MOUNT)
9980         local new_def_stripe_size=$((def_stripe_size * 2))
9981         $LFS setstripe -S $new_def_stripe_size $MOUNT ||
9982                 error "set stripe size on $MOUNT failed"
9983
9984         # new file created in $dir2 should inherit the new stripe size from
9985         # the filesystem default
9986         local file2=$dir2/$tfile-2
9987         touch $file2 || error "touch $file2 failed"
9988
9989         local file2_stripe_size=$($LFS getstripe -S $file2)
9990         [[ $file2_stripe_size -eq $new_def_stripe_size ]] ||
9991         {
9992                 echo "file2_stripe_size: '$file2_stripe_size'"
9993                 echo "new_def_stripe_size: '$new_def_stripe_size'"
9994                 error "$file2 didn't inherit stripe size $new_def_stripe_size"
9995         }
9996
9997         local dir3=$MOUNT/$tdir-3
9998         mkdir $dir3 || error "mkdir $dir3 failed"
9999         # $dir3 shouldn't have LOV EA, but "lfs getstripe -d $dir3" should show
10000         # the root layout, which is the actual default layout that will be used
10001         # when new files are created in $dir3.
10002         local dir3_layout=$(get_layout_param $dir3)
10003         local root_dir_layout=$(get_layout_param $MOUNT)
10004         [[ "$dir3_layout" = "$root_dir_layout" ]] ||
10005         {
10006                 echo "dir3_layout: '$dir3_layout'"
10007                 echo "root_dir_layout: '$root_dir_layout'"
10008                 error "$dir3 should show the default layout from $MOUNT"
10009         }
10010
10011         # set OST pool on root directory
10012         local pool=$TESTNAME
10013         pool_add $pool || error "add $pool failed"
10014         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
10015                 error "add targets to $pool failed"
10016
10017         $LFS setstripe -p $pool $MOUNT ||
10018                 error "set OST pool on $MOUNT failed"
10019
10020         # new file created in $dir3 should inherit the pool from
10021         # the filesystem default
10022         local file3=$dir3/$tfile-3
10023         touch $file3 || error "touch $file3 failed"
10024
10025         local file3_pool=$($LFS getstripe -p $file3)
10026         [[ "$file3_pool" = "$pool" ]] ||
10027                 error "$file3 ('$file3_pool') didn't inherit OST pool '$pool'"
10028
10029         local dir4=$MOUNT/$tdir-4
10030         mkdir $dir4 || error "mkdir $dir4 failed"
10031         local dir4_layout=$(get_layout_param $dir4)
10032         root_dir_layout=$(get_layout_param $MOUNT)
10033         echo "$LFS getstripe -d $dir4"
10034         $LFS getstripe -d $dir4
10035         echo "$LFS getstripe -d $MOUNT"
10036         $LFS getstripe -d $MOUNT
10037         [[ "$dir4_layout" = "$root_dir_layout" ]] ||
10038         {
10039                 echo "dir4_layout: '$dir4_layout'"
10040                 echo "root_dir_layout: '$root_dir_layout'"
10041                 error "$dir4 should show the default layout from $MOUNT"
10042         }
10043
10044         # new file created in $dir4 should inherit the pool from
10045         # the filesystem default
10046         local file4=$dir4/$tfile-4
10047         touch $file4 || error "touch $file4 failed"
10048
10049         local file4_pool=$($LFS getstripe -p $file4)
10050         [[ "$file4_pool" = "$pool" ]] ||
10051                 error "$file4 ('$file4_pool') didn't inherit OST pool $pool"
10052
10053         # new subdirectory under non-root directory should inherit
10054         # the default layout from its parent directory
10055         $LFS setstripe -S $new_def_stripe_size -p $pool $dir4 ||
10056                 error "set directory layout on $dir4 failed"
10057
10058         local dir5=$dir4/$tdir-5
10059         mkdir $dir5 || error "mkdir $dir5 failed"
10060
10061         dir4_layout=$(get_layout_param $dir4)
10062         local dir5_layout=$(get_layout_param $dir5)
10063         [[ "$dir4_layout" = "$dir5_layout" ]] ||
10064         {
10065                 echo "dir4_layout: '$dir4_layout'"
10066                 echo "dir5_layout: '$dir5_layout'"
10067                 error "$dir5 should inherit the default layout from $dir4"
10068         }
10069
10070         # though subdir under ROOT doesn't inherit default layout, but
10071         # its sub dir/file should be created with default layout.
10072         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
10073         [[ $MDS1_VERSION -ge $(version_code 2.12.59) ]] ||
10074                 skip "Need MDS version at least 2.12.59"
10075
10076         local default_lmv_count=$($LFS getdirstripe -D -c $MOUNT)
10077         local default_lmv_index=$($LFS getdirstripe -D -i $MOUNT)
10078         local default_lmv_hash=$($LFS getdirstripe -D -H $MOUNT)
10079
10080         if [ $default_lmv_hash == "none" ]; then
10081                 stack_trap "$LFS setdirstripe -D -d $MOUNT" EXIT
10082         else
10083                 stack_trap "$LFS setdirstripe -D -i $default_lmv_index \
10084                         -c $default_lmv_count -H $default_lmv_hash $MOUNT" EXIT
10085         fi
10086
10087         $LFS setdirstripe -D -c 2 $MOUNT ||
10088                 error "setdirstripe -D -c 2 failed"
10089         mkdir $MOUNT/$tdir-6 || error "mkdir $tdir-6 failed"
10090         local lmv_count=$($LFS getdirstripe -c $MOUNT/$tdir-6)
10091         [ $lmv_count -eq 2 ] || error "$tdir-6 stripe count $lmv_count"
10092
10093         # $dir4 layout includes pool
10094         $LFS setstripe -S $((new_def_stripe_size * 2)) $dir4
10095         [[ "$pool" = $($LFS getstripe -p -d $dir4) ]] ||
10096                 error "pool lost on setstripe"
10097         $LFS setstripe -E -1 -S $new_def_stripe_size $dir4
10098         [[ "$pool" = $($LFS getstripe -p -d $dir4) ]] ||
10099                 error "pool lost on compound layout setstripe"
10100 }
10101 run_test 65n "don't inherit default layout from root for new subdirectories"
10102
10103 test_65o() {
10104         (( $MDS1_VERSION >= $(version_code 2.14.57) )) ||
10105                 skip "need MDS version at least 2.14.57"
10106
10107         # set OST pool on root directory
10108         local pool=$TESTNAME
10109
10110         pool_add $pool || error "add $pool failed"
10111         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
10112                 error "add targets to $pool failed"
10113
10114         local dir1=$MOUNT/$tdir
10115
10116         mkdir $dir1 || error "mkdir $dir1 failed"
10117
10118         # set a new striping pattern on root directory
10119         local def_stripe_size=$($LFS getstripe -S $MOUNT)
10120
10121         $LFS setstripe -p $pool $dir1 ||
10122                 error "set directory layout on $dir1 failed"
10123
10124         # $dir1 layout includes pool
10125         $LFS setstripe -S $((def_stripe_size * 2)) $dir1
10126         [[ "$pool" = $($LFS getstripe -p -d $dir1) ]] ||
10127                 error "pool lost on setstripe"
10128         $LFS setstripe -E 1M -L mdt -E -1 -c 1 $dir1
10129         $LFS getstripe $dir1
10130         [[ "$pool" = $($LFS getstripe -p -d $dir1) ]] ||
10131                 error "pool lost on compound layout setstripe"
10132
10133         $LFS setdirstripe -i 0 -c 2 $dir1/dir2 ||
10134                 error "setdirstripe failed on sub-dir with inherited pool"
10135         $LFS getstripe $dir1/dir2
10136         [[ "$pool" = $($LFS getstripe -p -d $dir1/dir2) ]] ||
10137                 error "pool lost on compound layout setdirstripe"
10138
10139         $LFS setstripe -E -1 -c 1 $dir1
10140         $LFS getstripe -d $dir1
10141         [[ "$pool" = $($LFS getstripe -p -d $dir1) ]] ||
10142                 error "pool lost on setstripe"
10143 }
10144 run_test 65o "pool inheritance for mdt component"
10145
10146 test_65p () { # LU-16152
10147         local src_dir=$DIR/$tdir/src_dir
10148         local dst_dir=$DIR/$tdir/dst_dir
10149         local yaml_file=$DIR/$tdir/layout.yaml
10150         local border
10151
10152         (( $CLIENT_VERSION >= $(version_code 2.15.51) )) ||
10153                 skip "Need at least version 2.15.51"
10154
10155         test_mkdir -p $src_dir
10156         $LFS setstripe -E 2048M -c 4 -E EOF -c 8 $src_dir ||
10157                 error "failed to setstripe"
10158         $LFS getstripe --yaml -d $src_dir > $yaml_file ||
10159                 error "failed to getstripe"
10160
10161         test_mkdir -p $dst_dir
10162         $LFS setstripe --yaml $yaml_file $dst_dir ||
10163                 error "failed to setstripe with yaml file"
10164         border=$($LFS getstripe -d $dst_dir |
10165                 awk '/lcme_extent.e_end:/ { print $2; exit; }') ||
10166                 error "failed to getstripe"
10167
10168         # 2048M is 0x80000000, or 2147483648
10169         (( $border == 2147483648 )) ||
10170                 error "failed to handle huge number in yaml layout"
10171 }
10172 run_test 65p "setstripe with yaml file and huge number"
10173
10174 # bug 2543 - update blocks count on client
10175 test_66() {
10176         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10177
10178         local COUNT=${COUNT:-8}
10179         dd if=/dev/zero of=$DIR/f66 bs=1k count=$COUNT
10180         sync; sync_all_data; sync; sync_all_data
10181         cancel_lru_locks osc
10182         local BLOCKS=$(ls -s --block-size=1k $DIR/f66 | awk '{ print $1 }')
10183         (( BLOCKS >= COUNT )) || error "$DIR/f66 blocks $BLOCKS < $COUNT"
10184 }
10185 run_test 66 "update inode blocks count on client ==============="
10186
10187 meminfo() {
10188         awk '($1 == "'$1':") { print $2 }' /proc/meminfo
10189 }
10190
10191 swap_used() {
10192         swapon -s | awk '($1 == "'$1'") { print $4 }'
10193 }
10194
10195 # bug5265, obdfilter oa2dentry return -ENOENT
10196 # #define OBD_FAIL_SRV_ENOENT 0x217
10197 test_69() {
10198         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10199         remote_ost_nodsh && skip "remote OST with nodsh"
10200
10201         f="$DIR/$tfile"
10202         $LFS setstripe -c 1 -i 0 $f
10203
10204         $DIRECTIO write ${f}.2 0 1 || error "directio write error"
10205
10206         do_facet ost1 lctl set_param fail_loc=0x217
10207         $TRUNCATE $f 1 # vmtruncate() will ignore truncate() error.
10208         $DIRECTIO write $f 0 2 && error "write succeeded, expect -ENOENT"
10209
10210         do_facet ost1 lctl set_param fail_loc=0
10211         $DIRECTIO write $f 0 2 || error "write error"
10212
10213         cancel_lru_locks osc
10214         $DIRECTIO read $f 0 1 || error "read error"
10215
10216         do_facet ost1 lctl set_param fail_loc=0x217
10217         $DIRECTIO read $f 1 1 && error "read succeeded, expect -ENOENT"
10218
10219         do_facet ost1 lctl set_param fail_loc=0
10220         rm -f $f
10221 }
10222 run_test 69 "verify oa2dentry return -ENOENT doesn't LBUG ======"
10223
10224 test_71() {
10225         test_mkdir $DIR/$tdir
10226         $LFS setdirstripe -D -c$MDSCOUNT $DIR/$tdir
10227         bash rundbench -C -D $DIR/$tdir 2 || error "dbench failed!"
10228 }
10229 run_test 71 "Running dbench on lustre (don't segment fault) ===="
10230
10231 test_72a() { # bug 5695 - Test that on 2.6 remove_suid works properly
10232         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10233         [ "$RUNAS_ID" = "$UID" ] &&
10234                 skip_env "RUNAS_ID = UID = $UID -- skipping"
10235         # Check that testing environment is properly set up. Skip if not
10236         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_GID $RUNAS ||
10237                 skip_env "User $RUNAS_ID does not exist - skipping"
10238
10239         touch $DIR/$tfile
10240         chmod 777 $DIR/$tfile
10241         chmod ug+s $DIR/$tfile
10242         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=512 count=1 ||
10243                 error "$RUNAS dd $DIR/$tfile failed"
10244         # See if we are still setuid/sgid
10245         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
10246                 error "S/gid is not dropped on write"
10247         # Now test that MDS is updated too
10248         cancel_lru_locks mdc
10249         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
10250                 error "S/gid is not dropped on MDS"
10251         rm -f $DIR/$tfile
10252 }
10253 run_test 72a "Test that remove suid works properly (bug5695) ===="
10254
10255 test_72b() { # bug 24226 -- keep mode setting when size is not changing
10256         local perm
10257
10258         [ "$RUNAS_ID" = "$UID" ] &&
10259                 skip_env "RUNAS_ID = UID = $UID -- skipping"
10260         [ "$RUNAS_ID" -eq 0 ] &&
10261                 skip_env "RUNAS_ID = 0 -- skipping"
10262         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10263         # Check that testing environment is properly set up. Skip if not
10264         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_ID $RUNAS ||
10265                 skip_env "User $RUNAS_ID does not exist - skipping"
10266
10267         touch $DIR/${tfile}-f{g,u}
10268         test_mkdir $DIR/${tfile}-dg
10269         test_mkdir $DIR/${tfile}-du
10270         chmod 770 $DIR/${tfile}-{f,d}{g,u}
10271         chmod g+s $DIR/${tfile}-{f,d}g
10272         chmod u+s $DIR/${tfile}-{f,d}u
10273         for perm in 777 2777 4777; do
10274                 $RUNAS chmod $perm $DIR/${tfile}-fg && error "S/gid file allowed improper chmod to $perm"
10275                 $RUNAS chmod $perm $DIR/${tfile}-fu && error "S/uid file allowed improper chmod to $perm"
10276                 $RUNAS chmod $perm $DIR/${tfile}-dg && error "S/gid dir allowed improper chmod to $perm"
10277                 $RUNAS chmod $perm $DIR/${tfile}-du && error "S/uid dir allowed improper chmod to $perm"
10278         done
10279         true
10280 }
10281 run_test 72b "Test that we keep mode setting if without file data changed (bug 24226)"
10282
10283 # bug 3462 - multiple simultaneous MDC requests
10284 test_73() {
10285         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10286
10287         test_mkdir $DIR/d73-1
10288         test_mkdir $DIR/d73-2
10289         multiop_bg_pause $DIR/d73-1/f73-1 O_c || return 1
10290         pid1=$!
10291
10292         lctl set_param fail_loc=0x80000129
10293         $MULTIOP $DIR/d73-1/f73-2 Oc &
10294         sleep 1
10295         lctl set_param fail_loc=0
10296
10297         $MULTIOP $DIR/d73-2/f73-3 Oc &
10298         pid3=$!
10299
10300         kill -USR1 $pid1
10301         wait $pid1 || return 1
10302
10303         sleep 25
10304
10305         $CHECKSTAT -t file $DIR/d73-1/f73-1 || return 4
10306         $CHECKSTAT -t file $DIR/d73-1/f73-2 || return 5
10307         $CHECKSTAT -t file $DIR/d73-2/f73-3 || return 6
10308
10309         rm -rf $DIR/d73-*
10310 }
10311 run_test 73 "multiple MDC requests (should not deadlock)"
10312
10313 test_74a() { # bug 6149, 6184
10314         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10315
10316         touch $DIR/f74a
10317         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
10318         #
10319         # very important to OR with CFS_FAIL_ONCE (0x80000000) -- otherwise it
10320         # will spin in a tight reconnection loop
10321         $LCTL set_param fail_loc=0x8000030e
10322         # get any lock that won't be difficult - lookup works.
10323         ls $DIR/f74a
10324         $LCTL set_param fail_loc=0
10325         rm -f $DIR/f74a
10326         true
10327 }
10328 run_test 74a "ldlm_enqueue freed-export error path, ls (shouldn't LBUG)"
10329
10330 test_74b() { # bug 13310
10331         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10332
10333         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
10334         #
10335         # very important to OR with CFS_FAIL_ONCE (0x80000000) -- otherwise it
10336         # will spin in a tight reconnection loop
10337         $LCTL set_param fail_loc=0x8000030e
10338         # get a "difficult" lock
10339         touch $DIR/f74b
10340         $LCTL set_param fail_loc=0
10341         rm -f $DIR/f74b
10342         true
10343 }
10344 run_test 74b "ldlm_enqueue freed-export error path, touch (shouldn't LBUG)"
10345
10346 test_74c() {
10347         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10348
10349         #define OBD_FAIL_LDLM_NEW_LOCK
10350         $LCTL set_param fail_loc=0x319
10351         touch $DIR/$tfile && error "touch successful"
10352         $LCTL set_param fail_loc=0
10353         true
10354 }
10355 run_test 74c "ldlm_lock_create error path, (shouldn't LBUG)"
10356
10357 slab_lic=/sys/kernel/slab/lustre_inode_cache
10358 num_objects() {
10359         [ -f $slab_lic/shrink ] && echo 1 > $slab_lic/shrink
10360         [ -f $slab_lic/objects ] && awk '{ print $1 }' $slab_lic/objects ||
10361                 awk '/lustre_inode_cache/ { print $2; exit }' /proc/slabinfo
10362 }
10363
10364 test_76a() { # Now for b=20433, added originally in b=1443
10365         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10366
10367         cancel_lru_locks osc
10368         # there may be some slab objects cached per core
10369         local cpus=$(getconf _NPROCESSORS_ONLN 2>/dev/null)
10370         local before=$(num_objects)
10371         local count=$((512 * cpus))
10372         [ "$SLOW" = "no" ] && count=$((128 * cpus))
10373         local margin=$((count / 10))
10374         if [[ -f $slab_lic/aliases ]]; then
10375                 local aliases=$(cat $slab_lic/aliases)
10376                 (( aliases > 0 )) && margin=$((margin * aliases))
10377         fi
10378
10379         echo "before slab objects: $before"
10380         for i in $(seq $count); do
10381                 touch $DIR/$tfile
10382                 rm -f $DIR/$tfile
10383         done
10384         cancel_lru_locks osc
10385         local after=$(num_objects)
10386         echo "created: $count, after slab objects: $after"
10387         # shared slab counts are not very accurate, allow significant margin
10388         # the main goal is that the cache growth is not permanently > $count
10389         while (( after > before + margin )); do
10390                 sleep 1
10391                 after=$(num_objects)
10392                 wait=$((wait + 1))
10393                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
10394                 if (( wait > 60 )); then
10395                         error "inode slab grew from $before+$margin to $after"
10396                 fi
10397         done
10398 }
10399 run_test 76a "confirm clients recycle inodes properly ===="
10400
10401 test_76b() {
10402         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10403         [ $CLIENT_VERSION -ge $(version_code 2.13.55) ] || skip "not supported"
10404
10405         local count=512
10406         local before=$(num_objects)
10407
10408         for i in $(seq $count); do
10409                 mkdir $DIR/$tdir
10410                 rmdir $DIR/$tdir
10411         done
10412
10413         local after=$(num_objects)
10414         local wait=0
10415
10416         while (( after > before )); do
10417                 sleep 1
10418                 after=$(num_objects)
10419                 wait=$((wait + 1))
10420                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
10421                 if (( wait > 60 )); then
10422                         error "inode slab grew from $before to $after"
10423                 fi
10424         done
10425
10426         echo "slab objects before: $before, after: $after"
10427 }
10428 run_test 76b "confirm clients recycle directory inodes properly ===="
10429
10430 export ORIG_CSUM=""
10431 set_checksums()
10432 {
10433         # Note: in sptlrpc modes which enable its own bulk checksum, the
10434         # original crc32_le bulk checksum will be automatically disabled,
10435         # and the OBD_FAIL_OSC_CHECKSUM_SEND/OBD_FAIL_OSC_CHECKSUM_RECEIVE
10436         # will be checked by sptlrpc code against sptlrpc bulk checksum.
10437         # In this case set_checksums() will not be no-op, because sptlrpc
10438         # bulk checksum will be enabled all through the test.
10439
10440         [ "$ORIG_CSUM" ] || ORIG_CSUM=`lctl get_param -n osc.*.checksums | head -n1`
10441         lctl set_param -n osc.*.checksums $1
10442         return 0
10443 }
10444
10445 export ORIG_CSUM_TYPE="`lctl get_param -n osc.*osc-[^mM]*.checksum_type |
10446                         sed 's/.*\[\(.*\)\].*/\1/g' | head -n1`"
10447 CKSUM_TYPES=${CKSUM_TYPES:-$(lctl get_param -n osc.*osc-[^mM]*.checksum_type |
10448                              tr -d [] | head -n1)}
10449 set_checksum_type()
10450 {
10451         lctl set_param -n osc.*osc-[^mM]*.checksum_type $1
10452         rc=$?
10453         log "set checksum type to $1, rc = $rc"
10454         return $rc
10455 }
10456
10457 get_osc_checksum_type()
10458 {
10459         # arugment 1: OST name, like OST0000
10460         ost=$1
10461         checksum_type=$(lctl get_param -n osc.*${ost}-osc-[^mM]*.checksum_type |
10462                         sed 's/.*\[\(.*\)\].*/\1/g')
10463         rc=$?
10464         [ $rc -ne 0 ] && error "failed to get checksum type of $ost, rc = $rc, output = $checksum_type"
10465         echo $checksum_type
10466 }
10467
10468 F77_TMP=$TMP/f77-temp
10469 F77SZ=8
10470 setup_f77() {
10471         dd if=/dev/urandom of=$F77_TMP bs=1M count=$F77SZ || \
10472                 error "error writing to $F77_TMP"
10473 }
10474
10475 test_77a() { # bug 10889
10476         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10477         $GSS && skip_env "could not run with gss"
10478
10479         [ ! -f $F77_TMP ] && setup_f77
10480         set_checksums 1
10481         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ || error "dd error"
10482         set_checksums 0
10483         rm -f $DIR/$tfile
10484 }
10485 run_test 77a "normal checksum read/write operation"
10486
10487 test_77b() { # bug 10889
10488         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10489         $GSS && skip_env "could not run with gss"
10490
10491         [ ! -f $F77_TMP ] && setup_f77
10492         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
10493         $LCTL set_param fail_loc=0x80000409
10494         set_checksums 1
10495
10496         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
10497                 error "dd error: $?"
10498         $LCTL set_param fail_loc=0
10499
10500         for algo in $CKSUM_TYPES; do
10501                 cancel_lru_locks osc
10502                 set_checksum_type $algo
10503                 #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
10504                 $LCTL set_param fail_loc=0x80000408
10505                 cmp $F77_TMP $DIR/$tfile || error "file compare failed"
10506                 $LCTL set_param fail_loc=0
10507         done
10508         set_checksums 0
10509         set_checksum_type $ORIG_CSUM_TYPE
10510         rm -f $DIR/$tfile
10511 }
10512 run_test 77b "checksum error on client write, read"
10513
10514 cleanup_77c() {
10515         trap 0
10516         set_checksums 0
10517         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=0
10518         $check_ost &&
10519                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=0
10520         [ -n "$osc_file_prefix" ] && rm -f ${osc_file_prefix}*
10521         $check_ost && [ -n "$ost_file_prefix" ] &&
10522                 do_facet ost1 rm -f ${ost_file_prefix}\*
10523 }
10524
10525 test_77c() {
10526         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10527         $GSS && skip_env "could not run with gss"
10528         remote_ost_nodsh && skip "remote OST with nodsh"
10529
10530         local bad1
10531         local osc_file_prefix
10532         local osc_file
10533         local check_ost=false
10534         local ost_file_prefix
10535         local ost_file
10536         local orig_cksum
10537         local dump_cksum
10538         local fid
10539
10540         # ensure corruption will occur on first OSS/OST
10541         $LFS setstripe -i 0 $DIR/$tfile
10542
10543         [ ! -f $F77_TMP ] && setup_f77
10544         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
10545                 error "dd write error: $?"
10546         fid=$($LFS path2fid $DIR/$tfile)
10547
10548         if [ $OST1_VERSION -ge $(version_code 2.9.57) ]
10549         then
10550                 check_ost=true
10551                 ost_file_prefix=$(do_facet ost1 $LCTL get_param -n debug_path)
10552                 ost_file_prefix=${ost_file_prefix}-checksum_dump-ost-\\${fid}
10553         else
10554                 echo "OSS do not support bulk pages dump upon error"
10555         fi
10556
10557         osc_file_prefix=$($LCTL get_param -n debug_path)
10558         osc_file_prefix=${osc_file_prefix}-checksum_dump-osc-\\${fid}
10559
10560         trap cleanup_77c EXIT
10561
10562         set_checksums 1
10563         # enable bulk pages dump upon error on Client
10564         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=1
10565         # enable bulk pages dump upon error on OSS
10566         $check_ost &&
10567                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=1
10568
10569         # flush Client cache to allow next read to reach OSS
10570         cancel_lru_locks osc
10571
10572         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE       0x408
10573         $LCTL set_param fail_loc=0x80000408
10574         dd if=$DIR/$tfile of=/dev/null bs=1M || error "dd read error: $?"
10575         $LCTL set_param fail_loc=0
10576
10577         rm -f $DIR/$tfile
10578
10579         # check cksum dump on Client
10580         osc_file=$(ls ${osc_file_prefix}*)
10581         [ -n "$osc_file" ] || error "no checksum dump file on Client"
10582         # OBD_FAIL_OSC_CHECKSUM_RECEIVE corrupts with "bad1" at start of file
10583         bad1=$(dd if=$osc_file bs=1 count=4 2>/dev/null) || error "dd error: $?"
10584         [ $bad1 == "bad1" ] || error "unexpected corrupt pattern"
10585         orig_cksum=$(dd if=$F77_TMP bs=1 skip=4 count=1048572 2>/dev/null |
10586                      cksum)
10587         dump_cksum=$(dd if=$osc_file bs=1 skip=4 2>/dev/null | cksum)
10588         [[ "$orig_cksum" == "$dump_cksum" ]] ||
10589                 error "dump content does not match on Client"
10590
10591         $check_ost || skip "No need to check cksum dump on OSS"
10592
10593         # check cksum dump on OSS
10594         ost_file=$(do_facet ost1 ls ${ost_file_prefix}\*)
10595         [ -n "$ost_file" ] || error "no checksum dump file on OSS"
10596         orig_cksum=$(dd if=$F77_TMP bs=1048576 count=1 2>/dev/null | cksum)
10597         dump_cksum=$(do_facet ost1 dd if=$ost_file 2>/dev/null \| cksum)
10598         [[ "$orig_cksum" == "$dump_cksum" ]] ||
10599                 error "dump content does not match on OSS"
10600
10601         cleanup_77c
10602 }
10603 run_test 77c "checksum error on client read with debug"
10604
10605 test_77d() { # bug 10889
10606         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10607         $GSS && skip_env "could not run with gss"
10608
10609         stack_trap "rm -f $DIR/$tfile"
10610         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
10611         $LCTL set_param fail_loc=0x80000409
10612         set_checksums 1
10613         $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
10614                 error "direct write: rc=$?"
10615         $LCTL set_param fail_loc=0
10616         set_checksums 0
10617
10618         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
10619         $LCTL set_param fail_loc=0x80000408
10620         set_checksums 1
10621         cancel_lru_locks osc
10622         $DIRECTIO read $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
10623                 error "direct read: rc=$?"
10624         $LCTL set_param fail_loc=0
10625         set_checksums 0
10626 }
10627 run_test 77d "checksum error on OST direct write, read"
10628
10629 test_77f() { # bug 10889
10630         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10631         $GSS && skip_env "could not run with gss"
10632
10633         set_checksums 1
10634         stack_trap "rm -f $DIR/$tfile"
10635         for algo in $CKSUM_TYPES; do
10636                 cancel_lru_locks osc
10637                 set_checksum_type $algo
10638                 #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
10639                 $LCTL set_param fail_loc=0x409
10640                 $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) &&
10641                         error "direct write succeeded"
10642                 $LCTL set_param fail_loc=0
10643         done
10644         set_checksum_type $ORIG_CSUM_TYPE
10645         set_checksums 0
10646 }
10647 run_test 77f "repeat checksum error on write (expect error)"
10648
10649 test_77g() { # bug 10889
10650         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10651         $GSS && skip_env "could not run with gss"
10652         remote_ost_nodsh && skip "remote OST with nodsh"
10653
10654         [ ! -f $F77_TMP ] && setup_f77
10655
10656         local file=$DIR/$tfile
10657         stack_trap "rm -f $file" EXIT
10658
10659         $LFS setstripe -c 1 -i 0 $file
10660         #define OBD_FAIL_OST_CHECKSUM_RECEIVE       0x21a
10661         do_facet ost1 lctl set_param fail_loc=0x8000021a
10662         set_checksums 1
10663         dd if=$F77_TMP of=$file bs=1M count=$F77SZ ||
10664                 error "write error: rc=$?"
10665         do_facet ost1 lctl set_param fail_loc=0
10666         set_checksums 0
10667
10668         cancel_lru_locks osc
10669         #define OBD_FAIL_OST_CHECKSUM_SEND          0x21b
10670         do_facet ost1 lctl set_param fail_loc=0x8000021b
10671         set_checksums 1
10672         cmp $F77_TMP $file || error "file compare failed"
10673         do_facet ost1 lctl set_param fail_loc=0
10674         set_checksums 0
10675 }
10676 run_test 77g "checksum error on OST write, read"
10677
10678 test_77k() { # LU-10906
10679         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10680         $GSS && skip_env "could not run with gss"
10681
10682         local cksum_param="osc.$FSNAME*.checksums"
10683         local get_checksum="$LCTL get_param -n $cksum_param | head -n1"
10684         local checksum
10685         local i
10686
10687         [ "$ORIG_CSUM" ] || ORIG_CSUM=$(eval $get_checksum)
10688         stack_trap "wait_update $HOSTNAME '$get_checksum' $ORIG_CSUM || true"
10689         stack_trap "do_facet mgs $LCTL set_param -P $cksum_param=$ORIG_CSUM"
10690
10691         for i in 0 1; do
10692                 do_facet mgs $LCTL set_param -P $cksum_param=$i ||
10693                         error "failed to set checksum=$i on MGS"
10694                 wait_update $HOSTNAME "$get_checksum" $i
10695                 #remount
10696                 echo "remount client, checksum should be $i"
10697                 remount_client $MOUNT || error "failed to remount client"
10698                 checksum=$(eval $get_checksum)
10699                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
10700         done
10701         # remove persistent param to avoid races with checksum mountopt below
10702         do_facet mgs $LCTL set_param -P -d $cksum_param ||
10703                 error "failed to delete checksum on MGS"
10704
10705         for opt in "checksum" "nochecksum"; do
10706                 #remount with mount option
10707                 echo "remount client with option $opt, checksum should be $i"
10708                 umount_client $MOUNT || error "failed to umount client"
10709                 mount_client $MOUNT "$MOUNT_OPTS,$opt" ||
10710                         error "failed to mount client with option '$opt'"
10711                 checksum=$(eval $get_checksum)
10712                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
10713                 i=$((i - 1))
10714         done
10715
10716         remount_client $MOUNT || error "failed to remount client"
10717 }
10718 run_test 77k "enable/disable checksum correctly"
10719
10720 test_77l() {
10721         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10722         $GSS && skip_env "could not run with gss"
10723
10724         set_checksums 1
10725         stack_trap "set_checksums $ORIG_CSUM" EXIT
10726         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
10727
10728         set_checksum_type invalid && error "unexpected success of invalid checksum type"
10729
10730         $LFS setstripe -c 1 -i 0 $DIR/$tfile
10731         for algo in $CKSUM_TYPES; do
10732                 set_checksum_type $algo || error "fail to set checksum type $algo"
10733                 osc_algo=$(get_osc_checksum_type OST0000)
10734                 [ "$osc_algo" != "$algo" ] && error "checksum type is $osc_algo after setting it to $algo"
10735
10736                 # no locks, no reqs to let the connection idle
10737                 cancel_lru_locks osc
10738                 lru_resize_disable osc
10739                 wait_osc_import_state client ost1 IDLE
10740
10741                 # ensure ost1 is connected
10742                 stat $DIR/$tfile >/dev/null || error "can't stat"
10743                 wait_osc_import_state client ost1 FULL
10744
10745                 osc_algo=$(get_osc_checksum_type OST0000)
10746                 [ "$osc_algo" != "$algo" ] && error "checksum type changed from $algo to $osc_algo after reconnection"
10747         done
10748         return 0
10749 }
10750 run_test 77l "preferred checksum type is remembered after reconnected"
10751
10752 [ "$ORIG_CSUM" ] && set_checksums $ORIG_CSUM || true
10753 rm -f $F77_TMP
10754 unset F77_TMP
10755
10756 test_77m() {
10757         (( $CLIENT_VERSION >= $(version_code 2.14.52) )) ||
10758                 skip "Need at least version 2.14.52"
10759         local param=checksum_speed
10760
10761         $LCTL get_param $param || error "reading $param failed"
10762
10763         csum_speeds=$($LCTL get_param -n $param)
10764
10765         [[ "$csum_speeds" =~ "adler32" && "$csum_speeds" =~ "crc32" ]] ||
10766                 error "known checksum types are missing"
10767 }
10768 run_test 77m "Verify checksum_speed is correctly read"
10769
10770 check_filefrag_77n() {
10771         local nr_ext=0
10772         local starts=()
10773         local ends=()
10774
10775         while read extidx a b start end rest; do
10776                 if [[ "${extidx}" =~ ^[0-9]+: ]]; then
10777                         nr_ext=$(( $nr_ext + 1 ))
10778                         starts+=( ${start%..} )
10779                         ends+=( ${end%:} )
10780                 fi
10781         done < <( filefrag -sv $1 )
10782
10783         [[ $nr_ext -eq 2 ]] && [[ "${starts[-1]}" == $(( ${ends[0]} + 1 )) ]] && return 0
10784         return 1
10785 }
10786
10787 test_77n() {
10788         [[ "$CKSUM_TYPES" =~ t10 ]] || skip "no T10 checksum support on osc"
10789
10790         touch $DIR/$tfile
10791         $TRUNCATE $DIR/$tfile 0
10792         dd if=/dev/urandom of=$DIR/$tfile bs=4k conv=notrunc count=1 seek=0
10793         dd if=/dev/urandom of=$DIR/$tfile bs=4k conv=notrunc count=1 seek=2
10794         check_filefrag_77n $DIR/$tfile ||
10795                 skip "$tfile blocks not contiguous around hole"
10796
10797         set_checksums 1
10798         stack_trap "set_checksums $ORIG_CSUM" EXIT
10799         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
10800         stack_trap "rm -f $DIR/$tfile"
10801
10802         for algo in $CKSUM_TYPES; do
10803                 if [[ "$algo" =~ ^t10 ]]; then
10804                         set_checksum_type $algo ||
10805                                 error "fail to set checksum type $algo"
10806                         dd if=$DIR/$tfile of=/dev/null bs=12k count=1 iflag=direct ||
10807                                 error "fail to read $tfile with $algo"
10808                 fi
10809         done
10810         rm -f $DIR/$tfile
10811         return 0
10812 }
10813 run_test 77n "Verify read from a hole inside contiguous blocks with T10PI"
10814
10815 test_77o() {
10816         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
10817                 skip "Need MDS version at least 2.14.55"
10818         (( $OST1_VERSION >= $(version_code 2.14.55) )) ||
10819                 skip "Need OST version at least 2.14.55"
10820         local ofd=obdfilter
10821         local mdt=mdt
10822
10823         # print OST checksum_type
10824         echo "$ofd.$FSNAME-*.checksum_type:"
10825         do_nodes $(comma_list $(osts_nodes)) \
10826                 $LCTL get_param -n $ofd.$FSNAME-*.checksum_type
10827
10828         # print MDT checksum_type
10829         echo "$mdt.$FSNAME-*.checksum_type:"
10830         do_nodes $(comma_list $(mdts_nodes)) \
10831                 $LCTL get_param -n $mdt.$FSNAME-*.checksum_type
10832
10833         local o_count=$(do_nodes $(comma_list $(osts_nodes)) \
10834                    $LCTL get_param -n $ofd.$FSNAME-*.checksum_type | wc -l)
10835
10836         (( $o_count == $OSTCOUNT )) ||
10837                 error "found $o_count checksums, not \$MDSCOUNT=$OSTCOUNT"
10838
10839         local m_count=$(do_nodes $(comma_list $(mdts_nodes)) \
10840                    $LCTL get_param -n $mdt.$FSNAME-*.checksum_type | wc -l)
10841
10842         (( $m_count == $MDSCOUNT )) ||
10843                 error "found $m_count checksums, not \$MDSCOUNT=$MDSCOUNT"
10844 }
10845 run_test 77o "Verify checksum_type for server (mdt and ofd(obdfilter))"
10846
10847 cleanup_test_78() {
10848         trap 0
10849         rm -f $DIR/$tfile
10850 }
10851
10852 test_78() { # bug 10901
10853         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10854         remote_ost || skip_env "local OST"
10855
10856         NSEQ=5
10857         F78SIZE=$(($(awk '/MemFree:/ { print $2 }' /proc/meminfo) / 1024))
10858         echo "MemFree: $F78SIZE, Max file size: $MAXFREE"
10859         MEMTOTAL=$(($(awk '/MemTotal:/ { print $2 }' /proc/meminfo) / 1024))
10860         echo "MemTotal: $MEMTOTAL"
10861
10862         # reserve 256MB of memory for the kernel and other running processes,
10863         # and then take 1/2 of the remaining memory for the read/write buffers.
10864         if [ $MEMTOTAL -gt 512 ] ;then
10865                 MEMTOTAL=$(((MEMTOTAL - 256 ) / 2))
10866         else
10867                 # for those poor memory-starved high-end clusters...
10868                 MEMTOTAL=$((MEMTOTAL / 2))
10869         fi
10870         echo "Mem to use for directio: $MEMTOTAL"
10871
10872         [[ $F78SIZE -gt $MEMTOTAL ]] && F78SIZE=$MEMTOTAL
10873         [[ $F78SIZE -gt 512 ]] && F78SIZE=512
10874         [[ $F78SIZE -gt $((MAXFREE / 1024)) ]] && F78SIZE=$((MAXFREE / 1024))
10875         SMALLESTOST=$($LFS df $DIR | grep OST | awk '{ print $4 }' | sort -n |
10876                 head -n1)
10877         echo "Smallest OST: $SMALLESTOST"
10878         [[ $SMALLESTOST -lt 10240 ]] &&
10879                 skip "too small OSTSIZE, useless to run large O_DIRECT test"
10880
10881         trap cleanup_test_78 EXIT
10882
10883         [[ $F78SIZE -gt $((SMALLESTOST * $OSTCOUNT / 1024 - 80)) ]] &&
10884                 F78SIZE=$((SMALLESTOST * $OSTCOUNT / 1024 - 80))
10885
10886         [ "$SLOW" = "no" ] && NSEQ=1 && [ $F78SIZE -gt 32 ] && F78SIZE=32
10887         echo "File size: $F78SIZE"
10888         $LFS setstripe -c $OSTCOUNT $DIR/$tfile || error "setstripe failed"
10889         for i in $(seq 1 $NSEQ); do
10890                 FSIZE=$(($F78SIZE / ($NSEQ - $i + 1)))
10891                 echo directIO rdwr round $i of $NSEQ
10892                 $DIRECTIO rdwr $DIR/$tfile 0 $FSIZE 1048576||error "rdwr failed"
10893         done
10894
10895         cleanup_test_78
10896 }
10897 run_test 78 "handle large O_DIRECT writes correctly ============"
10898
10899 test_79() { # bug 12743
10900         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10901
10902         wait_delete_completed
10903
10904         BKTOTAL=$(calc_osc_kbytes kbytestotal)
10905         BKFREE=$(calc_osc_kbytes kbytesfree)
10906         BKAVAIL=$(calc_osc_kbytes kbytesavail)
10907
10908         STRING=`df -P $MOUNT | tail -n 1 | awk '{print $2","$3","$4}'`
10909         DFTOTAL=`echo $STRING | cut -d, -f1`
10910         DFUSED=`echo $STRING  | cut -d, -f2`
10911         DFAVAIL=`echo $STRING | cut -d, -f3`
10912         DFFREE=$(($DFTOTAL - $DFUSED))
10913
10914         ALLOWANCE=$((64 * $OSTCOUNT))
10915
10916         if [ $DFTOTAL -lt $(($BKTOTAL - $ALLOWANCE)) ] ||
10917            [ $DFTOTAL -gt $(($BKTOTAL + $ALLOWANCE)) ] ; then
10918                 error "df total($DFTOTAL) mismatch OST total($BKTOTAL)"
10919         fi
10920         if [ $DFFREE -lt $(($BKFREE - $ALLOWANCE)) ] ||
10921            [ $DFFREE -gt $(($BKFREE + $ALLOWANCE)) ] ; then
10922                 error "df free($DFFREE) mismatch OST free($BKFREE)"
10923         fi
10924         if [ $DFAVAIL -lt $(($BKAVAIL - $ALLOWANCE)) ] ||
10925            [ $DFAVAIL -gt $(($BKAVAIL + $ALLOWANCE)) ] ; then
10926                 error "df avail($DFAVAIL) mismatch OST avail($BKAVAIL)"
10927         fi
10928 }
10929 run_test 79 "df report consistency check ======================="
10930
10931 test_80() { # bug 10718
10932         remote_ost_nodsh && skip "remote OST with nodsh"
10933         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10934
10935         # relax strong synchronous semantics for slow backends like ZFS
10936         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
10937                 local soc="obdfilter.*.sync_lock_cancel"
10938                 local save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
10939
10940                 # "sync_on_lock_cancel" was broken by v2_11_55_0-26-g7059644e9a
10941                 if [ -z "$save" ]; then
10942                         soc="obdfilter.*.sync_on_lock_cancel"
10943                         save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
10944                 fi
10945
10946                 if [ "$save" != "never" ]; then
10947                         local hosts=$(comma_list $(osts_nodes))
10948
10949                         do_nodes $hosts $LCTL set_param $soc=never
10950                         stack_trap "do_nodes $hosts $LCTL set_param $soc=$save"
10951                 fi
10952         fi
10953
10954         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1M
10955         sync; sleep 1; sync
10956         local before=$(date +%s)
10957         cancel_lru_locks osc
10958         local after=$(date +%s)
10959         local diff=$((after - before))
10960         [ $diff -le 1 ] || error "elapsed for 1M@1T = $diff"
10961
10962         rm -f $DIR/$tfile
10963 }
10964 run_test 80 "Page eviction is equally fast at high offsets too"
10965
10966 test_81a() { # LU-456
10967         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10968         remote_ost_nodsh && skip "remote OST with nodsh"
10969
10970         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
10971         # MUST OR with the CFS_FAIL_ONCE (0x80000000)
10972         do_facet ost1 lctl set_param fail_loc=0x80000228
10973
10974         # write should trigger a retry and success
10975         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10976         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10977         RC=$?
10978         if [ $RC -ne 0 ] ; then
10979                 error "write should success, but failed for $RC"
10980         fi
10981 }
10982 run_test 81a "OST should retry write when get -ENOSPC ==============="
10983
10984 test_81b() { # LU-456
10985         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10986         remote_ost_nodsh && skip "remote OST with nodsh"
10987
10988         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
10989         # Don't OR with the CFS_FAIL_ONCE (0x80000000)
10990         do_facet ost1 lctl set_param fail_loc=0x228
10991
10992         # write should retry several times and return -ENOSPC finally
10993         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10994         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10995         RC=$?
10996         ENOSPC=28
10997         if [ $RC -ne $ENOSPC ] ; then
10998                 error "dd should fail for -ENOSPC, but succeed."
10999         fi
11000 }
11001 run_test 81b "OST should return -ENOSPC when retry still fails ======="
11002
11003 test_99() {
11004         [ -z "$(which cvs 2>/dev/null)" ] && skip_env "could not find cvs"
11005
11006         test_mkdir $DIR/$tdir.cvsroot
11007         chown $RUNAS_ID $DIR/$tdir.cvsroot
11008
11009         cd $TMP
11010         $RUNAS cvs -d $DIR/$tdir.cvsroot init || error "cvs init failed"
11011
11012         cd /etc/init.d
11013         # some versions of cvs import exit(1) when asked to import links or
11014         # files they can't read.  ignore those files.
11015         local toignore=$(find . -type l -printf '-I %f\n' -o \
11016                          ! -perm /4 -printf '-I %f\n')
11017         $RUNAS cvs -d $DIR/$tdir.cvsroot import -m "nomesg" $toignore \
11018                 $tdir.reposname vtag rtag
11019
11020         cd $DIR
11021         test_mkdir $DIR/$tdir.reposname
11022         chown $RUNAS_ID $DIR/$tdir.reposname
11023         $RUNAS cvs -d $DIR/$tdir.cvsroot co $tdir.reposname
11024
11025         cd $DIR/$tdir.reposname
11026         $RUNAS touch foo99
11027         $RUNAS cvs add -m 'addmsg' foo99
11028         $RUNAS cvs update
11029         $RUNAS cvs commit -m 'nomsg' foo99
11030         rm -fr $DIR/$tdir.cvsroot
11031 }
11032 run_test 99 "cvs strange file/directory operations"
11033
11034 test_100() {
11035         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11036         [[ "$NETTYPE" =~ tcp ]] ||
11037                 skip_env "TCP secure port test, not useful for NETTYPE=$NETTYPE"
11038         [[ -n "$(type -p ss)" ]] || skip_env "ss not available"
11039         remote_ost_nodsh && skip "remote OST with nodsh"
11040         remote_mds_nodsh && skip "remote MDS with nodsh"
11041         remote_servers || skip "useless for local single node setup"
11042
11043         ss -tna | ( rc=1; while read STATE SND RCV LOCAL REMOTE STAT; do
11044                 [[ "${REMOTE/*:/}" == "$ACCEPTOR_PORT" ]] || continue
11045
11046                 rc=0
11047                 if (( ${LOCAL/*:/} >= 1024 )); then
11048                         echo "bad: $PROT $SND $RCV $LOCAL $REMOTE $STAT"
11049                         ss -tna
11050                         error "local: ${LOCAL/*:/} > 1024 remote: ${REMOTE/*:/}"
11051                 fi
11052         done
11053         (( $rc == 0 )) || error "privileged port not found" )
11054 }
11055 run_test 100 "check local port using privileged port"
11056
11057 function get_named_value()
11058 {
11059     local tag=$1
11060
11061     grep -w "$tag" | sed "s/^$tag  *\([0-9]*\)  *.*/\1/"
11062 }
11063
11064 export CACHE_MAX=$($LCTL get_param -n llite.*.max_cached_mb |
11065                    awk '/^max_cached_mb/ { print $2 }')
11066
11067 cleanup_101a() {
11068         $LCTL set_param -n llite.*.max_cached_mb $CACHE_MAX
11069         trap 0
11070 }
11071
11072 test_101a() {
11073         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11074
11075         local s
11076         local discard
11077         local nreads=10000
11078         local cache_limit=32
11079
11080         $LCTL set_param -n osc.*-osc*.rpc_stats=0
11081         trap cleanup_101a EXIT
11082         $LCTL set_param -n llite.*.read_ahead_stats=0
11083         $LCTL set_param -n llite.*.max_cached_mb=$cache_limit
11084
11085         #
11086         # randomly read 10000 of 64K chunks from file 3x 32MB in size
11087         #
11088         echo "nreads: $nreads file size: $((cache_limit * 3))MB"
11089         $READS -f $DIR/$tfile -s$((cache_limit * 3192 * 1024)) -b65536 -C -n$nreads -t 180
11090
11091         discard=0
11092         for s in $($LCTL get_param -n llite.*.read_ahead_stats |
11093                    get_named_value 'read.but.discarded'); do
11094                         discard=$(($discard + $s))
11095         done
11096         cleanup_101a
11097
11098         $LCTL get_param osc.*-osc*.rpc_stats
11099         $LCTL get_param llite.*.read_ahead_stats
11100
11101         # Discard is generally zero, but sometimes a few random reads line up
11102         # and trigger larger readahead, which is wasted & leads to discards.
11103         if [[ $(($discard)) -gt $nreads ]]; then
11104                 error "too many ($discard) discarded pages"
11105         fi
11106         rm -f $DIR/$tfile || true
11107 }
11108 run_test 101a "check read-ahead for random reads"
11109
11110 setup_test101bc() {
11111         test_mkdir $DIR/$tdir
11112         local ssize=$1
11113         local FILE_LENGTH=$2
11114         STRIPE_OFFSET=0
11115
11116         local FILE_SIZE_MB=$((FILE_LENGTH / ssize))
11117
11118         local list=$(comma_list $(osts_nodes))
11119         set_osd_param $list '' read_cache_enable 0
11120         set_osd_param $list '' writethrough_cache_enable 0
11121
11122         trap cleanup_test101bc EXIT
11123         # prepare the read-ahead file
11124         $LFS setstripe -S $ssize -i $STRIPE_OFFSET -c $OSTCOUNT $DIR/$tfile
11125
11126         dd if=/dev/zero of=$DIR/$tfile bs=$ssize \
11127                                 count=$FILE_SIZE_MB 2> /dev/null
11128
11129 }
11130
11131 cleanup_test101bc() {
11132         trap 0
11133         rm -rf $DIR/$tdir
11134         rm -f $DIR/$tfile
11135
11136         local list=$(comma_list $(osts_nodes))
11137         set_osd_param $list '' read_cache_enable 1
11138         set_osd_param $list '' writethrough_cache_enable 1
11139 }
11140
11141 calc_total() {
11142         awk 'BEGIN{total=0}; {total+=$1}; END{print total}'
11143 }
11144
11145 ra_check_101() {
11146         local read_size=$1
11147         local stripe_size=$2
11148         local stride_length=$((stripe_size / read_size))
11149         local stride_width=$((stride_length * OSTCOUNT))
11150         local discard_limit=$(( ((stride_length - 1) * 3 / stride_width) *
11151                                 (stride_width - stride_length) ))
11152         local discard=$($LCTL get_param -n llite.*.read_ahead_stats |
11153                   get_named_value 'read.but.discarded' | calc_total)
11154
11155         if [[ $discard -gt $discard_limit ]]; then
11156                 $LCTL get_param llite.*.read_ahead_stats
11157                 error "($discard limit ${discard_limit}) discarded pages with size (${read_size})"
11158         else
11159                 echo "Read-ahead success for size ${read_size}"
11160         fi
11161 }
11162
11163 test_101b() {
11164         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11165         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11166
11167         local STRIPE_SIZE=1048576
11168         local STRIDE_SIZE=$((STRIPE_SIZE*OSTCOUNT))
11169
11170         if [ $SLOW == "yes" ]; then
11171                 local FILE_LENGTH=$((STRIDE_SIZE * 64))
11172         else
11173                 local FILE_LENGTH=$((STRIDE_SIZE * 8))
11174         fi
11175
11176         local ITERATION=$((FILE_LENGTH / STRIDE_SIZE))
11177
11178         # prepare the read-ahead file
11179         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
11180         cancel_lru_locks osc
11181         for BIDX in 2 4 8 16 32 64 128 256
11182         do
11183                 local BSIZE=$((BIDX*4096))
11184                 local READ_COUNT=$((STRIPE_SIZE/BSIZE))
11185                 local STRIDE_LENGTH=$((STRIDE_SIZE/BSIZE))
11186                 local OFFSET=$((STRIPE_SIZE/BSIZE*(OSTCOUNT - 1)))
11187                 $LCTL set_param -n llite.*.read_ahead_stats=0
11188                 $READS -f $DIR/$tfile  -l $STRIDE_LENGTH -o $OFFSET \
11189                               -s $FILE_LENGTH -b $STRIPE_SIZE -a $READ_COUNT -n $ITERATION
11190                 cancel_lru_locks osc
11191                 ra_check_101 $BSIZE $STRIPE_SIZE $FILE_LENGTH
11192         done
11193         cleanup_test101bc
11194         true
11195 }
11196 run_test 101b "check stride-io mode read-ahead ================="
11197
11198 test_101c() {
11199         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11200
11201         local STRIPE_SIZE=1048576
11202         local FILE_LENGTH=$((STRIPE_SIZE*100))
11203         local nreads=10000
11204         local rsize=65536
11205         local osc_rpc_stats
11206
11207         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
11208
11209         cancel_lru_locks osc
11210         $LCTL set_param osc.*.rpc_stats=0
11211         $READS -f $DIR/$tfile -s$FILE_LENGTH -b$rsize -n$nreads -t 180
11212         $LCTL get_param osc.*.rpc_stats
11213         for osc_rpc_stats in $($LCTL get_param -N osc.*.rpc_stats); do
11214                 local stats=$($LCTL get_param -n $osc_rpc_stats)
11215                 local lines=$(echo "$stats" | awk 'END {print NR;}')
11216                 local size
11217
11218                 if [ $lines -le 20 ]; then
11219                         echo "continue debug"
11220                         continue
11221                 fi
11222                 for size in 1 2 4 8; do
11223                         local rpc=$(echo "$stats" |
11224                                     awk '($1 == "'$size':") {print $2; exit; }')
11225                         [ $rpc != 0 ] && ((size * PAGE_SIZE < rsize)) &&
11226                                 error "Small $((size*PAGE_SIZE)) read IO $rpc!"
11227                 done
11228                 echo "$osc_rpc_stats check passed!"
11229         done
11230         cleanup_test101bc
11231         true
11232 }
11233 run_test 101c "check stripe_size aligned read-ahead"
11234
11235 test_101d() {
11236         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11237
11238         local file=$DIR/$tfile
11239         local sz_MB=${FILESIZE_101d:-80}
11240         local ra_MB=${READAHEAD_MB:-40}
11241
11242         local free_MB=$(($(df -P $DIR | tail -n 1 | awk '{ print $4 }') / 1024))
11243         [ $free_MB -lt $sz_MB ] &&
11244                 skip "Need free space ${sz_MB}M, have ${free_MB}M"
11245
11246         echo "Create test file $file size ${sz_MB}M, ${free_MB}M free"
11247         $LFS setstripe -c -1 $file || error "setstripe failed"
11248
11249         dd if=/dev/zero of=$file bs=1M count=$sz_MB || error "dd failed"
11250         echo Cancel LRU locks on lustre client to flush the client cache
11251         cancel_lru_locks osc
11252
11253         echo Disable read-ahead
11254         local old_RA=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
11255         $LCTL set_param -n llite.*.max_read_ahead_mb=0
11256         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb=$old_RA" EXIT
11257         $LCTL get_param -n llite.*.max_read_ahead_mb
11258
11259         echo "Reading the test file $file with read-ahead disabled"
11260         local sz_KB=$((sz_MB * 1024 / 4))
11261         # 10485760 bytes transferred in 0.000938 secs (11179579337 bytes/sec)
11262         # 104857600 bytes (105 MB) copied, 0.00876352 s, 12.0 GB/s
11263         local raOFF=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
11264                       sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
11265
11266         echo "Cancel LRU locks on lustre client to flush the client cache"
11267         cancel_lru_locks osc
11268         echo Enable read-ahead with ${ra_MB}MB
11269         $LCTL set_param -n llite.*.max_read_ahead_mb=$ra_MB
11270
11271         echo "Reading the test file $file with read-ahead enabled"
11272         local raON=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
11273                      sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
11274
11275         echo "read-ahead disabled time read $raOFF"
11276         echo "read-ahead enabled time read $raON"
11277
11278         rm -f $file
11279         wait_delete_completed
11280
11281         # use awk for this check instead of bash because it handles decimals
11282         awk "{ exit !($raOFF < 1.0 || $raOFF > $raON) }" <<<"ignore_me" ||
11283                 error "readahead ${raON}s > no-readahead ${raOFF}s ${sz_MB}M"
11284 }
11285 run_test 101d "file read with and without read-ahead enabled"
11286
11287 test_101e() {
11288         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11289
11290         local file=$DIR/$tfile
11291         local size_KB=500  #KB
11292         local count=100
11293         local bsize=1024
11294
11295         local free_KB=$(df -P $DIR | tail -n 1 | awk '{ print $4 }')
11296         local need_KB=$((count * size_KB))
11297         [[ $free_KB -le $need_KB ]] &&
11298                 skip_env "Need free space $need_KB, have $free_KB"
11299
11300         echo "Creating $count ${size_KB}K test files"
11301         for ((i = 0; i < $count; i++)); do
11302                 dd if=/dev/zero of=$file.$i bs=$bsize count=$size_KB 2>/dev/null
11303         done
11304
11305         echo "Cancel LRU locks on lustre client to flush the client cache"
11306         cancel_lru_locks $OSC
11307
11308         echo "Reset readahead stats"
11309         $LCTL set_param -n llite.*.read_ahead_stats=0
11310
11311         for ((i = 0; i < $count; i++)); do
11312                 dd if=$file.$i of=/dev/null bs=$bsize count=$size_KB 2>/dev/null
11313         done
11314
11315         $LCTL get_param llite.*.max_cached_mb
11316         $LCTL get_param llite.*.read_ahead_stats
11317         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11318                      get_named_value 'misses' | calc_total)
11319
11320         for ((i = 0; i < $count; i++)); do
11321                 rm -rf $file.$i 2>/dev/null
11322         done
11323
11324         #10000 means 20% reads are missing in readahead
11325         [[ $miss -lt 10000 ]] ||  error "misses too much for small reads"
11326 }
11327 run_test 101e "check read-ahead for small read(1k) for small files(500k)"
11328
11329 test_101f() {
11330         which iozone || skip_env "no iozone installed"
11331
11332         local old_debug=$($LCTL get_param debug)
11333         old_debug=${old_debug#*=}
11334         $LCTL set_param debug="reada mmap"
11335
11336         # create a test file
11337         iozone -i 0 -+n -r 1m -s 128m -w -f $DIR/$tfile > /dev/null 2>&1
11338
11339         echo Cancel LRU locks on lustre client to flush the client cache
11340         cancel_lru_locks osc
11341
11342         echo Reset readahead stats
11343         $LCTL set_param -n llite.*.read_ahead_stats=0
11344
11345         echo mmap read the file with small block size
11346         iozone -i 1 -u 1 -l 1 -+n -r 32k -s 128m -B -f $DIR/$tfile \
11347                 > /dev/null 2>&1
11348
11349         echo checking missing pages
11350         $LCTL get_param llite.*.read_ahead_stats
11351         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11352                         get_named_value 'misses' | calc_total)
11353
11354         $LCTL set_param debug="$old_debug"
11355         [ $miss -lt 3 ] || error "misses too much pages ('$miss')!"
11356         rm -f $DIR/$tfile
11357 }
11358 run_test 101f "check mmap read performance"
11359
11360 test_101g_brw_size_test() {
11361         local mb=$1
11362         local pages=$((mb * 1048576 / PAGE_SIZE))
11363         local file=$DIR/$tfile
11364
11365         $LCTL set_param osc.*.max_pages_per_rpc=${mb}M ||
11366                 { error "unable to set max_pages_per_rpc=${mb}M"; return 1; }
11367         for mp in $($LCTL get_param -n osc.*.max_pages_per_rpc); do
11368                 [ $mp -ne $pages ] && error "max_pages_per_rpc $mp != $pages" &&
11369                         return 2
11370         done
11371
11372         stack_trap "rm -f $file" EXIT
11373         $LCTL set_param -n osc.*.rpc_stats=0
11374
11375         # 10 RPCs should be enough for the test
11376         local count=10
11377         dd if=/dev/zero of=$file bs=${mb}M count=$count ||
11378                 { error "dd write ${mb} MB blocks failed"; return 3; }
11379         cancel_lru_locks osc
11380         dd of=/dev/null if=$file bs=${mb}M count=$count ||
11381                 { error "dd write ${mb} MB blocks failed"; return 4; }
11382
11383         # calculate number of full-sized read and write RPCs
11384         rpcs=($($LCTL get_param -n 'osc.*.rpc_stats' |
11385                 sed -n '/pages per rpc/,/^$/p' |
11386                 awk '/'$pages':/ { reads += $2; writes += $6 }; \
11387                 END { print reads,writes }'))
11388         # allow one extra full-sized read RPC for async readahead
11389         [[ ${rpcs[0]} == $count || ${rpcs[0]} == $((count + 1)) ]] ||
11390                 { error "${rpcs[0]} != $count read RPCs"; return 5; }
11391         [[ ${rpcs[1]} == $count ]] ||
11392                 { error "${rpcs[1]} != $count write RPCs"; return 6; }
11393 }
11394
11395 test_101g() {
11396         remote_ost_nodsh && skip "remote OST with nodsh"
11397
11398         local rpcs
11399         local osts=$(get_facets OST)
11400         local list=$(comma_list $(osts_nodes))
11401         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
11402         local brw_size="obdfilter.*.brw_size"
11403
11404         $LFS setstripe -i 0 -c 1 $DIR/$tfile
11405
11406         local orig_mb=$(do_facet ost1 $LCTL get_param -n $brw_size | head -n 1)
11407
11408         if { [ $OST1_VERSION -ge $(version_code 2.8.52) ] ||
11409                 { [ $OST1_VERSION -ge $(version_code 2.7.17) ] &&
11410                   [ $OST1_VERSION -lt $(version_code 2.7.50) ]; }; } &&
11411            { [ $CLIENT_VERSION -ge $(version_code 2.8.52) ] ||
11412                 { [ $CLIENT_VERSION -ge $(version_code 2.7.17) ] &&
11413                   [ $CLIENT_VERSION -lt $(version_code 2.7.50) ]; }; }; then
11414
11415                 [ $OST1_VERSION -ge $(version_code 2.9.52) ] &&
11416                         suffix="M"
11417
11418                 if [[ $orig_mb -lt 16 ]]; then
11419                         save_lustre_params $osts "$brw_size" > $p
11420                         do_nodes $list $LCTL set_param -n $brw_size=16$suffix ||
11421                                 error "set 16MB RPC size failed"
11422
11423                         echo "remount client to enable new RPC size"
11424                         remount_client $MOUNT || error "remount_client failed"
11425                 fi
11426
11427                 test_101g_brw_size_test 16 || error "16MB RPC test failed"
11428                 # should be able to set brw_size=12, but no rpc_stats for that
11429                 test_101g_brw_size_test 8 || error "8MB RPC test failed"
11430         fi
11431
11432         test_101g_brw_size_test 4 || error "4MB RPC test failed"
11433
11434         if [[ $orig_mb -lt 16 ]]; then
11435                 restore_lustre_params < $p
11436                 remount_client $MOUNT || error "remount_client restore failed"
11437         fi
11438
11439         rm -f $p $DIR/$tfile
11440 }
11441 run_test 101g "Big bulk(4/16 MiB) readahead"
11442
11443 test_101h() {
11444         $LFS setstripe -i 0 -c 1 $DIR/$tfile
11445
11446         dd if=/dev/zero of=$DIR/$tfile bs=1M count=70 ||
11447                 error "dd 70M file failed"
11448         echo Cancel LRU locks on lustre client to flush the client cache
11449         cancel_lru_locks osc
11450
11451         echo "Reset readahead stats"
11452         $LCTL set_param -n llite.*.read_ahead_stats 0
11453
11454         echo "Read 10M of data but cross 64M bundary"
11455         dd if=$DIR/$tfile of=/dev/null bs=10M skip=6 count=1
11456         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11457                      get_named_value 'misses' | calc_total)
11458         [ $miss -eq 1 ] || error "expected miss 1 but got $miss"
11459         rm -f $p $DIR/$tfile
11460 }
11461 run_test 101h "Readahead should cover current read window"
11462
11463 test_101i() {
11464         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 ||
11465                 error "dd 10M file failed"
11466
11467         local max_per_file_mb=$($LCTL get_param -n \
11468                 llite.*.max_read_ahead_per_file_mb 2>/dev/null)
11469         cancel_lru_locks osc
11470         stack_trap "$LCTL set_param llite.*.max_read_ahead_per_file_mb=$max_per_file_mb"
11471         $LCTL set_param llite.*.max_read_ahead_per_file_mb=1 ||
11472                 error "set max_read_ahead_per_file_mb to 1 failed"
11473
11474         echo "Reset readahead stats"
11475         $LCTL set_param llite.*.read_ahead_stats=0
11476
11477         dd if=$DIR/$tfile of=/dev/null bs=2M
11478
11479         $LCTL get_param llite.*.read_ahead_stats
11480         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11481                      awk '/misses/ { print $2 }')
11482         [ $miss -eq 5 ] || error "expected misses 5 but got $miss"
11483         rm -f $DIR/$tfile
11484 }
11485 run_test 101i "allow current readahead to exceed reservation"
11486
11487 test_101j() {
11488         $LFS setstripe -i 0 -c 1 $DIR/$tfile ||
11489                 error "setstripe $DIR/$tfile failed"
11490         local file_size=$((1048576 * 16))
11491         local old_ra=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
11492         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb $old_ra" EXIT
11493
11494         echo Disable read-ahead
11495         $LCTL set_param -n llite.*.max_read_ahead_mb=0
11496
11497         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$(($file_size / 1048576))
11498         for blk in $PAGE_SIZE 1048576 $file_size; do
11499                 cancel_lru_locks osc
11500                 echo "Reset readahead stats"
11501                 $LCTL set_param -n llite.*.read_ahead_stats=0
11502                 local count=$(($file_size / $blk))
11503                 dd if=$DIR/$tfile bs=$blk count=$count of=/dev/null
11504                 local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11505                              get_named_value 'failed.to.fast.read' | calc_total)
11506                 $LCTL get_param -n llite.*.read_ahead_stats
11507                 [ $miss -eq $count ] || error "expected $count got $miss"
11508         done
11509
11510         rm -f $p $DIR/$tfile
11511 }
11512 run_test 101j "A complete read block should be submitted when no RA"
11513
11514 test_readahead_base() {
11515         local file=$DIR/$tfile
11516         local size=$1
11517         local iosz
11518         local ramax
11519         local ranum
11520
11521         $LCTL set_param -n llite.*.read_ahead_stats=0
11522         # The first page is not accounted into readahead
11523         ramax=$(((size + PAGE_SIZE - 1) / PAGE_SIZE - 1))
11524         iosz=$(((size + 1048575) / 1048576 * 1048576))
11525         echo "Test readahead: size=$size ramax=$ramx iosz=$iosz"
11526
11527         $LCTL mark  "Test readahead: size=$size ramax=$ramx iosz=$iosz"
11528         fallocate -l $size $file || error "failed to fallocate $file"
11529         cancel_lru_locks osc
11530         $MULTIOP $file or${iosz}c || error "failed to read $file"
11531         $LCTL get_param -n llite.*.read_ahead_stats
11532         ranum=$($LCTL get_param -n llite.*.read_ahead_stats |
11533                 awk '/readahead.pages/ { print $7 }' | calc_total)
11534         (( $ranum <= $ramax )) ||
11535                 error "read-ahead pages is $ranum more than $ramax"
11536         rm -rf $file || error "failed to remove $file"
11537 }
11538
11539 test_101m()
11540 {
11541         local file=$DIR/$tfile
11542         local ramax
11543         local ranum
11544         local size
11545         local iosz
11546
11547         check_set_fallocate_or_skip
11548         stack_trap "rm -f $file" EXIT
11549
11550         test_readahead_base 4096
11551
11552         # file size: 16K = 16384
11553         test_readahead_base 16384
11554         test_readahead_base 16385
11555         test_readahead_base 16383
11556
11557         # file size: 1M + 1 = 1048576 + 1
11558         test_readahead_base 1048577
11559         # file size: 1M + 16K
11560         test_readahead_base $((1048576 + 16384))
11561
11562         # file size: stripe_size * (stripe_count - 1) + 16K
11563         $LFS setstripe -c -1 $file || error "failed to setstripe $file"
11564         test_readahead_base $((1048576 * (OSTCOUNT - 1) + 16384))
11565         # file size: stripe_size * stripe_count + 16K
11566         $LFS setstripe -c -1 $file || error "failed to setstripe $file"
11567         test_readahead_base $((1048576 * OSTCOUNT + 16384))
11568         # file size: 2 * stripe_size * stripe_count + 16K
11569         $LFS setstripe -c -1 $file || error "failed to setstripe $file"
11570         test_readahead_base $((2 * 1048576 * OSTCOUNT + 16384))
11571 }
11572 run_test 101m "read ahead for small file and last stripe of the file"
11573
11574 setup_test102() {
11575         test_mkdir $DIR/$tdir
11576         chown $RUNAS_ID $DIR/$tdir
11577         STRIPE_SIZE=65536
11578         STRIPE_OFFSET=1
11579         STRIPE_COUNT=$OSTCOUNT
11580         [[ $OSTCOUNT -gt 4 ]] && STRIPE_COUNT=4
11581
11582         trap cleanup_test102 EXIT
11583         cd $DIR
11584         $1 $LFS setstripe -S $STRIPE_SIZE -i $STRIPE_OFFSET -c $STRIPE_COUNT $tdir
11585         cd $DIR/$tdir
11586         for num in 1 2 3 4; do
11587                 for count in $(seq 1 $STRIPE_COUNT); do
11588                         for idx in $(seq 0 $[$STRIPE_COUNT - 1]); do
11589                                 local size=`expr $STRIPE_SIZE \* $num`
11590                                 local file=file"$num-$idx-$count"
11591                                 $1 $LFS setstripe -S $size -i $idx -c $count $file
11592                         done
11593                 done
11594         done
11595
11596         cd $DIR
11597         $1 tar cf $TMP/f102.tar $tdir --xattrs
11598 }
11599
11600 cleanup_test102() {
11601         trap 0
11602         rm -f $TMP/f102.tar
11603         rm -rf $DIR/d0.sanity/d102
11604 }
11605
11606 test_102a() {
11607         [ "$UID" != 0 ] && skip "must run as root"
11608         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep xattr)" ] &&
11609                 skip_env "must have user_xattr"
11610
11611         [ -z "$(which setfattr 2>/dev/null)" ] &&
11612                 skip_env "could not find setfattr"
11613
11614         local testfile=$DIR/$tfile
11615
11616         touch $testfile
11617         echo "set/get xattr..."
11618         setfattr -n trusted.name1 -v value1 $testfile ||
11619                 error "setfattr -n trusted.name1=value1 $testfile failed"
11620         getfattr -n trusted.name1 $testfile 2> /dev/null |
11621           grep "trusted.name1=.value1" ||
11622                 error "$testfile missing trusted.name1=value1"
11623
11624         setfattr -n user.author1 -v author1 $testfile ||
11625                 error "setfattr -n user.author1=author1 $testfile failed"
11626         getfattr -n user.author1 $testfile 2> /dev/null |
11627           grep "user.author1=.author1" ||
11628                 error "$testfile missing trusted.author1=author1"
11629
11630         echo "listxattr..."
11631         setfattr -n trusted.name2 -v value2 $testfile ||
11632                 error "$testfile unable to set trusted.name2"
11633         setfattr -n trusted.name3 -v value3 $testfile ||
11634                 error "$testfile unable to set trusted.name3"
11635         [ $(getfattr -d -m "^trusted" $testfile 2> /dev/null |
11636             grep "trusted.name" | wc -l) -eq 3 ] ||
11637                 error "$testfile missing 3 trusted.name xattrs"
11638
11639         setfattr -n user.author2 -v author2 $testfile ||
11640                 error "$testfile unable to set user.author2"
11641         setfattr -n user.author3 -v author3 $testfile ||
11642                 error "$testfile unable to set user.author3"
11643         [ $(getfattr -d -m "^user" $testfile 2> /dev/null |
11644             grep "user.author" | wc -l) -eq 3 ] ||
11645                 error "$testfile missing 3 user.author xattrs"
11646
11647         echo "remove xattr..."
11648         setfattr -x trusted.name1 $testfile ||
11649                 error "$testfile error deleting trusted.name1"
11650         getfattr -d -m trusted $testfile 2> /dev/null | grep "trusted.name1" &&
11651                 error "$testfile did not delete trusted.name1 xattr"
11652
11653         setfattr -x user.author1 $testfile ||
11654                 error "$testfile error deleting user.author1"
11655         echo "set lustre special xattr ..."
11656         $LFS setstripe -c1 $testfile
11657         local lovea=$(getfattr -n "trusted.lov" -e hex $testfile |
11658                 awk -F "=" '/trusted.lov/ { print $2 }' )
11659         setfattr -n "trusted.lov" -v $lovea $testfile ||
11660                 error "$testfile doesn't ignore setting trusted.lov again"
11661         setfattr -n "trusted.lov" -v "invalid_value" $testfile &&
11662                 error "$testfile allow setting invalid trusted.lov"
11663         rm -f $testfile
11664 }
11665 run_test 102a "user xattr test =================================="
11666
11667 check_102b_layout() {
11668         local layout="$*"
11669         local testfile=$DIR/$tfile
11670
11671         echo "test layout '$layout'"
11672         $LFS setstripe $layout $testfile || error "setstripe failed"
11673         $LFS getstripe -y $testfile
11674
11675         echo "get/set/list trusted.lov xattr ..." # b=10930
11676         local value=$(getfattr -n trusted.lov -e hex $testfile | grep trusted)
11677         [[ "$value" =~ "trusted.lov" ]] ||
11678                 error "can't get trusted.lov from $testfile"
11679         local stripe_count_orig=$($LFS getstripe -c $testfile) ||
11680                 error "getstripe failed"
11681
11682         $MCREATE $testfile.2 || error "mcreate $testfile.2 failed"
11683
11684         value=$(cut -d= -f2 <<<$value)
11685         # LU-13168: truncated xattr should fail if short lov_user_md header
11686         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
11687                 lens="${#value}" || lens="$(seq 4 2 ${#value})"
11688         for len in $lens; do
11689                 echo "setfattr $len $testfile.2"
11690                 setfattr -n trusted.lov -v ${value:0:$len} $testfile.2 &&
11691                         [ $len -lt 66 ] && error "short xattr len=$len worked"
11692         done
11693         local stripe_size=$($LFS getstripe -S $testfile.2)
11694         local stripe_count=$($LFS getstripe -c $testfile.2)
11695         [[ $stripe_size -eq 65536 ]] ||
11696                 error "stripe size $stripe_size != 65536"
11697         [[ $stripe_count -eq $stripe_count_orig ]] ||
11698                 error "stripe count $stripe_count != $stripe_count_orig"
11699         rm $testfile $testfile.2
11700 }
11701
11702 test_102b() {
11703         [ -z "$(which setfattr 2>/dev/null)" ] &&
11704                 skip_env "could not find setfattr"
11705         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11706
11707         # check plain layout
11708         check_102b_layout -S 65536 -i 1 -c $OSTCOUNT
11709
11710         # and also check composite layout
11711         check_102b_layout -E 1M -S 65536 -i 1 -c $OSTCOUNT -Eeof -S4M
11712
11713 }
11714 run_test 102b "getfattr/setfattr for trusted.lov EAs"
11715
11716 test_102c() {
11717         [ -z "$(which setfattr 2>/dev/null)" ] &&
11718                 skip_env "could not find setfattr"
11719         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11720
11721         # b10930: get/set/list lustre.lov xattr
11722         echo "get/set/list lustre.lov xattr ..."
11723         test_mkdir $DIR/$tdir
11724         chown $RUNAS_ID $DIR/$tdir
11725         local testfile=$DIR/$tdir/$tfile
11726         $RUNAS $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
11727                 error "setstripe failed"
11728         local STRIPECOUNT=$($RUNAS $LFS getstripe -c $testfile) ||
11729                 error "getstripe failed"
11730         $RUNAS getfattr -d -m "^lustre" $testfile 2> /dev/null | \
11731         grep "lustre.lov" || error "can't get lustre.lov from $testfile"
11732
11733         local testfile2=${testfile}2
11734         local value=`getfattr -n lustre.lov $testfile 2> /dev/null | \
11735                      grep "lustre.lov" |sed -e 's/[^=]\+=//'  `
11736
11737         $RUNAS $MCREATE $testfile2
11738         $RUNAS setfattr -n lustre.lov -v $value $testfile2
11739         local stripe_size=$($RUNAS $LFS getstripe -S $testfile2)
11740         local stripe_count=$($RUNAS $LFS getstripe -c $testfile2)
11741         [ $stripe_size -eq 65536 ] || error "stripe size $stripe_size != 65536"
11742         [ $stripe_count -eq $STRIPECOUNT ] ||
11743                 error "stripe count $stripe_count != $STRIPECOUNT"
11744 }
11745 run_test 102c "non-root getfattr/setfattr for lustre.lov EAs ==========="
11746
11747 compare_stripe_info1() {
11748         local stripe_index_all_zero=true
11749
11750         for num in 1 2 3 4; do
11751                 for count in $(seq 1 $STRIPE_COUNT); do
11752                         for offset in $(seq 0 $[$STRIPE_COUNT - 1]); do
11753                                 local size=$((STRIPE_SIZE * num))
11754                                 local file=file"$num-$offset-$count"
11755                                 stripe_size=$($LFS getstripe -S $PWD/$file)
11756                                 [[ $stripe_size -ne $size ]] &&
11757                                     error "$file: size $stripe_size != $size"
11758                                 stripe_count=$($LFS getstripe -c $PWD/$file)
11759                                 # allow fewer stripes to be created, ORI-601
11760                                 [[ $stripe_count -lt $(((3 * count + 3) / 4)) ]] &&
11761                                     error "$file: count $stripe_count != $count"
11762                                 stripe_index=$($LFS getstripe -i $PWD/$file)
11763                                 [[ $stripe_index -ne 0 ]] &&
11764                                         stripe_index_all_zero=false
11765                         done
11766                 done
11767         done
11768         $stripe_index_all_zero &&
11769                 error "all files are being extracted starting from OST index 0"
11770         return 0
11771 }
11772
11773 have_xattrs_include() {
11774         tar --help | grep -q xattrs-include &&
11775                 echo --xattrs-include="lustre.*"
11776 }
11777
11778 test_102d() {
11779         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11780         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11781
11782         XINC=$(have_xattrs_include)
11783         setup_test102
11784         tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
11785         cd $DIR/$tdir/$tdir
11786         compare_stripe_info1
11787 }
11788 run_test 102d "tar restore stripe info from tarfile,not keep osts"
11789
11790 test_102f() {
11791         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11792         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11793
11794         XINC=$(have_xattrs_include)
11795         setup_test102
11796         test_mkdir $DIR/$tdir.restore
11797         cd $DIR
11798         tar cf - --xattrs $tdir | tar xf - \
11799                 -C $DIR/$tdir.restore --xattrs $XINC
11800         cd $DIR/$tdir.restore/$tdir
11801         compare_stripe_info1
11802 }
11803 run_test 102f "tar copy files, not keep osts"
11804
11805 grow_xattr() {
11806         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep xattr)" ] &&
11807                 skip "must have user_xattr"
11808         [ -z "$(which setfattr 2>/dev/null)" ] &&
11809                 skip_env "could not find setfattr"
11810         [ -z "$(which getfattr 2>/dev/null)" ] &&
11811                 skip_env "could not find getfattr"
11812
11813         local xsize=${1:-1024}  # in bytes
11814         local file=$DIR/$tfile
11815         local value="$(generate_string $xsize)"
11816         local xbig=trusted.big
11817         local toobig=$2
11818
11819         touch $file
11820         log "save $xbig on $file"
11821         if [ -z "$toobig" ]
11822         then
11823                 setfattr -n $xbig -v $value $file ||
11824                         error "saving $xbig on $file failed"
11825         else
11826                 setfattr -n $xbig -v $value $file &&
11827                         error "saving $xbig on $file succeeded"
11828                 return 0
11829         fi
11830
11831         local orig=$(get_xattr_value $xbig $file)
11832         [[ "$orig" != "$value" ]] && error "$xbig different after saving $xbig"
11833
11834         local xsml=trusted.sml
11835         log "save $xsml on $file"
11836         setfattr -n $xsml -v val $file || error "saving $xsml on $file failed"
11837
11838         local new=$(get_xattr_value $xbig $file)
11839         [[ "$new" != "$orig" ]] && error "$xbig different after saving $xsml"
11840
11841         log "grow $xsml on $file"
11842         setfattr -n $xsml -v "$value" $file ||
11843                 error "growing $xsml on $file failed"
11844
11845         new=$(get_xattr_value $xbig $file)
11846         [[ "$new" != "$orig" ]] && error "$xbig different after growing $xsml"
11847         log "$xbig still valid after growing $xsml"
11848
11849         rm -f $file
11850 }
11851
11852 test_102h() { # bug 15777
11853         grow_xattr 1024
11854 }
11855 run_test 102h "grow xattr from inside inode to external block"
11856
11857 test_102ha() {
11858         large_xattr_enabled || skip_env "ea_inode feature disabled"
11859
11860         echo "setting xattr of max xattr size: $(max_xattr_size)"
11861         grow_xattr $(max_xattr_size)
11862
11863         echo "setting xattr of > max xattr size: $(max_xattr_size) + 10"
11864         echo "This should fail:"
11865         grow_xattr $(($(max_xattr_size) + 10)) 1
11866 }
11867 run_test 102ha "grow xattr from inside inode to external inode"
11868
11869 test_102i() { # bug 17038
11870         [ -z "$(which getfattr 2>/dev/null)" ] &&
11871                 skip "could not find getfattr"
11872
11873         touch $DIR/$tfile
11874         ln -s $DIR/$tfile $DIR/${tfile}link
11875         getfattr -n trusted.lov $DIR/$tfile ||
11876                 error "lgetxattr on $DIR/$tfile failed"
11877         getfattr -h -n trusted.lov $DIR/${tfile}link 2>&1 |
11878                 grep -i "no such attr" ||
11879                 error "error for lgetxattr on $DIR/${tfile}link is not ENODATA"
11880         rm -f $DIR/$tfile $DIR/${tfile}link
11881 }
11882 run_test 102i "lgetxattr test on symbolic link ============"
11883
11884 test_102j() {
11885         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11886         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11887
11888         XINC=$(have_xattrs_include)
11889         setup_test102 "$RUNAS"
11890         chown $RUNAS_ID $DIR/$tdir
11891         $RUNAS tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
11892         cd $DIR/$tdir/$tdir
11893         compare_stripe_info1 "$RUNAS"
11894 }
11895 run_test 102j "non-root tar restore stripe info from tarfile, not keep osts ==="
11896
11897 test_102k() {
11898         [ -z "$(which setfattr 2>/dev/null)" ] &&
11899                 skip "could not find setfattr"
11900
11901         touch $DIR/$tfile
11902         # b22187 just check that does not crash for regular file.
11903         setfattr -n trusted.lov $DIR/$tfile
11904         # b22187 'setfattr -n trusted.lov' should remove LOV EA for directories
11905         local test_kdir=$DIR/$tdir
11906         test_mkdir $test_kdir
11907         local default_size=$($LFS getstripe -S $test_kdir)
11908         local default_count=$($LFS getstripe -c $test_kdir)
11909         local default_offset=$($LFS getstripe -i $test_kdir)
11910         $LFS setstripe -S 65536 -i 0 -c $OSTCOUNT $test_kdir ||
11911                 error 'dir setstripe failed'
11912         setfattr -n trusted.lov $test_kdir
11913         local stripe_size=$($LFS getstripe -S $test_kdir)
11914         local stripe_count=$($LFS getstripe -c $test_kdir)
11915         local stripe_offset=$($LFS getstripe -i $test_kdir)
11916         [ $stripe_size -eq $default_size ] ||
11917                 error "stripe size $stripe_size != $default_size"
11918         [ $stripe_count -eq $default_count ] ||
11919                 error "stripe count $stripe_count != $default_count"
11920         [ $stripe_offset -eq $default_offset ] ||
11921                 error "stripe offset $stripe_offset != $default_offset"
11922         rm -rf $DIR/$tfile $test_kdir
11923 }
11924 run_test 102k "setfattr without parameter of value shouldn't cause a crash"
11925
11926 test_102l() {
11927         [ -z "$(which getfattr 2>/dev/null)" ] &&
11928                 skip "could not find getfattr"
11929
11930         # LU-532 trusted. xattr is invisible to non-root
11931         local testfile=$DIR/$tfile
11932
11933         touch $testfile
11934
11935         echo "listxattr as user..."
11936         chown $RUNAS_ID $testfile
11937         $RUNAS getfattr -d -m '.*' $testfile 2>&1 |
11938             grep -q "trusted" &&
11939                 error "$testfile trusted xattrs are user visible"
11940
11941         return 0;
11942 }
11943 run_test 102l "listxattr size test =================================="
11944
11945 test_102m() { # LU-3403 llite: error of listxattr when buffer is small
11946         local path=$DIR/$tfile
11947         touch $path
11948
11949         listxattr_size_check $path || error "listattr_size_check $path failed"
11950 }
11951 run_test 102m "Ensure listxattr fails on small bufffer ========"
11952
11953 cleanup_test102
11954
11955 getxattr() { # getxattr path name
11956         # Return the base64 encoding of the value of xattr name on path.
11957         local path=$1
11958         local name=$2
11959
11960         # # getfattr --absolute-names --encoding=base64 --name=trusted.lov $path
11961         # file: $path
11962         # trusted.lov=0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
11963         #
11964         # We print just 0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
11965
11966         getfattr --absolute-names --encoding=base64 --name=$name $path |
11967                 awk -F= -v name=$name '$1 == name {
11968                         print substr($0, index($0, "=") + 1);
11969         }'
11970 }
11971
11972 test_102n() { # LU-4101 mdt: protect internal xattrs
11973         [ -z "$(which setfattr 2>/dev/null)" ] &&
11974                 skip "could not find setfattr"
11975         if [ $MDS1_VERSION -lt $(version_code 2.5.50) ]
11976         then
11977                 skip "MDT < 2.5.50 allows setxattr on internal trusted xattrs"
11978         fi
11979
11980         local file0=$DIR/$tfile.0
11981         local file1=$DIR/$tfile.1
11982         local xattr0=$TMP/$tfile.0
11983         local xattr1=$TMP/$tfile.1
11984         local namelist="lov lma lmv link fid version som hsm"
11985         local name
11986         local value
11987
11988         rm -rf $file0 $file1 $xattr0 $xattr1
11989         touch $file0 $file1
11990
11991         # Get 'before' xattrs of $file1.
11992         getfattr --absolute-names --dump --match=- $file1 > $xattr0
11993
11994         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
11995                 namelist+=" lfsck_namespace"
11996         for name in $namelist; do
11997                 # Try to copy xattr from $file0 to $file1.
11998                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
11999
12000                 setfattr --name=trusted.$name --value="$value" $file1 ||
12001                         error "setxattr 'trusted.$name' failed"
12002
12003                 # Try to set a garbage xattr.
12004                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
12005
12006                 if [[ x$name == "xlov" ]]; then
12007                         setfattr --name=trusted.lov --value="$value" $file1 &&
12008                         error "setxattr invalid 'trusted.lov' success"
12009                 else
12010                         setfattr --name=trusted.$name --value="$value" $file1 ||
12011                                 error "setxattr invalid 'trusted.$name' failed"
12012                 fi
12013
12014                 # Try to remove the xattr from $file1. We don't care if this
12015                 # appears to succeed or fail, we just don't want there to be
12016                 # any changes or crashes.
12017                 setfattr --remove=$trusted.$name $file1 2> /dev/null
12018         done
12019
12020         if [ $MDS1_VERSION -gt $(version_code 2.6.50) ]
12021         then
12022                 name="lfsck_ns"
12023                 # Try to copy xattr from $file0 to $file1.
12024                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
12025
12026                 setfattr --name=trusted.$name --value="$value" $file1 ||
12027                         error "setxattr 'trusted.$name' failed"
12028
12029                 # Try to set a garbage xattr.
12030                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
12031
12032                 setfattr --name=trusted.$name --value="$value" $file1 ||
12033                         error "setxattr 'trusted.$name' failed"
12034
12035                 # Try to remove the xattr from $file1. We don't care if this
12036                 # appears to succeed or fail, we just don't want there to be
12037                 # any changes or crashes.
12038                 setfattr --remove=$trusted.$name $file1 2> /dev/null
12039         fi
12040
12041         # Get 'after' xattrs of file1.
12042         getfattr --absolute-names --dump --match=- $file1 > $xattr1
12043
12044         if ! diff $xattr0 $xattr1; then
12045                 error "before and after xattrs of '$file1' differ"
12046         fi
12047
12048         rm -rf $file0 $file1 $xattr0 $xattr1
12049
12050         return 0
12051 }
12052 run_test 102n "silently ignore setxattr on internal trusted xattrs"
12053
12054 test_102p() { # LU-4703 setxattr did not check ownership
12055         [ $MDS1_VERSION -lt $(version_code 2.5.56) ] &&
12056                 skip "MDS needs to be at least 2.5.56"
12057
12058         local testfile=$DIR/$tfile
12059
12060         touch $testfile
12061
12062         echo "setfacl as user..."
12063         $RUNAS setfacl -m "u:$RUNAS_ID:rwx" $testfile
12064         [ $? -ne 0 ] || error "setfacl by $RUNAS_ID was allowed on $testfile"
12065
12066         echo "setfattr as user..."
12067         setfacl -m "u:$RUNAS_ID:---" $testfile
12068         $RUNAS setfattr -x system.posix_acl_access $testfile
12069         [ $? -ne 0 ] || error "setfattr by $RUNAS_ID was allowed on $testfile"
12070 }
12071 run_test 102p "check setxattr(2) correctly fails without permission"
12072
12073 test_102q() {
12074         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] &&
12075                 skip "MDS needs to be at least 2.6.92"
12076
12077         orphan_linkea_check $DIR/$tfile || error "orphan_linkea_check"
12078 }
12079 run_test 102q "flistxattr should not return trusted.link EAs for orphans"
12080
12081 test_102r() {
12082         [ $MDS1_VERSION -lt $(version_code 2.6.93) ] &&
12083                 skip "MDS needs to be at least 2.6.93"
12084
12085         touch $DIR/$tfile || error "touch"
12086         setfattr -n user.$(basename $tfile) $DIR/$tfile || error "setfattr"
12087         getfattr -n user.$(basename $tfile) $DIR/$tfile || error "getfattr"
12088         rm $DIR/$tfile || error "rm"
12089
12090         #normal directory
12091         mkdir -p $DIR/$tdir || error "mkdir"
12092         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
12093         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
12094         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
12095                 error "$testfile error deleting user.author1"
12096         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
12097                 grep "user.$(basename $tdir)" &&
12098                 error "$tdir did not delete user.$(basename $tdir)"
12099         rmdir $DIR/$tdir || error "rmdir"
12100
12101         #striped directory
12102         test_mkdir $DIR/$tdir
12103         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
12104         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
12105         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
12106                 error "$testfile error deleting user.author1"
12107         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
12108                 grep "user.$(basename $tdir)" &&
12109                 error "$tdir did not delete user.$(basename $tdir)"
12110         rmdir $DIR/$tdir || error "rm striped dir"
12111 }
12112 run_test 102r "set EAs with empty values"
12113
12114 test_102s() {
12115         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
12116                 skip "MDS needs to be at least 2.11.52"
12117
12118         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
12119
12120         save_lustre_params client "llite.*.xattr_cache" > $save
12121
12122         for cache in 0 1; do
12123                 lctl set_param llite.*.xattr_cache=$cache
12124
12125                 rm -f $DIR/$tfile
12126                 touch $DIR/$tfile || error "touch"
12127                 for prefix in lustre security system trusted user; do
12128                         # Note getxattr() may fail with 'Operation not
12129                         # supported' or 'No such attribute' depending
12130                         # on prefix and cache.
12131                         getfattr -n $prefix.n102s $DIR/$tfile &&
12132                                 error "getxattr '$prefix.n102s' should fail (cache = $cache)"
12133                 done
12134         done
12135
12136         restore_lustre_params < $save
12137 }
12138 run_test 102s "getting nonexistent xattrs should fail"
12139
12140 test_102t() {
12141         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
12142                 skip "MDS needs to be at least 2.11.52"
12143
12144         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
12145
12146         save_lustre_params client "llite.*.xattr_cache" > $save
12147
12148         for cache in 0 1; do
12149                 lctl set_param llite.*.xattr_cache=$cache
12150
12151                 for buf_size in 0 256; do
12152                         rm -f $DIR/$tfile
12153                         touch $DIR/$tfile || error "touch"
12154                         setfattr -n user.multiop $DIR/$tfile
12155                         $MULTIOP $DIR/$tfile oa$buf_size ||
12156                                 error "cannot get zero length xattr value (buf_size = $buf_size)"
12157                 done
12158         done
12159
12160         restore_lustre_params < $save
12161 }
12162 run_test 102t "zero length xattr values handled correctly"
12163
12164 run_acl_subtest()
12165 {
12166         local test=$LUSTRE/tests/acl/$1.test
12167         local tmp=$(mktemp -t $1-XXXXXX).test
12168         local bin=$2
12169         local dmn=$3
12170         local grp=$4
12171         local nbd=$5
12172         export LANG=C
12173
12174
12175         local sedusers="-e s/bin/$bin/g -e s/daemon/$dmn/g"
12176         local sedgroups="-e s/:users/:$grp/g"
12177         [[ -z "$nbd" ]] || sedusers+=" -e s/nobody/$nbd/g"
12178
12179         sed $sedusers $sedgroups < $test > $tmp
12180         stack_trap "rm -f $tmp"
12181         [[ -s $tmp ]] || error "sed failed to create test script"
12182
12183         echo "performing $1 with bin='$bin' daemon='$dmn' users='$grp'..."
12184         $LUSTRE/tests/acl/run $tmp || error "run_acl_subtest '$1' failed"
12185 }
12186
12187 test_103a() {
12188         [ "$UID" != 0 ] && skip "must run as root"
12189         $GSS && skip_env "could not run under gss"
12190         [[ "$(lctl get_param -n mdc.*-mdc-*.connect_flags)" =~ "acl" ]] ||
12191                 skip_env "must have acl enabled"
12192         which setfacl || skip_env "could not find setfacl"
12193         remote_mds_nodsh && skip "remote MDS with nodsh"
12194
12195         ACLBIN=${ACLBIN:-"bin"}
12196         ACLDMN=${ACLDMN:-"daemon"}
12197         ACLGRP=${ACLGRP:-"users"}
12198         ACLNBD=${ACLNBD:-"nobody"}
12199
12200         if ! id $ACLBIN ||
12201            [[ "$(id -u $ACLBIN)" != "$(do_facet mds1 id -u $ACLBIN)" ]]; then
12202                 echo "bad 'bin' user '$ACLBIN', using '$USER0'"
12203                 ACLBIN=$USER0
12204                 if ! id $ACLBIN ; then
12205                         cat /etc/passwd
12206                         skip_env "can't find suitable ACL 'bin' $ACLBIN"
12207                 fi
12208         fi
12209         if ! id $ACLDMN || (( $(id -u $ACLDMN) < $(id -u $ACLBIN) )) ||
12210            [[ "$(id -u $ACLDMN)" != "$(do_facet mds1 id -u $ACLDMN)" ]]; then
12211                 echo "bad 'daemon' user '$ACLDMN', using '$USER1'"
12212                 ACLDMN=$USER1
12213                 if ! id $ACLDMN ; then
12214                         cat /etc/passwd
12215                         skip_env "can't find suitable ACL 'daemon' $ACLDMN"
12216                 fi
12217         fi
12218         if ! getent group $ACLGRP; then
12219                 echo "missing 'users' group '$ACLGRP', using '$TSTUSR'"
12220                 ACLGRP="$TSTUSR"
12221                 if ! getent group $ACLGRP; then
12222                         echo "cannot find group '$ACLGRP', adding it"
12223                         cat /etc/group
12224                         add_group 60000 $ACLGRP
12225                 fi
12226         fi
12227
12228         local bingid=$(getent group $ACLBIN | cut -d: -f 3)
12229         local dmngid=$(getent group $ACLDMN | cut -d: -f 3)
12230         local grpgid=$(getent group $ACLGRP | cut -d: -f 3)
12231
12232         if (( $bingid > $grpgid || $dmngid > $grpgid )); then
12233                 echo "group '$ACLGRP' has low gid=$grpgid, use '$TSTUSR'"
12234                 ACLGRP="$TSTUSR"
12235                 if ! getent group $ACLGRP; then
12236                         echo "cannot find group '$ACLGRP', adding it"
12237                         cat /etc/group
12238                         add_group 60000 $ACLGRP
12239                 fi
12240                 grpgid=$(getent group $ACLGRP | cut -d: -f 3)
12241                 if (( $bingid > $grpgid || $dmngid > $grpgid )); then
12242                         cat /etc/group
12243                         skip_env "$ACLGRP gid=$grpgid less than $bingid|$dmngid"
12244                 fi
12245         fi
12246
12247         gpasswd -a $ACLDMN $ACLBIN ||
12248                 error "setting client group failed"             # LU-5641
12249         do_facet mds1 gpasswd -a $ACLDMN $ACLBIN ||
12250                 error "setting MDS group failed"                # LU-5641
12251
12252         declare -a identity_old
12253
12254         for num in $(seq $MDSCOUNT); do
12255                 switch_identity $num true || identity_old[$num]=$?
12256         done
12257
12258         SAVE_UMASK=$(umask)
12259         umask 0022
12260         mkdir -p $DIR/$tdir
12261         cd $DIR/$tdir
12262
12263         run_acl_subtest cp $ACLBIN $ACLDMN $ACLGRP
12264         run_acl_subtest getfacl-noacl $ACLBIN $ACLDMN $ACLGRP
12265         run_acl_subtest misc $ACLBIN $ACLDMN $ACLGRP
12266         run_acl_subtest permissions $ACLBIN $ACLDMN $ACLGRP
12267         # LU-1482 mdd: Setting xattr are properly checked with and without ACLs
12268         # CentOS7- uses nobody=99, while newer distros use nobody=65534
12269         if ! id -u $ACLNBD ||
12270            (( $(id -u nobody) != $(do_facet mds1 id -u nobody) )); then
12271                 ACLNBD="nfsnobody"
12272                 if ! id -u $ACLNBD; then
12273                         ACLNBD=""
12274                 fi
12275         fi
12276         if [[ -n "$ACLNBD" ]] && ! getent group $ACLNBD; then
12277                 add_group $(id -u $ACLNBD) $ACLNBD
12278                 if ! getent group $ACLNBD; then
12279                         ACLNBD=""
12280                 fi
12281         fi
12282         if (( $MDS1_VERSION > $(version_code 2.8.55) )) &&
12283            [[ -n "$ACLNBD" ]] && which setfattr; then
12284                 run_acl_subtest permissions_xattr \
12285                         $ACLBIN $ACLDMN $ACLGRP $ACLNBD
12286         elif [[ -z "$ACLNBD" ]]; then
12287                 echo "skip 'permission_xattr' test - missing 'nobody' user/grp"
12288         else
12289                 echo "skip 'permission_xattr' test - missing setfattr command"
12290         fi
12291         run_acl_subtest setfacl $ACLBIN $ACLDMN $ACLGRP
12292
12293         # inheritance test got from HP
12294         cp $LUSTRE/tests/acl/make-tree . || error "cannot copy make-tree"
12295         chmod +x make-tree || error "chmod +x failed"
12296         run_acl_subtest inheritance $ACLBIN $ACLDMN $ACLGRP
12297         rm -f make-tree
12298
12299         echo "LU-974 ignore umask when acl is enabled..."
12300         run_acl_subtest 974 $ACLBIN $ACLDMN $ACLGRP
12301         if [ $MDSCOUNT -ge 2 ]; then
12302                 run_acl_subtest 974_remote $ACLBIN $ACLDMN $ACLGRP
12303         fi
12304
12305         echo "LU-2561 newly created file is same size as directory..."
12306         if [ "$mds1_FSTYPE" != "zfs" ]; then
12307                 run_acl_subtest 2561 $ACLBIN $ACLDMN $ACLGRP
12308         else
12309                 run_acl_subtest 2561_zfs $ACLBIN $ACLDMN $ACLGRP
12310         fi
12311
12312         run_acl_subtest 4924 $ACLBIN $ACLDMN $ACLGRP
12313
12314         cd $SAVE_PWD
12315         umask $SAVE_UMASK
12316
12317         for num in $(seq $MDSCOUNT); do
12318                 if [ "${identity_old[$num]}" = 1 ]; then
12319                         switch_identity $num false || identity_old[$num]=$?
12320                 fi
12321         done
12322 }
12323 run_test 103a "acl test"
12324
12325 test_103b() {
12326         declare -a pids
12327         local U
12328
12329         for U in {0..511}; do
12330                 {
12331                 local O=$(printf "%04o" $U)
12332
12333                 umask $(printf "%04o" $((511 ^ $O)))
12334                 $LFS setstripe -c 1 $DIR/$tfile.s$O
12335                 local S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.s$O))
12336
12337                 (( $S == ($O & 0666) )) ||
12338                         error "lfs setstripe $DIR/$tfile.s$O '$S' != '$O'"
12339
12340                 $LFS setstripe -E16M -c 1 -E1G -S4M $DIR/$tfile.p$O
12341                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.p$O))
12342                 (( $S == ($O & 0666) )) ||
12343                         error "lfs setstripe -E $DIR/$tfile.p$O '$S' != '$O'"
12344
12345                 $LFS setstripe -N2 -c 1 $DIR/$tfile.m$O
12346                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.m$O))
12347                 (( $S == ($O & 0666) )) ||
12348                         error "lfs setstripe -N2 $DIR/$tfile.m$O '$S' != '$O'"
12349                 rm -f $DIR/$tfile.[smp]$0
12350                 } &
12351                 local pid=$!
12352
12353                 # limit the concurrently running threads to 64. LU-11878
12354                 local idx=$((U % 64))
12355                 [ -z "${pids[idx]}" ] || wait ${pids[idx]}
12356                 pids[idx]=$pid
12357         done
12358         wait
12359 }
12360 run_test 103b "umask lfs setstripe"
12361
12362 test_103c() {
12363         mkdir -p $DIR/$tdir
12364         cp -rp $DIR/$tdir $DIR/$tdir.bak
12365
12366         [ -n "$(getfattr -d -m. $DIR/$tdir | grep posix_acl_default)" ] &&
12367                 error "$DIR/$tdir shouldn't contain default ACL"
12368         [ -n "$(getfattr -d -m. $DIR/$tdir.bak | grep posix_acl_default)" ] &&
12369                 error "$DIR/$tdir.bak shouldn't contain default ACL"
12370         true
12371 }
12372 run_test 103c "'cp -rp' won't set empty acl"
12373
12374 test_103e() {
12375         local numacl
12376         local fileacl
12377         local saved_debug=$($LCTL get_param -n debug)
12378
12379         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
12380                 skip "MDS needs to be at least 2.14.52"
12381
12382         large_xattr_enabled || skip_env "ea_inode feature disabled"
12383
12384         mkdir -p $DIR/$tdir
12385         # add big LOV EA to cause reply buffer overflow earlier
12386         $LFS setstripe -C 1000 $DIR/$tdir
12387         lctl set_param mdc.*-mdc*.stats=clear
12388
12389         $LCTL set_param debug=0
12390         stack_trap "$LCTL set_param debug=\"$saved_debug\"" EXIT
12391         stack_trap "$LCTL get_param mdc.*-mdc*.stats" EXIT
12392
12393         # add a large number of default ACLs (expect 8000+ for 2.13+)
12394         for U in {2..7000}; do
12395                 setfacl -d -m user:$U:rwx $DIR/$tdir ||
12396                         error "Able to add just $U default ACLs"
12397         done
12398         numacl=$(getfacl $DIR/$tdir |& grep -c "default:user")
12399         echo "$numacl default ACLs created"
12400
12401         stat $DIR/$tdir || error "Cannot stat directory"
12402         # check file creation
12403         touch $DIR/$tdir/$tfile ||
12404                 error "failed to create $tfile with $numacl default ACLs"
12405         stat $DIR/$tdir/$tfile  || error "Cannot stat file"
12406         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
12407         echo "$fileacl ACLs were inherited"
12408         (( $fileacl == $numacl )) ||
12409                 error "Not all default ACLs were inherited: $numacl != $fileacl"
12410         # check that new ACLs creation adds new ACLs to inherited ACLs
12411         setfacl -m user:19000:rwx $DIR/$tdir/$tfile ||
12412                 error "Cannot set new ACL"
12413         numacl=$((numacl + 1))
12414         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
12415         (( $fileacl == $numacl )) ||
12416                 error "failed to add new ACL: $fileacl != $numacl as expected"
12417         # adds more ACLs to a file to reach their maximum at 8000+
12418         numacl=0
12419         for U in {20000..25000}; do
12420                 setfacl -m user:$U:rwx $DIR/$tdir/$tfile || break
12421                 numacl=$((numacl + 1))
12422         done
12423         echo "Added $numacl more ACLs to the file"
12424         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
12425         echo "Total $fileacl ACLs in file"
12426         stat $DIR/$tdir/$tfile > /dev/null || error "Cannot stat file"
12427         rm -f $DIR/$tdir/$tfile || error "Cannot remove file"
12428         rmdir $DIR/$tdir || error "Cannot remove directory"
12429 }
12430 run_test 103e "inheritance of big amount of default ACLs"
12431
12432 test_103f() {
12433         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
12434                 skip "MDS needs to be at least 2.14.51"
12435
12436         large_xattr_enabled || skip_env "ea_inode feature disabled"
12437
12438         # enable changelog to consume more internal MDD buffers
12439         changelog_register
12440
12441         mkdir -p $DIR/$tdir
12442         # add big LOV EA
12443         $LFS setstripe -C 1000 $DIR/$tdir
12444         setfacl -d -m user:$U:rwx $DIR/$tdir || error "Cannot add default ACLs"
12445         mkdir $DIR/$tdir/inherited || error "failed to create subdirectory"
12446         rmdir $DIR/$tdir/inherited || error "Cannot remove subdirectory"
12447         rmdir $DIR/$tdir || error "Cannot remove directory"
12448 }
12449 run_test 103f "changelog doesn't interfere with default ACLs buffers"
12450
12451 test_104a() {
12452         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12453
12454         touch $DIR/$tfile
12455         lfs df || error "lfs df failed"
12456         lfs df -ih || error "lfs df -ih failed"
12457         lfs df -h $DIR || error "lfs df -h $DIR failed"
12458         lfs df -i $DIR || error "lfs df -i $DIR failed"
12459         lfs df $DIR/$tfile || error "lfs df $DIR/$tfile failed"
12460         lfs df -ih $DIR/$tfile || error "lfs df -ih $DIR/$tfile failed"
12461
12462         local OSC=$(lctl dl | grep OST0000-osc-[^M] | awk '{ print $4 }')
12463         lctl --device %$OSC deactivate
12464         lfs df || error "lfs df with deactivated OSC failed"
12465         lctl --device %$OSC activate
12466         # wait the osc back to normal
12467         wait_osc_import_ready client ost
12468
12469         lfs df || error "lfs df with reactivated OSC failed"
12470         rm -f $DIR/$tfile
12471 }
12472 run_test 104a "lfs df [-ih] [path] test ========================="
12473
12474 test_104b() {
12475         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12476         [ $RUNAS_ID -eq $UID ] &&
12477                 skip_env "RUNAS_ID = UID = $UID -- skipping"
12478
12479         denied_cnt=$(($($RUNAS $LFS check servers 2>&1 |
12480                         grep "Permission denied" | wc -l)))
12481         if [ $denied_cnt -ne 0 ]; then
12482                 error "lfs check servers test failed"
12483         fi
12484 }
12485 run_test 104b "$RUNAS lfs check servers test ===================="
12486
12487 #
12488 # Verify $1 is within range of $2.
12489 # Success when $1 is within range. That is, when $1 is >= 2% of $2 and
12490 # $1 is <= 2% of $2. Else Fail.
12491 #
12492 value_in_range() {
12493         # Strip all units (M, G, T)
12494         actual=$(echo $1 | tr -d A-Z)
12495         expect=$(echo $2 | tr -d A-Z)
12496
12497         expect_lo=$(($expect * 98 / 100)) # 2% below
12498         expect_hi=$(($expect * 102 / 100)) # 2% above
12499
12500         # permit 2% drift above and below
12501         (( $actual >= $expect_lo && $actual <= $expect_hi ))
12502 }
12503
12504 test_104c() {
12505         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12506         [ "$ost1_FSTYPE" == "zfs" ] || skip "zfs only test"
12507
12508         local ost_param="osd-zfs.$FSNAME-OST0000."
12509         local mdt_param="osd-zfs.$FSNAME-MDT0000."
12510         local ofacets=$(get_facets OST)
12511         local mfacets=$(get_facets MDS)
12512         local saved_ost_blocks=
12513         local saved_mdt_blocks=
12514
12515         echo "Before recordsize change"
12516         lfs_df=($($LFS df -h | grep "filesystem_summary:"))
12517         df=($(df -h | grep "$MOUNT"$))
12518
12519         # For checking.
12520         echo "lfs output : ${lfs_df[*]}"
12521         echo "df  output : ${df[*]}"
12522
12523         for facet in ${ofacets//,/ }; do
12524                 if [ -z $saved_ost_blocks ]; then
12525                         saved_ost_blocks=$(do_facet $facet \
12526                                 lctl get_param -n $ost_param.blocksize)
12527                         echo "OST Blocksize: $saved_ost_blocks"
12528                 fi
12529                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
12530                 do_facet $facet zfs set recordsize=32768 $ost
12531         done
12532
12533         # BS too small. Sufficient for functional testing.
12534         for facet in ${mfacets//,/ }; do
12535                 if [ -z $saved_mdt_blocks ]; then
12536                         saved_mdt_blocks=$(do_facet $facet \
12537                                 lctl get_param -n $mdt_param.blocksize)
12538                         echo "MDT Blocksize: $saved_mdt_blocks"
12539                 fi
12540                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
12541                 do_facet $facet zfs set recordsize=32768 $mdt
12542         done
12543
12544         # Give new values chance to reflect change
12545         sleep 2
12546
12547         echo "After recordsize change"
12548         lfs_df_after=($($LFS df -h | grep "filesystem_summary:"))
12549         df_after=($(df -h | grep "$MOUNT"$))
12550
12551         # For checking.
12552         echo "lfs output : ${lfs_df_after[*]}"
12553         echo "df  output : ${df_after[*]}"
12554
12555         # Verify lfs df
12556         value_in_range ${lfs_df_after[1]%.*} ${lfs_df[1]%.*} ||
12557                 error "lfs_df bytes: ${lfs_df_after[1]%.*} != ${lfs_df[1]%.*}"
12558         value_in_range ${lfs_df_after[2]%.*} ${lfs_df[2]%.*} ||
12559                 error "lfs_df used: ${lfs_df_after[2]%.*} != ${lfs_df[2]%.*}"
12560         value_in_range ${lfs_df_after[3]%.*} ${lfs_df[3]%.*} ||
12561                 error "lfs_df avail: ${lfs_df_after[3]%.*} != ${lfs_df[3]%.*}"
12562
12563         # Verify df
12564         value_in_range ${df_after[1]%.*} ${df[1]%.*} ||
12565                 error "df bytes: ${df_after[1]%.*} != ${df[1]%.*}"
12566         value_in_range ${df_after[2]%.*} ${df[2]%.*} ||
12567                 error "df used: ${df_after[2]%.*} != ${df[2]%.*}"
12568         value_in_range ${df_after[3]%.*} ${df[3]%.*} ||
12569                 error "df avail: ${df_after[3]%.*} != ${df[3]%.*}"
12570
12571         # Restore MDT recordize back to original
12572         for facet in ${mfacets//,/ }; do
12573                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
12574                 do_facet $facet zfs set recordsize=$saved_mdt_blocks $mdt
12575         done
12576
12577         # Restore OST recordize back to original
12578         for facet in ${ofacets//,/ }; do
12579                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
12580                 do_facet $facet zfs set recordsize=$saved_ost_blocks $ost
12581         done
12582
12583         return 0
12584 }
12585 run_test 104c "Verify df vs lfs_df stays same after recordsize change"
12586
12587 test_104d() {
12588         (( $RUNAS_ID != $UID )) ||
12589                 skip_env "RUNAS_ID = UID = $UID -- skipping"
12590
12591         (( $CLIENT_VERSION >= $(version_code 2.15.51) )) ||
12592                 skip "lustre version doesn't support lctl dl with non-root"
12593
12594         # debugfs only allows root users to access files, so the
12595         # previous move of the "devices" file to debugfs broke
12596         # "lctl dl" for non-root users. The LU-9680 Netlink
12597         # interface again allows non-root users to list devices.
12598         [ "$($RUNAS $LCTL dl | wc -l)" -ge 3 ] ||
12599                 error "lctl dl doesn't work for non root"
12600
12601         ost_count="$($RUNAS $LCTL dl | grep $FSNAME-OST* | wc -l)"
12602         [ "$ost_count" -eq $OSTCOUNT ]  ||
12603                 error "lctl dl reports wrong number of OST devices"
12604
12605         mdt_count="$($RUNAS $LCTL dl | grep $FSNAME-MDT* | wc -l)"
12606         [ "$mdt_count" -eq $MDSCOUNT ]  ||
12607                 error "lctl dl reports wrong number of MDT devices"
12608 }
12609 run_test 104d "$RUNAS lctl dl test"
12610
12611 test_105a() {
12612         # doesn't work on 2.4 kernels
12613         touch $DIR/$tfile
12614         if $(flock_is_enabled); then
12615                 flocks_test 1 on -f $DIR/$tfile || error "fail flock on"
12616         else
12617                 flocks_test 1 off -f $DIR/$tfile || error "fail flock off"
12618         fi
12619         rm -f $DIR/$tfile
12620 }
12621 run_test 105a "flock when mounted without -o flock test ========"
12622
12623 test_105b() {
12624         touch $DIR/$tfile
12625         if $(flock_is_enabled); then
12626                 flocks_test 1 on -c $DIR/$tfile || error "fail flock on"
12627         else
12628                 flocks_test 1 off -c $DIR/$tfile || error "fail flock off"
12629         fi
12630         rm -f $DIR/$tfile
12631 }
12632 run_test 105b "fcntl when mounted without -o flock test ========"
12633
12634 test_105c() {
12635         touch $DIR/$tfile
12636         if $(flock_is_enabled); then
12637                 flocks_test 1 on -l $DIR/$tfile || error "fail flock on"
12638         else
12639                 flocks_test 1 off -l $DIR/$tfile || error "fail flock off"
12640         fi
12641         rm -f $DIR/$tfile
12642 }
12643 run_test 105c "lockf when mounted without -o flock test"
12644
12645 test_105d() { # bug 15924
12646         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12647
12648         test_mkdir $DIR/$tdir
12649         flock_is_enabled || skip_env "mount w/o flock enabled"
12650         #define OBD_FAIL_LDLM_CP_CB_WAIT  0x315
12651         $LCTL set_param fail_loc=0x80000315
12652         flocks_test 2 $DIR/$tdir
12653 }
12654 run_test 105d "flock race (should not freeze) ========"
12655
12656 test_105e() { # bug 22660 && 22040
12657         flock_is_enabled || skip_env "mount w/o flock enabled"
12658
12659         touch $DIR/$tfile
12660         flocks_test 3 $DIR/$tfile
12661 }
12662 run_test 105e "Two conflicting flocks from same process"
12663
12664 test_106() { #bug 10921
12665         test_mkdir $DIR/$tdir
12666         $DIR/$tdir && error "exec $DIR/$tdir succeeded"
12667         chmod 777 $DIR/$tdir || error "chmod $DIR/$tdir failed"
12668 }
12669 run_test 106 "attempt exec of dir followed by chown of that dir"
12670
12671 test_107() {
12672         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12673
12674         CDIR=`pwd`
12675         local file=core
12676
12677         cd $DIR
12678         rm -f $file
12679
12680         local save_pattern=$(sysctl -n kernel.core_pattern)
12681         local save_uses_pid=$(sysctl -n kernel.core_uses_pid)
12682         sysctl -w kernel.core_pattern=$file
12683         sysctl -w kernel.core_uses_pid=0
12684
12685         ulimit -c unlimited
12686         sleep 60 &
12687         SLEEPPID=$!
12688
12689         sleep 1
12690
12691         kill -s 11 $SLEEPPID
12692         wait $SLEEPPID
12693         if [ -e $file ]; then
12694                 size=`stat -c%s $file`
12695                 [ $size -eq 0 ] && error "Fail to create core file $file"
12696         else
12697                 error "Fail to create core file $file"
12698         fi
12699         rm -f $file
12700         sysctl -w kernel.core_pattern=$save_pattern
12701         sysctl -w kernel.core_uses_pid=$save_uses_pid
12702         cd $CDIR
12703 }
12704 run_test 107 "Coredump on SIG"
12705
12706 test_110() {
12707         test_mkdir $DIR/$tdir
12708         test_mkdir $DIR/$tdir/$(str_repeat 'a' 255)
12709         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/$(str_repeat 'b' 256) &&
12710                 error "mkdir with 256 char should fail, but did not"
12711         touch $DIR/$tdir/$(str_repeat 'x' 255) ||
12712                 error "create with 255 char failed"
12713         touch $DIR/$tdir/$(str_repeat 'y' 256) &&
12714                 error "create with 256 char should fail, but did not"
12715
12716         ls -l $DIR/$tdir
12717         rm -rf $DIR/$tdir
12718 }
12719 run_test 110 "filename length checking"
12720
12721 test_116a() { # was previously test_116()
12722         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12723         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12724         remote_mds_nodsh && skip "remote MDS with nodsh"
12725
12726         echo -n "Free space priority "
12727         do_facet $SINGLEMDS lctl get_param -n lo[vd].*-mdtlov.qos_prio_free |
12728                 head -n1
12729         declare -a AVAIL
12730         free_min_max
12731
12732         [ $MINV -eq 0 ] && skip "no free space in OST$MINI, skip"
12733         [ $MINV -gt 10000000 ] && skip "too much free space in OST$MINI, skip"
12734         stack_trap simple_cleanup_common
12735
12736         # Check if we need to generate uneven OSTs
12737         test_mkdir -p $DIR/$tdir/OST${MINI}
12738         local FILL=$((MINV / 4))
12739         local DIFF=$((MAXV - MINV))
12740         local DIFF2=$((DIFF * 100 / MINV))
12741
12742         local threshold=$(do_facet $SINGLEMDS \
12743                 lctl get_param -n *.*MDT0000-mdtlov.qos_threshold_rr | head -n1)
12744         threshold=${threshold%%%}
12745         echo -n "Check for uneven OSTs: "
12746         echo -n "diff=${DIFF}KB (${DIFF2}%) must be > ${threshold}% ..."
12747
12748         if [[ $DIFF2 -gt $threshold ]]; then
12749                 echo "ok"
12750                 echo "Don't need to fill OST$MINI"
12751         else
12752                 # generate uneven OSTs. Write 2% over the QOS threshold value
12753                 echo "no"
12754                 DIFF=$((threshold - DIFF2 + 2))
12755                 DIFF2=$((MINV * DIFF / 100))
12756                 echo "Fill $DIFF% remaining space in OST$MINI with ${DIFF2}KB"
12757                 $LFS setstripe -i $MINI -c 1 $DIR/$tdir/OST${MINI} ||
12758                         error "setstripe failed"
12759                 DIFF=$((DIFF2 / 2048))
12760                 i=0
12761                 while [ $i -lt $DIFF ]; do
12762                         i=$((i + 1))
12763                         dd if=/dev/zero of=$DIR/$tdir/OST${MINI}/$tfile-$i \
12764                                 bs=2M count=1 2>/dev/null
12765                         echo -n .
12766                 done
12767                 echo .
12768                 sync
12769                 sleep_maxage
12770                 free_min_max
12771         fi
12772
12773         DIFF=$((MAXV - MINV))
12774         DIFF2=$((DIFF * 100 / MINV))
12775         echo -n "diff=$DIFF=$DIFF2% must be > $threshold% for QOS mode..."
12776         if [ $DIFF2 -gt $threshold ]; then
12777                 echo "ok"
12778         else
12779                 skip "QOS imbalance criteria not met"
12780         fi
12781
12782         MINI1=$MINI
12783         MINV1=$MINV
12784         MAXI1=$MAXI
12785         MAXV1=$MAXV
12786
12787         # now fill using QOS
12788         $LFS setstripe -c 1 $DIR/$tdir
12789         FILL=$((FILL / 200))
12790         if [ $FILL -gt 600 ]; then
12791                 FILL=600
12792         fi
12793         echo "writing $FILL files to QOS-assigned OSTs"
12794         i=0
12795         while [ $i -lt $FILL ]; do
12796                 i=$((i + 1))
12797                 dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=200k \
12798                         count=1 2>/dev/null
12799                 echo -n .
12800         done
12801         echo "wrote $i 200k files"
12802         sync
12803         sleep_maxage
12804
12805         echo "Note: free space may not be updated, so measurements might be off"
12806         free_min_max
12807         DIFF2=$((MAXV - MINV))
12808         echo "free space delta: orig $DIFF final $DIFF2"
12809         [ $DIFF2 -gt $DIFF ] && echo "delta got worse!"
12810         DIFF=$((MINV1 - ${AVAIL[$MINI1]}))
12811         echo "Wrote ${DIFF}KB to smaller OST $MINI1"
12812         DIFF2=$((MAXV1 - ${AVAIL[$MAXI1]}))
12813         echo "Wrote ${DIFF2}KB to larger OST $MAXI1"
12814         if [[ $DIFF -gt 0 ]]; then
12815                 FILL=$((DIFF2 * 100 / DIFF - 100))
12816                 echo "Wrote ${FILL}% more data to larger OST $MAXI1"
12817         fi
12818
12819         # Figure out which files were written where
12820         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
12821                awk '/'$MINI1': / {print $2; exit}')
12822         echo $UUID
12823         MINC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
12824         echo "$MINC files created on smaller OST $MINI1"
12825         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
12826                awk '/'$MAXI1': / {print $2; exit}')
12827         echo $UUID
12828         MAXC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
12829         echo "$MAXC files created on larger OST $MAXI1"
12830         if [[ $MINC -gt 0 ]]; then
12831                 FILL=$((MAXC * 100 / MINC - 100))
12832                 echo "Wrote ${FILL}% more files to larger OST $MAXI1"
12833         fi
12834         [[ $MAXC -gt $MINC ]] ||
12835                 error_ignore LU-9 "stripe QOS didn't balance free space"
12836 }
12837 run_test 116a "stripe QOS: free space balance ==================="
12838
12839 test_116b() { # LU-2093
12840         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12841         remote_mds_nodsh && skip "remote MDS with nodsh"
12842
12843 #define OBD_FAIL_MDS_OSC_CREATE_FAIL     0x147
12844         local old_rr=$(do_facet $SINGLEMDS lctl get_param -n \
12845                        lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr | head -1)
12846         [ -z "$old_rr" ] && skip "no QOS"
12847         do_facet $SINGLEMDS lctl set_param \
12848                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=0
12849         mkdir -p $DIR/$tdir
12850         do_facet $SINGLEMDS lctl set_param fail_loc=0x147
12851         createmany -o $DIR/$tdir/f- 20 || error "can't create"
12852         do_facet $SINGLEMDS lctl set_param fail_loc=0
12853         rm -rf $DIR/$tdir
12854         do_facet $SINGLEMDS lctl set_param \
12855                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=$old_rr
12856 }
12857 run_test 116b "QoS shouldn't LBUG if not enough OSTs found on the 2nd pass"
12858
12859 test_117() # bug 10891
12860 {
12861         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12862
12863         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
12864         #define OBD_FAIL_OST_SETATTR_CREDITS 0x21e
12865         lctl set_param fail_loc=0x21e
12866         > $DIR/$tfile || error "truncate failed"
12867         lctl set_param fail_loc=0
12868         echo "Truncate succeeded."
12869         rm -f $DIR/$tfile
12870 }
12871 run_test 117 "verify osd extend =========="
12872
12873 NO_SLOW_RESENDCOUNT=4
12874 export OLD_RESENDCOUNT=""
12875 set_resend_count () {
12876         local PROC_RESENDCOUNT="osc.${FSNAME}-OST*-osc-*.resend_count"
12877         OLD_RESENDCOUNT=$(lctl get_param -n $PROC_RESENDCOUNT | head -n1)
12878         lctl set_param -n $PROC_RESENDCOUNT $1
12879         echo resend_count is set to $(lctl get_param -n $PROC_RESENDCOUNT)
12880 }
12881
12882 # for reduce test_118* time (b=14842)
12883 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
12884
12885 # Reset async IO behavior after error case
12886 reset_async() {
12887         FILE=$DIR/reset_async
12888
12889         # Ensure all OSCs are cleared
12890         $LFS setstripe -c -1 $FILE
12891         dd if=/dev/zero of=$FILE bs=64k count=$OSTCOUNT
12892         sync
12893         rm $FILE
12894 }
12895
12896 test_118a() #bug 11710
12897 {
12898         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12899
12900         reset_async
12901
12902         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12903         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12904         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
12905
12906         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12907                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12908                 return 1;
12909         fi
12910         rm -f $DIR/$tfile
12911 }
12912 run_test 118a "verify O_SYNC works =========="
12913
12914 test_118b()
12915 {
12916         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12917         remote_ost_nodsh && skip "remote OST with nodsh"
12918
12919         reset_async
12920
12921         #define OBD_FAIL_SRV_ENOENT 0x217
12922         set_nodes_failloc "$(osts_nodes)" 0x217
12923         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12924         RC=$?
12925         set_nodes_failloc "$(osts_nodes)" 0
12926         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12927         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12928                     grep -c writeback)
12929
12930         if [[ $RC -eq 0 ]]; then
12931                 error "Must return error due to dropped pages, rc=$RC"
12932                 return 1;
12933         fi
12934
12935         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12936                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12937                 return 1;
12938         fi
12939
12940         echo "Dirty pages not leaked on ENOENT"
12941
12942         # Due to the above error the OSC will issue all RPCs syncronously
12943         # until a subsequent RPC completes successfully without error.
12944         $MULTIOP $DIR/$tfile Ow4096yc
12945         rm -f $DIR/$tfile
12946
12947         return 0
12948 }
12949 run_test 118b "Reclaim dirty pages on fatal error =========="
12950
12951 test_118c()
12952 {
12953         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12954
12955         # for 118c, restore the original resend count, LU-1940
12956         [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] &&
12957                                 set_resend_count $OLD_RESENDCOUNT
12958         remote_ost_nodsh && skip "remote OST with nodsh"
12959
12960         reset_async
12961
12962         #define OBD_FAIL_OST_EROFS               0x216
12963         set_nodes_failloc "$(osts_nodes)" 0x216
12964
12965         # multiop should block due to fsync until pages are written
12966         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
12967         MULTIPID=$!
12968         sleep 1
12969
12970         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
12971                 error "Multiop failed to block on fsync, pid=$MULTIPID"
12972         fi
12973
12974         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12975                     grep -c writeback)
12976         if [[ $WRITEBACK -eq 0 ]]; then
12977                 error "No page in writeback, writeback=$WRITEBACK"
12978         fi
12979
12980         set_nodes_failloc "$(osts_nodes)" 0
12981         wait $MULTIPID
12982         RC=$?
12983         if [[ $RC -ne 0 ]]; then
12984                 error "Multiop fsync failed, rc=$RC"
12985         fi
12986
12987         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12988         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12989                     grep -c writeback)
12990         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12991                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12992         fi
12993
12994         rm -f $DIR/$tfile
12995         echo "Dirty pages flushed via fsync on EROFS"
12996         return 0
12997 }
12998 run_test 118c "Fsync blocks on EROFS until dirty pages are flushed =========="
12999
13000 # continue to use small resend count to reduce test_118* time (b=14842)
13001 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
13002
13003 test_118d()
13004 {
13005         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13006         remote_ost_nodsh && skip "remote OST with nodsh"
13007
13008         reset_async
13009
13010         #define OBD_FAIL_OST_BRW_PAUSE_BULK
13011         set_nodes_failloc "$(osts_nodes)" 0x214
13012         # multiop should block due to fsync until pages are written
13013         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
13014         MULTIPID=$!
13015         sleep 1
13016
13017         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
13018                 error "Multiop failed to block on fsync, pid=$MULTIPID"
13019         fi
13020
13021         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13022                     grep -c writeback)
13023         if [[ $WRITEBACK -eq 0 ]]; then
13024                 error "No page in writeback, writeback=$WRITEBACK"
13025         fi
13026
13027         wait $MULTIPID || error "Multiop fsync failed, rc=$?"
13028         set_nodes_failloc "$(osts_nodes)" 0
13029
13030         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13031         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13032                     grep -c writeback)
13033         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13034                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13035         fi
13036
13037         rm -f $DIR/$tfile
13038         echo "Dirty pages gaurenteed flushed via fsync"
13039         return 0
13040 }
13041 run_test 118d "Fsync validation inject a delay of the bulk =========="
13042
13043 test_118f() {
13044         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13045
13046         reset_async
13047
13048         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
13049         lctl set_param fail_loc=0x8000040a
13050
13051         # Should simulate EINVAL error which is fatal
13052         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13053         RC=$?
13054         if [[ $RC -eq 0 ]]; then
13055                 error "Must return error due to dropped pages, rc=$RC"
13056         fi
13057
13058         lctl set_param fail_loc=0x0
13059
13060         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
13061         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13062         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13063                     grep -c writeback)
13064         if [[ $LOCKED -ne 0 ]]; then
13065                 error "Locked pages remain in cache, locked=$LOCKED"
13066         fi
13067
13068         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13069                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13070         fi
13071
13072         rm -f $DIR/$tfile
13073         echo "No pages locked after fsync"
13074
13075         reset_async
13076         return 0
13077 }
13078 run_test 118f "Simulate unrecoverable OSC side error =========="
13079
13080 test_118g() {
13081         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13082
13083         reset_async
13084
13085         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
13086         lctl set_param fail_loc=0x406
13087
13088         # simulate local -ENOMEM
13089         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13090         RC=$?
13091
13092         lctl set_param fail_loc=0
13093         if [[ $RC -eq 0 ]]; then
13094                 error "Must return error due to dropped pages, rc=$RC"
13095         fi
13096
13097         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
13098         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13099         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13100                         grep -c writeback)
13101         if [[ $LOCKED -ne 0 ]]; then
13102                 error "Locked pages remain in cache, locked=$LOCKED"
13103         fi
13104
13105         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13106                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13107         fi
13108
13109         rm -f $DIR/$tfile
13110         echo "No pages locked after fsync"
13111
13112         reset_async
13113         return 0
13114 }
13115 run_test 118g "Don't stay in wait if we got local -ENOMEM  =========="
13116
13117 test_118h() {
13118         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13119         remote_ost_nodsh && skip "remote OST with nodsh"
13120
13121         reset_async
13122
13123         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
13124         set_nodes_failloc "$(osts_nodes)" 0x20e
13125         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
13126         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13127         RC=$?
13128
13129         set_nodes_failloc "$(osts_nodes)" 0
13130         if [[ $RC -eq 0 ]]; then
13131                 error "Must return error due to dropped pages, rc=$RC"
13132         fi
13133
13134         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
13135         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13136         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13137                     grep -c writeback)
13138         if [[ $LOCKED -ne 0 ]]; then
13139                 error "Locked pages remain in cache, locked=$LOCKED"
13140         fi
13141
13142         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13143                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13144         fi
13145
13146         rm -f $DIR/$tfile
13147         echo "No pages locked after fsync"
13148
13149         return 0
13150 }
13151 run_test 118h "Verify timeout in handling recoverables errors  =========="
13152
13153 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
13154
13155 test_118i() {
13156         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13157         remote_ost_nodsh && skip "remote OST with nodsh"
13158
13159         reset_async
13160
13161         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
13162         set_nodes_failloc "$(osts_nodes)" 0x20e
13163
13164         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
13165         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
13166         PID=$!
13167         sleep 5
13168         set_nodes_failloc "$(osts_nodes)" 0
13169
13170         wait $PID
13171         RC=$?
13172         if [[ $RC -ne 0 ]]; then
13173                 error "got error, but should be not, rc=$RC"
13174         fi
13175
13176         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
13177         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13178         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
13179         if [[ $LOCKED -ne 0 ]]; then
13180                 error "Locked pages remain in cache, locked=$LOCKED"
13181         fi
13182
13183         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13184                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13185         fi
13186
13187         rm -f $DIR/$tfile
13188         echo "No pages locked after fsync"
13189
13190         return 0
13191 }
13192 run_test 118i "Fix error before timeout in recoverable error  =========="
13193
13194 [ "$SLOW" = "no" ] && set_resend_count 4
13195
13196 test_118j() {
13197         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13198         remote_ost_nodsh && skip "remote OST with nodsh"
13199
13200         reset_async
13201
13202         #define OBD_FAIL_OST_BRW_WRITE_BULK2     0x220
13203         set_nodes_failloc "$(osts_nodes)" 0x220
13204
13205         # return -EIO from OST
13206         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13207         RC=$?
13208         set_nodes_failloc "$(osts_nodes)" 0x0
13209         if [[ $RC -eq 0 ]]; then
13210                 error "Must return error due to dropped pages, rc=$RC"
13211         fi
13212
13213         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
13214         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13215         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
13216         if [[ $LOCKED -ne 0 ]]; then
13217                 error "Locked pages remain in cache, locked=$LOCKED"
13218         fi
13219
13220         # in recoverable error on OST we want resend and stay until it finished
13221         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13222                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13223         fi
13224
13225         rm -f $DIR/$tfile
13226         echo "No pages locked after fsync"
13227
13228         return 0
13229 }
13230 run_test 118j "Simulate unrecoverable OST side error =========="
13231
13232 test_118k()
13233 {
13234         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13235         remote_ost_nodsh && skip "remote OSTs with nodsh"
13236
13237         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
13238         set_nodes_failloc "$(osts_nodes)" 0x20e
13239         test_mkdir $DIR/$tdir
13240
13241         for ((i=0;i<10;i++)); do
13242                 (dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=1M count=10 || \
13243                         error "dd to $DIR/$tdir/$tfile-$i failed" )&
13244                 SLEEPPID=$!
13245                 sleep 0.500s
13246                 kill $SLEEPPID
13247                 wait $SLEEPPID
13248         done
13249
13250         set_nodes_failloc "$(osts_nodes)" 0
13251         rm -rf $DIR/$tdir
13252 }
13253 run_test 118k "bio alloc -ENOMEM and IO TERM handling ========="
13254
13255 test_118l() # LU-646
13256 {
13257         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13258
13259         test_mkdir $DIR/$tdir
13260         $MULTIOP $DIR/$tdir Dy || error "fsync dir failed"
13261         rm -rf $DIR/$tdir
13262 }
13263 run_test 118l "fsync dir"
13264
13265 test_118m() # LU-3066
13266 {
13267         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13268
13269         test_mkdir $DIR/$tdir
13270         $MULTIOP $DIR/$tdir DY || error "fdatasync dir failed"
13271         rm -rf $DIR/$tdir
13272 }
13273 run_test 118m "fdatasync dir ========="
13274
13275 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
13276
13277 test_118n()
13278 {
13279         local begin
13280         local end
13281
13282         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13283         remote_ost_nodsh && skip "remote OSTs with nodsh"
13284
13285         # Sleep to avoid a cached response.
13286         #define OBD_STATFS_CACHE_SECONDS 1
13287         sleep 2
13288
13289         # Inject a 10 second delay in the OST_STATFS handler.
13290         #define OBD_FAIL_OST_STATFS_DELAY 0x242
13291         set_nodes_failloc "$(osts_nodes)" 0x242
13292
13293         begin=$SECONDS
13294         stat --file-system $MOUNT > /dev/null
13295         end=$SECONDS
13296
13297         set_nodes_failloc "$(osts_nodes)" 0
13298
13299         if ((end - begin > 20)); then
13300             error "statfs took $((end - begin)) seconds, expected 10"
13301         fi
13302 }
13303 run_test 118n "statfs() sends OST_STATFS requests in parallel"
13304
13305 test_119a() # bug 11737
13306 {
13307         BSIZE=$((512 * 1024))
13308         directio write $DIR/$tfile 0 1 $BSIZE
13309         # We ask to read two blocks, which is more than a file size.
13310         # directio will indicate an error when requested and actual
13311         # sizes aren't equeal (a normal situation in this case) and
13312         # print actual read amount.
13313         NOB=`directio read $DIR/$tfile 0 2 $BSIZE | awk '/error/ {print $6}'`
13314         if [ "$NOB" != "$BSIZE" ]; then
13315                 error "read $NOB bytes instead of $BSIZE"
13316         fi
13317         rm -f $DIR/$tfile
13318 }
13319 run_test 119a "Short directIO read must return actual read amount"
13320
13321 test_119b() # bug 11737
13322 {
13323         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
13324
13325         $LFS setstripe -c 2 $DIR/$tfile || error "setstripe failed"
13326         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1 || error "dd failed"
13327         sync
13328         $MULTIOP $DIR/$tfile oO_RDONLY:O_DIRECT:r$((2048 * 1024)) ||
13329                 error "direct read failed"
13330         rm -f $DIR/$tfile
13331 }
13332 run_test 119b "Sparse directIO read must return actual read amount"
13333
13334 test_119c() # bug 13099
13335 {
13336         BSIZE=1048576
13337         directio write $DIR/$tfile 3 1 $BSIZE || error "direct write failed"
13338         directio readhole $DIR/$tfile 0 2 $BSIZE || error "reading hole failed"
13339         rm -f $DIR/$tfile
13340 }
13341 run_test 119c "Testing for direct read hitting hole"
13342
13343 test_120a() {
13344         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13345         remote_mds_nodsh && skip "remote MDS with nodsh"
13346         test_mkdir -i0 -c1 $DIR/$tdir
13347         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13348                 skip_env "no early lock cancel on server"
13349
13350         lru_resize_disable mdc
13351         lru_resize_disable osc
13352         cancel_lru_locks mdc
13353         # asynchronous object destroy at MDT could cause bl ast to client
13354         cancel_lru_locks osc
13355
13356         stat $DIR/$tdir > /dev/null
13357         can1=$(do_facet mds1 \
13358                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13359                awk '/ldlm_cancel/ {print $2}')
13360         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13361                awk '/ldlm_bl_callback/ {print $2}')
13362         test_mkdir -i0 -c1 $DIR/$tdir/d1
13363         can2=$(do_facet mds1 \
13364                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13365                awk '/ldlm_cancel/ {print $2}')
13366         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13367                awk '/ldlm_bl_callback/ {print $2}')
13368         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
13369         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
13370         lru_resize_enable mdc
13371         lru_resize_enable osc
13372 }
13373 run_test 120a "Early Lock Cancel: mkdir test"
13374
13375 test_120b() {
13376         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13377         remote_mds_nodsh && skip "remote MDS with nodsh"
13378         test_mkdir $DIR/$tdir
13379         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13380                 skip_env "no early lock cancel on server"
13381
13382         lru_resize_disable mdc
13383         lru_resize_disable osc
13384         cancel_lru_locks mdc
13385         stat $DIR/$tdir > /dev/null
13386         can1=$(do_facet $SINGLEMDS \
13387                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13388                awk '/ldlm_cancel/ {print $2}')
13389         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13390                awk '/ldlm_bl_callback/ {print $2}')
13391         touch $DIR/$tdir/f1
13392         can2=$(do_facet $SINGLEMDS \
13393                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13394                awk '/ldlm_cancel/ {print $2}')
13395         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13396                awk '/ldlm_bl_callback/ {print $2}')
13397         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
13398         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
13399         lru_resize_enable mdc
13400         lru_resize_enable osc
13401 }
13402 run_test 120b "Early Lock Cancel: create test"
13403
13404 test_120c() {
13405         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13406         remote_mds_nodsh && skip "remote MDS with nodsh"
13407         test_mkdir -i0 -c1 $DIR/$tdir
13408         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13409                 skip "no early lock cancel on server"
13410
13411         lru_resize_disable mdc
13412         lru_resize_disable osc
13413         test_mkdir -i0 -c1 $DIR/$tdir/d1
13414         test_mkdir -i0 -c1 $DIR/$tdir/d2
13415         touch $DIR/$tdir/d1/f1
13416         cancel_lru_locks mdc
13417         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 > /dev/null
13418         can1=$(do_facet mds1 \
13419                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13420                awk '/ldlm_cancel/ {print $2}')
13421         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13422                awk '/ldlm_bl_callback/ {print $2}')
13423         ln $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
13424         can2=$(do_facet mds1 \
13425                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13426                awk '/ldlm_cancel/ {print $2}')
13427         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13428                awk '/ldlm_bl_callback/ {print $2}')
13429         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
13430         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
13431         lru_resize_enable mdc
13432         lru_resize_enable osc
13433 }
13434 run_test 120c "Early Lock Cancel: link test"
13435
13436 test_120d() {
13437         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13438         remote_mds_nodsh && skip "remote MDS with nodsh"
13439         test_mkdir -i0 -c1 $DIR/$tdir
13440         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13441                 skip_env "no early lock cancel on server"
13442
13443         lru_resize_disable mdc
13444         lru_resize_disable osc
13445         touch $DIR/$tdir
13446         cancel_lru_locks mdc
13447         stat $DIR/$tdir > /dev/null
13448         can1=$(do_facet mds1 \
13449                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13450                awk '/ldlm_cancel/ {print $2}')
13451         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13452                awk '/ldlm_bl_callback/ {print $2}')
13453         chmod a+x $DIR/$tdir
13454         can2=$(do_facet mds1 \
13455                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13456                awk '/ldlm_cancel/ {print $2}')
13457         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13458                awk '/ldlm_bl_callback/ {print $2}')
13459         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
13460         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
13461         lru_resize_enable mdc
13462         lru_resize_enable osc
13463 }
13464 run_test 120d "Early Lock Cancel: setattr test"
13465
13466 test_120e() {
13467         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13468         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13469                 skip_env "no early lock cancel on server"
13470         remote_mds_nodsh && skip "remote MDS with nodsh"
13471
13472         local dlmtrace_set=false
13473
13474         test_mkdir -i0 -c1 $DIR/$tdir
13475         lru_resize_disable mdc
13476         lru_resize_disable osc
13477         ! $LCTL get_param debug | grep -q dlmtrace &&
13478                 $LCTL set_param debug=+dlmtrace && dlmtrace_set=true
13479         dd if=/dev/zero of=$DIR/$tdir/f1 count=1
13480         cancel_lru_locks mdc
13481         cancel_lru_locks osc
13482         dd if=$DIR/$tdir/f1 of=/dev/null
13483         stat $DIR/$tdir $DIR/$tdir/f1 > /dev/null
13484         # XXX client can not do early lock cancel of OST lock
13485         # during unlink (LU-4206), so cancel osc lock now.
13486         sleep 2
13487         cancel_lru_locks osc
13488         can1=$(do_facet mds1 \
13489                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13490                awk '/ldlm_cancel/ {print $2}')
13491         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13492                awk '/ldlm_bl_callback/ {print $2}')
13493         unlink $DIR/$tdir/f1
13494         sleep 5
13495         can2=$(do_facet mds1 \
13496                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13497                awk '/ldlm_cancel/ {print $2}')
13498         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13499                awk '/ldlm_bl_callback/ {print $2}')
13500         [ $can1 -ne $can2 ] && error "$((can2 - can1)) cancel RPC occured" &&
13501                 $LCTL dk $TMP/cancel.debug.txt
13502         [ $blk1 -ne $blk2 ] && error "$((blk2 - blk1)) blocking RPC occured" &&
13503                 $LCTL dk $TMP/blocking.debug.txt
13504         $dlmtrace_set && $LCTL set_param debug=-dlmtrace
13505         lru_resize_enable mdc
13506         lru_resize_enable osc
13507 }
13508 run_test 120e "Early Lock Cancel: unlink test"
13509
13510 test_120f() {
13511         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13512         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13513                 skip_env "no early lock cancel on server"
13514         remote_mds_nodsh && skip "remote MDS with nodsh"
13515
13516         test_mkdir -i0 -c1 $DIR/$tdir
13517         lru_resize_disable mdc
13518         lru_resize_disable osc
13519         test_mkdir -i0 -c1 $DIR/$tdir/d1
13520         test_mkdir -i0 -c1 $DIR/$tdir/d2
13521         dd if=/dev/zero of=$DIR/$tdir/d1/f1 count=1
13522         dd if=/dev/zero of=$DIR/$tdir/d2/f2 count=1
13523         cancel_lru_locks mdc
13524         cancel_lru_locks osc
13525         dd if=$DIR/$tdir/d1/f1 of=/dev/null
13526         dd if=$DIR/$tdir/d2/f2 of=/dev/null
13527         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2 > /dev/null
13528         # XXX client can not do early lock cancel of OST lock
13529         # during rename (LU-4206), so cancel osc lock now.
13530         sleep 2
13531         cancel_lru_locks osc
13532         can1=$(do_facet mds1 \
13533                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13534                awk '/ldlm_cancel/ {print $2}')
13535         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13536                awk '/ldlm_bl_callback/ {print $2}')
13537         mrename $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
13538         sleep 5
13539         can2=$(do_facet mds1 \
13540                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13541                awk '/ldlm_cancel/ {print $2}')
13542         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13543                awk '/ldlm_bl_callback/ {print $2}')
13544         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
13545         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
13546         lru_resize_enable mdc
13547         lru_resize_enable osc
13548 }
13549 run_test 120f "Early Lock Cancel: rename test"
13550
13551 test_120g() {
13552         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13553         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13554                 skip_env "no early lock cancel on server"
13555         remote_mds_nodsh && skip "remote MDS with nodsh"
13556
13557         lru_resize_disable mdc
13558         lru_resize_disable osc
13559         count=10000
13560         echo create $count files
13561         test_mkdir $DIR/$tdir
13562         cancel_lru_locks mdc
13563         cancel_lru_locks osc
13564         t0=$(date +%s)
13565
13566         can0=$(do_facet $SINGLEMDS \
13567                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13568                awk '/ldlm_cancel/ {print $2}')
13569         blk0=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13570                awk '/ldlm_bl_callback/ {print $2}')
13571         createmany -o $DIR/$tdir/f $count
13572         sync
13573         can1=$(do_facet $SINGLEMDS \
13574                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13575                awk '/ldlm_cancel/ {print $2}')
13576         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13577                awk '/ldlm_bl_callback/ {print $2}')
13578         t1=$(date +%s)
13579         echo total: $((can1-can0)) cancels, $((blk1-blk0)) blockings
13580         echo rm $count files
13581         rm -r $DIR/$tdir
13582         sync
13583         can2=$(do_facet $SINGLEMDS \
13584                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13585                awk '/ldlm_cancel/ {print $2}')
13586         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13587                awk '/ldlm_bl_callback/ {print $2}')
13588         t2=$(date +%s)
13589         echo total: $count removes in $((t2-t1))
13590         echo total: $((can2-can1)) cancels, $((blk2-blk1)) blockings
13591         sleep 2
13592         # wait for commitment of removal
13593         lru_resize_enable mdc
13594         lru_resize_enable osc
13595 }
13596 run_test 120g "Early Lock Cancel: performance test"
13597
13598 test_121() { #bug #10589
13599         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13600
13601         rm -rf $DIR/$tfile
13602         writes=$(LANG=C dd if=/dev/zero of=$DIR/$tfile count=1 2>&1 | awk -F '+' '/out$/ {print $1}')
13603 #define OBD_FAIL_LDLM_CANCEL_RACE        0x310
13604         lctl set_param fail_loc=0x310
13605         cancel_lru_locks osc > /dev/null
13606         reads=$(LANG=C dd if=$DIR/$tfile of=/dev/null 2>&1 | awk -F '+' '/in$/ {print $1}')
13607         lctl set_param fail_loc=0
13608         [[ $reads -eq $writes ]] ||
13609                 error "read $reads blocks, must be $writes blocks"
13610 }
13611 run_test 121 "read cancel race ========="
13612
13613 test_123a_base() { # was test 123, statahead(bug 11401)
13614         local lsx="$1"
13615
13616         ost_set_temp_seq_width_all $DATA_SEQ_MAX_WIDTH
13617
13618         SLOWOK=0
13619         if ! grep -q "processor.*: 1" /proc/cpuinfo; then
13620                 log "testing UP system. Performance may be lower than expected."
13621                 SLOWOK=1
13622         fi
13623         running_in_vm && SLOWOK=1
13624
13625         $LCTL set_param mdc.*.batch_stats=0
13626
13627         rm -rf $DIR/$tdir
13628         test_mkdir $DIR/$tdir
13629         NUMFREE=$(df -i -P $DIR | tail -n 1 | awk '{ print $4 }')
13630         [[ $NUMFREE -gt 100000 ]] && NUMFREE=100000 || NUMFREE=$((NUMFREE-1000))
13631         MULT=10
13632         for ((i=100, j=0; i<=$NUMFREE; j=$i, i=$((i * MULT)) )); do
13633                 createmany -o $DIR/$tdir/$tfile $j $((i - j))
13634
13635                 max=$(lctl get_param -n llite.*.statahead_max | head -n 1)
13636                 lctl set_param -n llite.*.statahead_max 0
13637                 lctl get_param llite.*.statahead_max
13638                 cancel_lru_locks mdc
13639                 cancel_lru_locks osc
13640                 stime=$(date +%s)
13641                 time $lsx $DIR/$tdir | wc -l
13642                 etime=$(date +%s)
13643                 delta=$((etime - stime))
13644                 log "$lsx $i files without statahead: $delta sec"
13645                 lctl set_param llite.*.statahead_max=$max
13646
13647                 swrong=$(lctl get_param -n llite.*.statahead_stats |
13648                          awk '/statahead.wrong:/ { print $NF }')
13649                 lctl get_param -n llite.*.statahead_max | grep '[0-9]'
13650                 cancel_lru_locks mdc
13651                 cancel_lru_locks osc
13652                 stime=$(date +%s)
13653                 time $lsx $DIR/$tdir | wc -l
13654                 etime=$(date +%s)
13655                 delta_sa=$((etime - stime))
13656                 log "$lsx $i files with statahead: $delta_sa sec"
13657                 lctl get_param -n llite.*.statahead_stats
13658                 ewrong=$(lctl get_param -n llite.*.statahead_stats |
13659                          awk '/statahead.wrong:/ { print $NF }')
13660
13661                 [[ $swrong -lt $ewrong ]] &&
13662                         log "statahead was stopped, maybe too many locks held!"
13663                 [[ $delta -eq 0 || $delta_sa -eq 0 ]] && continue
13664
13665                 if (( $delta_sa*100 > $delta*105 && $delta_sa > $delta+2)); then
13666                         max=$(lctl get_param -n llite.*.statahead_max |
13667                                 head -n 1)
13668                         lctl set_param -n llite.*.statahead_max 0
13669                         lctl get_param llite.*.statahead_max
13670                         cancel_lru_locks mdc
13671                         cancel_lru_locks osc
13672                         stime=$(date +%s)
13673                         time $lsx $DIR/$tdir | wc -l
13674                         etime=$(date +%s)
13675                         delta=$((etime - stime))
13676                         log "$lsx $i files again without statahead: $delta sec"
13677                         lctl set_param llite.*.statahead_max=$max
13678                         if (( $delta_sa*100 > delta*105 && delta_sa > delta+2 )); then
13679                                 if [ $SLOWOK -eq 0 ]; then
13680                                         error "$lsx $i files is slower with statahead!"
13681                                 else
13682                                         log "$lsx $i files is slower with statahead!"
13683                                 fi
13684                                 break
13685                         fi
13686                 fi
13687
13688                 [ $delta -gt 20 ] && break
13689                 [ $delta -gt 8 ] && MULT=$((50 / delta))
13690                 [ "$SLOW" = "no" -a $delta -gt 5 ] && break
13691         done
13692         log "$lsx done"
13693
13694         stime=$(date +%s)
13695         rm -r $DIR/$tdir
13696         sync
13697         etime=$(date +%s)
13698         delta=$((etime - stime))
13699         log "rm -r $DIR/$tdir/: $delta seconds"
13700         log "rm done"
13701         lctl get_param -n llite.*.statahead_stats
13702         $LCTL get_param mdc.*.batch_stats
13703 }
13704
13705 test_123aa() {
13706         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13707
13708         test_123a_base "ls -l"
13709 }
13710 run_test 123aa "verify statahead work"
13711
13712 test_123ab() {
13713         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13714
13715         statx_supported || skip_env "Test must be statx() syscall supported"
13716
13717         test_123a_base "$STATX -l"
13718 }
13719 run_test 123ab "verify statahead work by using statx"
13720
13721 test_123ac() {
13722         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13723
13724         statx_supported || skip_env "Test must be statx() syscall supported"
13725
13726         local rpcs_before
13727         local rpcs_after
13728         local agl_before
13729         local agl_after
13730
13731         cancel_lru_locks $OSC
13732         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
13733         agl_before=$($LCTL get_param -n llite.*.statahead_stats |
13734                      awk '/agl.total:/ { print $NF }')
13735         test_123a_base "$STATX -c \"%n %i %A %h %u %g %W %X %Z\" -D"
13736         test_123a_base "$STATX --cached=always -D"
13737         agl_after=$($LCTL get_param -n llite.*.statahead_stats |
13738                     awk '/agl.total:/ { print $NF }')
13739         [ $agl_before -eq $agl_after ] ||
13740                 error "Should not trigger AGL thread - $agl_before:$agl_after"
13741         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
13742         [ $rpcs_after -eq $rpcs_before ] ||
13743                 error "$STATX should not send glimpse RPCs to $OSC"
13744 }
13745 run_test 123ac "verify statahead work by using statx without glimpse RPCs"
13746
13747 test_batch_statahead() {
13748         local max=$1
13749         local batch_max=$2
13750         local num=10000
13751         local batch_rpcs
13752         local unbatch_rpcs
13753         local hit_total
13754
13755         echo -e "\nbatching: statahead_max=$max statahead_batch_max=$batch_max"
13756         $LCTL set_param mdc.*.batch_stats=0
13757         $LCTL set_param llite.*.statahead_max=$max
13758         $LCTL set_param llite.*.statahead_batch_max=$batch_max
13759         # Verify that batched statahead is faster than one without statahead
13760         test_123a_base "ls -l"
13761
13762         stack_trap "rm -rf $DIR/$tdir" EXIT
13763         mkdir $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
13764         createmany -o $DIR/$tdir/$tfile $num || error "failed to create files"
13765
13766         # unbatched statahead
13767         $LCTL set_param llite.*.statahead_batch_max=0
13768         $LCTL set_param llite.*.statahead_stats=clear
13769         $LCTL set_param mdc.*.stats=clear
13770         cancel_lru_locks mdc
13771         cancel_lru_locks osc
13772         time ls -l $DIR/$tdir | wc -l
13773         unbatch_rpcs=$(calc_stats mdc.*.stats ldlm_ibits_enqueue)
13774         sleep 2
13775         hit_total=$($LCTL get_param -n llite.*.statahead_stats |
13776                     awk '/hit.total:/ { print $NF }')
13777         # hit ratio should be larger than 75% (7500).
13778         (( $hit_total > 7500 )) ||
13779                 error "unbatched statahead hit count ($hit_total) is too low"
13780
13781         # batched statahead
13782         $LCTL set_param llite.*.statahead_batch_max=$batch_max
13783         $LCTL set_param llite.*.statahead_stats=clear
13784         $LCTL set_param mdc.*.batch_stats=clear
13785         $LCTL set_param mdc.*.stats=clear
13786         cancel_lru_locks mdc
13787         cancel_lru_locks osc
13788         time ls -l $DIR/$tdir | wc -l
13789         batch_rpcs=$(calc_stats mdc.*.stats mds_batch)
13790         # wait for statahead thread to quit and update statahead stats
13791         sleep 2
13792         hit_total=$($LCTL get_param -n llite.*.statahead_stats |
13793                     awk '/hit.total:/ { print $NF }')
13794         # hit ratio should be larger than 75% (7500).
13795         (( $hit_total > 7500 )) ||
13796                 error "batched statahead hit count ($hit_total) is too low"
13797
13798         echo "unbatched RPCs: $unbatch_rpcs, batched RPCs: $batch_rpcs"
13799         (( $unbatch_rpcs > $batch_rpcs )) ||
13800                 error "batched statahead does not reduce RPC count"
13801         $LCTL get_param mdc.*.batch_stats
13802 }
13803
13804 test_123ad() {
13805         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13806
13807         (( $MDS1_VERSION >= $(version_code 2.15.53) )) ||
13808                 skip "Need server version at least 2.15.53"
13809
13810         local max
13811         local batch_max
13812
13813         max=$($LCTL get_param -n llite.*.statahead_max | head -n 1)
13814         batch_max=$($LCTL get_param -n llite.*.statahead_batch_max | head -n 1)
13815
13816         stack_trap "$LCTL set_param llite.*.statahead_max=$max" EXIT
13817         stack_trap "$LCTL set_param llite.*.statahead_batch_max=$batch_max" EXIT
13818
13819         test_batch_statahead 32 32
13820         test_batch_statahead 2048 256
13821 }
13822 run_test 123ad "Verify batching statahead works correctly"
13823
13824 test_123b () { # statahead(bug 15027)
13825         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13826
13827         test_mkdir $DIR/$tdir
13828         createmany -o $DIR/$tdir/$tfile-%d 1000
13829
13830         cancel_lru_locks mdc
13831         cancel_lru_locks osc
13832
13833 #define OBD_FAIL_MDC_GETATTR_ENQUEUE     0x803
13834         lctl set_param fail_loc=0x80000803
13835         ls -lR $DIR/$tdir > /dev/null
13836         log "ls done"
13837         lctl set_param fail_loc=0x0
13838         lctl get_param -n llite.*.statahead_stats
13839         rm -r $DIR/$tdir
13840         sync
13841
13842 }
13843 run_test 123b "not panic with network error in statahead enqueue (bug 15027)"
13844
13845 test_123c() {
13846         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
13847
13848         test_mkdir -i 0 -c 1 $DIR/$tdir.0
13849         test_mkdir -i 1 -c 1 $DIR/$tdir.1
13850         touch $DIR/$tdir.1/{1..3}
13851         mv $DIR/$tdir.1/{1..3} $DIR/$tdir.0
13852
13853         remount_client $MOUNT
13854
13855         $MULTIOP $DIR/$tdir.0 Q
13856
13857         # let statahead to complete
13858         ls -l $DIR/$tdir.0 > /dev/null
13859
13860         testid=$(echo $TESTNAME | tr '_' ' ')
13861         dmesg | tac | sed "/$testid/,$ d" | grep "Can not initialize inode" &&
13862                 error "statahead warning" || true
13863 }
13864 run_test 123c "Can not initialize inode warning on DNE statahead"
13865
13866 test_123d() {
13867         local num=100
13868         local swrong
13869         local ewrong
13870
13871         test_mkdir -c -1 $DIR/$tdir || error "test_mkdir $DIR/$tdir failed"
13872         $LFS setdirstripe -D -c $MDSCOUNT $DIR/$tdir ||
13873                 error "setdirstripe $DIR/$tdir failed"
13874         createmany -d $DIR/$tdir/$tfile $num || error "createmany $num failed"
13875         remount_client $MOUNT
13876         $LCTL get_param llite.*.statahead_max
13877         $LCTL set_param llite.*.statahead_stats=0 ||
13878                 error "clear statahead_stats failed"
13879         swrong=$(lctl get_param -n llite.*.statahead_stats |
13880                  awk '/statahead.wrong:/ { print $NF }')
13881         ls -l $DIR/$tdir || error "ls -l $DIR/$tdir failed"
13882         # wait for statahead thread finished to update hit/miss stats.
13883         sleep 1
13884         $LCTL get_param -n llite.*.statahead_stats
13885         ewrong=$(lctl get_param -n llite.*.statahead_stats |
13886                  awk '/statahead.wrong:/ { print $NF }')
13887         (( $swrong == $ewrong )) ||
13888                 log "statahead was stopped, maybe too many locks held!"
13889 }
13890 run_test 123d "Statahead on striped directories works correctly"
13891
13892 test_123e() {
13893         local max
13894         local batch_max
13895         local dir=$DIR/$tdir
13896
13897         mkdir $dir || error "mkdir $dir failed"
13898         $LFS setstripe -C 32 $dir || error "setstripe $dir failed"
13899
13900         touch $dir/$tfile.{0..1000} || error "touch 1000 files failed"
13901
13902         max=$($LCTL get_param -n llite.*.statahead_max | head -n 1)
13903         batch_max=$($LCTL get_param -n llite.*.statahead_batch_max | head -n 1)
13904         stack_trap "$LCTL set_param llite.*.statahead_max=$max" EXIT
13905         stack_trap "$LCTL set_param llite.*.statahead_batch_max=$batch_max" EXIT
13906
13907         $LCTL set_param llite.*.statahead_max=2048
13908         $LCTL set_param llite.*.statahead_batch_max=1024
13909
13910         ls -l $dir
13911         $LCTL get_param mdc.*.batch_stats
13912         $LCTL get_param llite.*.statahead_*
13913 }
13914 run_test 123e "statahead with large wide striping"
13915
13916 test_123f() {
13917         local max
13918         local batch_max
13919         local dir=$DIR/$tdir
13920
13921         mkdir $dir || error "mkdir $dir failed"
13922         $LFS setstripe -C 1000 $dir || error "setstripe $dir failed"
13923
13924         touch $dir/$tfile.{0..200} || error "touch 200 files failed"
13925
13926         max=$($LCTL get_param -n llite.*.statahead_max | head -n 1)
13927         batch_max=$($LCTL get_param -n llite.*.statahead_batch_max | head -n 1)
13928
13929         $LCTL set_param llite.*.statahead_max=64
13930         $LCTL set_param llite.*.statahead_batch_max=64
13931
13932         ls -l $dir
13933         lctl get_param mdc.*.batch_stats
13934         lctl get_param llite.*.statahead_*
13935
13936         $LCTL set_param llite.*.statahead_max=$max
13937         $LCTL set_param llite.*.statahead_batch_max=$batch_max
13938 }
13939 run_test 123f "Retry mechanism with large wide striping files"
13940
13941 test_124a() {
13942         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13943         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13944                 skip_env "no lru resize on server"
13945
13946         local NR=2000
13947
13948         test_mkdir $DIR/$tdir
13949
13950         log "create $NR files at $DIR/$tdir"
13951         createmany -o $DIR/$tdir/f $NR ||
13952                 error "failed to create $NR files in $DIR/$tdir"
13953
13954         cancel_lru_locks mdc
13955         ls -l $DIR/$tdir > /dev/null
13956
13957         local NSDIR=""
13958         local LRU_SIZE=0
13959         for VALUE in $($LCTL get_param ldlm.namespaces.*mdc-*.lru_size); do
13960                 local PARAM=$(echo ${VALUE[0]} | cut -d "=" -f1)
13961                 LRU_SIZE=$($LCTL get_param -n $PARAM)
13962                 if [[ $LRU_SIZE -gt $(default_lru_size) ]]; then
13963                         NSDIR=$(echo $PARAM | cut -d "." -f1-3)
13964                         log "NSDIR=$NSDIR"
13965                         log "NS=$(basename $NSDIR)"
13966                         break
13967                 fi
13968         done
13969
13970         if [[ -z "$NSDIR" || $LRU_SIZE -lt $(default_lru_size) ]]; then
13971                 skip "Not enough cached locks created!"
13972         fi
13973         log "LRU=$LRU_SIZE"
13974
13975         local SLEEP=30
13976
13977         # We know that lru resize allows one client to hold $LIMIT locks
13978         # for 10h. After that locks begin to be killed by client.
13979         local MAX_HRS=10
13980         local LIMIT=$($LCTL get_param -n $NSDIR.pool.limit)
13981         log "LIMIT=$LIMIT"
13982         if [ $LIMIT -lt $LRU_SIZE ]; then
13983                 skip "Limit is too small $LIMIT"
13984         fi
13985
13986         # Make LVF so higher that sleeping for $SLEEP is enough to _start_
13987         # killing locks. Some time was spent for creating locks. This means
13988         # that up to the moment of sleep finish we must have killed some of
13989         # them (10-100 locks). This depends on how fast ther were created.
13990         # Many of them were touched in almost the same moment and thus will
13991         # be killed in groups.
13992         local LVF=$(($MAX_HRS * 60 * 60 / $SLEEP * $LIMIT / $LRU_SIZE * 100))
13993
13994         # Use $LRU_SIZE_B here to take into account real number of locks
13995         # created in the case of CMD, LRU_SIZE_B != $NR in most of cases
13996         local LRU_SIZE_B=$LRU_SIZE
13997         log "LVF=$LVF"
13998         local OLD_LVF=$($LCTL get_param -n $NSDIR.pool.lock_volume_factor)
13999         log "OLD_LVF=$OLD_LVF"
14000         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $LVF
14001
14002         # Let's make sure that we really have some margin. Client checks
14003         # cached locks every 10 sec.
14004         SLEEP=$((SLEEP+20))
14005         log "Sleep ${SLEEP} sec"
14006         local SEC=0
14007         while ((SEC<$SLEEP)); do
14008                 echo -n "..."
14009                 sleep 5
14010                 SEC=$((SEC+5))
14011                 LRU_SIZE=$($LCTL get_param -n $NSDIR/lru_size)
14012                 echo -n "$LRU_SIZE"
14013         done
14014         echo ""
14015         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $OLD_LVF
14016         local LRU_SIZE_A=$($LCTL get_param -n $NSDIR.lru_size)
14017
14018         [[ $LRU_SIZE_B -gt $LRU_SIZE_A ]] || {
14019                 error "No locks dropped in ${SLEEP}s. LRU size: $LRU_SIZE_A"
14020                 unlinkmany $DIR/$tdir/f $NR
14021                 return
14022         }
14023
14024         log "Dropped "$((LRU_SIZE_B-LRU_SIZE_A))" locks in ${SLEEP}s"
14025         log "unlink $NR files at $DIR/$tdir"
14026         unlinkmany $DIR/$tdir/f $NR
14027 }
14028 run_test 124a "lru resize ======================================="
14029
14030 get_max_pool_limit()
14031 {
14032         local limit=$($LCTL get_param \
14033                       -n ldlm.namespaces.*-MDT0000-mdc-*.pool.limit)
14034         local max=0
14035         for l in $limit; do
14036                 if [[ $l -gt $max ]]; then
14037                         max=$l
14038                 fi
14039         done
14040         echo $max
14041 }
14042
14043 test_124b() {
14044         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14045         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
14046                 skip_env "no lru resize on server"
14047
14048         LIMIT=$(get_max_pool_limit)
14049
14050         NR=$(($(default_lru_size)*20))
14051         if [[ $NR -gt $LIMIT ]]; then
14052                 log "Limit lock number by $LIMIT locks"
14053                 NR=$LIMIT
14054         fi
14055
14056         IFree=$(mdsrate_inodes_available)
14057         if [ $IFree -lt $NR ]; then
14058                 log "Limit lock number by $IFree inodes"
14059                 NR=$IFree
14060         fi
14061
14062         lru_resize_disable mdc
14063         test_mkdir -p $DIR/$tdir/disable_lru_resize
14064
14065         createmany -o $DIR/$tdir/disable_lru_resize/f $NR
14066         log "doing ls -la $DIR/$tdir/disable_lru_resize 3 times"
14067         cancel_lru_locks mdc
14068         stime=`date +%s`
14069         PID=""
14070         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
14071         PID="$PID $!"
14072         sleep 2
14073         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
14074         PID="$PID $!"
14075         sleep 2
14076         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
14077         PID="$PID $!"
14078         wait $PID
14079         etime=`date +%s`
14080         nolruresize_delta=$((etime-stime))
14081         log "ls -la time: $nolruresize_delta seconds"
14082         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
14083         unlinkmany $DIR/$tdir/disable_lru_resize/f $NR
14084
14085         lru_resize_enable mdc
14086         test_mkdir -p $DIR/$tdir/enable_lru_resize
14087
14088         createmany -o $DIR/$tdir/enable_lru_resize/f $NR
14089         log "doing ls -la $DIR/$tdir/enable_lru_resize 3 times"
14090         cancel_lru_locks mdc
14091         stime=`date +%s`
14092         PID=""
14093         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
14094         PID="$PID $!"
14095         sleep 2
14096         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
14097         PID="$PID $!"
14098         sleep 2
14099         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
14100         PID="$PID $!"
14101         wait $PID
14102         etime=`date +%s`
14103         lruresize_delta=$((etime-stime))
14104         log "ls -la time: $lruresize_delta seconds"
14105         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
14106
14107         if [ $lruresize_delta -gt $nolruresize_delta ]; then
14108                 log "ls -la is $(((lruresize_delta - $nolruresize_delta) * 100 / $nolruresize_delta))% slower with lru resize enabled"
14109         elif [ $nolruresize_delta -gt $lruresize_delta ]; then
14110                 log "ls -la is $(((nolruresize_delta - $lruresize_delta) * 100 / $nolruresize_delta))% faster with lru resize enabled"
14111         else
14112                 log "lru resize performs the same with no lru resize"
14113         fi
14114         unlinkmany $DIR/$tdir/enable_lru_resize/f $NR
14115 }
14116 run_test 124b "lru resize (performance test) ======================="
14117
14118 test_124c() {
14119         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14120         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
14121                 skip_env "no lru resize on server"
14122
14123         # cache ununsed locks on client
14124         local nr=100
14125         cancel_lru_locks mdc
14126         test_mkdir $DIR/$tdir
14127         createmany -o $DIR/$tdir/f $nr ||
14128                 error "failed to create $nr files in $DIR/$tdir"
14129         ls -l $DIR/$tdir > /dev/null
14130
14131         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
14132         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
14133         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
14134         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
14135         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
14136
14137         # set lru_max_age to 1 sec
14138         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
14139         echo "sleep $((recalc_p * 2)) seconds..."
14140         sleep $((recalc_p * 2))
14141
14142         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
14143         # restore lru_max_age
14144         $LCTL set_param -n $nsdir.lru_max_age $max_age
14145         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
14146         unlinkmany $DIR/$tdir/f $nr
14147 }
14148 run_test 124c "LRUR cancel very aged locks"
14149
14150 test_124d() {
14151         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14152         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
14153                 skip_env "no lru resize on server"
14154
14155         # cache ununsed locks on client
14156         local nr=100
14157
14158         lru_resize_disable mdc
14159         stack_trap "lru_resize_enable mdc" EXIT
14160
14161         cancel_lru_locks mdc
14162
14163         # asynchronous object destroy at MDT could cause bl ast to client
14164         test_mkdir $DIR/$tdir
14165         createmany -o $DIR/$tdir/f $nr ||
14166                 error "failed to create $nr files in $DIR/$tdir"
14167         stack_trap "unlinkmany $DIR/$tdir/f $nr" EXIT
14168
14169         ls -l $DIR/$tdir > /dev/null
14170
14171         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
14172         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
14173         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
14174         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
14175
14176         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
14177
14178         # set lru_max_age to 1 sec
14179         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
14180         stack_trap "$LCTL set_param -n $nsdir.lru_max_age $max_age" EXIT
14181
14182         echo "sleep $((recalc_p * 2)) seconds..."
14183         sleep $((recalc_p * 2))
14184
14185         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
14186
14187         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
14188 }
14189 run_test 124d "cancel very aged locks if lru-resize diasbaled"
14190
14191 test_125() { # 13358
14192         $LCTL get_param -n llite.*.client_type | grep -q local ||
14193                 skip "must run as local client"
14194         $LCTL get_param -n mdc.*-mdc-*.connect_flags | grep -q acl ||
14195                 skip_env "must have acl enabled"
14196         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
14197
14198         test_mkdir $DIR/$tdir
14199         $LFS setstripe -S 65536 -c -1 $DIR/$tdir || error "setstripe failed"
14200         setfacl -R -m u:$USER0:rwx $DIR/$tdir ||
14201                 error "setfacl $DIR/$tdir failed"
14202         ls -ld $DIR/$tdir || error "cannot access $DIR/$tdir"
14203 }
14204 run_test 125 "don't return EPROTO when a dir has a non-default striping and ACLs"
14205
14206 test_126() { # bug 12829/13455
14207         $GSS && skip_env "must run as gss disabled"
14208         $LCTL get_param -n llite.*.client_type | grep -q local ||
14209                 skip "must run as local client"
14210         [ "$UID" != 0 ] && skip "must run as root, not UID $UID"
14211
14212         $RUNAS -u 0 -g 1 touch $DIR/$tfile || error "touch failed"
14213         gid=`ls -n $DIR/$tfile | awk '{print $4}'`
14214         rm -f $DIR/$tfile
14215         [ $gid -eq "1" ] || error "gid is set to" $gid "instead of 1"
14216 }
14217 run_test 126 "check that the fsgid provided by the client is taken into account"
14218
14219 test_127a() { # bug 15521
14220         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14221         local name count samp unit min max sum sumsq
14222         local tmpfile=$TMP/$tfile.tmp
14223
14224         $LFS setstripe -i 0 -c 1 $DIR/$tfile || error "setstripe failed"
14225         echo "stats before reset"
14226         stack_trap "rm -f $tmpfile"
14227         local now=$(date +%s)
14228
14229         $LCTL get_param osc.*.stats | tee $tmpfile
14230
14231         local snapshot_time=$(awk '/snapshot_time/ { print $2; exit }' $tmpfile)
14232         local start_time=$(awk '/start_time/ { print $2; exit }' $tmpfile)
14233         local elapsed=$(awk '/elapsed_time/ { print $2; exit }' $tmpfile)
14234         local uptime=$(awk '{ print $1 }' /proc/uptime)
14235
14236         # snapshot_time should match POSIX epoch time, allow some delta for VMs
14237         (( ${snapshot_time%\.*} >= $now - 5 &&
14238            ${snapshot_time%\.*} <= $now + 5 )) ||
14239                 error "snapshot_time=$snapshot_time != now=$now"
14240         # elapsed _should_ be from mount, but at least less than uptime
14241         (( ${elapsed%\.*} < ${uptime%\.*} )) ||
14242                 error "elapsed=$elapsed > uptime=$uptime"
14243         (( ${snapshot_time%\.*} - ${start_time%\.*} >= ${elapsed%\.*} - 2 &&
14244            ${snapshot_time%\.*} - ${start_time%\.*} <= ${elapsed%\.*} + 2 )) ||
14245                 error "elapsed=$elapsed != $snapshot_time - $start_time"
14246
14247         $LCTL set_param osc.*.stats=0
14248         local reset=$(date +%s)
14249         local fsize=$((2048 * 1024))
14250
14251         dd if=/dev/zero of=$DIR/$tfile bs=$fsize count=1
14252         cancel_lru_locks osc
14253         dd if=$DIR/$tfile of=/dev/null bs=$fsize
14254
14255         now=$(date +%s)
14256         $LCTL get_param osc.*0000-osc-*.stats > $tmpfile
14257         while read name count samp unit min max sum sumsq; do
14258                 [[ "$samp" == "samples" ]] || continue
14259
14260                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
14261                 [ ! $min ] && error "Missing min value for $name proc entry"
14262                 eval $name=$count || error "Wrong proc format"
14263
14264                 case $name in
14265                 read_bytes|write_bytes)
14266                         [[ "$unit" =~ "bytes" ]] ||
14267                                 error "unit is not 'bytes': $unit"
14268                         (( $min >= 4096 )) || error "min is too small: $min"
14269                         (( $min <= $fsize )) || error "min is too big: $min"
14270                         (( $max >= 4096 )) || error "max is too small: $max"
14271                         (( $max <= $fsize )) || error "max is too big: $max"
14272                         (( $sum == $fsize )) || error "sum is wrong: $sum"
14273                         (( $sumsq >= ($fsize / 4096) * (4096 * 4096) )) ||
14274                                 error "sumsquare is too small: $sumsq"
14275                         (( $sumsq <= $fsize * $fsize )) ||
14276                                 error "sumsquare is too big: $sumsq"
14277                         ;;
14278                 ost_read|ost_write)
14279                         [[ "$unit" =~ "usec" ]] ||
14280                                 error "unit is not 'usec': $unit"
14281                         ;;
14282                 *)      ;;
14283                 esac
14284         done < $tmpfile
14285
14286         #check that we actually got some stats
14287         [ "$read_bytes" ] || error "Missing read_bytes stats"
14288         [ "$write_bytes" ] || error "Missing write_bytes stats"
14289         [ "$read_bytes" != 0 ] || error "no read done"
14290         [ "$write_bytes" != 0 ] || error "no write done"
14291
14292         snapshot_time=$(awk '/snapshot_time/ { print $2; exit }' $tmpfile)
14293         start_time=$(awk '/start_time/ { print $2; exit }' $tmpfile)
14294         elapsed=$(awk '/elapsed_time/ { print $2; exit }' $tmpfile)
14295
14296         # snapshot_time should match POSIX epoch time, allow some delta for VMs
14297         (( ${snapshot_time%\.*} >= $now - 5 &&
14298            ${snapshot_time%\.*} <= $now + 5 )) ||
14299                 error "reset snapshot_time=$snapshot_time != now=$now"
14300         # elapsed should be from time of stats reset
14301         (( ${elapsed%\.*} >= $now - $reset - 2 &&
14302            ${elapsed%\.*} <= $now - $reset + 2 )) ||
14303                 error "reset elapsed=$elapsed > $now - $reset"
14304         (( ${snapshot_time%\.*} - ${start_time%\.*} >= ${elapsed%\.*} - 2 &&
14305            ${snapshot_time%\.*} - ${start_time%\.*} <= ${elapsed%\.*} + 2 )) ||
14306                 error "reset elapsed=$elapsed != $snapshot_time - $start_time"
14307 }
14308 run_test 127a "verify the client stats are sane"
14309
14310 test_127b() { # bug LU-333
14311         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14312         local name count samp unit min max sum sumsq
14313
14314         echo "stats before reset"
14315         $LCTL get_param llite.*.stats
14316         $LCTL set_param llite.*.stats=0
14317
14318         # perform 2 reads and writes so MAX is different from SUM.
14319         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
14320         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
14321         cancel_lru_locks osc
14322         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
14323         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
14324
14325         $LCTL get_param llite.*.stats | grep samples > $TMP/$tfile.tmp
14326         stack_trap "rm -f $TMP/$tfile.tmp"
14327         while read name count samp unit min max sum sumsq; do
14328                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
14329                 eval $name=$count || error "Wrong proc format"
14330
14331                 case $name in
14332                 read_bytes|write_bytes)
14333                         [[ "$unit" =~ "bytes" ]] ||
14334                                 error "unit is not 'bytes': $unit"
14335                         (( $count == 2 )) || error "count is not 2: $count"
14336                         (( $min == $PAGE_SIZE )) ||
14337                                 error "min is not $PAGE_SIZE: $min"
14338                         (( $max == $PAGE_SIZE )) ||
14339                                 error "max is not $PAGE_SIZE: $max"
14340                         (( $sum == $PAGE_SIZE * 2 )) ||
14341                                 error "sum is not $((PAGE_SIZE * 2)): $sum"
14342                         ;;
14343                 read|write)
14344                         [[ "$unit" =~ "usec" ]] ||
14345                                 error "unit is not 'usec': $unit"
14346                         ;;
14347                 *)      ;;
14348                 esac
14349         done < $TMP/$tfile.tmp
14350
14351         #check that we actually got some stats
14352         [ "$read_bytes" ] || error "Missing read_bytes stats"
14353         [ "$write_bytes" ] || error "Missing write_bytes stats"
14354         [ "$read_bytes" != 0 ] || error "no read done"
14355         [ "$write_bytes" != 0 ] || error "no write done"
14356 }
14357 run_test 127b "verify the llite client stats are sane"
14358
14359 test_127c() { # LU-12394
14360         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
14361         local size
14362         local bsize
14363         local reads
14364         local writes
14365         local count
14366
14367         $LCTL set_param llite.*.extents_stats=1
14368         stack_trap "$LCTL set_param llite.*.extents_stats=0" EXIT
14369
14370         # Use two stripes so there is enough space in default config
14371         $LFS setstripe -c 2 $DIR/$tfile
14372
14373         # Extent stats start at 0-4K and go in power of two buckets
14374         # LL_HIST_START = 12 --> 2^12 = 4K
14375         # We do 3K*2^i, so 3K, 6K, 12K, 24K... hitting each bucket.
14376         # We do not do buckets larger than 64 MiB to avoid ENOSPC issues on
14377         # small configs
14378         for size in 3K 6K 12K 24K 48K 96K 192K 384K 768K 1536K 3M 6M 12M 24M 48M;
14379                 do
14380                 # Write and read, 2x each, second time at a non-zero offset
14381                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1
14382                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1 seek=10
14383                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1
14384                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1 seek=10
14385                 rm -f $DIR/$tfile
14386         done
14387
14388         $LCTL get_param llite.*.extents_stats
14389
14390         count=2
14391         for bsize in 4K 8K 16K 32K 64K 128K 256K 512K 1M 2M 4M 8M 16M 32M 64M;
14392                 do
14393                 local bucket=$($LCTL get_param -n llite.*.extents_stats |
14394                                 grep -m 1 $bsize)
14395                 reads=$(echo $bucket | awk '{print $5}')
14396                 writes=$(echo $bucket | awk '{print $9}')
14397                 [ "$reads" -eq $count ] ||
14398                         error "$reads reads in < $bsize bucket, expect $count"
14399                 [ "$writes" -eq $count ] ||
14400                         error "$writes writes in < $bsize bucket, expect $count"
14401         done
14402
14403         # Test mmap write and read
14404         $LCTL set_param llite.*.extents_stats=c
14405         size=512
14406         dd if=/dev/zero of=$DIR/$tfile bs=${size}K count=1
14407         $MULTIOP $DIR/$tfile OSMRUc || error "$MULTIOP $DIR/$tfile failed"
14408         $MULTIOP $DIR/$tfile OSMWUc || error "$MULTIOP $DIR/$tfile failed"
14409
14410         $LCTL get_param llite.*.extents_stats
14411
14412         count=$(((size*1024) / PAGE_SIZE))
14413
14414         bsize=$((2 * PAGE_SIZE / 1024))K
14415
14416         bucket=$($LCTL get_param -n llite.*.extents_stats |
14417                         grep -m 1 $bsize)
14418         reads=$(echo $bucket | awk '{print $5}')
14419         writes=$(echo $bucket | awk '{print $9}')
14420         # mmap writes fault in the page first, creating an additonal read
14421         [ "$reads" -eq $((2 * count)) ] ||
14422                 error "$reads reads in < $bsize bucket, expect $count"
14423         [ "$writes" -eq $count ] ||
14424                 error "$writes writes in < $bsize bucket, expect $count"
14425 }
14426 run_test 127c "test llite extent stats with regular & mmap i/o"
14427
14428 test_128() { # bug 15212
14429         touch $DIR/$tfile
14430         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
14431                 find $DIR/$tfile
14432                 find $DIR/$tfile
14433         EOF
14434
14435         result=$(grep error $TMP/$tfile.log)
14436         rm -f $DIR/$tfile $TMP/$tfile.log
14437         [ -z "$result" ] ||
14438                 error "consecutive find's under interactive lfs failed"
14439 }
14440 run_test 128 "interactive lfs for 2 consecutive find's"
14441
14442 set_dir_limits () {
14443         local mntdev
14444         local canondev
14445         local node
14446
14447         local ldproc=/proc/fs/ldiskfs
14448         local facets=$(get_facets MDS)
14449
14450         for facet in ${facets//,/ }; do
14451                 canondev=$(ldiskfs_canon \
14452                            *.$(convert_facet2label $facet).mntdev $facet)
14453                 do_facet $facet "test -e $ldproc/$canondev/max_dir_size" ||
14454                         ldproc=/sys/fs/ldiskfs
14455                 do_facet $facet "echo $1 >$ldproc/$canondev/max_dir_size"
14456                 do_facet $facet "echo $2 >$ldproc/$canondev/warning_dir_size"
14457         done
14458 }
14459
14460 check_mds_dmesg() {
14461         local facets=$(get_facets MDS)
14462         for facet in ${facets//,/ }; do
14463                 do_facet $facet "dmesg | tail -3 | grep $1" && return 0
14464         done
14465         return 1
14466 }
14467
14468 test_129() {
14469         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14470         [[ $MDS1_VERSION -ge $(version_code 2.5.56) ]] ||
14471                 skip "Need MDS version with at least 2.5.56"
14472         if [ "$mds1_FSTYPE" != ldiskfs ]; then
14473                 skip_env "ldiskfs only test"
14474         fi
14475         remote_mds_nodsh && skip "remote MDS with nodsh"
14476
14477         local ENOSPC=28
14478         local has_warning=false
14479
14480         rm -rf $DIR/$tdir
14481         mkdir -p $DIR/$tdir
14482
14483         # block size of mds1
14484         local maxsize=$(($($LCTL get_param -n mdc.*MDT0000*.blocksize) * 8))
14485         set_dir_limits $maxsize $((maxsize * 6 / 8))
14486         stack_trap "set_dir_limits 0 0"
14487         stack_trap "unlinkmany $DIR/$tdir/file_base_ 2000 || true"
14488         local dirsize=$(stat -c%s "$DIR/$tdir")
14489         local nfiles=0
14490         while (( $dirsize <= $maxsize )); do
14491                 $MCREATE $DIR/$tdir/file_base_$nfiles
14492                 rc=$?
14493                 # check two errors:
14494                 # ENOSPC for ext4 max_dir_size, which has been used since
14495                 # kernel v3.6-rc1-8-gdf981d03ee, lustre v2_4_50_0-79-gaed82035c0
14496                 if (( rc == ENOSPC )); then
14497                         set_dir_limits 0 0
14498                         echo "rc=$rc returned as expected after $nfiles files"
14499
14500                         createmany -o $DIR/$tdir/file_extra_$nfiles. 5 ||
14501                                 error "create failed w/o dir size limit"
14502
14503                         # messages may be rate limited if test is run repeatedly
14504                         check_mds_dmesg '"is approaching max"' ||
14505                                 echo "warning message should be output"
14506                         check_mds_dmesg '"has reached max"' ||
14507                                 echo "reached message should be output"
14508
14509                         dirsize=$(stat -c%s "$DIR/$tdir")
14510
14511                         [[ $dirsize -ge $maxsize ]] && return 0
14512                         error "dirsize $dirsize < $maxsize after $nfiles files"
14513                 elif (( rc != 0 )); then
14514                         break
14515                 fi
14516                 nfiles=$((nfiles + 1))
14517                 dirsize=$(stat -c%s "$DIR/$tdir")
14518         done
14519
14520         error "rc=$rc, size=$dirsize/$maxsize, mdt=$MDSCOUNT, nfiles=$nfiles"
14521 }
14522 run_test 129 "test directory size limit ========================"
14523
14524 OLDIFS="$IFS"
14525 cleanup_130() {
14526         trap 0
14527         IFS="$OLDIFS"
14528 }
14529
14530 test_130a() {
14531         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
14532         [[ -z "$filefrag_op" ]] || skip_env "filefrag does not support FIEMAP"
14533
14534         trap cleanup_130 EXIT RETURN
14535
14536         local fm_file=$DIR/$tfile
14537         $LFS setstripe -S 65536 -c 1 $fm_file || error "setstripe on $fm_file"
14538         dd if=/dev/zero of=$fm_file bs=65536 count=1 ||
14539                 error "dd failed for $fm_file"
14540
14541         # LU-1795: test filefrag/FIEMAP once, even if unsupported on ZFS
14542         filefrag -ves $fm_file
14543         local rc=$?
14544         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14545                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14546         (( $rc == 0 )) || error "filefrag $fm_file failed"
14547
14548         filefrag_op=$(filefrag -ve -k $fm_file |
14549                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
14550         local lun=$($LFS getstripe -i $fm_file)
14551
14552         local start_blk=$(echo $filefrag_op | cut -d: -f2 | cut -d. -f1)
14553         IFS=$'\n'
14554         local tot_len=0
14555         for line in $filefrag_op; do
14556                 local frag_lun=$(echo $line | cut -d: -f5)
14557                 local ext_len=$(echo $line | cut -d: -f4)
14558
14559                 if (( $frag_lun != $lun )); then
14560                         error "FIEMAP on 1-stripe file($fm_file) failed"
14561                         return
14562                 fi
14563                 (( tot_len += ext_len ))
14564         done
14565
14566         if (( lun != frag_lun || start_blk != 0 || tot_len != 64 )); then
14567                 error "FIEMAP on 1-stripe file($fm_file) failed"
14568                 return
14569         fi
14570
14571         echo "FIEMAP on single striped file succeeded"
14572 }
14573 run_test 130a "FIEMAP (1-stripe file)"
14574
14575 test_130b() {
14576         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
14577
14578         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
14579         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
14580         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14581                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14582
14583         trap cleanup_130 EXIT RETURN
14584
14585         local fm_file=$DIR/$tfile
14586         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
14587                 error "setstripe on $fm_file"
14588
14589         dd if=/dev/zero of=$fm_file bs=1M count=$OSTCOUNT ||
14590                 error "dd failed on $fm_file"
14591
14592         filefrag -ves $fm_file || error "filefrag $fm_file failed"
14593         filefrag_op=$(filefrag -ve -k $fm_file |
14594                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
14595
14596         local last_lun=$(echo $filefrag_op | cut -d: -f5 |
14597                          sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14598
14599         IFS=$'\n'
14600         local tot_len=0
14601         local num_luns=1
14602
14603         for line in $filefrag_op; do
14604                 local frag_lun=$(echo $line | cut -d: -f5 |
14605                                  sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14606                 local ext_len=$(echo $line | cut -d: -f4)
14607                 if (( $frag_lun != $last_lun )); then
14608                         if (( tot_len != 1024 )); then
14609                                 error "FIEMAP on $fm_file failed; returned len $tot_len for OST $last_lun instead of 1024"
14610                                 return
14611                         else
14612                                 (( num_luns += 1 ))
14613                                 tot_len=0
14614                         fi
14615                 fi
14616                 (( tot_len += ext_len ))
14617                 last_lun=$frag_lun
14618         done
14619         if (( num_luns != $OSTCOUNT || tot_len != 1024 )); then
14620                 error "FIEMAP on $fm_file failed; returned wrong number of luns or wrong len for OST $last_lun"
14621                 return
14622         fi
14623
14624         echo "FIEMAP on $OSTCOUNT-stripe file succeeded"
14625 }
14626 run_test 130b "FIEMAP ($OSTCOUNT-stripe file)"
14627
14628 test_130c() {
14629         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
14630
14631         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
14632         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
14633         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14634                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14635
14636         trap cleanup_130 EXIT RETURN
14637
14638         local fm_file=$DIR/$tfile
14639         $LFS setstripe -S 65536 -c 2 $fm_file || error "setstripe on $fm_file"
14640
14641         dd if=/dev/zero of=$fm_file seek=1 bs=1M count=1 ||
14642                 error "dd failed on $fm_file"
14643
14644         filefrag -ves $fm_file || error "filefrag $fm_file failed"
14645         filefrag_op=$(filefrag -ve -k $fm_file |
14646                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
14647
14648         local last_lun=$(echo $filefrag_op | cut -d: -f5 |
14649                          sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14650
14651         IFS=$'\n'
14652         local tot_len=0
14653         local num_luns=1
14654         for line in $filefrag_op; do
14655                 local frag_lun=$(echo $line | cut -d: -f5 |
14656                                  sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14657                 local ext_len=$(echo $line | cut -d: -f4)
14658                 if (( $frag_lun != $last_lun )); then
14659                         local logical=$(echo $line | cut -d: -f2 | cut -d. -f1)
14660                         if (( logical != 512 )); then
14661                                 error "FIEMAP on $fm_file failed; returned logical start for lun $logical instead of 512"
14662                                 return
14663                         fi
14664                         if (( tot_len != 512 )); then
14665                                 error "FIEMAP on $fm_file failed; returned len $tot_len for OST $last_lun instead of 1024"
14666                                 return
14667                         else
14668                                 (( num_luns += 1 ))
14669                                 tot_len=0
14670                         fi
14671                 fi
14672                 (( tot_len += ext_len ))
14673                 last_lun=$frag_lun
14674         done
14675         if (( num_luns != 2 || tot_len != 512 )); then
14676                 error "FIEMAP on $fm_file failed; returned wrong number of luns or wrong len for OST $last_lun"
14677                 return
14678         fi
14679
14680         echo "FIEMAP on 2-stripe file with hole succeeded"
14681 }
14682 run_test 130c "FIEMAP (2-stripe file with hole)"
14683
14684 test_130d() {
14685         (( $OSTCOUNT >= 3 )) || skip "needs >= 3 OSTs"
14686
14687         filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
14688         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
14689         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14690                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14691
14692         trap cleanup_130 EXIT RETURN
14693
14694         local fm_file=$DIR/$tfile
14695         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
14696                         error "setstripe on $fm_file"
14697
14698         local actual_stripe_count=$($LFS getstripe -c $fm_file)
14699         dd if=/dev/zero of=$fm_file bs=1M count=$actual_stripe_count ||
14700                 error "dd failed on $fm_file"
14701
14702         filefrag -ves $fm_file || error "filefrag $fm_file failed"
14703         filefrag_op=$(filefrag -ve -k $fm_file |
14704                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
14705
14706         local last_lun=$(echo $filefrag_op | cut -d: -f5 |
14707                          sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14708
14709         IFS=$'\n'
14710         local tot_len=0
14711         local num_luns=1
14712         for line in $filefrag_op; do
14713                 local frag_lun=$(echo $line | cut -d: -f5 |
14714                                  sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14715                 local ext_len=$(echo $line | cut -d: -f4)
14716                 if (( $frag_lun != $last_lun )); then
14717                         if (( tot_len != 1024 )); then
14718                                 error "FIEMAP on $fm_file failed; returned len $tot_len for OST $last_lun instead of 1024"
14719                                 return
14720                         else
14721                                 (( num_luns += 1 ))
14722                                 local tot_len=0
14723                         fi
14724                 fi
14725                 (( tot_len += ext_len ))
14726                 last_lun=$frag_lun
14727         done
14728         if (( num_luns != actual_stripe_count || tot_len != 1024 )); then
14729                 error "FIEMAP on $fm_file failed; returned wrong number of luns or wrong len for OST $last_lun"
14730                 return
14731         fi
14732
14733         echo "FIEMAP on N-stripe file succeeded"
14734 }
14735 run_test 130d "FIEMAP (N-stripe file)"
14736
14737 test_130e() {
14738         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
14739
14740         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
14741         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
14742         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14743                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14744
14745         trap cleanup_130 EXIT RETURN
14746
14747         local fm_file=$DIR/$tfile
14748         $LFS setstripe -S 131072 -c 2 $fm_file || error "setstripe on $fm_file"
14749
14750         local num_blks=512
14751         local expected_len=$(( (num_blks / 2) * 64 ))
14752         for ((i = 0; i < $num_blks; i++)); do
14753                 dd if=/dev/zero of=$fm_file count=1 bs=64k seek=$((2*$i)) \
14754                         conv=notrunc > /dev/null 2>&1
14755         done
14756
14757         filefrag -ves $fm_file || error "filefrag $fm_file failed"
14758         filefrag_op=$(filefrag -ve -k $fm_file |
14759                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
14760
14761         local last_lun=$(echo $filefrag_op | cut -d: -f5)
14762
14763         IFS=$'\n'
14764         local tot_len=0
14765         local num_luns=1
14766         for line in $filefrag_op; do
14767                 local frag_lun=$(echo $line | cut -d: -f5)
14768                 local ext_len=$(echo $line | cut -d: -f4)
14769                 if (( $frag_lun != $last_lun )); then
14770                         if (( tot_len != $expected_len )); then
14771                                 error "OST$last_lun $tot_len != $expected_len"
14772                         else
14773                                 (( num_luns += 1 ))
14774                                 tot_len=0
14775                         fi
14776                 fi
14777                 (( tot_len += ext_len ))
14778                 last_lun=$frag_lun
14779         done
14780         if (( num_luns != 2 || tot_len != $expected_len )); then
14781                 error "OST$last_lun $num_luns != 2, $tot_len != $expected_len"
14782         fi
14783
14784         echo "FIEMAP with continuation calls succeeded"
14785 }
14786 run_test 130e "FIEMAP (test continuation FIEMAP calls)"
14787
14788 test_130f() {
14789         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
14790         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
14791         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14792                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14793
14794         local fm_file=$DIR/$tfile
14795         $MULTIOP $fm_file oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T33554432c ||
14796                 error "multiop create with lov_delay_create on $fm_file"
14797
14798         filefrag -ves $fm_file || error "filefrag $fm_file failed"
14799         filefrag_extents=$(filefrag -vek $fm_file |
14800                            awk '/extents? found/ { print $2 }')
14801         if (( $filefrag_extents != 0 )); then
14802                 error "$fm_file: filefrag_extents=$filefrag_extents != 0"
14803         fi
14804
14805         rm -f $fm_file
14806 }
14807 run_test 130f "FIEMAP (unstriped file)"
14808
14809 test_130g() {
14810         (( $MDS1_VERSION >= $(version_code 2.12.53) )) ||
14811                 skip "Need MDS version with at least 2.12.53 for overstriping"
14812         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
14813         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
14814         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14815                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14816
14817         local file=$DIR/$tfile
14818         local nr=$((OSTCOUNT * 100))
14819
14820         $LFS setstripe -C $nr $file || error "failed to setstripe -C $nr $file"
14821
14822         stack_trap "rm -f $file"
14823         dd if=/dev/zero of=$file count=$nr bs=1M
14824         sync
14825         nr=$($LFS getstripe -c $file)
14826
14827         local extents=$(filefrag -v $file |
14828                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}' | wc -l)
14829
14830         echo "filefrag list $extents extents in file with stripecount $nr"
14831         if (( extents < nr )); then
14832                 $LFS getstripe $file
14833                 filefrag -v $file
14834                 error "filefrag printed $extents < $nr extents"
14835         fi
14836 }
14837 run_test 130g "FIEMAP (overstripe file)"
14838
14839 # Test for writev/readv
14840 test_131a() {
14841         rwv -f $DIR/$tfile -w -n 3 524288 1048576 1572864 ||
14842                 error "writev test failed"
14843         rwv -f $DIR/$tfile -r -v -n 2 1572864 1048576 ||
14844                 error "readv failed"
14845         rm -f $DIR/$tfile
14846 }
14847 run_test 131a "test iov's crossing stripe boundary for writev/readv"
14848
14849 test_131b() {
14850         local fsize=$((524288 + 1048576 + 1572864))
14851         rwv -f $DIR/$tfile -w -a -n 3 524288 1048576 1572864 &&
14852                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
14853                         error "append writev test failed"
14854
14855         ((fsize += 1572864 + 1048576))
14856         rwv -f $DIR/$tfile -w -a -n 2 1572864 1048576 &&
14857                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
14858                         error "append writev test failed"
14859         rm -f $DIR/$tfile
14860 }
14861 run_test 131b "test append writev"
14862
14863 test_131c() {
14864         rwv -f $DIR/$tfile -w -d -n 1 1048576 || return 0
14865         error "NOT PASS"
14866 }
14867 run_test 131c "test read/write on file w/o objects"
14868
14869 test_131d() {
14870         rwv -f $DIR/$tfile -w -n 1 1572864
14871         NOB=`rwv -f $DIR/$tfile -r -n 3 524288 524288 1048576 | awk '/error/ {print $6}'`
14872         if [ "$NOB" != 1572864 ]; then
14873                 error "Short read filed: read $NOB bytes instead of 1572864"
14874         fi
14875         rm -f $DIR/$tfile
14876 }
14877 run_test 131d "test short read"
14878
14879 test_131e() {
14880         rwv -f $DIR/$tfile -w -s 1048576 -n 1 1048576
14881         rwv -f $DIR/$tfile -r -z -s 0 -n 1 524288 || \
14882         error "read hitting hole failed"
14883         rm -f $DIR/$tfile
14884 }
14885 run_test 131e "test read hitting hole"
14886
14887 check_stats() {
14888         local facet=$1
14889         local op=$2
14890         local want=${3:-0}
14891         local res
14892
14893         # open             11 samples [usecs] 468 4793 13658 35791898
14894         case $facet in
14895         mds*) res=($(do_facet $facet \
14896                    $LCTL get_param mdt.$FSNAME-MDT0000.md_stats | grep "$op"))
14897                  ;;
14898         ost*) res=($(do_facet $facet \
14899                   $LCTL get_param obdfilter.$FSNAME-OST0000.stats | grep "$op"))
14900                  ;;
14901         *) error "Wrong facet '$facet'" ;;
14902         esac
14903         [[ -n "$res" ]] || error "counter for $op on $facet not incremented"
14904         # if $want is zero, it means any stat increment is ok.
14905         if (( $want > 0 )); then
14906                 local count=${res[1]}
14907
14908                 if (( $count != $want )); then
14909                         if [[ $facet =~ "mds" ]]; then
14910                                 do_nodes $(comma_list $(mdts_nodes)) \
14911                                         $LCTL get_param mdt.*.md_stats
14912                         else
14913                                 do_nodes $(comma_list $(osts-nodes)) \
14914                                         $LCTL get_param obdfilter.*.stats
14915                         fi
14916                         error "The $op counter on $facet is $count, not $want"
14917                 fi
14918         fi
14919 }
14920
14921 test_133a() {
14922         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14923         remote_ost_nodsh && skip "remote OST with nodsh"
14924         remote_mds_nodsh && skip "remote MDS with nodsh"
14925         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
14926                 skip_env "MDS doesn't support rename stats"
14927
14928         local testdir=$DIR/${tdir}/stats_testdir
14929
14930         mkdir -p $DIR/${tdir}
14931
14932         # clear stats.
14933         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14934         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
14935
14936         # verify mdt stats first.
14937         mkdir_on_mdt0 ${testdir} || error "mkdir_on_mdt0 failed"
14938         check_stats $SINGLEMDS "mkdir" 1
14939
14940         # clear "open" from "lfs mkdir" above
14941         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14942         touch ${testdir}/${tfile} || error "touch failed"
14943         check_stats $SINGLEMDS "open" 1
14944         check_stats $SINGLEMDS "close" 1
14945         [ $MDS1_VERSION -ge $(version_code 2.8.54) ] && {
14946                 mknod ${testdir}/${tfile}-pipe p || error "mknod failed"
14947                 check_stats $SINGLEMDS "mknod" 2
14948         }
14949         rm -f ${testdir}/${tfile}-pipe || error "pipe remove failed"
14950         check_stats $SINGLEMDS "unlink" 1
14951         rm -f ${testdir}/${tfile} || error "file remove failed"
14952         check_stats $SINGLEMDS "unlink" 2
14953
14954         # remove working dir and check mdt stats again.
14955         rmdir ${testdir} || error "rmdir failed"
14956         check_stats $SINGLEMDS "rmdir" 1
14957
14958         local testdir1=$DIR/${tdir}/stats_testdir1
14959         mkdir_on_mdt0 -p ${testdir}
14960         mkdir_on_mdt0 -p ${testdir1}
14961         touch ${testdir1}/test1
14962         mv ${testdir1}/test1 ${testdir} || error "file crossdir rename"
14963         check_stats $SINGLEMDS "crossdir_rename" 1
14964
14965         mv ${testdir}/test1 ${testdir}/test0 || error "file samedir rename"
14966         check_stats $SINGLEMDS "samedir_rename" 1
14967
14968         rm -rf $DIR/${tdir}
14969 }
14970 run_test 133a "Verifying MDT stats ========================================"
14971
14972 test_133b() {
14973         local res
14974
14975         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14976         remote_ost_nodsh && skip "remote OST with nodsh"
14977         remote_mds_nodsh && skip "remote MDS with nodsh"
14978
14979         local testdir=$DIR/${tdir}/stats_testdir
14980
14981         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
14982         mkdir_on_mdt0 ${testdir} || error "mkdir_on_mdt0 failed"
14983         touch ${testdir}/${tfile} || error "touch failed"
14984         cancel_lru_locks mdc
14985
14986         # clear stats.
14987         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14988         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
14989
14990         # extra mdt stats verification.
14991         chmod 444 ${testdir}/${tfile} || error "chmod failed"
14992         check_stats $SINGLEMDS "setattr" 1
14993         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14994         if [ $MDS1_VERSION -ne $(version_code 2.2.0) ]
14995         then            # LU-1740
14996                 ls -l ${testdir}/${tfile} > /dev/null|| error "ls failed"
14997                 check_stats $SINGLEMDS "getattr" 1
14998         fi
14999         rm -rf $DIR/${tdir}
15000
15001         # when DNE is enabled, MDT uses STATFS RPC to ping other targets
15002         # so the check below is not reliable
15003         [ $MDSCOUNT -eq 1 ] || return 0
15004
15005         # Sleep to avoid a cached response.
15006         #define OBD_STATFS_CACHE_SECONDS 1
15007         sleep 2
15008         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15009         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
15010         $LFS df || error "lfs failed"
15011         check_stats $SINGLEMDS "statfs" 1
15012
15013         # check aggregated statfs (LU-10018)
15014         [ $MDS1_VERSION -lt $(version_code 2.11.54) ] &&
15015                 return 0
15016         [ $CLIENT_VERSION -lt $(version_code 2.11.54) ] &&
15017                 return 0
15018         sleep 2
15019         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15020         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
15021         df $DIR
15022         check_stats $SINGLEMDS "statfs" 1
15023
15024         # We want to check that the client didn't send OST_STATFS to
15025         # ost1 but the MDT also uses OST_STATFS for precreate. So some
15026         # extra care is needed here.
15027         if remote_mds; then
15028                 local nid=$($LCTL list_nids | head -1 | sed  "s/\./\\\./g")
15029                 local param="obdfilter.$FSNAME-OST0000.exports.'$nid'.stats"
15030
15031                 res=$(do_facet ost1 $LCTL get_param $param | grep statfs)
15032                 [ "$res" ] && error "OST got STATFS"
15033         fi
15034
15035         return 0
15036 }
15037 run_test 133b "Verifying extra MDT stats =================================="
15038
15039 test_133c() {
15040         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15041         remote_ost_nodsh && skip "remote OST with nodsh"
15042         remote_mds_nodsh && skip "remote MDS with nodsh"
15043
15044         local testdir=$DIR/$tdir/stats_testdir
15045
15046         test_mkdir -p $testdir
15047
15048         # verify obdfilter stats.
15049         $LFS setstripe -c 1 -i 0 $testdir/$tfile
15050         sync
15051         cancel_lru_locks osc
15052         wait_delete_completed
15053
15054         # clear stats.
15055         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15056         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
15057
15058         dd if=/dev/zero of=$testdir/$tfile conv=notrunc bs=512k count=1 ||
15059                 error "dd failed"
15060         sync
15061         cancel_lru_locks osc
15062         check_stats ost1 "write" 1
15063
15064         dd if=$testdir/$tfile of=/dev/null bs=1k count=1 || error "dd failed"
15065         check_stats ost1 "read" 1
15066
15067         > $testdir/$tfile || error "truncate failed"
15068         check_stats ost1 "punch" 1
15069
15070         rm -f $testdir/$tfile || error "file remove failed"
15071         wait_delete_completed
15072         check_stats ost1 "destroy" 1
15073
15074         rm -rf $DIR/$tdir
15075 }
15076 run_test 133c "Verifying OST stats ========================================"
15077
15078 order_2() {
15079         local value=$1
15080         local orig=$value
15081         local order=1
15082
15083         while [ $value -ge 2 ]; do
15084                 order=$((order*2))
15085                 value=$((value/2))
15086         done
15087
15088         if [ $orig -gt $order ]; then
15089                 order=$((order*2))
15090         fi
15091         echo $order
15092 }
15093
15094 size_in_KMGT() {
15095     local value=$1
15096     local size=('K' 'M' 'G' 'T');
15097     local i=0
15098     local size_string=$value
15099
15100     while [ $value -ge 1024 ]; do
15101         if [ $i -gt 3 ]; then
15102             #T is the biggest unit we get here, if that is bigger,
15103             #just return XXXT
15104             size_string=${value}T
15105             break
15106         fi
15107         value=$((value >> 10))
15108         if [ $value -lt 1024 ]; then
15109             size_string=${value}${size[$i]}
15110             break
15111         fi
15112         i=$((i + 1))
15113     done
15114
15115     echo $size_string
15116 }
15117
15118 get_rename_size() {
15119         local size=$1
15120         local context=${2:-.}
15121         local sample=$(do_facet $SINGLEMDS $LCTL \
15122                 get_param mdt.$FSNAME-MDT0000.rename_stats |
15123                 grep -A1 $context |
15124                 awk '/ '${size}'/ {print $4}' | sed -e "s/,//g")
15125         echo $sample
15126 }
15127
15128 test_133d() {
15129         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15130         remote_ost_nodsh && skip "remote OST with nodsh"
15131         remote_mds_nodsh && skip "remote MDS with nodsh"
15132         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
15133                 skip_env "MDS doesn't support rename stats"
15134
15135         local testdir1=$DIR/${tdir}/stats_testdir1
15136         local testdir2=$DIR/${tdir}/stats_testdir2
15137         mkdir -p $DIR/${tdir} || error "mkdir $tdir failed"
15138
15139         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
15140
15141         mkdir_on_mdt0 ${testdir1} || error "mkdir $testdir1 failed"
15142         mkdir_on_mdt0 ${testdir2} || error "mkdir $testdir2 failed"
15143
15144         createmany -o $testdir1/test 512 || error "createmany failed"
15145
15146         # check samedir rename size
15147         mv ${testdir1}/test0 ${testdir1}/test_0
15148
15149         local testdir1_size=$(ls -l $DIR/${tdir} |
15150                 awk '/stats_testdir1/ {print $5}')
15151         local testdir2_size=$(ls -l $DIR/${tdir} |
15152                 awk '/stats_testdir2/ {print $5}')
15153
15154         testdir1_size=$(order_2 $testdir1_size)
15155         testdir2_size=$(order_2 $testdir2_size)
15156
15157         testdir1_size=$(size_in_KMGT $testdir1_size)
15158         testdir2_size=$(size_in_KMGT $testdir2_size)
15159
15160         echo "source rename dir size: ${testdir1_size}"
15161         echo "target rename dir size: ${testdir2_size}"
15162
15163         local cmd="do_facet $SINGLEMDS $LCTL "
15164         cmd+="get_param mdt.$FSNAME-MDT0000.rename_stats"
15165
15166         eval $cmd || error "$cmd failed"
15167         local samedir=$($cmd | grep 'same_dir')
15168         local same_sample=$(get_rename_size $testdir1_size)
15169         [ -z "$samedir" ] && error "samedir_rename_size count error"
15170         [[ $same_sample -eq 1 ]] ||
15171                 error "samedir_rename_size error $same_sample"
15172         echo "Check same dir rename stats success"
15173
15174         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
15175
15176         # check crossdir rename size
15177         mv ${testdir1}/test_0 ${testdir2}/test_0
15178
15179         testdir1_size=$(ls -l $DIR/${tdir} |
15180                 awk '/stats_testdir1/ {print $5}')
15181         testdir2_size=$(ls -l $DIR/${tdir} |
15182                 awk '/stats_testdir2/ {print $5}')
15183
15184         testdir1_size=$(order_2 $testdir1_size)
15185         testdir2_size=$(order_2 $testdir2_size)
15186
15187         testdir1_size=$(size_in_KMGT $testdir1_size)
15188         testdir2_size=$(size_in_KMGT $testdir2_size)
15189
15190         echo "source rename dir size: ${testdir1_size}"
15191         echo "target rename dir size: ${testdir2_size}"
15192
15193         eval $cmd || error "$cmd failed"
15194         local crossdir=$($cmd | grep 'crossdir')
15195         local src_sample=$(get_rename_size $testdir1_size crossdir_src)
15196         local tgt_sample=$(get_rename_size $testdir2_size crossdir_tgt)
15197         [ -z "$crossdir" ] && error "crossdir_rename_size count error"
15198         [[ $src_sample -eq 1 ]] ||
15199                 error "crossdir_rename_size error $src_sample"
15200         [[ $tgt_sample -eq 1 ]] ||
15201                 error "crossdir_rename_size error $tgt_sample"
15202         echo "Check cross dir rename stats success"
15203         rm -rf $DIR/${tdir}
15204 }
15205 run_test 133d "Verifying rename_stats ========================================"
15206
15207 test_133e() {
15208         remote_mds_nodsh && skip "remote MDS with nodsh"
15209         remote_ost_nodsh && skip "remote OST with nodsh"
15210         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15211
15212         local testdir=$DIR/${tdir}/stats_testdir
15213         local ctr f0 f1 bs=32768 count=42 sum
15214
15215         mkdir -p ${testdir} || error "mkdir failed"
15216
15217         $LFS setstripe -c 1 -i 0 ${testdir}/${tfile}
15218
15219         for ctr in {write,read}_bytes; do
15220                 sync
15221                 cancel_lru_locks osc
15222
15223                 do_facet ost1 $LCTL set_param -n \
15224                         "obdfilter.*.exports.clear=clear"
15225
15226                 if [ $ctr = write_bytes ]; then
15227                         f0=/dev/zero
15228                         f1=${testdir}/${tfile}
15229                 else
15230                         f0=${testdir}/${tfile}
15231                         f1=/dev/null
15232                 fi
15233
15234                 dd if=$f0 of=$f1 conv=notrunc bs=$bs count=$count || \
15235                         error "dd failed"
15236                 sync
15237                 cancel_lru_locks osc
15238
15239                 sum=$(do_facet ost1 $LCTL get_param \
15240                         "obdfilter.*.exports.*.stats" |
15241                         awk -v ctr=$ctr 'BEGIN { sum = 0 }
15242                                 $1 == ctr { sum += $7 }
15243                                 END { printf("%0.0f", sum) }')
15244
15245                 if ((sum != bs * count)); then
15246                         error "Bad $ctr sum, expected $((bs * count)), got $sum"
15247                 fi
15248         done
15249
15250         rm -rf $DIR/${tdir}
15251 }
15252 run_test 133e "Verifying OST {read,write}_bytes nid stats ================="
15253
15254 test_133f() {
15255         [[ $(lustre_version_code $facet) -ge $(version_code 2.7.65) ]] ||
15256                 skip "too old lustre for get_param -R ($facet_ver)"
15257
15258         # verifying readability.
15259         $LCTL get_param -R '*' &> /dev/null
15260
15261         # Verifing writability with badarea_io.
15262         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
15263         local skipped_params='force_lbug|changelog_mask|daemon_file'
15264         $LCTL list_param -FR '*' | grep '=' | tr -d = |
15265                 egrep -v "$skipped_params" |
15266                 xargs -n 1 find $proc_dirs -name |
15267                 xargs -n 1 badarea_io ||
15268                 error "client badarea_io failed"
15269
15270         # remount the FS in case writes/reads /proc break the FS
15271         cleanup || error "failed to unmount"
15272         setup || error "failed to setup"
15273 }
15274 run_test 133f "Check reads/writes of client lustre proc files with bad area io"
15275
15276 test_133g() {
15277         remote_mds_nodsh && skip "remote MDS with nodsh"
15278         remote_ost_nodsh && skip "remote OST with nodsh"
15279
15280         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
15281         local skipped_params="'force_lbug|changelog_mask|daemon_file'"
15282         local facet
15283         for facet in mds1 ost1; do
15284                 local facet_ver=$(lustre_version_code $facet)
15285                 if [ $facet_ver -ge $(version_code 2.7.65) ]; then
15286                         do_facet $facet "$LCTL get_param -R '*'" &> /dev/null
15287                 else
15288                         log "$facet: too old lustre for get_param -R"
15289                 fi
15290                 if [ $facet_ver -ge $(version_code 2.5.54) ]; then
15291                         do_facet $facet "$LCTL list_param -FR '*' | grep '=' |
15292                                 tr -d = | egrep -v $skipped_params |
15293                                 xargs -n 1 find $proc_dirs -name |
15294                                 xargs -n 1 badarea_io" ||
15295                                         error "$facet badarea_io failed"
15296                 else
15297                         skip_noexit "$facet: too old lustre for get_param -R"
15298                 fi
15299         done
15300
15301         # remount the FS in case writes/reads /proc break the FS
15302         cleanup || error "failed to unmount"
15303         setup || error "failed to setup"
15304 }
15305 run_test 133g "Check reads/writes of server lustre proc files with bad area io"
15306
15307 test_133h() {
15308         remote_mds_nodsh && skip "remote MDS with nodsh"
15309         remote_ost_nodsh && skip "remote OST with nodsh"
15310         [[ $MDS1_VERSION -lt $(version_code 2.9.54) ]] &&
15311                 skip "Need MDS version at least 2.9.54"
15312
15313         local facet
15314         for facet in client mds1 ost1; do
15315                 # Get the list of files that are missing the terminating newline
15316                 local plist=$(do_facet $facet
15317                         $LCTL list_param -FR '*' | grep '=' | tr -d =)
15318                 local ent
15319                 for ent in $plist; do
15320                         local missing=$(do_facet $facet $LCTL get_param $ent \|\
15321                                 awk -v FS='\v' -v RS='\v\v' \
15322                                 "'END { if(NR>0 && \\\$NF !~ /.*\\\n\$/) \
15323                                         print FILENAME}'" 2>/dev/null)
15324                         [ -z $missing ] || {
15325                                 do_facet $facet $LCTL get_param $ent | od -An -tx1
15326                                 error "file does not end with newline: $facet-$ent"
15327                         }
15328                 done
15329         done
15330 }
15331 run_test 133h "Proc files should end with newlines"
15332
15333 test_134a() {
15334         remote_mds_nodsh && skip "remote MDS with nodsh"
15335         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
15336                 skip "Need MDS version at least 2.7.54"
15337
15338         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
15339         cancel_lru_locks mdc
15340
15341         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
15342         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
15343         [ $unused -eq 0 ] || error "$unused locks are not cleared"
15344
15345         local nr=1000
15346         createmany -o $DIR/$tdir/f $nr ||
15347                 error "failed to create $nr files in $DIR/$tdir"
15348         unused=$($LCTL get_param -n $nsdir.lock_unused_count)
15349
15350         #define OBD_FAIL_LDLM_WATERMARK_LOW     0x327
15351         do_facet mds1 $LCTL set_param fail_loc=0x327
15352         do_facet mds1 $LCTL set_param fail_val=500
15353         touch $DIR/$tdir/m
15354
15355         echo "sleep 10 seconds ..."
15356         sleep 10
15357         local lck_cnt=$($LCTL get_param -n $nsdir.lock_unused_count)
15358
15359         do_facet mds1 $LCTL set_param fail_loc=0
15360         do_facet mds1 $LCTL set_param fail_val=0
15361         [ $lck_cnt -lt $unused ] ||
15362                 error "No locks reclaimed, before:$unused, after:$lck_cnt"
15363
15364         rm $DIR/$tdir/m
15365         unlinkmany $DIR/$tdir/f $nr
15366 }
15367 run_test 134a "Server reclaims locks when reaching lock_reclaim_threshold"
15368
15369 test_134b() {
15370         remote_mds_nodsh && skip "remote MDS with nodsh"
15371         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
15372                 skip "Need MDS version at least 2.7.54"
15373
15374         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
15375         cancel_lru_locks mdc
15376
15377         local low_wm=$(do_facet mds1 $LCTL get_param -n \
15378                         ldlm.lock_reclaim_threshold_mb)
15379         # disable reclaim temporarily
15380         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=0
15381
15382         #define OBD_FAIL_LDLM_WATERMARK_HIGH     0x328
15383         do_facet mds1 $LCTL set_param fail_loc=0x328
15384         do_facet mds1 $LCTL set_param fail_val=500
15385
15386         $LCTL set_param debug=+trace
15387
15388         local nr=600
15389         createmany -o $DIR/$tdir/f $nr &
15390         local create_pid=$!
15391
15392         echo "Sleep $TIMEOUT seconds ..."
15393         sleep $TIMEOUT
15394         if ! ps -p $create_pid  > /dev/null 2>&1; then
15395                 do_facet mds1 $LCTL set_param fail_loc=0
15396                 do_facet mds1 $LCTL set_param fail_val=0
15397                 do_facet mds1 $LCTL set_param \
15398                         ldlm.lock_reclaim_threshold_mb=${low_wm}m
15399                 error "createmany finished incorrectly!"
15400         fi
15401         do_facet mds1 $LCTL set_param fail_loc=0
15402         do_facet mds1 $LCTL set_param fail_val=0
15403         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=${low_wm}m
15404         wait $create_pid || return 1
15405
15406         unlinkmany $DIR/$tdir/f $nr
15407 }
15408 run_test 134b "Server rejects lock request when reaching lock_limit_mb"
15409
15410 test_135() {
15411         remote_mds_nodsh && skip "remote MDS with nodsh"
15412         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
15413                 skip "Need MDS version at least 2.13.50"
15414         local fname
15415
15416         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
15417
15418 #define OBD_FAIL_PLAIN_RECORDS 0x1319
15419         #set only one record at plain llog
15420         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1319 fail_val=1
15421
15422         ost_set_temp_seq_width_all $DATA_SEQ_MAX_WIDTH
15423
15424         #fill already existed plain llog each 64767
15425         #wrapping whole catalog
15426         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
15427
15428         createmany -o $DIR/$tdir/$tfile_ 64700
15429         for (( i = 0; i < 64700; i = i + 2 ))
15430         do
15431                 rm $DIR/$tdir/$tfile_$i &
15432                 rm $DIR/$tdir/$tfile_$((i + 1)) &
15433                 local pid=$!
15434                 wait $pid
15435         done
15436
15437         #waiting osp synchronization
15438         wait_delete_completed
15439 }
15440 run_test 135 "Race catalog processing"
15441
15442 test_136() {
15443         remote_mds_nodsh && skip "remote MDS with nodsh"
15444         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
15445                 skip "Need MDS version at least 2.13.50"
15446         local fname
15447
15448         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
15449         $LFS setstripe -c 1 -i 0 $DIR/$tdir || error "failed to set striping"
15450         #set only one record at plain llog
15451 #define OBD_FAIL_CATALOG_FULL_CHECK                0x131a
15452         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x131a fail_val=1
15453
15454         ost_set_temp_seq_width_all $DATA_SEQ_MAX_WIDTH
15455
15456         #fill already existed 2 plain llogs each 64767
15457         #wrapping whole catalog
15458         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
15459         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 3 / 2))
15460         wait_delete_completed
15461
15462         createmany -o $DIR/$tdir/$tfile_ 10
15463         sleep 25
15464
15465         do_facet $SINGLEMDS $LCTL set_param fail_val=3
15466         for (( i = 0; i < 10; i = i + 3 ))
15467         do
15468                 rm $DIR/$tdir/$tfile_$i &
15469                 rm $DIR/$tdir/$tfile_$((i + 1)) &
15470                 local pid=$!
15471                 wait $pid
15472                 sleep 7
15473                 rm $DIR/$tdir/$tfile_$((i + 2)) &
15474         done
15475
15476         #waiting osp synchronization
15477         wait_delete_completed
15478 }
15479 run_test 136 "Race catalog processing 2"
15480
15481 test_140() { #bug-17379
15482         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15483
15484         test_mkdir $DIR/$tdir
15485         cd $DIR/$tdir || error "Changing to $DIR/$tdir"
15486         cp $(which stat) . || error "Copying stat to $DIR/$tdir"
15487
15488         # VFS limits max symlink depth to 5(4KSTACK) or 7(8KSTACK) or 8
15489         # For kernel > 3.5, bellow only tests consecutive symlink (MAX 40)
15490         local i=0
15491         while i=$((i + 1)); do
15492                 test_mkdir $i
15493                 cd $i || error "Changing to $i"
15494                 ln -s ../stat stat || error "Creating stat symlink"
15495                 # Read the symlink until ELOOP present,
15496                 # not LBUGing the system is considered success,
15497                 # we didn't overrun the stack.
15498                 $OPENFILE -f O_RDONLY stat >/dev/null 2>&1; ret=$?
15499                 if [ $ret -ne 0 ]; then
15500                         if [ $ret -eq 40 ]; then
15501                                 break  # -ELOOP
15502                         else
15503                                 error "Open stat symlink"
15504                                         return
15505                         fi
15506                 fi
15507         done
15508         i=$((i - 1))
15509         echo "The symlink depth = $i"
15510         [ $i -eq 5 ] || [ $i -eq 7 ] || [ $i -eq 8 ] || [ $i -eq 40 ] ||
15511                 error "Invalid symlink depth"
15512
15513         # Test recursive symlink
15514         ln -s symlink_self symlink_self
15515         $OPENFILE -f O_RDONLY symlink_self >/dev/null 2>&1; ret=$?
15516         echo "open symlink_self returns $ret"
15517         [ $ret -eq 40 ] || error "recursive symlink doesn't return -ELOOP"
15518 }
15519 run_test 140 "Check reasonable stack depth (shouldn't LBUG) ===="
15520
15521 test_150a() {
15522         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15523
15524         local TF="$TMP/$tfile"
15525
15526         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15527         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
15528         cp $TF $DIR/$tfile
15529         cancel_lru_locks $OSC
15530         cmp $TF $DIR/$tfile || error "$TMP/$tfile $DIR/$tfile differ"
15531         remount_client $MOUNT
15532         df -P $MOUNT
15533         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (remount)"
15534
15535         $TRUNCATE $TF 6000
15536         $TRUNCATE $DIR/$tfile 6000
15537         cancel_lru_locks $OSC
15538         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (truncate1)"
15539
15540         echo "12345" >>$TF
15541         echo "12345" >>$DIR/$tfile
15542         cancel_lru_locks $OSC
15543         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append1)"
15544
15545         echo "12345" >>$TF
15546         echo "12345" >>$DIR/$tfile
15547         cancel_lru_locks $OSC
15548         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append2)"
15549 }
15550 run_test 150a "truncate/append tests"
15551
15552 test_150b() {
15553         check_set_fallocate_or_skip
15554         local out
15555
15556         touch $DIR/$tfile
15557         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15558         out=$(check_fallocate $DIR/$tfile 2>&1) ||
15559                 skip_eopnotsupp "$out|check_fallocate failed"
15560 }
15561 run_test 150b "Verify fallocate (prealloc) functionality"
15562
15563 test_150bb() {
15564         check_set_fallocate_or_skip
15565
15566         touch $DIR/$tfile
15567         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15568         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=20 || error "dd failed"
15569         > $DIR/$tfile
15570         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
15571         # precomputed md5sum for 20MB of zeroes
15572         local expect="8f4e33f3dc3e414ff94e5fb6905cba8c"
15573         local sum=($(md5sum $DIR/$tfile))
15574
15575         [[ "${sum[0]}" == "$expect" ]] || error "fallocate unwritten is not zero"
15576
15577         check_set_fallocate 1
15578
15579         > $DIR/$tfile
15580         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
15581         sum=($(md5sum $DIR/$tfile))
15582
15583         [[ "${sum[0]}" == "$expect" ]] || error "fallocate zero is not zero"
15584 }
15585 run_test 150bb "Verify fallocate modes both zero space"
15586
15587 test_150c() {
15588         check_set_fallocate_or_skip
15589         local striping="-c2"
15590
15591         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15592         $LFS setstripe -c $OSTCOUNT -S1M $DIR/$tfile || error "setstripe failed"
15593         fallocate -l ${OSTCOUNT}m $DIR/$tfile || error "fallocate failed"
15594         local bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
15595         local want=$((OSTCOUNT * 1048576))
15596
15597         # Must allocate all requested space, not more than 5% extra
15598         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
15599                 error "bytes $bytes is not $want"
15600
15601         rm -f $DIR/$tfile
15602
15603         echo "verify fallocate on PFL file"
15604
15605         [[ "x$DOM" == "xyes" ]] && striping="-L mdt"
15606
15607         $LFS setstripe -E1M $striping -E16M -c3 -Eeof -c 4 $DIR/$tfile ||
15608                 error "Create $DIR/$tfile failed"
15609         fallocate -l $((1048576 * 512)) $DIR/$tfile || error "fallocate failed"
15610         bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
15611         want=$((512 * 1048576))
15612
15613         # Must allocate all requested space, not more than 5% extra
15614         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
15615                 error "bytes $bytes is not $want"
15616 }
15617 run_test 150c "Verify fallocate Size and Blocks"
15618
15619 test_150d() {
15620         check_set_fallocate_or_skip
15621         local striping="-c2"
15622
15623         [[ "x$DOM" == "xyes" ]] && striping="-L mdt"
15624
15625         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15626         $LFS setstripe -E1M $striping -E eof -c $OSTCOUNT -S1M $DIR/$tdir ||
15627                 error "setstripe failed"
15628         fallocate -o 1G -l ${OSTCOUNT}m $DIR/$tdir || error "fallocate failed"
15629         local bytes=$(($(stat -c '%b * %B' $DIR/$tdir)))
15630         local want=$((OSTCOUNT * 1048576))
15631
15632         # Must allocate all requested space, not more than 5% extra
15633         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
15634                 error "bytes $bytes is not $want"
15635 }
15636 run_test 150d "Verify fallocate Size and Blocks - Non zero start"
15637
15638 test_150e() {
15639         check_set_fallocate_or_skip
15640
15641         echo "df before:"
15642         $LFS df
15643         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15644         $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
15645                 error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
15646
15647         # Find OST with Minimum Size
15648         min_size_ost=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
15649                        sort -un | head -1)
15650
15651         # Get 100MB per OST of the available space to reduce run time
15652         # else 60% of the available space if we are running SLOW tests
15653         if [ $SLOW == "no" ]; then
15654                 local space=$((1024 * 100 * OSTCOUNT))
15655         else
15656                 local space=$(((min_size_ost * 60)/100 * OSTCOUNT))
15657         fi
15658
15659         fallocate -l${space}k $DIR/$tfile ||
15660                 error "fallocate ${space}k $DIR/$tfile failed"
15661         echo "'fallocate -l ${space}k $DIR/$tfile' succeeded"
15662
15663         # get size immediately after fallocate. This should be correctly
15664         # updated
15665         local size=$(stat -c '%s' $DIR/$tfile)
15666         local used=$(( $(stat -c '%b * %B' $DIR/$tfile) / 1024))
15667
15668         # Sleep for a while for statfs to get updated. And not pull from cache.
15669         sleep 2
15670
15671         echo "df after fallocate:"
15672         $LFS df
15673
15674         (( size / 1024 == space )) || error "size $size != requested $space"
15675         [ "$ost1_FSTYPE" != ldiskfs ] || (( used >= space )) ||
15676                 error "used $used < space $space"
15677
15678         rm $DIR/$tfile || error "rm failed"
15679         sync
15680         wait_delete_completed
15681
15682         echo "df after unlink:"
15683         $LFS df
15684 }
15685 run_test 150e "Verify 60% of available OST space consumed by fallocate"
15686
15687 test_150f() {
15688         local size
15689         local blocks
15690         local want_size_before=20480 # in bytes
15691         local want_blocks_before=40 # 512 sized blocks
15692         local want_blocks_after=24  # 512 sized blocks
15693         local length=$(((want_blocks_before - want_blocks_after) * 512))
15694
15695         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
15696                 skip "need at least 2.14.0 for fallocate punch"
15697
15698         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
15699                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
15700         fi
15701
15702         check_set_fallocate_or_skip
15703         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15704
15705         [[ "x$DOM" == "xyes" ]] &&
15706                 $LFS setstripe -E1M -L mdt -E eof $DIR/$tfile
15707
15708         echo "Verify fallocate punch: Range within the file range"
15709         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
15710                 error "dd failed for bs 4096 and count 5"
15711
15712         # Call fallocate with punch range which is within the file range
15713         out=$(fallocate -p --offset 4096 -l $length $DIR/$tfile 2>&1) ||
15714                 skip_eopnotsupp "$out|fallocate: offset 4096 and length $length"
15715         # client must see changes immediately after fallocate
15716         size=$(stat -c '%s' $DIR/$tfile)
15717         blocks=$(stat -c '%b' $DIR/$tfile)
15718
15719         # Verify punch worked.
15720         (( blocks == want_blocks_after )) ||
15721                 error "punch failed: blocks $blocks != $want_blocks_after"
15722
15723         (( size == want_size_before )) ||
15724                 error "punch failed: size $size != $want_size_before"
15725
15726         # Verify there is hole in file
15727         local data_off=$(lseek_test -d 4096 $DIR/$tfile)
15728         # precomputed md5sum
15729         local expect="4a9a834a2db02452929c0a348273b4aa"
15730
15731         cksum=($(md5sum $DIR/$tfile))
15732         [[ "${cksum[0]}" == "$expect" ]] ||
15733                 error "unexpected MD5SUM after punch: ${cksum[0]}"
15734
15735         # Start second sub-case for fallocate punch.
15736         echo "Verify fallocate punch: Range overlapping and less than blocksize"
15737         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
15738                 error "dd failed for bs 4096 and count 5"
15739
15740         # Punch range less than block size will have no change in block count
15741         want_blocks_after=40  # 512 sized blocks
15742
15743         # Punch overlaps two blocks and less than blocksize
15744         out=$(fallocate -p --offset 4000 -l 3000 $DIR/$tfile 2>&1) ||
15745                 skip_eopnotsupp "$out|fallocate: offset 4000 length 3000"
15746         size=$(stat -c '%s' $DIR/$tfile)
15747         blocks=$(stat -c '%b' $DIR/$tfile)
15748
15749         # Verify punch worked.
15750         (( blocks == want_blocks_after )) ||
15751                 error "punch failed: blocks $blocks != $want_blocks_after"
15752
15753         (( size == want_size_before )) ||
15754                 error "punch failed: size $size != $want_size_before"
15755
15756         # Verify if range is really zero'ed out. We expect Zeros.
15757         # precomputed md5sum
15758         expect="c57ec5d769c3dbe3426edc3f7d7e11d3"
15759         cksum=($(md5sum $DIR/$tfile))
15760         [[ "${cksum[0]}" == "$expect" ]] ||
15761                 error "unexpected MD5SUM after punch: ${cksum[0]}"
15762 }
15763 run_test 150f "Verify fallocate punch functionality"
15764
15765 test_150g() {
15766         local space
15767         local size
15768         local blocks
15769         local blocks_after
15770         local size_after
15771         local BS=4096 # Block size in bytes
15772
15773         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
15774                 skip "need at least 2.14.0 for fallocate punch"
15775
15776         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
15777                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
15778         fi
15779
15780         check_set_fallocate_or_skip
15781         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15782
15783         if [[ "x$DOM" == "xyes" ]]; then
15784                 $LFS setstripe -E2M -L mdt -E eof -c${OSTCOUNT} $DIR/$tfile ||
15785                         error "$LFS setstripe DoM + ${OSTCOUNT} OST failed"
15786         else
15787                 $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
15788                         error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
15789         fi
15790
15791         # Get 100MB per OST of the available space to reduce run time
15792         # else 60% of the available space if we are running SLOW tests
15793         if [ $SLOW == "no" ]; then
15794                 space=$((1024 * 100 * OSTCOUNT))
15795         else
15796                 # Find OST with Minimum Size
15797                 space=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
15798                         sort -un | head -1)
15799                 echo "min size OST: $space"
15800                 space=$(((space * 60)/100 * OSTCOUNT))
15801         fi
15802         # space in 1k units, round to 4k blocks
15803         local blkcount=$((space * 1024 / $BS))
15804
15805         echo "Verify fallocate punch: Very large Range"
15806         fallocate -l${space}k $DIR/$tfile ||
15807                 error "fallocate ${space}k $DIR/$tfile failed"
15808         # write 1M at the end, start and in the middle
15809         yes 'A' | dd of=$DIR/$tfile bs=$BS count=256 ||
15810                 error "dd failed: bs $BS count 256"
15811         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount - 256)) count=256 ||
15812                 error "dd failed: bs $BS count 256 seek $((blkcount - 256))"
15813         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount / 2)) count=1024 ||
15814                 error "dd failed: bs $BS count 256 seek $((blkcount / 2))"
15815
15816         # Gather stats.
15817         size=$(stat -c '%s' $DIR/$tfile)
15818
15819         # gather punch length.
15820         local punch_size=$((size - (BS * 2)))
15821
15822         echo "punch_size = $punch_size"
15823         echo "size - punch_size: $((size - punch_size))"
15824         echo "size - punch_size in blocks: $(((size - punch_size)/BS))"
15825
15826         # Call fallocate to punch all except 2 blocks. We leave the
15827         # first and the last block
15828         echo "fallocate -p --offset $BS -l $punch_size $DIR/$tfile"
15829         out=$(fallocate -p --offset $BS -l $punch_size $DIR/$tfile 2>&1) ||
15830                 skip_eopnotsupp "$out|fallocate: offset $BS length $punch_size"
15831
15832         size_after=$(stat -c '%s' $DIR/$tfile)
15833         blocks_after=$(stat -c '%b' $DIR/$tfile)
15834
15835         # Verify punch worked.
15836         # Size should be kept
15837         (( size == size_after )) ||
15838                 error "punch failed: size $size != $size_after"
15839
15840         # two 4k data blocks to remain plus possible 1 extra extent block
15841         (( blocks_after <= ((BS / 512) * 3) )) ||
15842                 error "too many blocks remains: $blocks_after"
15843
15844         # Verify that file has hole between the first and the last blocks
15845         local hole_start=$(lseek_test -l 0 $DIR/$tfile)
15846         local hole_end=$(lseek_test -d $BS $DIR/$tfile)
15847
15848         echo "Hole at [$hole_start, $hole_end)"
15849         (( hole_start == BS )) ||
15850                 error "no hole at offset $BS after punch"
15851
15852         (( hole_end == BS + punch_size )) ||
15853                 error "data at offset $hole_end < $((BS + punch_size))"
15854 }
15855 run_test 150g "Verify fallocate punch on large range"
15856
15857 test_150h() {
15858         local file=$DIR/$tfile
15859         local size
15860
15861         check_set_fallocate_or_skip
15862         statx_supported || skip_env "Test must be statx() syscall supported"
15863
15864         # fallocate() does not update the size information on the MDT
15865         fallocate -l 16K $file || error "failed to fallocate $file"
15866         cancel_lru_locks $OSC
15867         # STATX with cached-always mode will not send glimpse RPCs to OST,
15868         # it uses the caching attrs on the client side as much as possible.
15869         size=$($STATX --cached=always -c %s $file)
15870         [ $size == 16384 ] ||
15871                 error "size after fallocate() is $size, expected 16384"
15872 }
15873 run_test 150h "Verify extend fallocate updates the file size"
15874
15875 #LU-2902 roc_hit was not able to read all values from lproc
15876 function roc_hit_init() {
15877         local list=$(comma_list $(osts_nodes))
15878         local dir=$DIR/$tdir-check
15879         local file=$dir/$tfile
15880         local BEFORE
15881         local AFTER
15882         local idx
15883
15884         test_mkdir $dir
15885         #use setstripe to do a write to every ost
15886         for i in $(seq 0 $((OSTCOUNT-1))); do
15887                 $LFS setstripe -c 1 -i $i $dir || error "$LFS setstripe $file failed"
15888                 dd if=/dev/urandom of=$file bs=4k count=4 2>&1 > /dev/null
15889                 idx=$(printf %04x $i)
15890                 BEFORE=$(get_osd_param $list *OST*$idx stats |
15891                         awk '$1 == "cache_access" {sum += $7}
15892                                 END { printf("%0.0f", sum) }')
15893
15894                 cancel_lru_locks osc
15895                 cat $file >/dev/null
15896
15897                 AFTER=$(get_osd_param $list *OST*$idx stats |
15898                         awk '$1 == "cache_access" {sum += $7}
15899                                 END { printf("%0.0f", sum) }')
15900
15901                 echo BEFORE:$BEFORE AFTER:$AFTER
15902                 if ! let "AFTER - BEFORE == 4"; then
15903                         rm -rf $dir
15904                         error "roc_hit is not safe to use"
15905                 fi
15906                 rm $file
15907         done
15908
15909         rm -rf $dir
15910 }
15911
15912 function roc_hit() {
15913         local list=$(comma_list $(osts_nodes))
15914         echo $(get_osd_param $list '' stats |
15915                 awk '$1 == "cache_hit" {sum += $7}
15916                         END { printf("%0.0f", sum) }')
15917 }
15918
15919 function set_cache() {
15920         local on=1
15921
15922         if [ "$2" == "off" ]; then
15923                 on=0;
15924         fi
15925         local list=$(comma_list $(osts_nodes))
15926         set_osd_param $list '' $1_cache_enable $on
15927
15928         cancel_lru_locks osc
15929 }
15930
15931 test_151() {
15932         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15933         remote_ost_nodsh && skip "remote OST with nodsh"
15934         (( CLIENT_VERSION == OST1_VERSION )) ||
15935                 skip "LU-13081: no interop testing for OSS cache"
15936
15937         local CPAGES=3
15938         local list=$(comma_list $(osts_nodes))
15939
15940         # check whether obdfilter is cache capable at all
15941         if ! get_osd_param $list '' read_cache_enable >/dev/null; then
15942                 skip "not cache-capable obdfilter"
15943         fi
15944
15945         # check cache is enabled on all obdfilters
15946         if get_osd_param $list '' read_cache_enable | grep 0; then
15947                 skip "oss cache is disabled"
15948         fi
15949
15950         set_osd_param $list '' writethrough_cache_enable 1
15951
15952         # check write cache is enabled on all obdfilters
15953         if get_osd_param $list '' writethrough_cache_enable | grep 0; then
15954                 skip "oss write cache is NOT enabled"
15955         fi
15956
15957         roc_hit_init
15958
15959         #define OBD_FAIL_OBD_NO_LRU  0x609
15960         do_nodes $list $LCTL set_param fail_loc=0x609
15961
15962         # pages should be in the case right after write
15963         dd if=/dev/urandom of=$DIR/$tfile bs=4k count=$CPAGES ||
15964                 error "dd failed"
15965
15966         local BEFORE=$(roc_hit)
15967         cancel_lru_locks osc
15968         cat $DIR/$tfile >/dev/null
15969         local AFTER=$(roc_hit)
15970
15971         do_nodes $list $LCTL set_param fail_loc=0
15972
15973         if ! let "AFTER - BEFORE == CPAGES"; then
15974                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
15975         fi
15976
15977         cancel_lru_locks osc
15978         # invalidates OST cache
15979         do_nodes $list "echo 1 > /proc/sys/vm/drop_caches"
15980         set_osd_param $list '' read_cache_enable 0
15981         cat $DIR/$tfile >/dev/null
15982
15983         # now data shouldn't be found in the cache
15984         BEFORE=$(roc_hit)
15985         cancel_lru_locks osc
15986         cat $DIR/$tfile >/dev/null
15987         AFTER=$(roc_hit)
15988         if let "AFTER - BEFORE != 0"; then
15989                 error "IN CACHE: before: $BEFORE, after: $AFTER"
15990         fi
15991
15992         set_osd_param $list '' read_cache_enable 1
15993         rm -f $DIR/$tfile
15994 }
15995 run_test 151 "test cache on oss and controls ==============================="
15996
15997 test_152() {
15998         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15999
16000         local TF="$TMP/$tfile"
16001
16002         # simulate ENOMEM during write
16003 #define OBD_FAIL_OST_NOMEM      0x226
16004         lctl set_param fail_loc=0x80000226
16005         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
16006         cp $TF $DIR/$tfile
16007         sync || error "sync failed"
16008         lctl set_param fail_loc=0
16009
16010         # discard client's cache
16011         cancel_lru_locks osc
16012
16013         # simulate ENOMEM during read
16014         lctl set_param fail_loc=0x80000226
16015         cmp $TF $DIR/$tfile || error "cmp failed"
16016         lctl set_param fail_loc=0
16017
16018         rm -f $TF
16019 }
16020 run_test 152 "test read/write with enomem ============================"
16021
16022 test_153() {
16023         $MULTIOP $DIR/$tfile Ow4096Ycu || error "multiop failed"
16024 }
16025 run_test 153 "test if fdatasync does not crash ======================="
16026
16027 dot_lustre_fid_permission_check() {
16028         local fid=$1
16029         local ffid=$MOUNT/.lustre/fid/$fid
16030         local test_dir=$2
16031
16032         echo "stat fid $fid"
16033         stat $ffid || error "stat $ffid failed."
16034         echo "touch fid $fid"
16035         touch $ffid || error "touch $ffid failed."
16036         echo "write to fid $fid"
16037         cat /etc/hosts > $ffid || error "write $ffid failed."
16038         echo "read fid $fid"
16039         diff /etc/hosts $ffid || error "read $ffid failed."
16040         echo "append write to fid $fid"
16041         cat /etc/hosts >> $ffid || error "append write $ffid failed."
16042         echo "rename fid $fid"
16043         mv $ffid $test_dir/$tfile.1 &&
16044                 error "rename $ffid to $tfile.1 should fail."
16045         touch $test_dir/$tfile.1
16046         mv $test_dir/$tfile.1 $ffid &&
16047                 error "rename $tfile.1 to $ffid should fail."
16048         rm -f $test_dir/$tfile.1
16049         echo "truncate fid $fid"
16050         $TRUNCATE $ffid 777 || error "truncate $ffid failed."
16051         echo "link fid $fid"
16052         ln -f $ffid $test_dir/tfile.lnk || error "link $ffid failed."
16053         if [[ $($LCTL get_param -n mdc.*-mdc-*.connect_flags) =~ acl ]]; then
16054                 echo "setfacl fid $fid"
16055                 setfacl -R -m u:$USER0:rwx $ffid ||
16056                         error "setfacl $ffid failed"
16057                 echo "getfacl fid $fid"
16058                 getfacl $ffid || error "getfacl $ffid failed."
16059         fi
16060         echo "unlink fid $fid"
16061         unlink $MOUNT/.lustre/fid/$fid && error "unlink $ffid should fail."
16062         echo "mknod fid $fid"
16063         mknod $ffid c 1 3 && error "mknod $ffid should fail."
16064
16065         fid=[0xf00000400:0x1:0x0]
16066         ffid=$MOUNT/.lustre/fid/$fid
16067
16068         echo "stat non-exist fid $fid"
16069         stat $ffid > /dev/null && error "stat non-exist $ffid should fail."
16070         echo "write to non-exist fid $fid"
16071         cat /etc/hosts > $ffid && error "write non-exist $ffid should fail."
16072         echo "link new fid $fid"
16073         ln $test_dir/$tfile $ffid && error "link $ffid should fail."
16074
16075         mkdir -p $test_dir/$tdir
16076         touch $test_dir/$tdir/$tfile
16077         fid=$($LFS path2fid $test_dir/$tdir)
16078         rc=$?
16079         [ $rc -ne 0 ] &&
16080                 error "error: could not get fid for $test_dir/$dir/$tfile."
16081
16082         ffid=$MOUNT/.lustre/fid/$fid
16083
16084         echo "ls $fid"
16085         ls $ffid || error "ls $ffid failed."
16086         echo "touch $fid/$tfile.1"
16087         touch $ffid/$tfile.1 || error "touch $ffid/$tfile.1 failed."
16088
16089         echo "touch $MOUNT/.lustre/fid/$tfile"
16090         touch $MOUNT/.lustre/fid/$tfile && \
16091                 error "touch $MOUNT/.lustre/fid/$tfile should fail."
16092
16093         echo "setxattr to $MOUNT/.lustre/fid"
16094         setfattr -n trusted.name1 -v value1 $MOUNT/.lustre/fid
16095
16096         echo "listxattr for $MOUNT/.lustre/fid"
16097         getfattr -d -m "^trusted" $MOUNT/.lustre/fid
16098
16099         echo "delxattr from $MOUNT/.lustre/fid"
16100         setfattr -x trusted.name1 $MOUNT/.lustre/fid
16101
16102         echo "touch invalid fid: $MOUNT/.lustre/fid/[0x200000400:0x2:0x3]"
16103         touch $MOUNT/.lustre/fid/[0x200000400:0x2:0x3] &&
16104                 error "touch invalid fid should fail."
16105
16106         echo "touch non-normal fid: $MOUNT/.lustre/fid/[0x1:0x2:0x0]"
16107         touch $MOUNT/.lustre/fid/[0x1:0x2:0x0] &&
16108                 error "touch non-normal fid should fail."
16109
16110         echo "rename $tdir to $MOUNT/.lustre/fid"
16111         mrename $test_dir/$tdir $MOUNT/.lustre/fid &&
16112                 error "rename to $MOUNT/.lustre/fid should fail."
16113
16114         if [ $MDS1_VERSION -ge $(version_code 2.3.51) ]
16115         then            # LU-3547
16116                 local old_obf_mode=$(stat --format="%a" $DIR/.lustre/fid)
16117                 local new_obf_mode=777
16118
16119                 echo "change mode of $DIR/.lustre/fid to $new_obf_mode"
16120                 chmod $new_obf_mode $DIR/.lustre/fid ||
16121                         error "chmod $new_obf_mode $DIR/.lustre/fid failed"
16122
16123                 local obf_mode=$(stat --format=%a $DIR/.lustre/fid)
16124                 [ $obf_mode -eq $new_obf_mode ] ||
16125                         error "stat $DIR/.lustre/fid returned wrong mode $obf_mode"
16126
16127                 echo "restore mode of $DIR/.lustre/fid to $old_obf_mode"
16128                 chmod $old_obf_mode $DIR/.lustre/fid ||
16129                         error "chmod $old_obf_mode $DIR/.lustre/fid failed"
16130         fi
16131
16132         $OPENFILE -f O_LOV_DELAY_CREATE:O_CREAT $test_dir/$tfile-2
16133         fid=$($LFS path2fid $test_dir/$tfile-2)
16134
16135         if [ $MDS1_VERSION -ge $(version_code 2.6.50) ]
16136         then # LU-5424
16137                 echo "cp /etc/passwd $MOUNT/.lustre/fid/$fid"
16138                 cp /etc/passwd $MOUNT/.lustre/fid/$fid ||
16139                         error "create lov data thru .lustre failed"
16140         fi
16141         echo "cp /etc/passwd $test_dir/$tfile-2"
16142         cp /etc/passwd $test_dir/$tfile-2 ||
16143                 error "copy to $test_dir/$tfile-2 failed."
16144         echo "diff /etc/passwd $MOUNT/.lustre/fid/$fid"
16145         diff /etc/passwd $MOUNT/.lustre/fid/$fid ||
16146                 error "diff /etc/passwd $MOUNT/.lustre/fid/$fid failed."
16147
16148         rm -rf $test_dir/tfile.lnk
16149         rm -rf $test_dir/$tfile-2
16150 }
16151
16152 test_154A() {
16153         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
16154                 skip "Need MDS version at least 2.4.1"
16155
16156         local tf=$DIR/$tfile
16157         touch $tf
16158
16159         local fid=$($LFS path2fid $tf)
16160         [ -z "$fid" ] && error "path2fid unable to get $tf FID"
16161
16162         # check that we get the same pathname back
16163         local rootpath
16164         local found
16165         for rootpath in "$MOUNT" "$MOUNT///" "$MOUNT/$tfile"; do
16166                 echo "$rootpath $fid"
16167                 found=$($LFS fid2path $rootpath "$fid")
16168                 [ -z "$found" ] && error "fid2path unable to get '$fid' path"
16169                 [ "$found" == "$tf" ] || error "fid2path $found != $tf"
16170         done
16171
16172         # check wrong root path format
16173         rootpath=$MOUNT"_wrong"
16174         found=$($LFS fid2path $rootpath "$fid")
16175         [ -z "$found" ] || error "should fail ($rootpath != $MOUNT)"
16176 }
16177 run_test 154A "lfs path2fid and fid2path basic checks"
16178
16179 test_154B() {
16180         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
16181                 skip "Need MDS version at least 2.4.1"
16182
16183         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
16184         touch $DIR/$tdir/$tfile || error "touch $DIR/$tdir/$tfile failed"
16185         local linkea=$($LL_DECODE_LINKEA $DIR/$tdir/$tfile | grep 'pfid')
16186         [ -z "$linkea" ] && error "decode linkea $DIR/$tdir/$tfile failed"
16187
16188         local name=$(echo $linkea | awk '/pfid/ {print $5}' | sed -e "s/'//g")
16189         local PFID=$(echo $linkea | awk '/pfid/ {print $3}' | sed -e "s/,//g")
16190
16191         # check that we get the same pathname
16192         echo "PFID: $PFID, name: $name"
16193         local FOUND=$($LFS fid2path $MOUNT "$PFID")
16194         [ -z "$FOUND" ] && error "fid2path unable to get $PFID path"
16195         [ "$FOUND/$name" != "$DIR/$tdir/$tfile" ] &&
16196                 error "ll_decode_linkea has $FOUND/$name != $DIR/$tdir/$tfile"
16197
16198         rm -rf $DIR/$tdir || error "Can not delete directory $DIR/$tdir"
16199 }
16200 run_test 154B "verify the ll_decode_linkea tool"
16201
16202 test_154a() {
16203         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16204         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
16205         (( $MDS1_VERSION >= $(version_code 2.2.51) )) ||
16206                 skip "Need MDS version at least 2.2.51"
16207         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
16208
16209         cp /etc/hosts $DIR/$tfile
16210
16211         fid=$($LFS path2fid $DIR/$tfile)
16212         rc=$?
16213         [ $rc -ne 0 ] && error "error: could not get fid for $DIR/$tfile."
16214
16215         dot_lustre_fid_permission_check "$fid" $DIR ||
16216                 error "dot lustre permission check $fid failed"
16217
16218         ls -a $MOUNT | grep "\.lustre" && error ".lustre should not be listed"
16219
16220         rm -rf $MOUNT/.lustre && error ".lustre is not allowed to be unlinked"
16221
16222         touch $MOUNT/.lustre/file &&
16223                 error "creation is not allowed under .lustre"
16224
16225         mkdir $MOUNT/.lustre/dir &&
16226                 error "mkdir is not allowed under .lustre"
16227
16228         rm -rf $DIR/$tfile
16229 }
16230 run_test 154a "Open-by-FID"
16231
16232 test_154b() {
16233         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16234         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
16235         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16236         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
16237                 skip "Need MDS version at least 2.2.51"
16238
16239         local remote_dir=$DIR/$tdir/remote_dir
16240         local MDTIDX=1
16241         local rc=0
16242
16243         mkdir -p $DIR/$tdir
16244         $LFS mkdir -i $MDTIDX $remote_dir ||
16245                 error "create remote directory failed"
16246
16247         cp /etc/hosts $remote_dir/$tfile
16248
16249         fid=$($LFS path2fid $remote_dir/$tfile)
16250         rc=$?
16251         [ $rc -ne 0 ] && error "error: could not get fid for $remote_dir/$tfile"
16252
16253         dot_lustre_fid_permission_check "$fid" $remote_dir ||
16254                 error "dot lustre permission check $fid failed"
16255         rm -rf $DIR/$tdir
16256 }
16257 run_test 154b "Open-by-FID for remote directory"
16258
16259 test_154c() {
16260         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
16261                 skip "Need MDS version at least 2.4.1"
16262
16263         touch $DIR/$tfile.1 $DIR/$tfile.2 $DIR/$tfile.3
16264         local FID1=$($LFS path2fid $DIR/$tfile.1)
16265         local FID2=$($LFS path2fid $DIR/$tfile.2)
16266         local FID3=$($LFS path2fid $DIR/$tfile.3)
16267
16268         local N=1
16269         $LFS path2fid $DIR/$tfile.[123] | while read PATHNAME FID; do
16270                 [ "$PATHNAME" = "$DIR/$tfile.$N:" ] ||
16271                         error "path2fid pathname $PATHNAME != $DIR/$tfile.$N:"
16272                 local want=FID$N
16273                 [ "$FID" = "${!want}" ] ||
16274                         error "path2fid $PATHNAME FID $FID != FID$N ${!want}"
16275                 N=$((N + 1))
16276         done
16277
16278         $LFS fid2path $MOUNT "$FID1" "$FID2" "$FID3" | while read PATHNAME;
16279         do
16280                 [ "$PATHNAME" = "$DIR/$tfile.$N" ] ||
16281                         error "fid2path pathname $PATHNAME != $DIR/$tfile.$N:"
16282                 N=$((N + 1))
16283         done
16284 }
16285 run_test 154c "lfs path2fid and fid2path multiple arguments"
16286
16287 test_154d() {
16288         remote_mds_nodsh && skip "remote MDS with nodsh"
16289         [[ $MDS1_VERSION -lt $(version_code 2.5.53) ]] &&
16290                 skip "Need MDS version at least 2.5.53"
16291
16292         if remote_mds; then
16293                 nid=$($LCTL list_nids | sed  "s/\./\\\./g")
16294         else
16295                 nid="0@lo"
16296         fi
16297         local proc_ofile="mdt.*.exports.'$nid'.open_files"
16298         local fd
16299         local cmd
16300
16301         rm -f $DIR/$tfile
16302         touch $DIR/$tfile
16303
16304         local fid=$($LFS path2fid $DIR/$tfile)
16305         # Open the file
16306         fd=$(free_fd)
16307         cmd="exec $fd<$DIR/$tfile"
16308         eval $cmd
16309         local fid_list=$(do_facet $SINGLEMDS $LCTL get_param $proc_ofile)
16310         echo "$fid_list" | grep "$fid"
16311         rc=$?
16312
16313         cmd="exec $fd>/dev/null"
16314         eval $cmd
16315         if [ $rc -ne 0 ]; then
16316                 error "FID $fid not found in open files list $fid_list"
16317         fi
16318 }
16319 run_test 154d "Verify open file fid"
16320
16321 test_154e()
16322 {
16323         [[ $MDS1_VERSION -lt $(version_code 2.6.50) ]] &&
16324                 skip "Need MDS version at least 2.6.50"
16325
16326         if ls -a $MOUNT | grep -q '^\.lustre$'; then
16327                 error ".lustre returned by readdir"
16328         fi
16329 }
16330 run_test 154e ".lustre is not returned by readdir"
16331
16332 test_154f() {
16333         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
16334
16335         # create parent directory on a single MDT to avoid cross-MDT hardlinks
16336         mkdir_on_mdt0 $DIR/$tdir
16337         # test dirs inherit from its stripe
16338         mkdir -p $DIR/$tdir/foo1 || error "mkdir error"
16339         mkdir -p $DIR/$tdir/foo2 || error "mkdir error"
16340         cp /etc/hosts $DIR/$tdir/foo1/$tfile
16341         ln $DIR/$tdir/foo1/$tfile $DIR/$tdir/foo2/link
16342         touch $DIR/f
16343
16344         # get fid of parents
16345         local FID0=$($LFS path2fid $DIR/$tdir)
16346         local FID1=$($LFS path2fid $DIR/$tdir/foo1)
16347         local FID2=$($LFS path2fid $DIR/$tdir/foo2)
16348         local FID3=$($LFS path2fid $DIR)
16349
16350         # check that path2fid --parents returns expected <parent_fid>/name
16351         # 1) test for a directory (single parent)
16352         local parent=$($LFS path2fid --parents $DIR/$tdir/foo1)
16353         [ "$parent" == "$FID0/foo1" ] ||
16354                 error "expected parent: $FID0/foo1, got: $parent"
16355
16356         # 2) test for a file with nlink > 1 (multiple parents)
16357         parent=$($LFS path2fid --parents $DIR/$tdir/foo1/$tfile)
16358         echo "$parent" | grep -F "$FID1/$tfile" ||
16359                 error "$FID1/$tfile not returned in parent list"
16360         echo "$parent" | grep -F "$FID2/link" ||
16361                 error "$FID2/link not returned in parent list"
16362
16363         # 3) get parent by fid
16364         local file_fid=$($LFS path2fid $DIR/$tdir/foo1/$tfile)
16365         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
16366         echo "$parent" | grep -F "$FID1/$tfile" ||
16367                 error "$FID1/$tfile not returned in parent list (by fid)"
16368         echo "$parent" | grep -F "$FID2/link" ||
16369                 error "$FID2/link not returned in parent list (by fid)"
16370
16371         # 4) test for entry in root directory
16372         parent=$($LFS path2fid --parents $DIR/f)
16373         echo "$parent" | grep -F "$FID3/f" ||
16374                 error "$FID3/f not returned in parent list"
16375
16376         # 5) test it on root directory
16377         [ -z "$($LFS path2fid --parents $MOUNT 2>/dev/null)" ] ||
16378                 error "$MOUNT should not have parents"
16379
16380         # enable xattr caching and check that linkea is correctly updated
16381         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
16382         save_lustre_params client "llite.*.xattr_cache" > $save
16383         lctl set_param llite.*.xattr_cache 1
16384
16385         # 6.1) linkea update on rename
16386         mv $DIR/$tdir/foo1/$tfile $DIR/$tdir/foo2/$tfile.moved
16387
16388         # get parents by fid
16389         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
16390         # foo1 should no longer be returned in parent list
16391         echo "$parent" | grep -F "$FID1" &&
16392                 error "$FID1 should no longer be in parent list"
16393         # the new path should appear
16394         echo "$parent" | grep -F "$FID2/$tfile.moved" ||
16395                 error "$FID2/$tfile.moved is not in parent list"
16396
16397         # 6.2) linkea update on unlink
16398         rm -f $DIR/$tdir/foo2/link
16399         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
16400         # foo2/link should no longer be returned in parent list
16401         echo "$parent" | grep -F "$FID2/link" &&
16402                 error "$FID2/link should no longer be in parent list"
16403         true
16404
16405         rm -f $DIR/f
16406         restore_lustre_params < $save
16407         rm -f $save
16408 }
16409 run_test 154f "get parent fids by reading link ea"
16410
16411 test_154g()
16412 {
16413         [[ $MDS1_VERSION -ge $(version_code 2.6.92) &&
16414            $CLIENT_VERSION -gt $(version_code 2.6.99) ]] ||
16415                 skip "Need MDS version at least 2.6.92"
16416
16417         mkdir_on_mdt0 $DIR/$tdir
16418         llapi_fid_test -d $DIR/$tdir
16419 }
16420 run_test 154g "various llapi FID tests"
16421
16422 test_154h()
16423 {
16424         (( $CLIENT_VERSION >= $(version_code 2.15.55.1) )) ||
16425                 skip "Need client at least version 2.15.55.1"
16426
16427         # Create an empty file
16428         touch $DIR/$tfile
16429
16430         # Get FID (interactive mode) and save under $TMP/$tfile.log
16431         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
16432                 path2fid $DIR/$tfile
16433         EOF
16434
16435         fid=$(cat $TMP/$tfile.log)
16436         # $fid should not be empty
16437         [[ ! -z $fid ]] || error "FID is empty"
16438         $LFS rmfid $DIR "$fid" || error "rmfid failed for $fid"
16439 }
16440 run_test 154h "Verify interactive path2fid"
16441
16442 test_155_small_load() {
16443     local temp=$TMP/$tfile
16444     local file=$DIR/$tfile
16445
16446     dd if=/dev/urandom of=$temp bs=6096 count=1 || \
16447         error "dd of=$temp bs=6096 count=1 failed"
16448     cp $temp $file
16449     cancel_lru_locks $OSC
16450     cmp $temp $file || error "$temp $file differ"
16451
16452     $TRUNCATE $temp 6000
16453     $TRUNCATE $file 6000
16454     cmp $temp $file || error "$temp $file differ (truncate1)"
16455
16456     echo "12345" >>$temp
16457     echo "12345" >>$file
16458     cmp $temp $file || error "$temp $file differ (append1)"
16459
16460     echo "12345" >>$temp
16461     echo "12345" >>$file
16462     cmp $temp $file || error "$temp $file differ (append2)"
16463
16464     rm -f $temp $file
16465     true
16466 }
16467
16468 test_155_big_load() {
16469         remote_ost_nodsh && skip "remote OST with nodsh"
16470
16471         local temp=$TMP/$tfile
16472         local file=$DIR/$tfile
16473
16474         free_min_max
16475         local cache_size=$(do_facet ost$((MAXI+1)) \
16476                 "awk '/cache/ {sum+=\\\$4} END {print sum}' /proc/cpuinfo")
16477
16478         # LU-16042: can not get the cache size on Arm64 VM here, fallback to a
16479         # pre-set value
16480         if [ -z "$cache_size" ]; then
16481                 cache_size=256
16482         fi
16483         local large_file_size=$((cache_size * 2))
16484
16485         echo "OSS cache size: $cache_size KB"
16486         echo "Large file size: $large_file_size KB"
16487
16488         [ $MAXV -le $large_file_size ] &&
16489                 skip_env "max available OST size needs > $large_file_size KB"
16490
16491         $LFS setstripe $file -c 1 -i $MAXI || error "$LFS setstripe $file failed"
16492
16493         dd if=/dev/urandom of=$temp bs=$large_file_size count=1k ||
16494                 error "dd of=$temp bs=$large_file_size count=1k failed"
16495         cp $temp $file
16496         ls -lh $temp $file
16497         cancel_lru_locks osc
16498         cmp $temp $file || error "$temp $file differ"
16499
16500         rm -f $temp $file
16501         true
16502 }
16503
16504 save_writethrough() {
16505         local facets=$(get_facets OST)
16506
16507         save_lustre_params $facets "osd-*.*.writethrough_cache_enable" > $1
16508 }
16509
16510 test_155a() {
16511         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16512
16513         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16514
16515         save_writethrough $p
16516
16517         set_cache read on
16518         set_cache writethrough on
16519         test_155_small_load
16520         restore_lustre_params < $p
16521         rm -f $p
16522 }
16523 run_test 155a "Verify small file correctness: read cache:on write_cache:on"
16524
16525 test_155b() {
16526         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16527
16528         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16529
16530         save_writethrough $p
16531
16532         set_cache read on
16533         set_cache writethrough off
16534         test_155_small_load
16535         restore_lustre_params < $p
16536         rm -f $p
16537 }
16538 run_test 155b "Verify small file correctness: read cache:on write_cache:off"
16539
16540 test_155c() {
16541         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16542
16543         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16544
16545         save_writethrough $p
16546
16547         set_cache read off
16548         set_cache writethrough on
16549         test_155_small_load
16550         restore_lustre_params < $p
16551         rm -f $p
16552 }
16553 run_test 155c "Verify small file correctness: read cache:off write_cache:on"
16554
16555 test_155d() {
16556         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16557
16558         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16559
16560         save_writethrough $p
16561
16562         set_cache read off
16563         set_cache writethrough off
16564         test_155_small_load
16565         restore_lustre_params < $p
16566         rm -f $p
16567 }
16568 run_test 155d "Verify small file correctness: read cache:off write_cache:off"
16569
16570 test_155e() {
16571         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16572
16573         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16574
16575         save_writethrough $p
16576
16577         set_cache read on
16578         set_cache writethrough on
16579         test_155_big_load
16580         restore_lustre_params < $p
16581         rm -f $p
16582 }
16583 run_test 155e "Verify big file correctness: read cache:on write_cache:on"
16584
16585 test_155f() {
16586         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16587
16588         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16589
16590         save_writethrough $p
16591
16592         set_cache read on
16593         set_cache writethrough off
16594         test_155_big_load
16595         restore_lustre_params < $p
16596         rm -f $p
16597 }
16598 run_test 155f "Verify big file correctness: read cache:on write_cache:off"
16599
16600 test_155g() {
16601         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16602
16603         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16604
16605         save_writethrough $p
16606
16607         set_cache read off
16608         set_cache writethrough on
16609         test_155_big_load
16610         restore_lustre_params < $p
16611         rm -f $p
16612 }
16613 run_test 155g "Verify big file correctness: read cache:off write_cache:on"
16614
16615 test_155h() {
16616         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16617
16618         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16619
16620         save_writethrough $p
16621
16622         set_cache read off
16623         set_cache writethrough off
16624         test_155_big_load
16625         restore_lustre_params < $p
16626         rm -f $p
16627 }
16628 run_test 155h "Verify big file correctness: read cache:off write_cache:off"
16629
16630 test_156() {
16631         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16632         remote_ost_nodsh && skip "remote OST with nodsh"
16633         [ $OST1_VERSION -lt $(version_code 2.6.93) ] &&
16634                 skip "stats not implemented on old servers"
16635         [ "$ost1_FSTYPE" = "zfs" ] &&
16636                 skip "LU-1956/LU-2261: stats not implemented on OSD ZFS"
16637         (( CLIENT_VERSION == OST1_VERSION )) ||
16638                 skip "LU-13081: no interop testing for OSS cache"
16639
16640         local CPAGES=3
16641         local BEFORE
16642         local AFTER
16643         local file="$DIR/$tfile"
16644         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16645
16646         save_writethrough $p
16647         roc_hit_init
16648
16649         log "Turn on read and write cache"
16650         set_cache read on
16651         set_cache writethrough on
16652
16653         log "Write data and read it back."
16654         log "Read should be satisfied from the cache."
16655         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
16656         BEFORE=$(roc_hit)
16657         cancel_lru_locks osc
16658         cat $file >/dev/null
16659         AFTER=$(roc_hit)
16660         if ! let "AFTER - BEFORE == CPAGES"; then
16661                 error "NOT IN CACHE (2): before: $BEFORE, after: $AFTER"
16662         else
16663                 log "cache hits: before: $BEFORE, after: $AFTER"
16664         fi
16665
16666         log "Read again; it should be satisfied from the cache."
16667         BEFORE=$AFTER
16668         cancel_lru_locks osc
16669         cat $file >/dev/null
16670         AFTER=$(roc_hit)
16671         if ! let "AFTER - BEFORE == CPAGES"; then
16672                 error "NOT IN CACHE (3): before: $BEFORE, after: $AFTER"
16673         else
16674                 log "cache hits:: before: $BEFORE, after: $AFTER"
16675         fi
16676
16677         log "Turn off the read cache and turn on the write cache"
16678         set_cache read off
16679         set_cache writethrough on
16680
16681         log "Read again; it should be satisfied from the cache."
16682         BEFORE=$(roc_hit)
16683         cancel_lru_locks osc
16684         cat $file >/dev/null
16685         AFTER=$(roc_hit)
16686         if ! let "AFTER - BEFORE == CPAGES"; then
16687                 error "NOT IN CACHE (4): before: $BEFORE, after: $AFTER"
16688         else
16689                 log "cache hits:: before: $BEFORE, after: $AFTER"
16690         fi
16691
16692         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
16693                 # > 2.12.56 uses pagecache if cached
16694                 log "Read again; it should not be satisfied from the cache."
16695                 BEFORE=$AFTER
16696                 cancel_lru_locks osc
16697                 cat $file >/dev/null
16698                 AFTER=$(roc_hit)
16699                 if ! let "AFTER - BEFORE == 0"; then
16700                         error "IN CACHE (5): before: $BEFORE, after: $AFTER"
16701                 else
16702                         log "cache hits:: before: $BEFORE, after: $AFTER"
16703                 fi
16704         fi
16705
16706         log "Write data and read it back."
16707         log "Read should be satisfied from the cache."
16708         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
16709         BEFORE=$(roc_hit)
16710         cancel_lru_locks osc
16711         cat $file >/dev/null
16712         AFTER=$(roc_hit)
16713         if ! let "AFTER - BEFORE == CPAGES"; then
16714                 error "NOT IN CACHE (6): before: $BEFORE, after: $AFTER"
16715         else
16716                 log "cache hits:: before: $BEFORE, after: $AFTER"
16717         fi
16718
16719         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
16720                 # > 2.12.56 uses pagecache if cached
16721                 log "Read again; it should not be satisfied from the cache."
16722                 BEFORE=$AFTER
16723                 cancel_lru_locks osc
16724                 cat $file >/dev/null
16725                 AFTER=$(roc_hit)
16726                 if ! let "AFTER - BEFORE == 0"; then
16727                         error "IN CACHE (7): before: $BEFORE, after: $AFTER"
16728                 else
16729                         log "cache hits:: before: $BEFORE, after: $AFTER"
16730                 fi
16731         fi
16732
16733         log "Turn off read and write cache"
16734         set_cache read off
16735         set_cache writethrough off
16736
16737         log "Write data and read it back"
16738         log "It should not be satisfied from the cache."
16739         rm -f $file
16740         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
16741         cancel_lru_locks osc
16742         BEFORE=$(roc_hit)
16743         cat $file >/dev/null
16744         AFTER=$(roc_hit)
16745         if ! let "AFTER - BEFORE == 0"; then
16746                 error_ignore bz20762 "IN CACHE (8):before:$BEFORE,after:$AFTER"
16747         else
16748                 log "cache hits:: before: $BEFORE, after: $AFTER"
16749         fi
16750
16751         log "Turn on the read cache and turn off the write cache"
16752         set_cache read on
16753         set_cache writethrough off
16754
16755         log "Write data and read it back"
16756         log "It should not be satisfied from the cache."
16757         rm -f $file
16758         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
16759         BEFORE=$(roc_hit)
16760         cancel_lru_locks osc
16761         cat $file >/dev/null
16762         AFTER=$(roc_hit)
16763         if ! let "AFTER - BEFORE == 0"; then
16764                 error_ignore bz20762 "IN CACHE (9):before:$BEFORE,after:$AFTER"
16765         else
16766                 log "cache hits:: before: $BEFORE, after: $AFTER"
16767         fi
16768
16769         log "Read again; it should be satisfied from the cache."
16770         BEFORE=$(roc_hit)
16771         cancel_lru_locks osc
16772         cat $file >/dev/null
16773         AFTER=$(roc_hit)
16774         if ! let "AFTER - BEFORE == CPAGES"; then
16775                 error "NOT IN CACHE (1): before: $BEFORE, after: $AFTER"
16776         else
16777                 log "cache hits:: before: $BEFORE, after: $AFTER"
16778         fi
16779
16780         restore_lustre_params < $p
16781         rm -f $p $file
16782 }
16783 run_test 156 "Verification of tunables"
16784
16785 test_160a() {
16786         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16787         remote_mds_nodsh && skip "remote MDS with nodsh"
16788         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
16789                 skip "Need MDS version at least 2.2.0"
16790
16791         changelog_register || error "changelog_register failed"
16792         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16793         changelog_users $SINGLEMDS | grep -q $cl_user ||
16794                 error "User $cl_user not found in changelog_users"
16795
16796         mkdir_on_mdt0 $DIR/$tdir
16797
16798         # change something
16799         test_mkdir -p $DIR/$tdir/pics/2008/zachy
16800         changelog_clear 0 || error "changelog_clear failed"
16801         touch $DIR/$tdir/pics/2008/zachy/$tfile                 # open 1
16802         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg       # open 2
16803         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
16804         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
16805         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
16806         rm $DIR/$tdir/pics/desktop.jpg
16807
16808         echo "verifying changelog mask"
16809         changelog_chmask "-MKDIR"
16810         changelog_chmask "-CLOSE"
16811
16812         test_mkdir -p $DIR/$tdir/pics/zach/sofia                # not logged
16813         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # not logged
16814
16815         changelog_chmask "+MKDIR"
16816         changelog_chmask "+CLOSE"
16817
16818         test_mkdir -p $DIR/$tdir/pics/2008/sofia                # mkdir 1
16819         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # open 3
16820
16821         MKDIRS=$(changelog_dump | grep -c "MKDIR")
16822         CLOSES=$(changelog_dump | grep -c "CLOSE")
16823         [ $MKDIRS -eq 1 ] || error "MKDIR changelog mask count $MKDIRS != 1"
16824         [ $CLOSES -eq 3 ] || error "CLOSE changelog mask count $CLOSES != 3"
16825
16826         # verify contents
16827         echo "verifying target fid"
16828         local fidc=$(changelog_extract_field "CREAT" "$tfile" "t=")
16829         local fidf=$($LFS path2fid $DIR/$tdir/pics/zach/$tfile)
16830         [ "$fidc" == "$fidf" ] ||
16831                 error "changelog '$tfile' fid $fidc != file fid $fidf"
16832         echo "verifying parent fid"
16833         # The FID returned from the Changelog may be the directory shard on
16834         # a different MDT, and not the FID returned by path2fid on the parent.
16835         # Instead of comparing FIDs, verify that fid2path(fidp) is correct,
16836         # since this is what will matter when recreating this file in the tree.
16837         local fidp=$(changelog_extract_field "CREAT" "$tfile" "p=")
16838         local pathp=$($LFS fid2path $MOUNT "$fidp")
16839         [ "${pathp%/}" == "$DIR/$tdir/pics/zach" ] ||
16840                 error "changelog fid2path($fidc) $pathp != $DIR/$tdir/pics/zach"
16841
16842         echo "getting records for $cl_user"
16843         changelog_users $SINGLEMDS
16844         local user_rec1=$(changelog_user_rec $SINGLEMDS $cl_user)
16845         local nclr=3
16846         __changelog_clear $SINGLEMDS $cl_user +$nclr ||
16847                 error "changelog_clear failed"
16848         local user_rec2=$(changelog_user_rec $SINGLEMDS $cl_user)
16849         echo "verifying user clear: $user_rec1 + $nclr == $user_rec2"
16850         [ $user_rec2 == $((user_rec1 + nclr)) ] ||
16851                 error "user index expect $user_rec1 + $nclr != $user_rec2"
16852
16853         local min0_rec=$(changelog_users $SINGLEMDS |
16854                 awk 'min == "" || $2 < min { min = $2 }; END { print min }')
16855         local first_rec=$($LFS changelog $(facet_svc $SINGLEMDS) |
16856                           awk '{ print $1; exit; }')
16857
16858         changelog_dump | tail -n 5
16859         echo "verifying user min purge: $min0_rec + 1 == $first_rec"
16860         [ $first_rec == $((min0_rec + 1)) ] ||
16861                 error "first index should be $min0_rec + 1 not $first_rec"
16862
16863         # LU-3446 changelog index reset on MDT restart
16864         local cur_rec1=$(changelog_users $SINGLEMDS |
16865                          awk '/^current.index:/ { print $NF }')
16866         changelog_clear 0 ||
16867                 error "clear all changelog records for $cl_user failed"
16868         stop $SINGLEMDS || error "Fail to stop $SINGLEMDS"
16869         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
16870                 error "Fail to start $SINGLEMDS"
16871         local cur_rec2=$(changelog_users $SINGLEMDS |
16872                          awk '/^current.index:/ { print $NF }')
16873         echo "verifying index survives MDT restart: $cur_rec1 == $cur_rec2"
16874         [ $cur_rec1 == $cur_rec2 ] ||
16875                 error "current index should be $cur_rec1 not $cur_rec2"
16876
16877         echo "verifying users from this test are deregistered"
16878         changelog_deregister || error "changelog_deregister failed"
16879         changelog_users $SINGLEMDS | grep -q $cl_user &&
16880                 error "User '$cl_user' still in changelog_users"
16881
16882         # lctl get_param -n mdd.*.changelog_users
16883         # current_index: 144
16884         # ID    index (idle seconds)
16885         # cl3   144   (2) mask=<list>
16886         if [ -z "$(changelog_users $SINGLEMDS | grep -v current.index)" ]; then
16887                 # this is the normal case where all users were deregistered
16888                 # make sure no new records are added when no users are present
16889                 local last_rec1=$(changelog_users $SINGLEMDS |
16890                                   awk '/^current.index:/ { print $NF }')
16891                 touch $DIR/$tdir/chloe
16892                 local last_rec2=$(changelog_users $SINGLEMDS |
16893                                   awk '/^current.index:/ { print $NF }')
16894                 echo "verify changelogs are off: $last_rec1 == $last_rec2"
16895                 [ $last_rec1 == $last_rec2 ] || error "changelogs not off"
16896         else
16897                 # any changelog users must be leftovers from a previous test
16898                 changelog_users $SINGLEMDS
16899                 echo "other changelog users; can't verify off"
16900         fi
16901 }
16902 run_test 160a "changelog sanity"
16903
16904 test_160b() { # LU-3587
16905         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16906         remote_mds_nodsh && skip "remote MDS with nodsh"
16907         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
16908                 skip "Need MDS version at least 2.2.0"
16909
16910         changelog_register || error "changelog_register failed"
16911         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16912         changelog_users $SINGLEMDS | grep -q $cl_user ||
16913                 error "User '$cl_user' not found in changelog_users"
16914
16915         local longname1=$(str_repeat a 255)
16916         local longname2=$(str_repeat b 255)
16917
16918         cd $DIR
16919         echo "creating very long named file"
16920         touch $longname1 || error "create of '$longname1' failed"
16921         echo "renaming very long named file"
16922         mv $longname1 $longname2
16923
16924         changelog_dump | grep RENME | tail -n 5
16925         rm -f $longname2
16926 }
16927 run_test 160b "Verify that very long rename doesn't crash in changelog"
16928
16929 test_160c() {
16930         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16931         remote_mds_nodsh && skip "remote MDS with nodsh"
16932
16933         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
16934                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
16935                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
16936                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
16937
16938         local rc=0
16939
16940         # Registration step
16941         changelog_register || error "changelog_register failed"
16942
16943         rm -rf $DIR/$tdir
16944         mkdir -p $DIR/$tdir
16945         $MCREATE $DIR/$tdir/foo_160c
16946         changelog_chmask "-TRUNC"
16947         $TRUNCATE $DIR/$tdir/foo_160c 200
16948         changelog_chmask "+TRUNC"
16949         $TRUNCATE $DIR/$tdir/foo_160c 199
16950         changelog_dump | tail -n 5
16951         local truncs=$(changelog_dump | tail -n 5 | grep -c TRUNC)
16952         [ $truncs -eq 1 ] || error "TRUNC changelog mask count $truncs != 1"
16953 }
16954 run_test 160c "verify that changelog log catch the truncate event"
16955
16956 test_160d() {
16957         remote_mds_nodsh && skip "remote MDS with nodsh"
16958         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16959         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16960         [[ $MDS1_VERSION -ge $(version_code 2.7.60) ]] ||
16961                 skip "Need MDS version at least 2.7.60"
16962
16963         # Registration step
16964         changelog_register || error "changelog_register failed"
16965
16966         mkdir -p $DIR/$tdir/migrate_dir
16967         changelog_clear 0 || error "changelog_clear failed"
16968
16969         $LFS migrate -m 1 $DIR/$tdir/migrate_dir || error "migrate fails"
16970         changelog_dump | tail -n 5
16971         local migrates=$(changelog_dump | grep -c "MIGRT")
16972         [ $migrates -eq 1 ] || error "MIGRATE changelog count $migrates != 1"
16973 }
16974 run_test 160d "verify that changelog log catch the migrate event"
16975
16976 test_160e() {
16977         remote_mds_nodsh && skip "remote MDS with nodsh"
16978
16979         # Create a user
16980         changelog_register || error "changelog_register failed"
16981
16982         local MDT0=$(facet_svc $SINGLEMDS)
16983         local rc
16984
16985         # No user (expect fail)
16986         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister
16987         rc=$?
16988         if [ $rc -eq 0 ]; then
16989                 error "Should fail without user"
16990         elif [ $rc -ne 4 ]; then
16991                 error "changelog_deregister failed with $rc, expect 4(CMD_HELP)"
16992         fi
16993
16994         # Delete a future user (expect fail)
16995         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister "cl77"
16996         rc=$?
16997         if [ $rc -eq 0 ]; then
16998                 error "Deleted non-existant user cl77"
16999         elif [ $rc -ne 2 ]; then
17000                 error "changelog_deregister failed with $rc, expect 2 (ENOENT)"
17001         fi
17002
17003         # Clear to a bad index (1 billion should be safe)
17004         $LFS changelog_clear $MDT0 "${CL_USERS[$SINGLEMDS]%% *}" 1000000000
17005         rc=$?
17006
17007         if [ $rc -eq 0 ]; then
17008                 error "Successfully cleared to invalid CL index"
17009         elif [ $rc -ne 22 ]; then
17010                 error "changelog_clear failed with $rc, expected 22 (EINVAL)"
17011         fi
17012 }
17013 run_test 160e "changelog negative testing (should return errors)"
17014
17015 test_160f() {
17016         remote_mds_nodsh && skip "remote MDS with nodsh" && return
17017         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
17018                 skip "Need MDS version at least 2.10.56"
17019
17020         local mdts=$(comma_list $(mdts_nodes))
17021
17022         # Create a user
17023         changelog_register || error "first changelog_register failed"
17024         changelog_register || error "second changelog_register failed"
17025         local cl_users
17026         declare -A cl_user1
17027         declare -A cl_user2
17028         local user_rec1
17029         local user_rec2
17030         local i
17031
17032         # generate some changelog records to accumulate on each MDT
17033         # use all_char because created files should be evenly distributed
17034         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
17035                 error "test_mkdir $tdir failed"
17036         log "$(date +%s): creating first files"
17037         for ((i = 0; i < MDSCOUNT * 2; i++)); do
17038                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT)) ||
17039                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT)) failed"
17040         done
17041
17042         # check changelogs have been generated
17043         local start=$SECONDS
17044         local idle_time=$((MDSCOUNT * 5 + 5))
17045         local nbcl=$(changelog_dump | wc -l)
17046         [[ $nbcl -eq 0 ]] && error "no changelogs found"
17047
17048         for param in "changelog_max_idle_time=$idle_time" \
17049                      "changelog_gc=1" \
17050                      "changelog_min_gc_interval=2" \
17051                      "changelog_min_free_cat_entries=3"; do
17052                 local MDT0=$(facet_svc $SINGLEMDS)
17053                 local var="${param%=*}"
17054                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
17055
17056                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
17057                 do_nodes $mdts $LCTL set_param mdd.*.$param
17058         done
17059
17060         # force cl_user2 to be idle (1st part), but also cancel the
17061         # cl_user1 records so that it is not evicted later in the test.
17062         local sleep1=$((idle_time / 2))
17063         echo "$(date +%s): sleep1 $sleep1/${idle_time}s"
17064         sleep $sleep1
17065
17066         # simulate changelog catalog almost full
17067         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
17068         do_nodes $mdts "$LCTL set_param fail_loc=0x1313 fail_val=3"
17069
17070         for i in $(seq $MDSCOUNT); do
17071                 cl_users=(${CL_USERS[mds$i]})
17072                 cl_user1[mds$i]="${cl_users[0]}"
17073                 cl_user2[mds$i]="${cl_users[1]}"
17074
17075                 [ -n "${cl_user1[mds$i]}" ] ||
17076                         error "mds$i: no user registered"
17077                 [ -n "${cl_user2[mds$i]}" ] ||
17078                         error "mds$i: only ${cl_user2[mds$i]} is registered"
17079
17080                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17081                 [ -n "$user_rec1" ] ||
17082                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17083                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
17084                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17085                 [ -n "$user_rec2" ] ||
17086                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17087                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
17088                      "$user_rec1 + 2 == $user_rec2"
17089                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
17090                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
17091                               "$user_rec1 + 2, but is $user_rec2"
17092                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
17093                 [ -n "$user_rec2" ] ||
17094                         error "mds$i: User ${cl_user2[mds$i]} not registered"
17095                 [ $user_rec1 == $user_rec2 ] ||
17096                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
17097                               "$user_rec1, but is $user_rec2"
17098         done
17099
17100         # force cl_user2 idle (2nd part) to just exceed changelog_max_idle_time
17101         local sleep2=$((idle_time - (SECONDS - start) + 1))
17102         echo "$(date +%s): sleep2 $sleep2/${idle_time}s"
17103         sleep $sleep2
17104
17105         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
17106         # cl_user1 should be OK because it recently processed records.
17107         echo "$(date +%s): creating $((MDSCOUNT * 2)) files"
17108         for ((i = 0; i < MDSCOUNT * 2; i++)); do
17109                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT+2))||
17110                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT+2)) failed"
17111         done
17112
17113         # ensure gc thread is done
17114         for i in $(mdts_nodes); do
17115                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
17116                         error "$i: GC-thread not done"
17117         done
17118
17119         local first_rec
17120         for (( i = 1; i <= MDSCOUNT; i++ )); do
17121                 # check cl_user1 still registered
17122                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
17123                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17124                 # check cl_user2 unregistered
17125                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
17126                         error "mds$i: User ${cl_user2[mds$i]} still registered"
17127
17128                 # check changelogs are present and starting at $user_rec1 + 1
17129                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17130                 [ -n "$user_rec1" ] ||
17131                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17132                 first_rec=$($LFS changelog $(facet_svc mds$i) |
17133                             awk '{ print $1; exit; }')
17134
17135                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
17136                 [ $((user_rec1 + 1)) == $first_rec ] ||
17137                         error "mds$i: rec $first_rec != $user_rec1 + 1"
17138         done
17139 }
17140 run_test 160f "changelog garbage collect (timestamped users)"
17141
17142 test_160g() {
17143         remote_mds_nodsh && skip "remote MDS with nodsh"
17144         [[ $MDS1_VERSION -ge $(version_code 2.14.55) ]] ||
17145                 skip "Need MDS version at least 2.14.55"
17146
17147         local mdts=$(comma_list $(mdts_nodes))
17148
17149         # Create a user
17150         changelog_register || error "first changelog_register failed"
17151         changelog_register || error "second changelog_register failed"
17152         local cl_users
17153         declare -A cl_user1
17154         declare -A cl_user2
17155         local user_rec1
17156         local user_rec2
17157         local i
17158
17159         # generate some changelog records to accumulate on each MDT
17160         # use all_char because created files should be evenly distributed
17161         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
17162                 error "test_mkdir $tdir failed"
17163         for ((i = 0; i < MDSCOUNT; i++)); do
17164                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
17165                         error "create $DIR/$tdir/d$i.1 failed"
17166         done
17167
17168         # check changelogs have been generated
17169         local nbcl=$(changelog_dump | wc -l)
17170         (( $nbcl > 0 )) || error "no changelogs found"
17171
17172         # reduce the max_idle_indexes value to make sure we exceed it
17173         for param in "changelog_max_idle_indexes=2" \
17174                      "changelog_gc=1" \
17175                      "changelog_min_gc_interval=2"; do
17176                 local MDT0=$(facet_svc $SINGLEMDS)
17177                 local var="${param%=*}"
17178                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
17179
17180                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
17181                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
17182                         error "unable to set mdd.*.$param"
17183         done
17184
17185         local start=$SECONDS
17186         for i in $(seq $MDSCOUNT); do
17187                 cl_users=(${CL_USERS[mds$i]})
17188                 cl_user1[mds$i]="${cl_users[0]}"
17189                 cl_user2[mds$i]="${cl_users[1]}"
17190
17191                 [ -n "${cl_user1[mds$i]}" ] ||
17192                         error "mds$i: user1 is not registered"
17193                 [ -n "${cl_user2[mds$i]}" ] ||
17194                         error "mds$i: only ${cl_user1[mds$i]} is registered"
17195
17196                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17197                 [ -n "$user_rec1" ] ||
17198                         error "mds$i: user1 ${cl_user1[mds$i]} not found"
17199                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
17200                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17201                 [ -n "$user_rec2" ] ||
17202                         error "mds$i: user1 ${cl_user1[mds$i]} not found (2)"
17203                 echo "mds$i: verifying user1 ${cl_user1[mds$i]} clear: " \
17204                      "$user_rec1 + 2 == $user_rec2"
17205                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
17206                         error "mds$i: user1 ${cl_user1[mds$i]} index " \
17207                               "expected $user_rec1 + 2, but is $user_rec2"
17208                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
17209                 [ -n "$user_rec2" ] ||
17210                         error "mds$i: user2 ${cl_user2[mds$i]} not found"
17211                 [ $user_rec1 == $user_rec2 ] ||
17212                         error "mds$i: user2 ${cl_user2[mds$i]} index " \
17213                               "expected $user_rec1, but is $user_rec2"
17214         done
17215
17216         # ensure we are past the previous changelog_min_gc_interval set above
17217         local sleep2=$((start + 2 - SECONDS))
17218         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
17219         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
17220         # cl_user1 should be OK because it recently processed records.
17221         for ((i = 0; i < MDSCOUNT; i++)); do
17222                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 ||
17223                         error "create $DIR/$tdir/d$i.3 failed"
17224         done
17225
17226         # ensure gc thread is done
17227         for i in $(mdts_nodes); do
17228                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
17229                         error "$i: GC-thread not done"
17230         done
17231
17232         local first_rec
17233         for (( i = 1; i <= MDSCOUNT; i++ )); do
17234                 # check cl_user1 still registered
17235                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
17236                         error "mds$i: user1 ${cl_user1[mds$i]} not found (3)"
17237                 # check cl_user2 unregistered
17238                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
17239                         error "mds$i: user2 ${cl_user2[mds$i]} is registered"
17240
17241                 # check changelogs are present and starting at $user_rec1 + 1
17242                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17243                 [ -n "$user_rec1" ] ||
17244                         error "mds$i: user1 ${cl_user1[mds$i]} not found (4)"
17245                 first_rec=$($LFS changelog $(facet_svc mds$i) |
17246                             awk '{ print $1; exit; }')
17247
17248                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
17249                 [ $((user_rec1 + 1)) == $first_rec ] ||
17250                         error "mds$i: rec $first_rec != $user_rec1 + 1"
17251         done
17252 }
17253 run_test 160g "changelog garbage collect on idle records"
17254
17255 test_160h() {
17256         remote_mds_nodsh && skip "remote MDS with nodsh" && return
17257         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
17258                 skip "Need MDS version at least 2.10.56"
17259
17260         local mdts=$(comma_list $(mdts_nodes))
17261
17262         # Create a user
17263         changelog_register || error "first changelog_register failed"
17264         changelog_register || error "second changelog_register failed"
17265         local cl_users
17266         declare -A cl_user1
17267         declare -A cl_user2
17268         local user_rec1
17269         local user_rec2
17270         local i
17271
17272         # generate some changelog records to accumulate on each MDT
17273         # use all_char because created files should be evenly distributed
17274         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
17275                 error "test_mkdir $tdir failed"
17276         for ((i = 0; i < MDSCOUNT; i++)); do
17277                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
17278                         error "create $DIR/$tdir/d$i.1 failed"
17279         done
17280
17281         # check changelogs have been generated
17282         local nbcl=$(changelog_dump | wc -l)
17283         [[ $nbcl -eq 0 ]] && error "no changelogs found"
17284
17285         for param in "changelog_max_idle_time=10" \
17286                      "changelog_gc=1" \
17287                      "changelog_min_gc_interval=2"; do
17288                 local MDT0=$(facet_svc $SINGLEMDS)
17289                 local var="${param%=*}"
17290                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
17291
17292                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
17293                 do_nodes $mdts $LCTL set_param mdd.*.$param
17294         done
17295
17296         # force cl_user2 to be idle (1st part)
17297         sleep 9
17298
17299         for i in $(seq $MDSCOUNT); do
17300                 cl_users=(${CL_USERS[mds$i]})
17301                 cl_user1[mds$i]="${cl_users[0]}"
17302                 cl_user2[mds$i]="${cl_users[1]}"
17303
17304                 [ -n "${cl_user1[mds$i]}" ] ||
17305                         error "mds$i: no user registered"
17306                 [ -n "${cl_user2[mds$i]}" ] ||
17307                         error "mds$i: only ${cl_user2[mds$i]} is registered"
17308
17309                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17310                 [ -n "$user_rec1" ] ||
17311                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17312                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
17313                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17314                 [ -n "$user_rec2" ] ||
17315                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17316                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
17317                      "$user_rec1 + 2 == $user_rec2"
17318                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
17319                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
17320                               "$user_rec1 + 2, but is $user_rec2"
17321                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
17322                 [ -n "$user_rec2" ] ||
17323                         error "mds$i: User ${cl_user2[mds$i]} not registered"
17324                 [ $user_rec1 == $user_rec2 ] ||
17325                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
17326                               "$user_rec1, but is $user_rec2"
17327         done
17328
17329         # force cl_user2 to be idle (2nd part) and to reach
17330         # changelog_max_idle_time
17331         sleep 2
17332
17333         # force each GC-thread start and block then
17334         # one per MDT/MDD, set fail_val accordingly
17335         #define OBD_FAIL_FORCE_GC_THREAD 0x1316
17336         do_nodes $mdts $LCTL set_param fail_loc=0x1316
17337
17338         # generate more changelogs to trigger fail_loc
17339         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
17340                 error "create $DIR/$tdir/${tfile}bis failed"
17341
17342         # stop MDT to stop GC-thread, should be done in back-ground as it will
17343         # block waiting for the thread to be released and exit
17344         declare -A stop_pids
17345         for i in $(seq $MDSCOUNT); do
17346                 stop mds$i &
17347                 stop_pids[mds$i]=$!
17348         done
17349
17350         for i in $(mdts_nodes); do
17351                 local facet
17352                 local nb=0
17353                 local facets=$(facets_up_on_host $i)
17354
17355                 for facet in ${facets//,/ }; do
17356                         if [[ $facet == mds* ]]; then
17357                                 nb=$((nb + 1))
17358                         fi
17359                 done
17360                 # ensure each MDS's gc threads are still present and all in "R"
17361                 # state (OBD_FAIL_FORCE_GC_THREAD effect!)
17362                 [[ $(do_node $i pgrep chlg_gc_thread | wc -l) -eq $nb ]] ||
17363                         error "$i: expected $nb GC-thread"
17364                 wait_update $i \
17365                         "ps -C chlg_gc_thread -o state --no-headers | uniq" \
17366                         "R" 20 ||
17367                         error "$i: GC-thread not found in R-state"
17368                 # check umounts of each MDT on MDS have reached kthread_stop()
17369                 [[ $(do_node $i pgrep umount | wc -l) -eq $nb ]] ||
17370                         error "$i: expected $nb umount"
17371                 wait_update $i \
17372                         "ps -C umount -o state --no-headers | uniq" "D" 20 ||
17373                         error "$i: umount not found in D-state"
17374         done
17375
17376         # release all GC-threads
17377         do_nodes $mdts $LCTL set_param fail_loc=0
17378
17379         # wait for MDT stop to complete
17380         for i in $(seq $MDSCOUNT); do
17381                 wait ${stop_pids[mds$i]} || error "mds$i: stop failed"
17382         done
17383
17384         # XXX
17385         # may try to check if any orphan changelog records are present
17386         # via ldiskfs/zfs and llog_reader...
17387
17388         # re-start/mount MDTs
17389         for i in $(seq $MDSCOUNT); do
17390                 start mds$i $(mdsdevname $i) $MDS_MOUNT_OPTS ||
17391                         error "Fail to start mds$i"
17392         done
17393
17394         local first_rec
17395         for i in $(seq $MDSCOUNT); do
17396                 # check cl_user1 still registered
17397                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
17398                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17399                 # check cl_user2 unregistered
17400                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
17401                         error "mds$i: User ${cl_user2[mds$i]} still registered"
17402
17403                 # check changelogs are present and starting at $user_rec1 + 1
17404                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17405                 [ -n "$user_rec1" ] ||
17406                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17407                 first_rec=$($LFS changelog $(facet_svc mds$i) |
17408                             awk '{ print $1; exit; }')
17409
17410                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
17411                 [ $((user_rec1 + 1)) == $first_rec ] ||
17412                         error "mds$i: first index should be $user_rec1 + 1, " \
17413                               "but is $first_rec"
17414         done
17415 }
17416 run_test 160h "changelog gc thread stop upon umount, orphan records delete " \
17417               "during mount"
17418
17419 test_160i() {
17420
17421         local mdts=$(comma_list $(mdts_nodes))
17422
17423         changelog_register || error "first changelog_register failed"
17424
17425         # generate some changelog records to accumulate on each MDT
17426         # use all_char because created files should be evenly distributed
17427         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
17428                 error "test_mkdir $tdir failed"
17429         for ((i = 0; i < MDSCOUNT; i++)); do
17430                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
17431                         error "create $DIR/$tdir/d$i.1 failed"
17432         done
17433
17434         # check changelogs have been generated
17435         local nbcl=$(changelog_dump | wc -l)
17436         [[ $nbcl -eq 0 ]] && error "no changelogs found"
17437
17438         # simulate race between register and unregister
17439         # XXX as fail_loc is set per-MDS, with DNE configs the race
17440         # simulation will only occur for one MDT per MDS and for the
17441         # others the normal race scenario will take place
17442         #define CFS_FAIL_CHLOG_USER_REG_UNREG_RACE          0x1315
17443         do_nodes $mdts $LCTL set_param fail_loc=0x10001315
17444         do_nodes $mdts $LCTL set_param fail_val=1
17445
17446         # unregister 1st user
17447         changelog_deregister &
17448         local pid1=$!
17449         # wait some time for deregister work to reach race rdv
17450         sleep 2
17451         # register 2nd user
17452         changelog_register || error "2nd user register failed"
17453
17454         wait $pid1 || error "1st user deregister failed"
17455
17456         local i
17457         local last_rec
17458         declare -A LAST_REC
17459         for i in $(seq $MDSCOUNT); do
17460                 if changelog_users mds$i | grep "^cl"; then
17461                         # make sure new records are added with one user present
17462                         LAST_REC[mds$i]=$(changelog_users $SINGLEMDS |
17463                                           awk '/^current.index:/ { print $NF }')
17464                 else
17465                         error "mds$i has no user registered"
17466                 fi
17467         done
17468
17469         # generate more changelog records to accumulate on each MDT
17470         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
17471                 error "create $DIR/$tdir/${tfile}bis failed"
17472
17473         for i in $(seq $MDSCOUNT); do
17474                 last_rec=$(changelog_users $SINGLEMDS |
17475                            awk '/^current.index:/ { print $NF }')
17476                 echo "verify changelogs are on: $last_rec != ${LAST_REC[mds$i]}"
17477                 [ $last_rec != ${LAST_REC[mds$i]} ] ||
17478                         error "changelogs are off on mds$i"
17479         done
17480 }
17481 run_test 160i "changelog user register/unregister race"
17482
17483 test_160j() {
17484         remote_mds_nodsh && skip "remote MDS with nodsh"
17485         [[ $MDS1_VERSION -lt $(version_code 2.12.56) ]] &&
17486                 skip "Need MDS version at least 2.12.56"
17487
17488         mount_client $MOUNT2 || error "mount_client on $MOUNT2 failed"
17489         stack_trap "umount $MOUNT2" EXIT
17490
17491         changelog_register || error "first changelog_register failed"
17492         stack_trap "changelog_deregister" EXIT
17493
17494         # generate some changelog
17495         # use all_char because created files should be evenly distributed
17496         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
17497                 error "mkdir $tdir failed"
17498         for ((i = 0; i < MDSCOUNT; i++)); do
17499                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
17500                         error "create $DIR/$tdir/d$i.1 failed"
17501         done
17502
17503         # open the changelog device
17504         exec 3>/dev/changelog-$FSNAME-MDT0000
17505         stack_trap "exec 3>&-" EXIT
17506         exec 4</dev/changelog-$FSNAME-MDT0000
17507         stack_trap "exec 4<&-" EXIT
17508
17509         # umount the first lustre mount
17510         umount $MOUNT
17511         stack_trap "mount_client $MOUNT" EXIT
17512
17513         # read changelog, which may or may not fail, but should not crash
17514         cat <&4 >/dev/null
17515
17516         # clear changelog
17517         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
17518         changelog_users $SINGLEMDS | grep -q $cl_user ||
17519                 error "User $cl_user not found in changelog_users"
17520
17521         printf 'clear:'$cl_user':0' >&3
17522 }
17523 run_test 160j "client can be umounted while its chanangelog is being used"
17524
17525 test_160k() {
17526         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17527         remote_mds_nodsh && skip "remote MDS with nodsh"
17528
17529         mkdir -p $DIR/$tdir/1/1
17530
17531         changelog_register || error "changelog_register failed"
17532         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
17533
17534         changelog_users $SINGLEMDS | grep -q $cl_user ||
17535                 error "User '$cl_user' not found in changelog_users"
17536 #define OBD_FAIL_MDS_CHANGELOG_REORDER 0x15d
17537         do_facet mds1 $LCTL set_param fail_loc=0x8000015d fail_val=3
17538         rmdir $DIR/$tdir/1/1 & sleep 1
17539         mkdir $DIR/$tdir/2
17540         touch $DIR/$tdir/2/2
17541         rm -rf $DIR/$tdir/2
17542
17543         wait
17544         sleep 4
17545
17546         changelog_dump | grep rmdir || error "rmdir not recorded"
17547 }
17548 run_test 160k "Verify that changelog records are not lost"
17549
17550 # Verifies that a file passed as a parameter has recently had an operation
17551 # performed on it that has generated an MTIME changelog which contains the
17552 # correct parent FID. As files might reside on a different MDT from the
17553 # parent directory in DNE configurations, the FIDs are translated to paths
17554 # before being compared, which should be identical
17555 compare_mtime_changelog() {
17556         local file="${1}"
17557         local mdtidx
17558         local mtime
17559         local cl_fid
17560         local pdir
17561         local dir
17562
17563         mdtidx=$($LFS getstripe --mdt-index $file)
17564         mdtidx=$(printf "%04x" $mdtidx)
17565
17566         # Obtain the parent FID from the MTIME changelog
17567         mtime=$($LFS changelog $FSNAME-MDT$mdtidx | tail -n 1 | grep MTIME)
17568         [ -z "$mtime" ] && error "MTIME changelog not recorded"
17569
17570         cl_fid=$(sed -e 's/.* p=//' -e 's/ .*//' <<<$mtime)
17571         [ -z "$cl_fid" ] && error "parent FID not present"
17572
17573         # Verify that the path for the parent FID is the same as the path for
17574         # the test directory
17575         pdir=$($LFS fid2path $MOUNT "$cl_fid")
17576
17577         dir=$(dirname $1)
17578
17579         [[ "${pdir%/}" == "$dir" ]] ||
17580                 error "MTIME changelog parent FID is wrong, expected $dir, got $pdir"
17581 }
17582
17583 test_160l() {
17584         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17585
17586         remote_mds_nodsh && skip "remote MDS with nodsh"
17587         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
17588                 skip "Need MDS version at least 2.13.55"
17589
17590         local cl_user
17591
17592         changelog_register || error "changelog_register failed"
17593         cl_user="${CL_USERS[$SINGLEMDS]%% *}"
17594
17595         changelog_users $SINGLEMDS | grep -q $cl_user ||
17596                 error "User '$cl_user' not found in changelog_users"
17597
17598         # Clear some types so that MTIME changelogs are generated
17599         changelog_chmask "-CREAT"
17600         changelog_chmask "-CLOSE"
17601
17602         test_mkdir $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
17603
17604         # Test CL_MTIME during setattr
17605         touch $DIR/$tdir/$tfile
17606         compare_mtime_changelog $DIR/$tdir/$tfile
17607
17608         # Test CL_MTIME during close
17609         $MULTIOP $DIR/$tdir/${tfile}_2 O_2w4096c || error "multiop failed"
17610         compare_mtime_changelog $DIR/$tdir/${tfile}_2
17611 }
17612 run_test 160l "Verify that MTIME changelog records contain the parent FID"
17613
17614 test_160m() {
17615         remote_mds_nodsh && skip "remote MDS with nodsh" && return
17616         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
17617                 skip "Need MDS version at least 2.14.51"
17618         local cl_users
17619         local cl_user1
17620         local cl_user2
17621         local pid1
17622
17623         # Create a user
17624         changelog_register || error "first changelog_register failed"
17625         changelog_register || error "second changelog_register failed"
17626
17627         cl_users=(${CL_USERS[mds1]})
17628         cl_user1="${cl_users[0]}"
17629         cl_user2="${cl_users[1]}"
17630         # generate some changelog records to accumulate on MDT0
17631         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
17632         createmany -m $DIR/$tdir/$tfile 50 ||
17633                 error "create $DIR/$tdir/$tfile failed"
17634         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
17635         rm -f $DIR/$tdir
17636
17637         # check changelogs have been generated
17638         local nbcl=$(changelog_dump | wc -l)
17639         [[ $nbcl -eq 0 ]] && error "no changelogs found"
17640
17641 #define OBD_FAIL_MDS_CHANGELOG_RACE      0x15f
17642         do_facet mds1 $LCTL set_param fail_loc=0x8000015f fail_val=0
17643
17644         __changelog_clear mds1 $cl_user1 +10
17645         __changelog_clear mds1 $cl_user2 0 &
17646         pid1=$!
17647         sleep 2
17648         __changelog_clear mds1 $cl_user1 0 ||
17649                 error "fail to cancel record for $cl_user1"
17650         wait $pid1
17651         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
17652 }
17653 run_test 160m "Changelog clear race"
17654
17655 test_160n() {
17656         remote_mds_nodsh && skip "remote MDS with nodsh" && return
17657         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
17658                 skip "Need MDS version at least 2.14.51"
17659         local cl_users
17660         local cl_user1
17661         local cl_user2
17662         local pid1
17663         local first_rec
17664         local last_rec=0
17665
17666         # Create a user
17667         changelog_register || error "first changelog_register failed"
17668
17669         cl_users=(${CL_USERS[mds1]})
17670         cl_user1="${cl_users[0]}"
17671
17672         # generate some changelog records to accumulate on MDT0
17673         test_mkdir -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
17674         first_rec=$(changelog_users $SINGLEMDS |
17675                         awk '/^current.index:/ { print $NF }')
17676         while (( last_rec < (( first_rec + 65000)) )); do
17677                 createmany -m $DIR/$tdir/$tfile 10000 ||
17678                         error "create $DIR/$tdir/$tfile failed"
17679
17680                 for i in $(seq 0 10000); do
17681                         mrename $DIR/$tdir/$tfile$i $DIR/$tdir/$tfile-new$i \
17682                                 > /dev/null
17683                 done
17684
17685                 unlinkmany $DIR/$tdir/$tfile-new 10000 ||
17686                         error "unlinkmany failed unlink"
17687                 last_rec=$(changelog_users $SINGLEMDS |
17688                         awk '/^current.index:/ { print $NF }')
17689                 echo last record $last_rec
17690                 (( last_rec == 0 )) && error "no changelog found"
17691         done
17692
17693 #define OBD_FAIL_MDS_CHANGELOG_DEL       0x16c
17694         do_facet mds1 $LCTL set_param fail_loc=0x8000016c fail_val=0
17695
17696         __changelog_clear mds1 $cl_user1 0 &
17697         pid1=$!
17698         sleep 2
17699         __changelog_clear mds1 $cl_user1 0 ||
17700                 error "fail to cancel record for $cl_user1"
17701         wait $pid1
17702         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
17703 }
17704 run_test 160n "Changelog destroy race"
17705
17706 test_160o() {
17707         local mdt="$(facet_svc $SINGLEMDS)"
17708
17709         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
17710         remote_mds_nodsh && skip "remote MDS with nodsh"
17711         [ $MDS1_VERSION -ge $(version_code 2.14.52) ] ||
17712                 skip "Need MDS version at least 2.14.52"
17713
17714         changelog_register --user test_160o -m unlnk+close+open ||
17715                 error "changelog_register failed"
17716
17717         do_facet $SINGLEMDS $LCTL --device $mdt \
17718                                 changelog_register -u "Tt3_-#" &&
17719                 error "bad symbols in name should fail"
17720
17721         do_facet $SINGLEMDS $LCTL --device $mdt \
17722                                 changelog_register -u test_160o &&
17723                 error "the same name registration should fail"
17724
17725         do_facet $SINGLEMDS $LCTL --device $mdt \
17726                         changelog_register -u test_160toolongname &&
17727                 error "too long name registration should fail"
17728
17729         changelog_chmask "MARK+HSM"
17730         lctl get_param mdd.*.changelog*mask
17731         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
17732         changelog_users $SINGLEMDS | grep -q $cl_user ||
17733                 error "User $cl_user not found in changelog_users"
17734         #verify username
17735         echo $cl_user | grep -q test_160o ||
17736                 error "User $cl_user has no specific name 'test160o'"
17737
17738         # change something
17739         changelog_clear 0 || error "changelog_clear failed"
17740         # generate some changelog records to accumulate on MDT0
17741         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
17742         touch $DIR/$tdir/$tfile                 # open 1
17743
17744         OPENS=$(changelog_dump | grep -c "OPEN")
17745         [[ $OPENS -eq 1 ]] || error "OPEN changelog mask count $OPENS != 1"
17746
17747         # must be no MKDIR it wasn't set as user mask
17748         MKDIR=$(changelog_dump | grep -c "MKDIR")
17749         [[ $MKDIR -eq 0 ]] || error "MKDIR changelog mask found $MKDIR > 0"
17750
17751         oldmask=$(do_facet $SINGLEMDS $LCTL get_param \
17752                                 mdd.$mdt.changelog_current_mask -n)
17753         # register maskless user
17754         changelog_register || error "changelog_register failed"
17755         # effective mask should be not changed because it is not minimal
17756         mask=$(do_facet $SINGLEMDS $LCTL get_param \
17757                                 mdd.$mdt.changelog_current_mask -n)
17758         [[ $mask == $oldmask ]] || error "mask was changed: $mask vs $oldmask"
17759         # set server mask to minimal value
17760         changelog_chmask "MARK"
17761         # check effective mask again, should be treated as DEFMASK now
17762         mask=$(do_facet $SINGLEMDS $LCTL get_param \
17763                                 mdd.$mdt.changelog_current_mask -n)
17764         [[ $mask == *"HLINK"* ]] || error "mask is not DEFMASK as expected"
17765
17766         if (( $MDS1_VERSION >= $(version_code 2.15.52) )) ; then
17767                 # set server mask back to some value
17768                 changelog_chmask "CLOSE,UNLNK"
17769                 # check effective mask again, should not remain as DEFMASK
17770                 mask=$(do_facet $SINGLEMDS $LCTL get_param \
17771                                 mdd.$mdt.changelog_current_mask -n)
17772                 [[ $mask != *"HLINK"* ]] || error "mask is still DEFMASK"
17773         fi
17774
17775         do_facet $SINGLEMDS $LCTL --device $mdt \
17776                                 changelog_deregister -u test_160o ||
17777                 error "cannot deregister by name"
17778 }
17779 run_test 160o "changelog user name and mask"
17780
17781 test_160p() {
17782         remote_mds_nodsh && skip "remote MDS with nodsh" && return
17783         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
17784                 skip "Need MDS version at least 2.14.51"
17785         [[ "$mds1_FSTYPE" == "ldiskfs" ]] || skip "ldiskfs only test"
17786         local cl_users
17787         local cl_user1
17788         local entry_count
17789
17790         # Create a user
17791         changelog_register || error "first changelog_register failed"
17792
17793         cl_users=(${CL_USERS[mds1]})
17794         cl_user1="${cl_users[0]}"
17795
17796         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
17797         createmany -m $DIR/$tdir/$tfile 50 ||
17798                 error "create $DIR/$tdir/$tfile failed"
17799         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
17800         rm -rf $DIR/$tdir
17801
17802         # check changelogs have been generated
17803         entry_count=$(changelog_dump | wc -l)
17804         ((entry_count != 0)) || error "no changelog entries found"
17805
17806         # remove changelog_users and check that orphan entries are removed
17807         stop mds1
17808         local dev=$(mdsdevname 1)
17809         do_facet mds1 "$DEBUGFS -w -R 'rm changelog_users' $dev"
17810         start mds1 $dev $MDS_MOUNT_OPTS || error "cannot start mds1"
17811         entry_count=$(changelog_dump | wc -l)
17812         ((entry_count == 0)) ||
17813                 error "found $entry_count changelog entries, expected none"
17814 }
17815 run_test 160p "Changelog orphan cleanup with no users"
17816
17817 test_160q() {
17818         local mdt="$(facet_svc $SINGLEMDS)"
17819         local clu
17820
17821         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
17822         remote_mds_nodsh && skip "remote MDS with nodsh"
17823         [ $MDS1_VERSION -ge $(version_code 2.14.54) ] ||
17824                 skip "Need MDS version at least 2.14.54"
17825
17826         # set server mask to minimal value like server init does
17827         changelog_chmask "MARK"
17828         clu=$(do_facet $SINGLEMDS $LCTL --device $mdt changelog_register -n) ||
17829                 error "changelog_register failed"
17830         # check effective mask again, should be treated as DEFMASK now
17831         mask=$(do_facet $SINGLEMDS $LCTL get_param \
17832                                 mdd.$mdt.changelog_current_mask -n)
17833         do_facet $SINGLEMDS $LCTL --device $mdt changelog_deregister $clu ||
17834                 error "changelog_deregister failed"
17835         [[ $mask == *"HLINK"* ]] || error "mask is not DEFMASK as expected"
17836 }
17837 run_test 160q "changelog effective mask is DEFMASK if not set"
17838
17839 test_160s() {
17840         remote_mds_nodsh && skip "remote MDS with nodsh"
17841         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
17842                 skip "Need MDS version at least 2.14.55"
17843
17844         local mdts=$(comma_list $(mdts_nodes))
17845
17846         #define OBD_FAIL_TIME_IN_CHLOG_USER     0x1314
17847         do_nodes $mdts $LCTL set_param fail_loc=0x1314 \
17848                                        fail_val=$((24 * 3600 * 10))
17849
17850         # Create a user which is 10 days old
17851         changelog_register || error "first changelog_register failed"
17852         local cl_users
17853         declare -A cl_user1
17854         local i
17855
17856         # generate some changelog records to accumulate on each MDT
17857         # use all_char because created files should be evenly distributed
17858         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
17859                 error "test_mkdir $tdir failed"
17860         for ((i = 0; i < MDSCOUNT; i++)); do
17861                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
17862                         error "create $DIR/$tdir/d$i.1 failed"
17863         done
17864
17865         # check changelogs have been generated
17866         local nbcl=$(changelog_dump | wc -l)
17867         (( nbcl > 0 )) || error "no changelogs found"
17868
17869         # reduce the max_idle_indexes value to make sure we exceed it
17870         for param in "changelog_max_idle_indexes=2097446912" \
17871                      "changelog_max_idle_time=2592000" \
17872                      "changelog_gc=1" \
17873                      "changelog_min_gc_interval=2"; do
17874                 local MDT0=$(facet_svc $SINGLEMDS)
17875                 local var="${param%=*}"
17876                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
17877
17878                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
17879                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
17880                         error "unable to set mdd.*.$param"
17881         done
17882
17883         local start=$SECONDS
17884         for i in $(seq $MDSCOUNT); do
17885                 cl_users=(${CL_USERS[mds$i]})
17886                 cl_user1[mds$i]="${cl_users[0]}"
17887
17888                 [[ -n "${cl_user1[mds$i]}" ]] ||
17889                         error "mds$i: no user registered"
17890         done
17891
17892         #define OBD_FAIL_MDS_CHANGELOG_IDX_PUMP   0x16d
17893         do_nodes $mdts $LCTL set_param fail_loc=0x16d fail_val=500000000
17894
17895         # ensure we are past the previous changelog_min_gc_interval set above
17896         local sleep2=$((start + 2 - SECONDS))
17897         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
17898
17899         # Generate one more changelog to trigger GC
17900         for ((i = 0; i < MDSCOUNT; i++)); do
17901                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 $DIR/$tdir/d$i.4 ||
17902                         error "create $DIR/$tdir/d$i.3 failed"
17903         done
17904
17905         # ensure gc thread is done
17906         for node in $(mdts_nodes); do
17907                 wait_update $node "pgrep chlg_gc_thread" "" 20 ||
17908                         error "$node: GC-thread not done"
17909         done
17910
17911         do_nodes $mdts $LCTL set_param fail_loc=0
17912
17913         for (( i = 1; i <= MDSCOUNT; i++ )); do
17914                 # check cl_user1 is purged
17915                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" &&
17916                         error "mds$i: User ${cl_user1[mds$i]} is registered"
17917         done
17918         return 0
17919 }
17920 run_test 160s "changelog garbage collect on idle records * time"
17921
17922 test_160t() {
17923         remote_mds_nodsh && skip "remote MDS with nodsh"
17924         (( $MDS1_VERSION >= $(version_code 2.15.50) )) ||
17925                 skip "Need MDS version at least 2.15.50"
17926
17927         local MDT0=$(facet_svc $SINGLEMDS)
17928         local cl_users
17929         local cl_user1
17930         local cl_user2
17931         local start
17932
17933         changelog_register --user user1 -m all ||
17934                 error "user1 failed to register"
17935
17936         mkdir_on_mdt0 $DIR/$tdir
17937         # create default overstripe to maximize changelog size
17938         $LFS setstripe  -C 8 $DIR/$tdir || error "setstripe failed"
17939         createmany -o $DIR/$tdir/u1_ 2000 || error "createmany for user1 failed"
17940         llog_size1=$(do_facet mds1 $LCTL get_param -n mdd.$MDT0.changelog_size)
17941
17942         # user2 consumes less records so less space
17943         changelog_register --user user2 || error "user2 failed to register"
17944         createmany -o $DIR/$tdir/u2_ 500 || error "createmany for user2 failed"
17945         llog_size2=$(do_facet mds1 $LCTL get_param -n mdd.$MDT0.changelog_size)
17946
17947         # check changelogs have been generated
17948         local nbcl=$(changelog_dump | wc -l)
17949         (( nbcl > 0 )) || error "no changelogs found"
17950
17951         # reduce the changelog_min_gc_interval to force check
17952         for param in "changelog_gc=1" "changelog_min_gc_interval=2"; do
17953                 local var="${param%=*}"
17954                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
17955
17956                 stack_trap "do_facet mds1 $LCTL set_param mdd.$MDT0.$var=$old"
17957                 do_facet mds1 $LCTL set_param mdd.$MDT0.$param ||
17958                         error "unable to set mdd.*.$param"
17959         done
17960
17961         start=$SECONDS
17962         cl_users=(${CL_USERS[mds1]})
17963         cl_user1="${cl_users[0]}"
17964         cl_user2="${cl_users[1]}"
17965
17966         [[ -n $cl_user1 ]] ||
17967                 error "mds1: user #1 isn't registered"
17968         [[ -n $cl_user2 ]] ||
17969                 error "mds1: user #2 isn't registered"
17970
17971         # ensure we are past the previous changelog_min_gc_interval set above
17972         local sleep2=$((start + 2 - SECONDS))
17973         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
17974
17975         #define OBD_FAIL_MDS_CHANGELOG_ENOSPC 0x018c
17976         do_facet mds1 $LCTL set_param fail_loc=0x018c \
17977                         fail_val=$(((llog_size1 + llog_size2) / 2))
17978
17979         # Generate more changelog to trigger GC
17980         createmany -o $DIR/$tdir/u3_ 4 ||
17981                 error "create failed for more files"
17982
17983         # ensure gc thread is done
17984         wait_update_facet mds1 "pgrep chlg_gc_thread" "" 20 ||
17985                 error "mds1: GC-thread not done"
17986
17987         do_facet mds1 $LCTL set_param fail_loc=0
17988
17989         # check cl_user1 is purged
17990         changelog_users mds1 | grep -q "$cl_user1" &&
17991                 error "User $cl_user1 is registered"
17992         # check cl_user2 is not purged
17993         changelog_users mds1 | grep -q "$cl_user2" ||
17994                 error "User $cl_user2 is not registered"
17995 }
17996 run_test 160t "changelog garbage collect on lack of space"
17997
17998 test_161a() {
17999         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18000
18001         test_mkdir -c1 $DIR/$tdir
18002         cp /etc/hosts $DIR/$tdir/$tfile
18003         test_mkdir -c1 $DIR/$tdir/foo1
18004         test_mkdir -c1 $DIR/$tdir/foo2
18005         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/sofia
18006         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/zachary
18007         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/luna
18008         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/thor
18009         local FID=$($LFS path2fid $DIR/$tdir/$tfile | tr -d '[]')
18010         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
18011                 $LFS fid2path $DIR $FID
18012                 error "bad link ea"
18013         fi
18014         # middle
18015         rm $DIR/$tdir/foo2/zachary
18016         # last
18017         rm $DIR/$tdir/foo2/thor
18018         # first
18019         rm $DIR/$tdir/$tfile
18020         # rename
18021         mv $DIR/$tdir/foo1/sofia $DIR/$tdir/foo2/maggie
18022         [ "$($LFS fid2path $FSNAME --link 1 $FID)" != "$tdir/foo2/maggie" ] &&
18023                 { $LFS fid2path $DIR $FID; error "bad link rename"; }
18024         rm $DIR/$tdir/foo2/maggie
18025
18026         # overflow the EA
18027         local longname=$tfile.avg_len_is_thirty_two_
18028         stack_trap "unlinkmany $DIR/$tdir/foo2/$longname 1000 || \
18029                 error_noexit 'failed to unlink many hardlinks'" EXIT
18030         createmany -l$DIR/$tdir/foo1/luna $DIR/$tdir/foo2/$longname 1000 ||
18031                 error "failed to hardlink many files"
18032         links=$($LFS fid2path $DIR $FID | wc -l)
18033         echo -n "${links}/1000 links in link EA"
18034         [[ $links -gt 60 ]] || error "expected at least 60 links in link EA"
18035 }
18036 run_test 161a "link ea sanity"
18037
18038 test_161b() {
18039         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18040         [ $MDSCOUNT -lt 2 ] && skip_env "skipping remote directory test"
18041
18042         local MDTIDX=1
18043         local remote_dir=$DIR/$tdir/remote_dir
18044
18045         mkdir -p $DIR/$tdir
18046         $LFS mkdir -i $MDTIDX $remote_dir ||
18047                 error "create remote directory failed"
18048
18049         cp /etc/hosts $remote_dir/$tfile
18050         mkdir -p $remote_dir/foo1
18051         mkdir -p $remote_dir/foo2
18052         ln $remote_dir/$tfile $remote_dir/foo1/sofia
18053         ln $remote_dir/$tfile $remote_dir/foo2/zachary
18054         ln $remote_dir/$tfile $remote_dir/foo1/luna
18055         ln $remote_dir/$tfile $remote_dir/foo2/thor
18056
18057         local FID=$($LFS path2fid $remote_dir/$tfile | tr -d '[' |
18058                      tr -d ']')
18059         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
18060                 $LFS fid2path $DIR $FID
18061                 error "bad link ea"
18062         fi
18063         # middle
18064         rm $remote_dir/foo2/zachary
18065         # last
18066         rm $remote_dir/foo2/thor
18067         # first
18068         rm $remote_dir/$tfile
18069         # rename
18070         mv $remote_dir/foo1/sofia $remote_dir/foo2/maggie
18071         local link_path=$($LFS fid2path $FSNAME --link 1 $FID)
18072         if [ "$DIR/$link_path" != "$remote_dir/foo2/maggie" ]; then
18073                 $LFS fid2path $DIR $FID
18074                 error "bad link rename"
18075         fi
18076         rm $remote_dir/foo2/maggie
18077
18078         # overflow the EA
18079         local longname=filename_avg_len_is_thirty_two_
18080         createmany -l$remote_dir/foo1/luna $remote_dir/foo2/$longname 1000 ||
18081                 error "failed to hardlink many files"
18082         links=$($LFS fid2path $DIR $FID | wc -l)
18083         echo -n "${links}/1000 links in link EA"
18084         [[ ${links} -gt 60 ]] ||
18085                 error "expected at least 60 links in link EA"
18086         unlinkmany $remote_dir/foo2/$longname 1000 ||
18087         error "failed to unlink many hardlinks"
18088 }
18089 run_test 161b "link ea sanity under remote directory"
18090
18091 test_161c() {
18092         remote_mds_nodsh && skip "remote MDS with nodsh"
18093         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18094         [[ $MDS1_VERSION -lt $(version_code 2.1.5) ]] &&
18095                 skip "Need MDS version at least 2.1.5"
18096
18097         # define CLF_RENAME_LAST 0x0001
18098         # rename overwrite a target having nlink = 1 (changelog flag 0x1)
18099         changelog_register || error "changelog_register failed"
18100
18101         rm -rf $DIR/$tdir
18102         test_mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir
18103         touch $DIR/$tdir/foo_161c
18104         touch $DIR/$tdir/bar_161c
18105         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
18106         changelog_dump | grep RENME | tail -n 5
18107         local flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
18108         changelog_clear 0 || error "changelog_clear failed"
18109         if [ x$flags != "x0x1" ]; then
18110                 error "flag $flags is not 0x1"
18111         fi
18112
18113         echo "rename overwrite target with nlink = 1, changelog flags=$flags"
18114         # rename overwrite a target having nlink > 1 (changelog flag 0x0)
18115         touch $DIR/$tdir/foo_161c
18116         touch $DIR/$tdir/bar_161c
18117         ln $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
18118         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
18119         changelog_dump | grep RENME | tail -n 5
18120         flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
18121         changelog_clear 0 || error "changelog_clear failed"
18122         if [ x$flags != "x0x0" ]; then
18123                 error "flag $flags is not 0x0"
18124         fi
18125         echo "rename overwrite a target having nlink > 1," \
18126                 "changelog record has flags of $flags"
18127
18128         # rename doesn't overwrite a target (changelog flag 0x0)
18129         touch $DIR/$tdir/foo_161c
18130         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/foo2_161c
18131         changelog_dump | grep RENME | tail -n 5
18132         flags=$(changelog_dump | grep RENME | tail -1 | cut -f5 -d' ')
18133         changelog_clear 0 || error "changelog_clear failed"
18134         if [ x$flags != "x0x0" ]; then
18135                 error "flag $flags is not 0x0"
18136         fi
18137         echo "rename doesn't overwrite a target," \
18138                 "changelog record has flags of $flags"
18139
18140         # define CLF_UNLINK_LAST 0x0001
18141         # unlink a file having nlink = 1 (changelog flag 0x1)
18142         rm -f $DIR/$tdir/foo2_161c
18143         changelog_dump | grep UNLNK | tail -n 5
18144         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
18145         changelog_clear 0 || error "changelog_clear failed"
18146         if [ x$flags != "x0x1" ]; then
18147                 error "flag $flags is not 0x1"
18148         fi
18149         echo "unlink a file having nlink = 1," \
18150                 "changelog record has flags of $flags"
18151
18152         # unlink a file having nlink > 1 (changelog flag 0x0)
18153         ln -f $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
18154         rm -f $DIR/$tdir/foobar_161c
18155         changelog_dump | grep UNLNK | tail -n 5
18156         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
18157         changelog_clear 0 || error "changelog_clear failed"
18158         if [ x$flags != "x0x0" ]; then
18159                 error "flag $flags is not 0x0"
18160         fi
18161         echo "unlink a file having nlink > 1, changelog record flags '$flags'"
18162 }
18163 run_test 161c "check CL_RENME[UNLINK] changelog record flags"
18164
18165 test_161d() {
18166         remote_mds_nodsh && skip "remote MDS with nodsh"
18167         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
18168
18169         local pid
18170         local fid
18171
18172         changelog_register || error "changelog_register failed"
18173
18174         # work in a standalone dir to avoid locking on $DIR/$MOUNT to
18175         # interfer with $MOUNT/.lustre/fid/ access
18176         mkdir $DIR/$tdir
18177         [[ $? -eq 0 ]] || error "mkdir failed"
18178
18179         #define OBD_FAIL_LLITE_CREATE_NODE_PAUSE 0x140c | CFS_FAIL_ONCE
18180         $LCTL set_param fail_loc=0x8000140c
18181         # 5s pause
18182         $LCTL set_param fail_val=5
18183
18184         # create file
18185         echo foofoo > $DIR/$tdir/$tfile &
18186         pid=$!
18187
18188         # wait for create to be delayed
18189         sleep 2
18190
18191         ps -p $pid
18192         [[ $? -eq 0 ]] || error "create should be blocked"
18193
18194         local tempfile="$(mktemp --tmpdir $tfile.XXXXXX)"
18195         stack_trap "rm -f $tempfile"
18196         fid=$(changelog_extract_field "CREAT" "$tfile" "t=")
18197         cat $MOUNT/.lustre/fid/$fid 2>/dev/null >$tempfile || error "cat failed"
18198         # some delay may occur during ChangeLog publishing and file read just
18199         # above, that could allow file write to happen finally
18200         [[ -s $tempfile ]] && echo "file should be empty"
18201
18202         $LCTL set_param fail_loc=0
18203
18204         wait $pid
18205         [[ $? -eq 0 ]] || error "create failed"
18206 }
18207 run_test 161d "create with concurrent .lustre/fid access"
18208
18209 check_path() {
18210         local expected="$1"
18211         shift
18212         local fid="$2"
18213
18214         local path
18215         path=$($LFS fid2path "$@")
18216         local rc=$?
18217
18218         if [ $rc -ne 0 ]; then
18219                 error "path looked up of '$expected' failed: rc=$rc"
18220         elif [ "$path" != "$expected" ]; then
18221                 error "path looked up '$path' instead of '$expected'"
18222         else
18223                 echo "FID '$fid' resolves to path '$path' as expected"
18224         fi
18225 }
18226
18227 test_162a() { # was test_162
18228         test_mkdir -p -c1 $DIR/$tdir/d2
18229         touch $DIR/$tdir/d2/$tfile
18230         touch $DIR/$tdir/d2/x1
18231         touch $DIR/$tdir/d2/x2
18232         test_mkdir -p -c1 $DIR/$tdir/d2/a/b/c
18233         test_mkdir -p -c1 $DIR/$tdir/d2/p/q/r
18234         # regular file
18235         local fid=$($LFS path2fid $DIR/$tdir/d2/$tfile | tr -d '[]')
18236         check_path "$tdir/d2/$tfile" $FSNAME "$fid" --link 0
18237
18238         # softlink
18239         ln -s $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/slink
18240         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink | tr -d '[]')
18241         check_path "$tdir/d2/p/q/r/slink" $FSNAME "$fid" --link 0
18242
18243         # softlink to wrong file
18244         ln -s /this/is/garbage $DIR/$tdir/d2/p/q/r/slink.wrong
18245         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink.wrong | tr -d '[]')
18246         check_path "$tdir/d2/p/q/r/slink.wrong" $FSNAME "$fid" --link 0
18247
18248         # hardlink
18249         ln $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/hlink
18250         mv $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/a/b/c/new_file
18251         fid=$($LFS path2fid $DIR/$tdir/d2/a/b/c/new_file | tr -d '[]')
18252         # fid2path dir/fsname should both work
18253         check_path "$tdir/d2/a/b/c/new_file" $FSNAME "$fid" --link 1
18254         check_path "$DIR/$tdir/d2/p/q/r/hlink" $DIR "$fid" --link 0
18255
18256         # hardlink count: check that there are 2 links
18257         local nlinks=$($LFS fid2path $DIR "$fid" | wc -l)
18258         [ $nlinks -eq 2 ] || error "expect 2 links, found $nlinks"
18259
18260         # hardlink indexing: remove the first link
18261         rm $DIR/$tdir/d2/p/q/r/hlink
18262         check_path "$tdir/d2/a/b/c/new_file" $FSNAME $fid --link 0
18263 }
18264 run_test 162a "path lookup sanity"
18265
18266 test_162b() {
18267         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18268         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18269
18270         mkdir $DIR/$tdir
18271         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
18272                                 error "create striped dir failed"
18273
18274         local FID=$($LFS getdirstripe $DIR/$tdir/striped_dir |
18275                                         tail -n 1 | awk '{print $2}')
18276         stat $MOUNT/.lustre/fid/$FID && error "sub_stripe can be accessed"
18277
18278         touch $DIR/$tdir/striped_dir/f{0..4} || error "touch f0..4 failed"
18279         mkdir $DIR/$tdir/striped_dir/d{0..4} || error "mkdir d0..4 failed"
18280
18281         # regular file
18282         for ((i=0;i<5;i++)); do
18283                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/f$i | tr -d '[]') ||
18284                         error "get fid for f$i failed"
18285                 check_path "$tdir/striped_dir/f$i" $FSNAME $FID --link 0
18286
18287                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/d$i | tr -d '[]') ||
18288                         error "get fid for d$i failed"
18289                 check_path "$tdir/striped_dir/d$i" $FSNAME $FID --link 0
18290         done
18291
18292         return 0
18293 }
18294 run_test 162b "striped directory path lookup sanity"
18295
18296 # LU-4239: Verify fid2path works with paths 100 or more directories deep
18297 test_162c() {
18298         [[ $MDS1_VERSION -lt $(version_code 2.7.51) ]] &&
18299                 skip "Need MDS version at least 2.7.51"
18300
18301         local lpath=$tdir.local
18302         local rpath=$tdir.remote
18303
18304         test_mkdir $DIR/$lpath
18305         test_mkdir $DIR/$rpath
18306
18307         for ((i = 0; i <= 101; i++)); do
18308                 lpath="$lpath/$i"
18309                 mkdir $DIR/$lpath
18310                 FID=$($LFS path2fid $DIR/$lpath | tr -d '[]') ||
18311                         error "get fid for local directory $DIR/$lpath failed"
18312                 check_path "$DIR/$lpath" $MOUNT $FID --link 0
18313
18314                 rpath="$rpath/$i"
18315                 test_mkdir $DIR/$rpath
18316                 FID=$($LFS path2fid $DIR/$rpath | tr -d '[]') ||
18317                         error "get fid for remote directory $DIR/$rpath failed"
18318                 check_path "$DIR/$rpath" $MOUNT $FID --link 0
18319         done
18320
18321         return 0
18322 }
18323 run_test 162c "fid2path works with paths 100 or more directories deep"
18324
18325 oalr_event_count() {
18326         local event="${1}"
18327         local trace="${2}"
18328
18329         awk -v name="${FSNAME}-OST0000" \
18330             -v event="${event}" \
18331             '$1 == "TRACE" && $2 == event && $3 == name' \
18332             "${trace}" |
18333         wc -l
18334 }
18335
18336 oalr_expect_event_count() {
18337         local event="${1}"
18338         local trace="${2}"
18339         local expect="${3}"
18340         local count
18341
18342         count=$(oalr_event_count "${event}" "${trace}")
18343         if ((count == expect)); then
18344                 return 0
18345         fi
18346
18347         error_noexit "${event} event count was '${count}', expected ${expect}"
18348         cat "${trace}" >&2
18349         exit 1
18350 }
18351
18352 cleanup_165() {
18353         do_facet ost1 killall --quiet -KILL ofd_access_log_reader || true
18354         stop ost1
18355         start ost1 "$(ostdevname 1)" $OST_MOUNT_OPTS
18356 }
18357
18358 setup_165() {
18359         sync # Flush previous IOs so we can count log entries.
18360         do_facet ost1 $LCTL set_param "obdfilter.${FSNAME}-OST0000.access_log_size=4096"
18361         stack_trap cleanup_165 EXIT
18362 }
18363
18364 test_165a() {
18365         local trace="/tmp/${tfile}.trace"
18366         local rc
18367         local count
18368
18369         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
18370                 skip "OFD access log unsupported"
18371
18372         setup_165
18373         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
18374         sleep 5
18375
18376         do_facet ost1 ofd_access_log_reader --list
18377         stop ost1
18378
18379         do_facet ost1 killall -TERM ofd_access_log_reader
18380         wait
18381         rc=$?
18382
18383         if ((rc != 0)); then
18384                 error "ofd_access_log_reader exited with rc = '${rc}'"
18385         fi
18386
18387         # Parse trace file for discovery events:
18388         oalr_expect_event_count alr_log_add "${trace}" 1
18389         oalr_expect_event_count alr_log_eof "${trace}" 1
18390         oalr_expect_event_count alr_log_free "${trace}" 1
18391 }
18392 run_test 165a "ofd access log discovery"
18393
18394 test_165b() {
18395         local trace="/tmp/${tfile}.trace"
18396         local file="${DIR}/${tfile}"
18397         local pfid1
18398         local pfid2
18399         local -a entry
18400         local rc
18401         local count
18402         local size
18403         local flags
18404
18405         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
18406                 skip "OFD access log unsupported"
18407
18408         setup_165
18409         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
18410         sleep 5
18411
18412         do_facet ost1 ofd_access_log_reader --list
18413
18414         lfs setstripe -c 1 -i 0 "${file}"
18415         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
18416                 error "cannot create '${file}'"
18417
18418         sleep 5
18419         do_facet ost1 killall -TERM ofd_access_log_reader
18420         wait
18421         rc=$?
18422
18423         if ((rc != 0)); then
18424                 error "ofd_access_log_reader exited with rc = '${rc}'"
18425         fi
18426
18427         oalr_expect_event_count alr_log_entry "${trace}" 1
18428
18429         pfid1=$($LFS path2fid "${file}")
18430
18431         # 1     2             3   4    5     6   7    8    9     10
18432         # TRACE alr_log_entry OST PFID BEGIN END TIME SIZE COUNT FLAGS
18433         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
18434
18435         echo "entry = '${entry[*]}'" >&2
18436
18437         pfid2=${entry[4]}
18438         if [[ "${pfid1}" != "${pfid2}" ]]; then
18439                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
18440         fi
18441
18442         size=${entry[8]}
18443         if ((size != 1048576)); then
18444                 error "entry '${entry[*]}' has invalid io size '${size}', expected 1048576"
18445         fi
18446
18447         flags=${entry[10]}
18448         if [[ "${flags}" != "w" ]]; then
18449                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'w'"
18450         fi
18451
18452         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
18453         sleep 5
18454
18455         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r524288c ||
18456                 error "cannot read '${file}'"
18457         sleep 5
18458
18459         do_facet ost1 killall -TERM ofd_access_log_reader
18460         wait
18461         rc=$?
18462
18463         if ((rc != 0)); then
18464                 error "ofd_access_log_reader exited with rc = '${rc}'"
18465         fi
18466
18467         oalr_expect_event_count alr_log_entry "${trace}" 1
18468
18469         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
18470         echo "entry = '${entry[*]}'" >&2
18471
18472         pfid2=${entry[4]}
18473         if [[ "${pfid1}" != "${pfid2}" ]]; then
18474                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
18475         fi
18476
18477         size=${entry[8]}
18478         if ((size != 524288)); then
18479                 error "entry '${entry[*]}' has invalid io size '${size}', 524288"
18480         fi
18481
18482         flags=${entry[10]}
18483         if [[ "${flags}" != "r" ]]; then
18484                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'r'"
18485         fi
18486 }
18487 run_test 165b "ofd access log entries are produced and consumed"
18488
18489 test_165c() {
18490         local trace="/tmp/${tfile}.trace"
18491         local file="${DIR}/${tdir}/${tfile}"
18492
18493         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
18494                 skip "OFD access log unsupported"
18495
18496         test_mkdir "${DIR}/${tdir}"
18497
18498         setup_165
18499         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
18500         sleep 5
18501
18502         lfs setstripe -c 1 -i 0 "${DIR}/${tdir}"
18503
18504         # 4096 / 64 = 64. Create twice as many entries.
18505         for ((i = 0; i < 128; i++)); do
18506                 $MULTIOP "${file}-${i}" oO_CREAT:O_WRONLY:w512c ||
18507                         error "cannot create file"
18508         done
18509
18510         sync
18511
18512         do_facet ost1 killall -TERM ofd_access_log_reader
18513         wait
18514         rc=$?
18515         if ((rc != 0)); then
18516                 error "ofd_access_log_reader exited with rc = '${rc}'"
18517         fi
18518
18519         unlinkmany  "${file}-%d" 128
18520 }
18521 run_test 165c "full ofd access logs do not block IOs"
18522
18523 oal_get_read_count() {
18524         local stats="$1"
18525
18526         # STATS lustre-OST0001 alr_read_count 1
18527
18528         do_facet ost1 cat "${stats}" |
18529         awk '$1 == "STATS" && $3 == "alr_read_count" { count = $4; }
18530              END { print count; }'
18531 }
18532
18533 oal_expect_read_count() {
18534         local stats="$1"
18535         local count
18536         local expect="$2"
18537
18538         # Ask ofd_access_log_reader to write stats.
18539         do_facet ost1 killall -USR1 ofd_access_log_reader
18540
18541         # Allow some time for things to happen.
18542         sleep 1
18543
18544         count=$(oal_get_read_count "${stats}")
18545         if ((count == expect)); then
18546                 return 0
18547         fi
18548
18549         error_noexit "bad read count, got ${count}, expected ${expect}"
18550         do_facet ost1 cat "${stats}" >&2
18551         exit 1
18552 }
18553
18554 test_165d() {
18555         local stats="/tmp/${tfile}.stats"
18556         local file="${DIR}/${tdir}/${tfile}"
18557         local param="obdfilter.${FSNAME}-OST0000.access_log_mask"
18558
18559         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
18560                 skip "OFD access log unsupported"
18561
18562         test_mkdir "${DIR}/${tdir}"
18563
18564         setup_165
18565         do_facet ost1 ofd_access_log_reader --stats="${stats}" &
18566         sleep 5
18567
18568         lfs setstripe -c 1 -i 0 "${file}"
18569
18570         do_facet ost1 lctl set_param "${param}=rw"
18571         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
18572                 error "cannot create '${file}'"
18573         oal_expect_read_count "${stats}" 1
18574
18575         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
18576                 error "cannot read '${file}'"
18577         oal_expect_read_count "${stats}" 2
18578
18579         do_facet ost1 lctl set_param "${param}=r"
18580         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
18581                 error "cannot create '${file}'"
18582         oal_expect_read_count "${stats}" 2
18583
18584         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
18585                 error "cannot read '${file}'"
18586         oal_expect_read_count "${stats}" 3
18587
18588         do_facet ost1 lctl set_param "${param}=w"
18589         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
18590                 error "cannot create '${file}'"
18591         oal_expect_read_count "${stats}" 4
18592
18593         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
18594                 error "cannot read '${file}'"
18595         oal_expect_read_count "${stats}" 4
18596
18597         do_facet ost1 lctl set_param "${param}=0"
18598         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
18599                 error "cannot create '${file}'"
18600         oal_expect_read_count "${stats}" 4
18601
18602         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
18603                 error "cannot read '${file}'"
18604         oal_expect_read_count "${stats}" 4
18605
18606         do_facet ost1 killall -TERM ofd_access_log_reader
18607         wait
18608         rc=$?
18609         if ((rc != 0)); then
18610                 error "ofd_access_log_reader exited with rc = '${rc}'"
18611         fi
18612 }
18613 run_test 165d "ofd_access_log mask works"
18614
18615 test_165e() {
18616         local stats="/tmp/${tfile}.stats"
18617         local file0="${DIR}/${tdir}-0/${tfile}"
18618         local file1="${DIR}/${tdir}-1/${tfile}"
18619
18620         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
18621                 skip "OFD access log unsupported"
18622
18623         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
18624
18625         test_mkdir -c 1 -i 0 "${DIR}/${tdir}-0"
18626         test_mkdir -c 1 -i 1 "${DIR}/${tdir}-1"
18627
18628         lfs setstripe -c 1 -i 0 "${file0}"
18629         lfs setstripe -c 1 -i 0 "${file1}"
18630
18631         setup_165
18632         do_facet ost1 ofd_access_log_reader -I 1 --stats="${stats}" &
18633         sleep 5
18634
18635         $MULTIOP "${file0}" oO_CREAT:O_WRONLY:w512c ||
18636                 error "cannot create '${file0}'"
18637         sync
18638         oal_expect_read_count "${stats}" 0
18639
18640         $MULTIOP "${file1}" oO_CREAT:O_WRONLY:w512c ||
18641                 error "cannot create '${file1}'"
18642         sync
18643         oal_expect_read_count "${stats}" 1
18644
18645         do_facet ost1 killall -TERM ofd_access_log_reader
18646         wait
18647         rc=$?
18648         if ((rc != 0)); then
18649                 error "ofd_access_log_reader exited with rc = '${rc}'"
18650         fi
18651 }
18652 run_test 165e "ofd_access_log MDT index filter works"
18653
18654 test_165f() {
18655         local trace="/tmp/${tfile}.trace"
18656         local rc
18657         local count
18658
18659         setup_165
18660         do_facet ost1 timeout 60 ofd_access_log_reader \
18661                 --exit-on-close --debug=- --trace=- > "${trace}" &
18662         sleep 5
18663         stop ost1
18664
18665         wait
18666         rc=$?
18667
18668         if ((rc != 0)); then
18669                 error_noexit "ofd_access_log_reader exited with rc = '${rc}'"
18670                 cat "${trace}"
18671                 exit 1
18672         fi
18673 }
18674 run_test 165f "ofd_access_log_reader --exit-on-close works"
18675
18676 test_169() {
18677         # do directio so as not to populate the page cache
18678         log "creating a 10 Mb file"
18679         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c ||
18680                 error "multiop failed while creating a file"
18681         log "starting reads"
18682         dd if=$DIR/$tfile of=/dev/null bs=4096 &
18683         log "truncating the file"
18684         $MULTIOP $DIR/$tfile oO_TRUNC:c ||
18685                 error "multiop failed while truncating the file"
18686         log "killing dd"
18687         kill %+ || true # reads might have finished
18688         echo "wait until dd is finished"
18689         wait
18690         log "removing the temporary file"
18691         rm -rf $DIR/$tfile || error "tmp file removal failed"
18692 }
18693 run_test 169 "parallel read and truncate should not deadlock"
18694
18695 test_170() {
18696         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18697
18698         $LCTL clear     # bug 18514
18699         $LCTL debug_daemon start $TMP/${tfile}_log_good
18700         touch $DIR/$tfile
18701         $LCTL debug_daemon stop
18702         sed -e "s/^...../a/g" $TMP/${tfile}_log_good > $TMP/${tfile}_log_bad ||
18703                 error "sed failed to read log_good"
18704
18705         $LCTL debug_daemon start $TMP/${tfile}_log_good
18706         rm -rf $DIR/$tfile
18707         $LCTL debug_daemon stop
18708
18709         $LCTL df $TMP/${tfile}_log_bad > $TMP/${tfile}_log_bad.out 2>&1 ||
18710                error "lctl df log_bad failed"
18711
18712         local bad_line=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
18713         local good_line1=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
18714
18715         $LCTL df $TMP/${tfile}_log_good > $TMP/${tfile}_log_good.out 2>&1
18716         local good_line2=$(tail -n 1 $TMP/${tfile}_log_good.out | awk '{print $5}')
18717
18718         [ "$bad_line" ] && [ "$good_line1" ] && [ "$good_line2" ] ||
18719                 error "bad_line good_line1 good_line2 are empty"
18720
18721         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
18722         cat $TMP/${tfile}_log_bad >> $TMP/${tfile}_logs_corrupt
18723         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
18724
18725         $LCTL df $TMP/${tfile}_logs_corrupt > $TMP/${tfile}_log_bad.out 2>&1
18726         local bad_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
18727         local good_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
18728
18729         [ "$bad_line_new" ] && [ "$good_line_new" ] ||
18730                 error "bad_line_new good_line_new are empty"
18731
18732         local expected_good=$((good_line1 + good_line2*2))
18733
18734         rm -f $TMP/${tfile}*
18735         # LU-231, short malformed line may not be counted into bad lines
18736         if [ $bad_line -ne $bad_line_new ] &&
18737                    [ $bad_line -ne $((bad_line_new - 1)) ]; then
18738                 error "expected $bad_line bad lines, but got $bad_line_new"
18739                 return 1
18740         fi
18741
18742         if [ $expected_good -ne $good_line_new ]; then
18743                 error "expected $expected_good good lines, but got $good_line_new"
18744                 return 2
18745         fi
18746         true
18747 }
18748 run_test 170 "test lctl df to handle corrupted log ====================="
18749
18750 test_171() { # bug20592
18751         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18752
18753         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
18754         $LCTL set_param fail_loc=0x50e
18755         $LCTL set_param fail_val=3000
18756         multiop_bg_pause $DIR/$tfile O_s || true
18757         local MULTIPID=$!
18758         kill -USR1 $MULTIPID
18759         # cause log dump
18760         sleep 3
18761         wait $MULTIPID
18762         if dmesg | grep "recursive fault"; then
18763                 error "caught a recursive fault"
18764         fi
18765         $LCTL set_param fail_loc=0
18766         true
18767 }
18768 run_test 171 "test libcfs_debug_dumplog_thread stuck in do_exit() ======"
18769
18770 test_172() {
18771
18772         #define OBD_FAIL_OBD_CLEANUP  0x60e
18773         $LCTL set_param fail_loc=0x60e
18774         umount $MOUNT || error "umount $MOUNT failed"
18775         stack_trap "mount_client $MOUNT"
18776
18777         (( $($LCTL dl | egrep -c " osc | lov | lmv | mdc ") > 0 )) ||
18778                 error "no client OBDs are remained"
18779
18780         $LCTL dl | while read devno state type name foo; do
18781                 case $type in
18782                 lov|osc|lmv|mdc)
18783                         $LCTL --device $name cleanup
18784                         $LCTL --device $name detach
18785                         ;;
18786                 *)
18787                         # skip server devices
18788                         ;;
18789                 esac
18790         done
18791
18792         if (( $($LCTL dl | egrep -c " osc | lov | lmv | mdc ") > 0 )); then
18793                 $LCTL dl | egrep " osc | lov | lmv | mdc "
18794                 error "some client OBDs are still remained"
18795         fi
18796
18797 }
18798 run_test 172 "manual device removal with lctl cleanup/detach ======"
18799
18800 # it would be good to share it with obdfilter-survey/iokit-libecho code
18801 setup_obdecho_osc () {
18802         local rc=0
18803         local ost_nid=$1
18804         local obdfilter_name=$2
18805         echo "Creating new osc for $obdfilter_name on $ost_nid"
18806         # make sure we can find loopback nid
18807         $LCTL add_uuid $ost_nid $ost_nid >/dev/null 2>&1
18808
18809         [ $rc -eq 0 ] && { $LCTL attach osc ${obdfilter_name}_osc     \
18810                            ${obdfilter_name}_osc_UUID || rc=2; }
18811         [ $rc -eq 0 ] && { $LCTL --device ${obdfilter_name}_osc setup \
18812                            ${obdfilter_name}_UUID  $ost_nid || rc=3; }
18813         return $rc
18814 }
18815
18816 cleanup_obdecho_osc () {
18817         local obdfilter_name=$1
18818         $LCTL --device ${obdfilter_name}_osc cleanup >/dev/null
18819         $LCTL --device ${obdfilter_name}_osc detach  >/dev/null
18820         return 0
18821 }
18822
18823 obdecho_test() {
18824         local OBD=$1
18825         local node=$2
18826         local pages=${3:-64}
18827         local rc=0
18828         local id
18829
18830         local count=10
18831         local obd_size=$(get_obd_size $node $OBD)
18832         local page_size=$(get_page_size $node)
18833         if [[ -n "$obd_size" ]]; then
18834                 local new_count=$((obd_size / (pages * page_size / 1024)))
18835                 [[ $new_count -ge $count ]] || count=$new_count
18836         fi
18837
18838         do_facet $node "$LCTL attach echo_client ec ec_uuid" || rc=1
18839         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec setup $OBD" ||
18840                            rc=2; }
18841         if [ $rc -eq 0 ]; then
18842             id=$(do_facet $node "$LCTL --device ec create 1"  | awk '/object id/ {print $6}')
18843             [ ${PIPESTATUS[0]} -eq 0 -a -n "$id" ] || rc=3
18844         fi
18845         echo "New object id is $id"
18846         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec getattr $id" ||
18847                            rc=4; }
18848         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec "                 \
18849                            "test_brw $count w v $pages $id" || rc=4; }
18850         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec destroy $id 1" ||
18851                            rc=4; }
18852         [ $rc -eq 0 ] || [ $rc -gt 2 ] &&
18853                 { do_facet $node "$LCTL --device ec cleanup" || rc=5; }
18854         [ $rc -eq 0 ] || [ $rc -gt 1 ] &&
18855                 { do_facet $node "$LCTL --device ec detach" || rc=6; }
18856         [ $rc -ne 0 ] && echo "obecho_create_test failed: $rc"
18857         return $rc
18858 }
18859
18860 test_180a() {
18861         skip "obdecho on osc is no longer supported"
18862 }
18863 run_test 180a "test obdecho on osc"
18864
18865 test_180b() {
18866         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18867         remote_ost_nodsh && skip "remote OST with nodsh"
18868
18869         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
18870                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
18871                 error "failed to load module obdecho"
18872
18873         local target=$(do_facet ost1 $LCTL dl |
18874                        awk '/obdfilter/ { print $4; exit; }')
18875
18876         if [ -n "$target" ]; then
18877                 obdecho_test $target ost1 || error "obdecho_test failed with $?"
18878         else
18879                 do_facet ost1 $LCTL dl
18880                 error "there is no obdfilter target on ost1"
18881         fi
18882 }
18883 run_test 180b "test obdecho directly on obdfilter"
18884
18885 test_180c() { # LU-2598
18886         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18887         remote_ost_nodsh && skip "remote OST with nodsh"
18888         [[ $MDS1_VERSION -lt $(version_code 2.4.0) ]] &&
18889                 skip "Need MDS version at least 2.4.0"
18890
18891         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
18892                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
18893                 error "failed to load module obdecho"
18894
18895         local target=$(do_facet ost1 $LCTL dl |
18896                        awk '/obdfilter/ { print $4; exit; }')
18897
18898         if [ -n "$target" ]; then
18899                 local pages=16384 # 64MB bulk I/O RPC size
18900
18901                 obdecho_test "$target" ost1 "$pages" ||
18902                         error "obdecho_test with pages=$pages failed with $?"
18903         else
18904                 do_facet ost1 $LCTL dl
18905                 error "there is no obdfilter target on ost1"
18906         fi
18907 }
18908 run_test 180c "test huge bulk I/O size on obdfilter, don't LASSERT"
18909
18910 test_181() { # bug 22177
18911         test_mkdir $DIR/$tdir
18912         # create enough files to index the directory
18913         createmany -o $DIR/$tdir/foobar 4000
18914         # print attributes for debug purpose
18915         lsattr -d .
18916         # open dir
18917         multiop_bg_pause $DIR/$tdir D_Sc || return 1
18918         MULTIPID=$!
18919         # remove the files & current working dir
18920         unlinkmany $DIR/$tdir/foobar 4000
18921         rmdir $DIR/$tdir
18922         kill -USR1 $MULTIPID
18923         wait $MULTIPID
18924         stat $DIR/$tdir && error "open-unlinked dir was not removed!"
18925         return 0
18926 }
18927 run_test 181 "Test open-unlinked dir ========================"
18928
18929 test_182a() {
18930         local fcount=1000
18931         local tcount=10
18932
18933         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
18934
18935         $LCTL set_param mdc.*.rpc_stats=clear
18936
18937         for (( i = 0; i < $tcount; i++ )) ; do
18938                 mkdir $DIR/$tdir/$i
18939         done
18940
18941         for (( i = 0; i < $tcount; i++ )) ; do
18942                 createmany -o $DIR/$tdir/$i/f- $fcount &
18943         done
18944         wait
18945
18946         for (( i = 0; i < $tcount; i++ )) ; do
18947                 unlinkmany $DIR/$tdir/$i/f- $fcount &
18948         done
18949         wait
18950
18951         $LCTL get_param mdc.*.rpc_stats
18952
18953         rm -rf $DIR/$tdir
18954 }
18955 run_test 182a "Test parallel modify metadata operations from mdc"
18956
18957 test_182b() {
18958         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
18959         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
18960         local dcount=1000
18961         local tcount=10
18962         local stime
18963         local etime
18964         local delta
18965
18966         do_facet mds1 $LCTL list_param \
18967                 osp.$FSNAME-MDT*-osp-MDT*.rpc_stats ||
18968                 skip "MDS lacks parallel RPC handling"
18969
18970         $LFS mkdir -i 0 $DIR/$tdir || error "creating dir $DIR/$tdir"
18971
18972         rpc_count=$(do_facet mds1 $LCTL get_param -n \
18973                     osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight)
18974
18975         stime=$(date +%s)
18976         createmany -i 0 -d $DIR/$tdir/t- $tcount
18977
18978         for (( i = 0; i < $tcount; i++ )) ; do
18979                 createmany -i 0 -d $DIR/$tdir/t-$i/d- 0 $dcount &
18980         done
18981         wait
18982         etime=$(date +%s)
18983         delta=$((etime - stime))
18984         echo "Time for file creation $delta sec for $rpc_count parallel RPCs"
18985
18986         stime=$(date +%s)
18987         for (( i = 0; i < $tcount; i++ )) ; do
18988                 unlinkmany -d $DIR/$tdir/$i/d- $dcount &
18989         done
18990         wait
18991         etime=$(date +%s)
18992         delta=$((etime - stime))
18993         echo "Time for file removal $delta sec for $rpc_count parallel RPCs"
18994
18995         rm -rf $DIR/$tdir
18996
18997         $LFS mkdir -i 0 $DIR/$tdir || error "creating dir $DIR/$tdir"
18998
18999         do_facet mds1 $LCTL set_param osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight=1
19000
19001         stime=$(date +%s)
19002         createmany -i 0 -d $DIR/$tdir/t- $tcount
19003
19004         for (( i = 0; i < $tcount; i++ )) ; do
19005                 createmany -i 0 -d $DIR/$tdir/t-$i/d- 0 $dcount &
19006         done
19007         wait
19008         etime=$(date +%s)
19009         delta=$((etime - stime))
19010         echo "Time for file creation $delta sec for 1 RPC sent at a time"
19011
19012         stime=$(date +%s)
19013         for (( i = 0; i < $tcount; i++ )) ; do
19014                 unlinkmany -d $DIR/$tdir/t-$i/d- $dcount &
19015         done
19016         wait
19017         etime=$(date +%s)
19018         delta=$((etime - stime))
19019         echo "Time for file removal $delta sec for 1 RPC sent at a time"
19020
19021         do_facet mds1 $LCTL set_param osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight=$rpc_count
19022 }
19023 run_test 182b "Test parallel modify metadata operations from osp"
19024
19025 test_183() { # LU-2275
19026         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19027         remote_mds_nodsh && skip "remote MDS with nodsh"
19028         [[ $MDS1_VERSION -lt $(version_code 2.3.56) ]] &&
19029                 skip "Need MDS version at least 2.3.56"
19030
19031         mkdir_on_mdt0 $DIR/$tdir || error "creating dir $DIR/$tdir"
19032         echo aaa > $DIR/$tdir/$tfile
19033
19034 #define OBD_FAIL_MDS_NEGATIVE_POSITIVE  0x148
19035         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x148
19036
19037         ls -l $DIR/$tdir && error "ls succeeded, should have failed"
19038         cat $DIR/$tdir/$tfile && error "cat succeeded, should have failed"
19039
19040         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
19041
19042         # Flush negative dentry cache
19043         touch $DIR/$tdir/$tfile
19044
19045         # We are not checking for any leaked references here, they'll
19046         # become evident next time we do cleanup with module unload.
19047         rm -rf $DIR/$tdir
19048 }
19049 run_test 183 "No crash or request leak in case of strange dispositions ========"
19050
19051 # test suite 184 is for LU-2016, LU-2017
19052 test_184a() {
19053         check_swap_layouts_support
19054
19055         dir0=$DIR/$tdir/$testnum
19056         test_mkdir -p -c1 $dir0
19057         ref1=/etc/passwd
19058         ref2=/etc/group
19059         file1=$dir0/f1
19060         file2=$dir0/f2
19061         $LFS setstripe -c1 $file1
19062         cp $ref1 $file1
19063         $LFS setstripe -c2 $file2
19064         cp $ref2 $file2
19065         gen1=$($LFS getstripe -g $file1)
19066         gen2=$($LFS getstripe -g $file2)
19067
19068         $LFS swap_layouts $file1 $file2 || error "swap of file layout failed"
19069         gen=$($LFS getstripe -g $file1)
19070         [[ $gen1 != $gen ]] ||
19071                 error "Layout generation on $file1 does not change"
19072         gen=$($LFS getstripe -g $file2)
19073         [[ $gen2 != $gen ]] ||
19074                 error "Layout generation on $file2 does not change"
19075
19076         cmp $ref1 $file2 || error "content compare failed ($ref1 != $file2)"
19077         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
19078
19079         lfsck_verify_pfid $file1 $file2 || error "PFID are not transferred"
19080 }
19081 run_test 184a "Basic layout swap"
19082
19083 test_184b() {
19084         check_swap_layouts_support
19085
19086         dir0=$DIR/$tdir/$testnum
19087         mkdir -p $dir0 || error "creating dir $dir0"
19088         file1=$dir0/f1
19089         file2=$dir0/f2
19090         file3=$dir0/f3
19091         dir1=$dir0/d1
19092         dir2=$dir0/d2
19093         mkdir $dir1 $dir2
19094         $LFS setstripe -c1 $file1
19095         $LFS setstripe -c2 $file2
19096         $LFS setstripe -c1 $file3
19097         chown $RUNAS_ID $file3
19098         gen1=$($LFS getstripe -g $file1)
19099         gen2=$($LFS getstripe -g $file2)
19100
19101         $LFS swap_layouts $dir1 $dir2 &&
19102                 error "swap of directories layouts should fail"
19103         $LFS swap_layouts $dir1 $file1 &&
19104                 error "swap of directory and file layouts should fail"
19105         $RUNAS $LFS swap_layouts $file1 $file2 &&
19106                 error "swap of file we cannot write should fail"
19107         $LFS swap_layouts $file1 $file3 &&
19108                 error "swap of file with different owner should fail"
19109         /bin/true # to clear error code
19110 }
19111 run_test 184b "Forbidden layout swap (will generate errors)"
19112
19113 test_184c() {
19114         local cmpn_arg=$(cmp -n 2>&1 | grep "invalid option")
19115         [ -n "$cmpn_arg" ] && skip_env "cmp does not support -n"
19116         check_swap_layouts_support
19117         check_swap_layout_no_dom $DIR
19118
19119         local dir0=$DIR/$tdir/$testnum
19120         mkdir -p $dir0 || error "creating dir $dir0"
19121
19122         local ref1=$dir0/ref1
19123         local ref2=$dir0/ref2
19124         local file1=$dir0/file1
19125         local file2=$dir0/file2
19126         # create a file large enough for the concurrent test
19127         dd if=/dev/urandom of=$ref1 bs=1M count=$((RANDOM % 50 + 20))
19128         dd if=/dev/urandom of=$ref2 bs=1M count=$((RANDOM % 50 + 20))
19129         echo "ref file size: ref1($(stat -c %s $ref1))," \
19130              "ref2($(stat -c %s $ref2))"
19131
19132         cp $ref2 $file2
19133         dd if=$ref1 of=$file1 bs=16k &
19134         local DD_PID=$!
19135
19136         # Make sure dd starts to copy file, but wait at most 5 seconds
19137         local loops=0
19138         while [ ! -s $file1 -a $((loops++)) -lt 50 ]; do sleep 0.1; done
19139
19140         $LFS swap_layouts $file1 $file2
19141         local rc=$?
19142         wait $DD_PID
19143         [[ $? == 0 ]] || error "concurrent write on $file1 failed"
19144         [[ $rc == 0 ]] || error "swap of $file1 and $file2 failed"
19145
19146         # how many bytes copied before swapping layout
19147         local copied=$(stat -c %s $file2)
19148         local remaining=$(stat -c %s $ref1)
19149         remaining=$((remaining - copied))
19150         echo "Copied $copied bytes before swapping layout..."
19151
19152         cmp -n $copied $file1 $ref2 | grep differ &&
19153                 error "Content mismatch [0, $copied) of ref2 and file1"
19154         cmp -n $copied $file2 $ref1 ||
19155                 error "Content mismatch [0, $copied) of ref1 and file2"
19156         cmp -i $copied:$copied -n $remaining $file1 $ref1 ||
19157                 error "Content mismatch [$copied, EOF) of ref1 and file1"
19158
19159         # clean up
19160         rm -f $ref1 $ref2 $file1 $file2
19161 }
19162 run_test 184c "Concurrent write and layout swap"
19163
19164 test_184d() {
19165         check_swap_layouts_support
19166         check_swap_layout_no_dom $DIR
19167         [ -z "$(which getfattr 2>/dev/null)" ] &&
19168                 skip_env "no getfattr command"
19169
19170         local file1=$DIR/$tdir/$tfile-1
19171         local file2=$DIR/$tdir/$tfile-2
19172         local file3=$DIR/$tdir/$tfile-3
19173         local lovea1
19174         local lovea2
19175
19176         mkdir -p $DIR/$tdir
19177         touch $file1 || error "create $file1 failed"
19178         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
19179                 error "create $file2 failed"
19180         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
19181                 error "create $file3 failed"
19182         lovea1=$(get_layout_param $file1)
19183
19184         $LFS swap_layouts $file2 $file3 ||
19185                 error "swap $file2 $file3 layouts failed"
19186         $LFS swap_layouts $file1 $file2 ||
19187                 error "swap $file1 $file2 layouts failed"
19188
19189         lovea2=$(get_layout_param $file2)
19190         echo "$lovea1"
19191         echo "$lovea2"
19192         [ "$lovea1" == "$lovea2" ] || error "lovea $lovea1 != $lovea2"
19193
19194         lovea1=$(getfattr -n trusted.lov $file1 | grep ^trusted)
19195         [[ -z "$lovea1" ]] || error "$file1 shouldn't have lovea"
19196 }
19197 run_test 184d "allow stripeless layouts swap"
19198
19199 test_184e() {
19200         [[ $MDS1_VERSION -ge $(version_code 2.6.94) ]] ||
19201                 skip "Need MDS version at least 2.6.94"
19202         check_swap_layouts_support
19203         check_swap_layout_no_dom $DIR
19204         [ -z "$(which getfattr 2>/dev/null)" ] &&
19205                 skip_env "no getfattr command"
19206
19207         local file1=$DIR/$tdir/$tfile-1
19208         local file2=$DIR/$tdir/$tfile-2
19209         local file3=$DIR/$tdir/$tfile-3
19210         local lovea
19211
19212         mkdir -p $DIR/$tdir
19213         touch $file1 || error "create $file1 failed"
19214         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
19215                 error "create $file2 failed"
19216         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
19217                 error "create $file3 failed"
19218
19219         $LFS swap_layouts $file1 $file2 ||
19220                 error "swap $file1 $file2 layouts failed"
19221
19222         lovea=$(getfattr -n trusted.lov $file1 | grep ^trusted)
19223         [[ -z "$lovea" ]] || error "$file1 shouldn't have lovea"
19224
19225         echo 123 > $file1 || error "Should be able to write into $file1"
19226
19227         $LFS swap_layouts $file1 $file3 ||
19228                 error "swap $file1 $file3 layouts failed"
19229
19230         echo 123 > $file1 || error "Should be able to write into $file1"
19231
19232         rm -rf $file1 $file2 $file3
19233 }
19234 run_test 184e "Recreate layout after stripeless layout swaps"
19235
19236 test_184f() {
19237         # Create a file with name longer than sizeof(struct stat) ==
19238         # 144 to see if we can get chars from the file name to appear
19239         # in the returned striping. Note that 'f' == 0x66.
19240         local file=$(for ((i = 0; i < 200; i++)); do echo -n f; done)
19241
19242         mkdir -p $DIR/$tdir
19243         mcreate $DIR/$tdir/$file
19244         if lfs find --stripe-count 0x6666 $DIR/$tdir | grep $file; then
19245                 error "IOC_MDC_GETFILEINFO returned garbage striping"
19246         fi
19247 }
19248 run_test 184f "IOC_MDC_GETFILEINFO for files with long names but no striping"
19249
19250 test_185() { # LU-2441
19251         # LU-3553 - no volatile file support in old servers
19252         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
19253                 skip "Need MDS version at least 2.3.60"
19254
19255         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
19256         touch $DIR/$tdir/spoo
19257         local mtime1=$(stat -c "%Y" $DIR/$tdir)
19258         local fid=$($MULTIOP $DIR/$tdir VFw4096c) ||
19259                 error "cannot create/write a volatile file"
19260         [ "$FILESET" == "" ] &&
19261         $CHECKSTAT -t file $MOUNT/.lustre/fid/$fid 2>/dev/null &&
19262                 error "FID is still valid after close"
19263
19264         multiop_bg_pause $DIR/$tdir vVw4096_c
19265         local multi_pid=$!
19266
19267         local OLD_IFS=$IFS
19268         IFS=":"
19269         local fidv=($fid)
19270         IFS=$OLD_IFS
19271         # assume that the next FID for this client is sequential, since stdout
19272         # is unfortunately eaten by multiop_bg_pause
19273         local n=$((${fidv[1]} + 1))
19274         local next_fid="${fidv[0]}:$(printf "0x%x" $n):${fidv[2]}"
19275         if [ "$FILESET" == "" ]; then
19276                 $CHECKSTAT -t file $MOUNT/.lustre/fid/$next_fid ||
19277                         error "FID is missing before close"
19278         fi
19279         kill -USR1 $multi_pid
19280         # 1 second delay, so if mtime change we will see it
19281         sleep 1
19282         local mtime2=$(stat -c "%Y" $DIR/$tdir)
19283         [[ $mtime1 == $mtime2 ]] || error "mtime has changed"
19284 }
19285 run_test 185 "Volatile file support"
19286
19287 function create_check_volatile() {
19288         local idx=$1
19289         local tgt
19290
19291         $MULTIOP $MOUNT/.lustre/fid V${idx}Fw4096_c >&/tmp/${tfile}.fid &
19292         local PID=$!
19293         sleep 1
19294         local FID=$(cat /tmp/${tfile}.fid)
19295         [ "$FID" == "" ] && error "can't get FID for volatile"
19296         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID || error "can't stat $FID"
19297         tgt=$($LFS getstripe -m $MOUNT/.lustre/fid/$FID)
19298         [ "$tgt" != "$idx" ] && error "wrong MDS $tgt, expected $idx"
19299         kill -USR1 $PID
19300         wait
19301         sleep 1
19302         cancel_lru_locks mdc # flush opencache
19303         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID && error "can stat $FID"
19304         return 0
19305 }
19306
19307 test_185a(){
19308         # LU-12516 - volatile creation via .lustre
19309         [[ $MDS1_VERSION -ge $(version_code 2.12.55) ]] ||
19310                 skip "Need MDS version at least 2.3.55"
19311
19312         create_check_volatile 0
19313         [ $MDSCOUNT -lt 2 ] && return 0
19314
19315         # DNE case
19316         create_check_volatile 1
19317
19318         return 0
19319 }
19320 run_test 185a "Volatile file creation in .lustre/fid/"
19321
19322 test_187a() {
19323         remote_mds_nodsh && skip "remote MDS with nodsh"
19324         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
19325                 skip "Need MDS version at least 2.3.0"
19326
19327         local dir0=$DIR/$tdir/$testnum
19328         mkdir -p $dir0 || error "creating dir $dir0"
19329
19330         local file=$dir0/file1
19331         dd if=/dev/urandom of=$file count=10 bs=1M conv=fsync
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         # clean up
19339         rm -f $file1
19340 }
19341 run_test 187a "Test data version change"
19342
19343 test_187b() {
19344         remote_mds_nodsh && skip "remote MDS with nodsh"
19345         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
19346                 skip "Need MDS version at least 2.3.0"
19347
19348         local dir0=$DIR/$tdir/$testnum
19349         mkdir -p $dir0 || error "creating dir $dir0"
19350
19351         declare -a DV=$($MULTIOP $dir0 Vw1000xYw1000xY | cut -f3 -d" ")
19352         [[ ${DV[0]} != ${DV[1]} ]] ||
19353                 error "data version did not change on write"\
19354                       " ${DV[0]} == ${DV[1]}"
19355
19356         # clean up
19357         rm -f $file1
19358 }
19359 run_test 187b "Test data version change on volatile file"
19360
19361 test_200() {
19362         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19363         remote_mgs_nodsh && skip "remote MGS with nodsh"
19364         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
19365
19366         local POOL=${POOL:-cea1}
19367         local POOL_ROOT=${POOL_ROOT:-$DIR/d200.pools}
19368         local POOL_DIR_NAME=${POOL_DIR_NAME:-dir_tst}
19369         # Pool OST targets
19370         local first_ost=0
19371         local last_ost=$(($OSTCOUNT - 1))
19372         local ost_step=2
19373         local ost_list=$(seq $first_ost $ost_step $last_ost)
19374         local ost_range="$first_ost $last_ost $ost_step"
19375         local test_path=$POOL_ROOT/$POOL_DIR_NAME
19376         local file_dir=$POOL_ROOT/file_tst
19377         local subdir=$test_path/subdir
19378         local rc=0
19379
19380         while : ; do
19381                 # former test_200a test_200b
19382                 pool_add $POOL                          || { rc=$? ; break; }
19383                 pool_add_targets  $POOL $ost_range      || { rc=$? ; break; }
19384                 # former test_200c test_200d
19385                 mkdir -p $test_path
19386                 pool_set_dir      $POOL $test_path      || { rc=$? ; break; }
19387                 pool_check_dir    $POOL $test_path      || { rc=$? ; break; }
19388                 mkdir -p $subdir
19389                 pool_check_dir    $POOL $subdir         || { rc=$? ; break; }
19390                 pool_dir_rel_path $POOL $POOL_DIR_NAME $POOL_ROOT \
19391                                                         || { rc=$? ; break; }
19392                 # former test_200e test_200f
19393                 local files=$((OSTCOUNT*3))
19394                 pool_alloc_files  $POOL $test_path $files "$ost_list" \
19395                                                         || { rc=$? ; break; }
19396                 pool_create_files $POOL $file_dir $files "$ost_list" \
19397                                                         || { rc=$? ; break; }
19398                 # former test_200g test_200h
19399                 pool_lfs_df $POOL                       || { rc=$? ; break; }
19400                 pool_file_rel_path $POOL $test_path     || { rc=$? ; break; }
19401
19402                 # former test_201a test_201b test_201c
19403                 pool_remove_first_target $POOL          || { rc=$? ; break; }
19404
19405                 local f=$test_path/$tfile
19406                 pool_remove_all_targets $POOL $f        || { rc=$? ; break; }
19407                 pool_remove $POOL $f                    || { rc=$? ; break; }
19408                 break
19409         done
19410
19411         destroy_test_pools
19412
19413         return $rc
19414 }
19415 run_test 200 "OST pools"
19416
19417 # usage: default_attr <count | size | offset>
19418 default_attr() {
19419         $LCTL get_param -n lov.$FSNAME-clilov-\*.stripe${1}
19420 }
19421
19422 # usage: check_default_stripe_attr
19423 check_default_stripe_attr() {
19424         ACTUAL=$($LFS getstripe $* $DIR/$tdir)
19425         case $1 in
19426         --stripe-count|-c)
19427                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr count);;
19428         --stripe-size|-S)
19429                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr size);;
19430         --stripe-index|-i)
19431                 EXPECTED=-1;;
19432         *)
19433                 error "unknown getstripe attr '$1'"
19434         esac
19435
19436         [ $ACTUAL == $EXPECTED ] ||
19437                 error "$DIR/$tdir has $1 '$ACTUAL', not '$EXPECTED'"
19438 }
19439
19440 test_204a() {
19441         test_mkdir $DIR/$tdir
19442         $LFS setstripe --stripe-count 0 --stripe-size 0 --stripe-index -1 $DIR/$tdir
19443
19444         check_default_stripe_attr --stripe-count
19445         check_default_stripe_attr --stripe-size
19446         check_default_stripe_attr --stripe-index
19447 }
19448 run_test 204a "Print default stripe attributes"
19449
19450 test_204b() {
19451         test_mkdir $DIR/$tdir
19452         $LFS setstripe --stripe-count 1 $DIR/$tdir
19453
19454         check_default_stripe_attr --stripe-size
19455         check_default_stripe_attr --stripe-index
19456 }
19457 run_test 204b "Print default stripe size and offset"
19458
19459 test_204c() {
19460         test_mkdir $DIR/$tdir
19461         $LFS setstripe --stripe-size 65536 $DIR/$tdir
19462
19463         check_default_stripe_attr --stripe-count
19464         check_default_stripe_attr --stripe-index
19465 }
19466 run_test 204c "Print default stripe count and offset"
19467
19468 test_204d() {
19469         test_mkdir $DIR/$tdir
19470         $LFS setstripe --stripe-index 0 $DIR/$tdir
19471
19472         check_default_stripe_attr --stripe-count
19473         check_default_stripe_attr --stripe-size
19474 }
19475 run_test 204d "Print default stripe count and size"
19476
19477 test_204e() {
19478         test_mkdir $DIR/$tdir
19479         $LFS setstripe -d $DIR/$tdir
19480
19481         check_default_stripe_attr --stripe-count --raw
19482         check_default_stripe_attr --stripe-size --raw
19483         check_default_stripe_attr --stripe-index --raw
19484 }
19485 run_test 204e "Print raw stripe attributes"
19486
19487 test_204f() {
19488         test_mkdir $DIR/$tdir
19489         $LFS setstripe --stripe-count 1 $DIR/$tdir
19490
19491         check_default_stripe_attr --stripe-size --raw
19492         check_default_stripe_attr --stripe-index --raw
19493 }
19494 run_test 204f "Print raw stripe size and offset"
19495
19496 test_204g() {
19497         test_mkdir $DIR/$tdir
19498         $LFS setstripe --stripe-size 65536 $DIR/$tdir
19499
19500         check_default_stripe_attr --stripe-count --raw
19501         check_default_stripe_attr --stripe-index --raw
19502 }
19503 run_test 204g "Print raw stripe count and offset"
19504
19505 test_204h() {
19506         test_mkdir $DIR/$tdir
19507         $LFS setstripe --stripe-index 0 $DIR/$tdir
19508
19509         check_default_stripe_attr --stripe-count --raw
19510         check_default_stripe_attr --stripe-size --raw
19511 }
19512 run_test 204h "Print raw stripe count and size"
19513
19514 # Figure out which job scheduler is being used, if any,
19515 # or use a fake one
19516 if [ -n "$SLURM_JOB_ID" ]; then # SLURM
19517         JOBENV=SLURM_JOB_ID
19518 elif [ -n "$LSB_JOBID" ]; then # Load Sharing Facility
19519         JOBENV=LSB_JOBID
19520 elif [ -n "$PBS_JOBID" ]; then # PBS/Maui/Moab
19521         JOBENV=PBS_JOBID
19522 elif [ -n "$LOADL_STEPID" ]; then # LoadLeveller
19523         JOBENV=LOADL_STEP_ID
19524 elif [ -n "$JOB_ID" ]; then # Sun Grid Engine
19525         JOBENV=JOB_ID
19526 else
19527         $LCTL list_param jobid_name > /dev/null 2>&1
19528         if [ $? -eq 0 ]; then
19529                 JOBENV=nodelocal
19530         else
19531                 JOBENV=FAKE_JOBID
19532         fi
19533 fi
19534 LUSTRE_JOBID_SIZE=31 # plus NUL terminator
19535
19536 verify_jobstats() {
19537         local cmd=($1)
19538         shift
19539         local facets="$@"
19540
19541 # we don't really need to clear the stats for this test to work, since each
19542 # command has a unique jobid, but it makes debugging easier if needed.
19543 #       for facet in $facets; do
19544 #               local dev=$(convert_facet2label $facet)
19545 #               # clear old jobstats
19546 #               do_facet $facet lctl set_param *.$dev.job_stats="clear"
19547 #       done
19548
19549         # use a new JobID for each test, or we might see an old one
19550         [ "$JOBENV" = "FAKE_JOBID" ] &&
19551                 FAKE_JOBID=id.$testnum.$(basename ${cmd[0]}).$RANDOM
19552
19553         JOBVAL=${!JOBENV:0:$LUSTRE_JOBID_SIZE}
19554
19555         [ "$JOBENV" = "nodelocal" ] && {
19556                 FAKE_JOBID=id.$testnum.%e.$RANDOM
19557                 $LCTL set_param jobid_name=$FAKE_JOBID
19558                 JOBVAL=${FAKE_JOBID/\%e/$(basename ${cmd[0]})}
19559         }
19560
19561         log "Test: ${cmd[*]}"
19562         log "Using JobID environment $($LCTL get_param -n jobid_var)=$JOBVAL"
19563
19564         if [ $JOBENV = "FAKE_JOBID" ]; then
19565                 FAKE_JOBID=$JOBVAL ${cmd[*]}
19566         else
19567                 ${cmd[*]}
19568         fi
19569
19570         # all files are created on OST0000
19571         for facet in $facets; do
19572                 local stats="*.$(convert_facet2label $facet).job_stats"
19573
19574                 # strip out libtool wrappers for in-tree executables
19575                 if (( $(do_facet $facet lctl get_param $stats |
19576                         sed -e 's/\.lt-/./' | grep -cw $JOBVAL) != 1 )); then
19577                         do_facet $facet lctl get_param $stats
19578                         error "No jobstats for $JOBVAL found on $facet::$stats"
19579                 fi
19580         done
19581 }
19582
19583 jobstats_set() {
19584         local new_jobenv=$1
19585
19586         set_persistent_param_and_check client "jobid_var" \
19587                 "$FSNAME.sys.jobid_var" $new_jobenv
19588 }
19589
19590 test_205a() { # Job stats
19591         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19592         [[ $MDS1_VERSION -ge $(version_code 2.7.1) ]] ||
19593                 skip "Need MDS version with at least 2.7.1"
19594         remote_mgs_nodsh && skip "remote MGS with nodsh"
19595         remote_mds_nodsh && skip "remote MDS with nodsh"
19596         remote_ost_nodsh && skip "remote OST with nodsh"
19597         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep jobstats)" ] &&
19598                 skip "Server doesn't support jobstats"
19599         [[ $JOBID_VAR = disable ]] && skip_env "jobstats is disabled"
19600
19601         local old_jobenv=$($LCTL get_param -n jobid_var)
19602         [ $old_jobenv != $JOBENV ] && jobstats_set $JOBENV
19603         stack_trap "jobstats_set $old_jobenv" EXIT
19604
19605         changelog_register
19606
19607         local old_jobid_name=$($LCTL get_param jobid_name)
19608         stack_trap "$LCTL set_param $old_jobid_name" EXIT
19609
19610         local old_interval=$(do_facet $SINGLEMDS lctl get_param -n \
19611                                 mdt.*.job_cleanup_interval | head -n 1)
19612         local new_interval=5
19613         do_facet $SINGLEMDS \
19614                 $LCTL set_param mdt.*.job_cleanup_interval=$new_interval
19615         stack_trap "do_facet $SINGLEMDS \
19616                 $LCTL set_param mdt.*.job_cleanup_interval=$old_interval" EXIT
19617         local start=$SECONDS
19618
19619         local cmd
19620         # mkdir
19621         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir"
19622         verify_jobstats "$cmd" "$SINGLEMDS"
19623         # rmdir
19624         cmd="rmdir $DIR/$tdir"
19625         verify_jobstats "$cmd" "$SINGLEMDS"
19626         # mkdir on secondary MDT
19627         if [ $MDSCOUNT -gt 1 ]; then
19628                 cmd="lfs mkdir -i 1 $DIR/$tdir.remote"
19629                 verify_jobstats "$cmd" "mds2"
19630         fi
19631         # mknod
19632         cmd="mknod $DIR/$tfile c 1 3"
19633         verify_jobstats "$cmd" "$SINGLEMDS"
19634         # unlink
19635         cmd="rm -f $DIR/$tfile"
19636         verify_jobstats "$cmd" "$SINGLEMDS"
19637         # create all files on OST0000 so verify_jobstats can find OST stats
19638         # open & close
19639         cmd="$LFS setstripe -i 0 -c 1 $DIR/$tfile"
19640         verify_jobstats "$cmd" "$SINGLEMDS"
19641         # setattr
19642         cmd="touch $DIR/$tfile"
19643         verify_jobstats "$cmd" "$SINGLEMDS ost1"
19644         # write
19645         cmd="dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=sync"
19646         verify_jobstats "$cmd" "ost1"
19647         # read
19648         cancel_lru_locks osc
19649         cmd="dd if=$DIR/$tfile of=/dev/null bs=1M count=1 iflag=direct"
19650         verify_jobstats "$cmd" "ost1"
19651         # truncate
19652         cmd="$TRUNCATE $DIR/$tfile 0"
19653         verify_jobstats "$cmd" "$SINGLEMDS ost1"
19654         # rename
19655         cmd="mv -f $DIR/$tfile $DIR/$tdir.rename"
19656         verify_jobstats "$cmd" "$SINGLEMDS"
19657         # jobstats expiry - sleep until old stats should be expired
19658         local left=$((new_interval + 5 - (SECONDS - start)))
19659         [ $left -ge 0 ] && wait_update_facet $SINGLEMDS \
19660                 "lctl get_param *.*.job_stats | grep -c 'job_id.*mkdir'" \
19661                         "0" $left
19662         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir.expire"
19663         verify_jobstats "$cmd" "$SINGLEMDS"
19664         [ $(do_facet $SINGLEMDS lctl get_param *.*.job_stats |
19665             grep -c "job_id.*mkdir") -gt 1 ] && error "old jobstats not expired"
19666
19667         # Ensure that jobid are present in changelog (if supported by MDS)
19668         if [ $MDS1_VERSION -ge $(version_code 2.6.52) ];then
19669                 changelog_dump | tail -10
19670                 jobids=$(changelog_dump | tail -9 | grep -c "j=")
19671                 [ $jobids -eq 9 ] ||
19672                         error "Wrong changelog jobid count $jobids != 9"
19673
19674                 # LU-5862
19675                 JOBENV="disable"
19676                 jobstats_set $JOBENV
19677                 touch $DIR/$tfile
19678                 changelog_dump | grep $tfile
19679                 jobids=$(changelog_dump | grep $tfile | tail -1 | grep -c "j=")
19680                 [ $jobids -eq 0 ] ||
19681                         error "Unexpected jobids when jobid_var=$JOBENV"
19682         fi
19683
19684         # test '%j' access to environment variable - if supported
19685         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%h.E"; then
19686                 JOBENV="JOBCOMPLEX"
19687                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
19688
19689                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
19690         fi
19691
19692         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%H.E"; then
19693                 JOBENV="JOBCOMPLEX"
19694                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname -s).E"
19695
19696                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
19697         fi
19698
19699         # test '%j' access to per-session jobid - if supported
19700         if lctl list_param jobid_this_session > /dev/null 2>&1
19701         then
19702                 lctl set_param jobid_var=session jobid_name="S.%j.%e.%u.%h.E"
19703                 lctl set_param jobid_this_session=$USER
19704
19705                 JOBENV="JOBCOMPLEX"
19706                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
19707
19708                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
19709         fi
19710 }
19711 run_test 205a "Verify job stats"
19712
19713 # LU-13117, LU-13597, LU-16599
19714 test_205b() {
19715         (( $MDS1_VERSION >= $(version_code 2.13.54.91) )) ||
19716                 skip "Need MDS version at least 2.13.54.91"
19717
19718         local job_stats="mdt.*.job_stats"
19719         local old_jobid=$(do_facet mds1 $LCTL get_param jobid_var)
19720
19721         do_facet mds1 $LCTL set_param $job_stats=clear
19722
19723         # Setting jobid_var to USER might not be supported
19724         [[ -n "$old_jobid" ]] && stack_trap "$LCTL set_param $old_jobid"
19725         $LCTL set_param jobid_var=USER || true
19726         stack_trap "$LCTL set_param $($LCTL get_param jobid_name)"
19727         $LCTL set_param jobid_name="%j.%e.%u"
19728
19729         env -i USERTESTJOBSTATS=foolish touch $DIR/$tfile.1
19730         do_facet mds1 $LCTL get_param $job_stats | grep "job_id:.*foolish" &&
19731                 { do_facet mds1 $LCTL get_param $job_stats;
19732                   error "Unexpected jobid found"; }
19733         do_facet mds1 $LCTL get_param $job_stats | grep "open:.*min.*max.*sum"||
19734                 { do_facet mds1 $LCTL get_param $job_stats;
19735                   error "wrong job_stats format found"; }
19736
19737         (( $MDS1_VERSION <= $(version_code 2.15.0) )) &&
19738                 echo "MDS does not yet escape jobid" && return 0
19739
19740         mkdir_on_mdt0 $DIR/$tdir
19741         $LCTL set_param jobid_var=TEST205b
19742         env -i TEST205b="has sp" touch $DIR/$tdir/$tfile.2
19743         local jobid=$(do_facet mds1 $LCTL get_param $job_stats |
19744                       awk '/has\\x20sp/ {print $3}')
19745         [[ -n "$jobid" ]] || { do_facet mds1 $LCTL get_param $job_stats;
19746                   error "jobid not escaped"; }
19747
19748         if (( $MDS1_VERSION >= $(version_code 2.15.53.139) )); then
19749                 # need to run such a command on mds1:
19750                 # lctl set_param mdt.$FSNAME-MDT0000.job_stats='"has\x20sp.touch.0"'
19751                 #
19752                 # there might be multiple MDTs on single mds server, so need to
19753                 # specifiy MDT0000. Or the command will fail due to other MDTs
19754                 do_facet_vp mds1 $LCTL set_param mdt.$FSNAME-MDT0000.job_stats=$jobid ||
19755                         error "cannot clear escaped jobid in job_stats";
19756         else
19757                 echo "MDS does not support clearing escaped jobid"
19758         fi
19759 }
19760 run_test 205b "Verify job stats jobid and output format"
19761
19762 # LU-13733
19763 test_205c() {
19764         $LCTL set_param llite.*.stats=0
19765         dd if=/dev/zero of=$DIR/$tfile.1 bs=4k count=1
19766         $LCTL get_param llite.*.stats
19767         $LCTL get_param llite.*.stats | grep \
19768                 "write_bytes *1 samples \[bytes\] 4096 4096 4096 16777216" ||
19769                         error "wrong client stats format found"
19770 }
19771 run_test 205c "Verify client stats format"
19772
19773 test_205d() {
19774         local file=$DIR/$tdir/$tfile
19775
19776         (( $MDS1_VERSION >= $(version_code 2.15.53) )) ||
19777                 skip "need lustre >= 2.15.53 for lljobstat"
19778         (( $OST1_VERSION >= $(version_code 2.15.53) )) ||
19779                 skip "need lustre >= 2.15.53 for lljobstat"
19780         verify_yaml_available || skip_env "YAML verification not installed"
19781
19782         test_mkdir -i 0 $DIR/$tdir
19783         $LFS setstripe -E 1M -L mdt -E -1 $file || error "create file failed"
19784
19785         dd if=/dev/zero of=$file bs=1M count=10 conv=sync ||
19786                 error "failed to write data to $file"
19787         mv $file $file.2
19788
19789         do_facet mds1 "$LCTL get_param -n mdt.$FSNAME-MDT0000.rename_stats"
19790         echo -n 'verify rename_stats...'
19791         do_facet mds1 "$LCTL get_param -n mdt.$FSNAME-MDT0000.rename_stats" |
19792                 verify_yaml || error "rename_stats is not valid YAML"
19793         echo " OK"
19794
19795         echo -n 'verify mdt job_stats...'
19796         do_facet mds1 "$LCTL get_param -n mdt.$FSNAME-MDT0000.job_stats" |
19797                 verify_yaml || error "job_stats on mds1 is not valid YAML"
19798         echo " OK"
19799
19800         echo -n 'verify ost job_stats...'
19801         do_facet ost1 "$LCTL get_param -n obdfilter.$FSNAME-OST0000.job_stats" |
19802                 verify_yaml || error "job_stats on ost1 is not valid YAML"
19803         echo " OK"
19804 }
19805 run_test 205d "verify the format of some stats files"
19806
19807 test_205e() {
19808         local ops_comma
19809         local file=$DIR/$tdir/$tfile
19810         local -a cli_params
19811
19812         (( $MDS1_VERSION >= $(version_code 2.15.53) )) ||
19813                 skip "need lustre >= 2.15.53 for lljobstat"
19814         (( $OST1_VERSION >= $(version_code 2.15.53) )) ||
19815                 skip "need lustre >= 2.15.53 for lljobstat"
19816         verify_yaml_available || skip_env "YAML verification not installed"
19817
19818         cli_params=( $($LCTL get_param jobid_name jobid_var) )
19819         $LCTL set_param jobid_var=nodelocal jobid_name=205e.%e.%u
19820         stack_trap "$LCTL set_param ${cli_params[*]}" EXIT
19821
19822         mkdir_on_mdt0 $DIR/$tdir || error "failed to create dir"
19823
19824         $LFS setstripe -E EOF -i 0 -c 1 $file ||
19825                 error "failed to create $file on ost1"
19826         dd if=/dev/zero of=$file bs=1M count=10 oflag=sync ||
19827                 error "failed to write data to $file"
19828
19829         do_facet mds1 "$LCTL get_param *.*.job_stats"
19830         do_facet ost1 "$LCTL get_param *.*.job_stats"
19831
19832         do_facet ost1 "lljobstat -n 1 -i 0 -c 1000"
19833         do_facet ost1 "lljobstat -n 1 -i 0 -c 1000" | verify_yaml ||
19834                 error "The output of lljobstat is not an valid YAML"
19835
19836         # verify that job dd.0 does exist and has some ops on ost1
19837         # typically this line is like:
19838         # - 205e.dd.0:            {ops: 20, ...}
19839         ops_comma=$(do_facet ost1 "lljobstat -n 1 -i 0 -c 1000" |
19840                     awk '$2=="205e.dd.0:" {print $4}')
19841
19842         (( ${ops_comma%,} >= 10 )) ||
19843                 error "cannot find job 205e.dd.0 with ops >= 10"
19844 }
19845 run_test 205e "verify the output of lljobstat"
19846
19847 test_205f() {
19848         verify_yaml_available || skip_env "YAML verification not installed"
19849
19850         # check both qos_ost_weights and qos_mdt_weights
19851         do_facet mds1 $LCTL get_param -n lod.*.qos*weights
19852         do_facet mds1 $LCTL get_param -n lod.*.qos*weights | verify_yaml ||
19853                 error "qos_ost_weights is not valid YAML"
19854 }
19855 run_test 205f "verify qos_ost_weights YAML format "
19856
19857 __test_205_jobstats_dump() {
19858         local -a pids
19859         local nbr_instance=$1
19860
19861         while true; do
19862                 if (( ${#pids[@]} >= nbr_instance )); then
19863                         wait ${pids[@]}
19864                         pids=()
19865                 fi
19866
19867                 do_facet mds1 "$LCTL get_param mdt.*.job_stats > /dev/null" &
19868                 pids+=( $! )
19869         done
19870 }
19871
19872 __test_205_cleanup() {
19873         kill $@
19874         # Clear all job entries
19875         do_facet mds1 "$LCTL set_param mdt.*.job_stats=clear"
19876 }
19877
19878 test_205g() {
19879         local -a mds1_params
19880         local -a cli_params
19881         local pids
19882         local interval=5
19883
19884         mds1_params=( $(do_facet mds1 $LCTL get_param mdt.*.job_cleanup_interval) )
19885         do_facet mds1 $LCTL set_param mdt.*.job_cleanup_interval=$interval
19886         stack_trap "do_facet mds1 $LCTL set_param ${mds1_params[*]}" EXIT
19887
19888         cli_params=( $($LCTL get_param jobid_name jobid_var) )
19889         $LCTL set_param jobid_var=TEST205G_ID jobid_name=%j.%p
19890         stack_trap "$LCTL set_param ${cli_params[*]}" EXIT
19891
19892         # start jobs loop
19893         export TEST205G_ID=205g
19894         stack_trap "unset TEST205G_ID" EXIT
19895         while true; do
19896                 printf $DIR/$tfile.{0001..1000} | xargs -P10 -n1 touch
19897         done & pids="$! "
19898
19899         __test_205_jobstats_dump 4 & pids+="$! "
19900         stack_trap "__test_205_cleanup $pids" EXIT INT
19901
19902         [[ $SLOW == "no" ]] && sleep 90 || sleep 240
19903 }
19904 run_test 205g "stress test for job_stats procfile"
19905
19906 # LU-1480, LU-1773 and LU-1657
19907 test_206() {
19908         mkdir -p $DIR/$tdir
19909         $LFS setstripe -c -1 $DIR/$tdir
19910 #define OBD_FAIL_LOV_INIT 0x1403
19911         $LCTL set_param fail_loc=0xa0001403
19912         $LCTL set_param fail_val=1
19913         touch $DIR/$tdir/$tfile || true
19914 }
19915 run_test 206 "fail lov_init_raid0() doesn't lbug"
19916
19917 test_207a() {
19918         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
19919         local fsz=`stat -c %s $DIR/$tfile`
19920         cancel_lru_locks mdc
19921
19922         # do not return layout in getattr intent
19923 #define OBD_FAIL_MDS_NO_LL_GETATTR 0x170
19924         $LCTL set_param fail_loc=0x170
19925         local sz=`stat -c %s $DIR/$tfile`
19926
19927         [ $fsz -eq $sz ] || error "file size expected $fsz, actual $sz"
19928
19929         rm -rf $DIR/$tfile
19930 }
19931 run_test 207a "can refresh layout at glimpse"
19932
19933 test_207b() {
19934         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
19935         local cksum=`md5sum $DIR/$tfile`
19936         local fsz=`stat -c %s $DIR/$tfile`
19937         cancel_lru_locks mdc
19938         cancel_lru_locks osc
19939
19940         # do not return layout in getattr intent
19941 #define OBD_FAIL_MDS_NO_LL_OPEN 0x171
19942         $LCTL set_param fail_loc=0x171
19943
19944         # it will refresh layout after the file is opened but before read issues
19945         echo checksum is "$cksum"
19946         echo "$cksum" |md5sum -c --quiet || error "file differs"
19947
19948         rm -rf $DIR/$tfile
19949 }
19950 run_test 207b "can refresh layout at open"
19951
19952 test_208() {
19953         # FIXME: in this test suite, only RD lease is used. This is okay
19954         # for now as only exclusive open is supported. After generic lease
19955         # is done, this test suite should be revised. - Jinshan
19956
19957         remote_mds_nodsh && skip "remote MDS with nodsh"
19958         [[ $MDS1_VERSION -ge $(version_code 2.4.52) ]] ||
19959                 skip "Need MDS version at least 2.4.52"
19960
19961         echo "==== test 1: verify get lease work"
19962         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eRE+eU || error "get lease error"
19963
19964         echo "==== test 2: verify lease can be broken by upcoming open"
19965         $MULTIOP $DIR/$tfile oO_RDWR:eR_E-eUc &
19966         local PID=$!
19967         sleep 2
19968
19969         $MULTIOP $DIR/$tfile oO_RDWR:c
19970         kill -USR1 $PID && wait $PID || error "break lease error"
19971
19972         echo "==== test 3: verify lease can't be granted if an open already exists"
19973         $MULTIOP $DIR/$tfile oO_RDWR:_c &
19974         local PID=$!
19975         sleep 2
19976
19977         $MULTIOP $DIR/$tfile oO_RDWR:eReUc && error "apply lease should fail"
19978         kill -USR1 $PID && wait $PID || error "open file error"
19979
19980         echo "==== test 4: lease can sustain over recovery"
19981         $MULTIOP $DIR/$tfile oO_RDWR:eR_E+eUc &
19982         PID=$!
19983         sleep 2
19984
19985         fail mds1
19986
19987         kill -USR1 $PID && wait $PID || error "lease broken over recovery"
19988
19989         echo "==== test 5: lease broken can't be regained by replay"
19990         $MULTIOP $DIR/$tfile oO_RDWR:eR_E-eUc &
19991         PID=$!
19992         sleep 2
19993
19994         # open file to break lease and then recovery
19995         $MULTIOP $DIR/$tfile oO_RDWR:c || error "open file error"
19996         fail mds1
19997
19998         kill -USR1 $PID && wait $PID || error "lease not broken over recovery"
19999
20000         rm -f $DIR/$tfile
20001 }
20002 run_test 208 "Exclusive open"
20003
20004 test_209() {
20005         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep disp_stripe)" ] &&
20006                 skip_env "must have disp_stripe"
20007
20008         touch $DIR/$tfile
20009         sync; sleep 5; sync;
20010
20011         echo 3 > /proc/sys/vm/drop_caches
20012         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
20013                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
20014         req_before=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
20015
20016         # open/close 500 times
20017         for i in $(seq 500); do
20018                 cat $DIR/$tfile
20019         done
20020
20021         echo 3 > /proc/sys/vm/drop_caches
20022         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
20023                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
20024         req_after=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
20025
20026         echo "before: $req_before, after: $req_after"
20027         [ $((req_after - req_before)) -ge 300 ] &&
20028                 error "open/close requests are not freed"
20029         return 0
20030 }
20031 run_test 209 "read-only open/close requests should be freed promptly"
20032
20033 test_210() {
20034         local pid
20035
20036         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eW_E+eUc &
20037         pid=$!
20038         sleep 1
20039
20040         $LFS getstripe $DIR/$tfile
20041         kill -USR1 $pid
20042         wait $pid || error "multiop failed"
20043
20044         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
20045         pid=$!
20046         sleep 1
20047
20048         $LFS getstripe $DIR/$tfile
20049         kill -USR1 $pid
20050         wait $pid || error "multiop failed"
20051 }
20052 run_test 210 "lfs getstripe does not break leases"
20053
20054 test_212() {
20055         size=`date +%s`
20056         size=$((size % 8192 + 1))
20057         dd if=/dev/urandom of=$DIR/f212 bs=1k count=$size
20058         sendfile $DIR/f212 $DIR/f212.xyz || error "sendfile wrong"
20059         rm -f $DIR/f212 $DIR/f212.xyz
20060 }
20061 run_test 212 "Sendfile test ============================================"
20062
20063 test_213() {
20064         dd if=/dev/zero of=$DIR/$tfile bs=4k count=4
20065         cancel_lru_locks osc
20066         lctl set_param fail_loc=0x8000040f
20067         # generate a read lock
20068         cat $DIR/$tfile > /dev/null
20069         # write to the file, it will try to cancel the above read lock.
20070         cat /etc/hosts >> $DIR/$tfile
20071 }
20072 run_test 213 "OSC lock completion and cancel race don't crash - bug 18829"
20073
20074 test_214() { # for bug 20133
20075         mkdir -p $DIR/$tdir/d214c || error "mkdir $DIR/$tdir/d214c failed"
20076         for (( i=0; i < 340; i++ )) ; do
20077                 touch $DIR/$tdir/d214c/a$i
20078         done
20079
20080         ls -l $DIR/$tdir || error "ls -l $DIR/d214p failed"
20081         mv $DIR/$tdir/d214c $DIR/ || error "mv $DIR/d214p/d214c $DIR/ failed"
20082         ls $DIR/d214c || error "ls $DIR/d214c failed"
20083         rm -rf $DIR/$tdir || error "rm -rf $DIR/d214* failed"
20084         rm -rf $DIR/d214* || error "rm -rf $DIR/d214* failed"
20085 }
20086 run_test 214 "hash-indexed directory test - bug 20133"
20087
20088 # having "abc" as 1st arg, creates $TMP/lnet_abc.out and $TMP/lnet_abc.sys
20089 create_lnet_proc_files() {
20090         lctl get_param -n $1 >$TMP/lnet_$1.sys || error "cannot read lnet.$1"
20091 }
20092
20093 # counterpart of create_lnet_proc_files
20094 remove_lnet_proc_files() {
20095         rm -f $TMP/lnet_$1.sys
20096 }
20097
20098 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
20099 # 3rd arg as regexp for body
20100 check_lnet_proc_stats() {
20101         local l=$(cat "$TMP/lnet_$1" |wc -l)
20102         [ $l = 1 ] || (cat "$TMP/lnet_$1" && error "$2 is not of 1 line: $l")
20103
20104         grep -E "$3" "$TMP/lnet_$1" || (cat "$TMP/lnet_$1" && error "$2 misformatted")
20105 }
20106
20107 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
20108 # 3rd arg as regexp for body, 4th arg as regexp for 1st line, 5th arg is
20109 # optional and can be regexp for 2nd line (lnet.routes case)
20110 check_lnet_proc_entry() {
20111         local blp=2          # blp stands for 'position of 1st line of body'
20112         [ -z "$5" ] || blp=3 # lnet.routes case
20113
20114         local l=$(cat "$TMP/lnet_$1" |wc -l)
20115         # subtracting one from $blp because the body can be empty
20116         [ "$l" -ge "$(($blp - 1))" ] || (cat "$TMP/lnet_$1" && error "$2 is too short: $l")
20117
20118         sed -n '1 p' "$TMP/lnet_$1" |grep -E "$4" >/dev/null ||
20119                 (cat "$TMP/lnet_$1" && error "1st line of $2 misformatted")
20120
20121         [ "$5" = "" ] || sed -n '2 p' "$TMP/lnet_$1" |grep -E "$5" >/dev/null ||
20122                 (cat "$TMP/lnet_$1" && error "2nd line of $2 misformatted")
20123
20124         # bail out if any unexpected line happened
20125         sed -n "$blp p" "$TMP/lnet_$1" | grep -Ev "$3"
20126         [ "$?" != 0 ] || error "$2 misformatted"
20127 }
20128
20129 test_215() { # for bugs 18102, 21079, 21517
20130         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20131
20132         local N='(0|[1-9][0-9]*)'       # non-negative numeric
20133         local P='[1-9][0-9]*'           # positive numeric
20134         local I='(0|-?[1-9][0-9]*|NA)'  # any numeric (0 | >0 | <0) or NA if no value
20135         local NET='[a-z][a-z0-9]*'      # LNET net like o2ib2
20136         local ADDR='[0-9.]+'            # LNET addr like 10.0.0.1
20137         local NID="$ADDR@$NET"          # LNET nid like 10.0.0.1@o2ib2
20138
20139         local L1 # regexp for 1st line
20140         local L2 # regexp for 2nd line (optional)
20141         local BR # regexp for the rest (body)
20142
20143         # lnet.stats should look as 11 space-separated non-negative numerics
20144         BR="^$N $N $N $N $N $N $N $N $N $N $N$"
20145         create_lnet_proc_files "stats"
20146         check_lnet_proc_stats "stats.sys" "lnet.stats" "$BR"
20147         remove_lnet_proc_files "stats"
20148
20149         # lnet.routes should look like this:
20150         # Routing disabled/enabled
20151         # net hops priority state router
20152         # where net is a string like tcp0, hops > 0, priority >= 0,
20153         # state is up/down,
20154         # router is a string like 192.168.1.1@tcp2
20155         L1="^Routing (disabled|enabled)$"
20156         L2="^net +hops +priority +state +router$"
20157         BR="^$NET +$N +(0|1) +(up|down) +$NID$"
20158         create_lnet_proc_files "routes"
20159         check_lnet_proc_entry "routes.sys" "lnet.routes" "$BR" "$L1" "$L2"
20160         remove_lnet_proc_files "routes"
20161
20162         # lnet.routers should look like this:
20163         # ref rtr_ref alive_cnt state last_ping ping_sent deadline down_ni router
20164         # where ref > 0, rtr_ref > 0, alive_cnt >= 0, state is up/down,
20165         # last_ping >= 0, ping_sent is boolean (0/1), deadline and down_ni are
20166         # numeric (0 or >0 or <0), router is a string like 192.168.1.1@tcp2
20167         L1="^ref +rtr_ref +alive +router$"
20168         BR="^$P +$P +(up|down) +$NID$"
20169         create_lnet_proc_files "routers"
20170         check_lnet_proc_entry "routers.sys" "lnet.routers" "$BR" "$L1"
20171         remove_lnet_proc_files "routers"
20172
20173         # lnet.peers should look like this:
20174         # nid refs state last max rtr min tx min queue
20175         # where nid is a string like 192.168.1.1@tcp2, refs > 0,
20176         # state is up/down/NA, max >= 0. last, rtr, min, tx, min are
20177         # numeric (0 or >0 or <0), queue >= 0.
20178         L1="^nid +refs +state +last +max +rtr +min +tx +min +queue$"
20179         BR="^$NID +$P +(up|down|NA) +$I +$N +$I +$I +$I +$I +$N$"
20180         create_lnet_proc_files "peers"
20181         check_lnet_proc_entry "peers.sys" "lnet.peers" "$BR" "$L1"
20182         remove_lnet_proc_files "peers"
20183
20184         # lnet.buffers  should look like this:
20185         # pages count credits min
20186         # where pages >=0, count >=0, credits and min are numeric (0 or >0 or <0)
20187         L1="^pages +count +credits +min$"
20188         BR="^ +$N +$N +$I +$I$"
20189         create_lnet_proc_files "buffers"
20190         check_lnet_proc_entry "buffers.sys" "lnet.buffers" "$BR" "$L1"
20191         remove_lnet_proc_files "buffers"
20192
20193         # lnet.nis should look like this:
20194         # nid status alive refs peer rtr max tx min
20195         # where nid is a string like 192.168.1.1@tcp2, status is up/down,
20196         # alive is numeric (0 or >0 or <0), refs >= 0, peer >= 0,
20197         # rtr >= 0, max >=0, tx and min are numeric (0 or >0 or <0).
20198         L1="^nid +status +alive +refs +peer +rtr +max +tx +min$"
20199         BR="^$NID +(up|down) +$I +$N +$N +$N +$N +$I +$I$"
20200         create_lnet_proc_files "nis"
20201         check_lnet_proc_entry "nis.sys" "lnet.nis" "$BR" "$L1"
20202         remove_lnet_proc_files "nis"
20203
20204         # can we successfully write to lnet.stats?
20205         lctl set_param -n stats=0 || error "cannot write to lnet.stats"
20206 }
20207 run_test 215 "lnet exists and has proper content - bugs 18102, 21079, 21517"
20208
20209 test_216() { # bug 20317
20210         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20211         remote_ost_nodsh && skip "remote OST with nodsh"
20212
20213         local node
20214         local facets=$(get_facets OST)
20215         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
20216
20217         save_lustre_params client "osc.*.contention_seconds" > $p
20218         save_lustre_params $facets \
20219                 "ldlm.namespaces.filter-*.max_nolock_bytes" >> $p
20220         save_lustre_params $facets \
20221                 "ldlm.namespaces.filter-*.contended_locks" >> $p
20222         save_lustre_params $facets \
20223                 "ldlm.namespaces.filter-*.contention_seconds" >> $p
20224         clear_stats osc.*.osc_stats
20225
20226         # agressive lockless i/o settings
20227         do_nodes $(comma_list $(osts_nodes)) \
20228                 "lctl set_param -n ldlm.namespaces.*.max_nolock_bytes=2000000 \
20229                         ldlm.namespaces.filter-*.contended_locks=0 \
20230                         ldlm.namespaces.filter-*.contention_seconds=60"
20231         lctl set_param -n osc.*.contention_seconds=60
20232
20233         $DIRECTIO write $DIR/$tfile 0 10 4096
20234         $CHECKSTAT -s 40960 $DIR/$tfile
20235
20236         # disable lockless i/o
20237         do_nodes $(comma_list $(osts_nodes)) \
20238                 "lctl set_param -n ldlm.namespaces.filter-*.max_nolock_bytes=0 \
20239                         ldlm.namespaces.filter-*.contended_locks=32 \
20240                         ldlm.namespaces.filter-*.contention_seconds=0"
20241         lctl set_param -n osc.*.contention_seconds=0
20242         clear_stats osc.*.osc_stats
20243
20244         dd if=/dev/zero of=$DIR/$tfile count=0
20245         $CHECKSTAT -s 0 $DIR/$tfile
20246
20247         restore_lustre_params <$p
20248         rm -f $p
20249         rm $DIR/$tfile
20250 }
20251 run_test 216 "check lockless direct write updates file size and kms correctly"
20252
20253 test_217() { # bug 22430
20254         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20255
20256         local node
20257
20258         for node in $(nodes_list); do
20259                 local nid=$(host_nids_address $node $NETTYPE)
20260                 local node_ip=$(do_node $node getent ahostsv4 $node |
20261                                 awk '{ print $1; exit; }')
20262
20263                 echo "node: '$node', nid: '$nid', node_ip='$node_ip'"
20264                 # if hostname matches any NID, use hostname for better testing
20265                 if [[ -z "$nid" || "$nid" =~ "$node_ip" ]]; then
20266                         echo "lctl ping node $node@$NETTYPE"
20267                         lctl ping $node@$NETTYPE
20268                 else # otherwise, at least test 'lctl ping' is working
20269                         echo "lctl ping nid $(h2nettype $nid)"
20270                         lctl ping $(h2nettype $nid)
20271                         echo "skipping $node (no hyphen detected)"
20272                 fi
20273         done
20274 }
20275 run_test 217 "check lctl ping for hostnames with embedded hyphen ('-')"
20276
20277 test_218() {
20278         # do directio so as not to populate the page cache
20279         log "creating a 10 Mb file"
20280         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c ||
20281                 error "multiop failed while creating a file"
20282         log "starting reads"
20283         dd if=$DIR/$tfile of=/dev/null bs=4096 &
20284         log "truncating the file"
20285         $MULTIOP $DIR/$tfile oO_TRUNC:c ||
20286                 error "multiop failed while truncating the file"
20287         log "killing dd"
20288         kill %+ || true # reads might have finished
20289         echo "wait until dd is finished"
20290         wait
20291         log "removing the temporary file"
20292         rm -rf $DIR/$tfile || error "tmp file removal failed"
20293 }
20294 run_test 218 "parallel read and truncate should not deadlock"
20295
20296 test_219() {
20297         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20298
20299         # write one partial page
20300         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1
20301         # set no grant so vvp_io_commit_write will do sync write
20302         $LCTL set_param fail_loc=0x411
20303         # write a full page at the end of file
20304         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=1 conv=notrunc
20305
20306         $LCTL set_param fail_loc=0
20307         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=3
20308         $LCTL set_param fail_loc=0x411
20309         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1 seek=2 conv=notrunc
20310
20311         # LU-4201
20312         dd if=/dev/zero of=$DIR/$tfile-2 bs=1024 count=1
20313         $CHECKSTAT -s 1024 $DIR/$tfile-2 || error "checkstat wrong size"
20314 }
20315 run_test 219 "LU-394: Write partial won't cause uncontiguous pages vec at LND"
20316
20317 test_220() { #LU-325
20318         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20319         remote_ost_nodsh && skip "remote OST with nodsh"
20320         remote_mds_nodsh && skip "remote MDS with nodsh"
20321         remote_mgs_nodsh && skip "remote MGS with nodsh"
20322
20323         local OSTIDX=0
20324
20325         # create on MDT0000 so the last_id and next_id are correct
20326         mkdir_on_mdt0 $DIR/$tdir
20327         local OST=$($LFS df $DIR | awk '/OST:'$OSTIDX'/ { print $1 }')
20328         OST=${OST%_UUID}
20329
20330         # on the mdt's osc
20331         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $OST)
20332         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
20333                         osp.$mdtosc_proc1.prealloc_last_id)
20334         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
20335                         osp.$mdtosc_proc1.prealloc_next_id)
20336
20337         $LFS df -i
20338
20339         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=-1
20340         #define OBD_FAIL_OST_ENOINO              0x229
20341         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0x229
20342         create_pool $FSNAME.$TESTNAME || return 1
20343         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $OST || return 2
20344
20345         $LFS setstripe $DIR/$tdir -i $OSTIDX -c 1 -p $FSNAME.$TESTNAME
20346
20347         MDSOBJS=$((last_id - next_id))
20348         echo "preallocated objects on MDS is $MDSOBJS" "($last_id - $next_id)"
20349
20350         blocks=$($LFS df $MOUNT | awk '($1 == '$OSTIDX') { print $4 }')
20351         echo "OST still has $count kbytes free"
20352
20353         echo "create $MDSOBJS files @next_id..."
20354         createmany -o $DIR/$tdir/f $MDSOBJS || return 3
20355
20356         local last_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
20357                         osp.$mdtosc_proc1.prealloc_last_id)
20358         local next_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
20359                         osp.$mdtosc_proc1.prealloc_next_id)
20360
20361         echo "after creation, last_id=$last_id2, next_id=$next_id2"
20362         $LFS df -i
20363
20364         echo "cleanup..."
20365
20366         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=0
20367         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0
20368
20369         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $OST ||
20370                 error "$LCTL pool_remove $FSNAME.$TESTNAME $OST failed"
20371         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
20372                 error "$LCTL pool_destroy $FSNAME.$TESTNAME failed"
20373         echo "unlink $MDSOBJS files @$next_id..."
20374         unlinkmany $DIR/$tdir/f $MDSOBJS || error "unlinkmany failed"
20375 }
20376 run_test 220 "preallocated MDS objects still used if ENOSPC from OST"
20377
20378 test_221() {
20379         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20380
20381         dd if=`which date` of=$MOUNT/date oflag=sync
20382         chmod +x $MOUNT/date
20383
20384         #define OBD_FAIL_LLITE_FAULT_TRUNC_RACE  0x1401
20385         $LCTL set_param fail_loc=0x80001401
20386
20387         $MOUNT/date > /dev/null
20388         rm -f $MOUNT/date
20389 }
20390 run_test 221 "make sure fault and truncate race to not cause OOM"
20391
20392 test_222a () {
20393         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20394
20395         rm -rf $DIR/$tdir
20396         test_mkdir $DIR/$tdir
20397         $LFS setstripe -c 1 -i 0 $DIR/$tdir
20398         createmany -o $DIR/$tdir/$tfile 10
20399         cancel_lru_locks mdc
20400         cancel_lru_locks osc
20401         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
20402         $LCTL set_param fail_loc=0x31a
20403         ls -l $DIR/$tdir > /dev/null || error "AGL for ls failed"
20404         $LCTL set_param fail_loc=0
20405         rm -r $DIR/$tdir
20406 }
20407 run_test 222a "AGL for ls should not trigger CLIO lock failure"
20408
20409 test_222b () {
20410         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20411
20412         rm -rf $DIR/$tdir
20413         test_mkdir $DIR/$tdir
20414         $LFS setstripe -c 1 -i 0 $DIR/$tdir
20415         createmany -o $DIR/$tdir/$tfile 10
20416         cancel_lru_locks mdc
20417         cancel_lru_locks osc
20418         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
20419         $LCTL set_param fail_loc=0x31a
20420         rm -r $DIR/$tdir || error "AGL for rmdir failed"
20421         $LCTL set_param fail_loc=0
20422 }
20423 run_test 222b "AGL for rmdir should not trigger CLIO lock failure"
20424
20425 test_223 () {
20426         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20427
20428         rm -rf $DIR/$tdir
20429         test_mkdir $DIR/$tdir
20430         $LFS setstripe -c 1 -i 0 $DIR/$tdir
20431         createmany -o $DIR/$tdir/$tfile 10
20432         cancel_lru_locks mdc
20433         cancel_lru_locks osc
20434         #define OBD_FAIL_LDLM_AGL_NOLOCK          0x31b
20435         $LCTL set_param fail_loc=0x31b
20436         ls -l $DIR/$tdir > /dev/null || error "reenqueue failed"
20437         $LCTL set_param fail_loc=0
20438         rm -r $DIR/$tdir
20439 }
20440 run_test 223 "osc reenqueue if without AGL lock granted ======================="
20441
20442 test_224a() { # LU-1039, MRP-303
20443         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20444         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB   0x508
20445         $LCTL set_param fail_loc=0x508
20446         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 conv=fsync
20447         $LCTL set_param fail_loc=0
20448         df $DIR
20449 }
20450 run_test 224a "Don't panic on bulk IO failure"
20451
20452 test_224bd_sub() { # LU-1039, MRP-303
20453         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20454         local timeout=$1
20455
20456         shift
20457         dd if=/dev/urandom of=$TMP/$tfile bs=1M count=1
20458
20459         $LFS setstripe -c 1 -i 0 $DIR/$tfile
20460
20461         dd if=$TMP/$tfile of=$DIR/$tfile bs=1M count=1
20462         cancel_lru_locks osc
20463         set_checksums 0
20464         stack_trap "set_checksums $ORIG_CSUM" EXIT
20465         local at_max_saved=0
20466
20467         # adaptive timeouts may prevent seeing the issue
20468         if at_is_enabled; then
20469                 at_max_saved=$(at_max_get mds)
20470                 at_max_set 0 mds client
20471                 stack_trap "at_max_set $at_max_saved mds client" EXIT
20472         fi
20473
20474         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB2   0x515
20475         do_facet ost1 $LCTL set_param fail_val=$timeout fail_loc=0x80000515
20476         dd of=$TMP/$tfile.new if=$DIR/$tfile bs=1M count=1 || "$@"
20477
20478         do_facet ost1 $LCTL set_param fail_loc=0
20479         cmp $TMP/$tfile $TMP/$tfile.new || error "file contents wrong"
20480         df $DIR
20481 }
20482
20483 test_224b() {
20484         test_224bd_sub 3 error "dd failed"
20485 }
20486 run_test 224b "Don't panic on bulk IO failure"
20487
20488 test_224c() { # LU-6441
20489         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20490         remote_mds_nodsh && skip "remote MDS with nodsh"
20491
20492         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
20493         save_writethrough $p
20494         set_cache writethrough on
20495
20496         local pages_per_rpc=$($LCTL get_param osc.*.max_pages_per_rpc)
20497         local at_max=$($LCTL get_param -n at_max)
20498         local timeout=$($LCTL get_param -n timeout)
20499         local test_at="at_max"
20500         local param_at="$FSNAME.sys.at_max"
20501         local test_timeout="timeout"
20502         local param_timeout="$FSNAME.sys.timeout"
20503
20504         $LCTL set_param -n osc.*.max_pages_per_rpc=1024
20505
20506         set_persistent_param_and_check client "$test_at" "$param_at" 0
20507         set_persistent_param_and_check client "$test_timeout" "$param_timeout" 5
20508
20509         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB3 0x520
20510         do_facet ost1 "$LCTL set_param fail_loc=0x520"
20511         $LFS setstripe -c 1 -i 0 $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_231a()
21875 {
21876         # For simplicity this test assumes that max_pages_per_rpc
21877         # is the same across all OSCs
21878         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
21879         local bulk_size=$((max_pages * PAGE_SIZE))
21880         local brw_size=$(do_facet ost1 $LCTL get_param -n obdfilter.*.brw_size |
21881                                        head -n 1)
21882
21883         mkdir -p $DIR/$tdir
21884         $LFS setstripe -S ${brw_size}M $DIR/$tdir ||
21885                 error "failed to set stripe with -S ${brw_size}M option"
21886
21887         # clear the OSC stats
21888         $LCTL set_param osc.*.stats=0 &>/dev/null
21889         stop_writeback
21890
21891         # Client writes $bulk_size - there must be 1 rpc for $max_pages.
21892         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=$bulk_size count=1 \
21893                 oflag=direct &>/dev/null || error "dd failed"
21894
21895         sync; sleep 1; sync # just to be safe
21896         local nrpcs=$($LCTL get_param osc.*.stats |awk '/ost_write/ {print $2}')
21897         if [ x$nrpcs != "x1" ]; then
21898                 $LCTL get_param osc.*.stats
21899                 error "found $nrpcs ost_write RPCs, not 1 as expected"
21900         fi
21901
21902         start_writeback
21903         # Drop the OSC cache, otherwise we will read from it
21904         cancel_lru_locks osc
21905
21906         # clear the OSC stats
21907         $LCTL set_param osc.*.stats=0 &>/dev/null
21908
21909         # Client reads $bulk_size.
21910         dd if=$DIR/$tdir/$tfile of=/dev/null bs=$bulk_size count=1 \
21911                 iflag=direct &>/dev/null || error "dd failed"
21912
21913         nrpcs=$($LCTL get_param osc.*.stats | awk '/ost_read/ { print $2 }')
21914         if [ x$nrpcs != "x1" ]; then
21915                 $LCTL get_param osc.*.stats
21916                 error "found $nrpcs ost_read RPCs, not 1 as expected"
21917         fi
21918 }
21919 run_test 231a "checking that reading/writing of BRW RPC size results in one RPC"
21920
21921 test_231b() {
21922         mkdir -p $DIR/$tdir
21923         local i
21924         for i in {0..1023}; do
21925                 dd if=/dev/zero of=$DIR/$tdir/$tfile conv=notrunc \
21926                         seek=$((2 * i)) bs=4096 count=1 &>/dev/null ||
21927                         error "dd of=$DIR/$tdir/$tfile seek=$((2 * i)) failed"
21928         done
21929         sync
21930 }
21931 run_test 231b "must not assert on fully utilized OST request buffer"
21932
21933 test_232a() {
21934         mkdir -p $DIR/$tdir
21935         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
21936
21937         #define OBD_FAIL_LDLM_OST_LVB            0x31c
21938         do_facet ost1 $LCTL set_param fail_loc=0x31c
21939
21940         # ignore dd failure
21941         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1 || true
21942
21943         do_facet ost1 $LCTL set_param fail_loc=0
21944         umount_client $MOUNT || error "umount failed"
21945         mount_client $MOUNT || error "mount failed"
21946         stop ost1 || error "cannot stop ost1"
21947         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
21948 }
21949 run_test 232a "failed lock should not block umount"
21950
21951 test_232b() {
21952         [ $MDS1_VERSION -ge $(version_code 2.10.58) ] ||
21953                 skip "Need MDS version at least 2.10.58"
21954
21955         mkdir -p $DIR/$tdir
21956         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
21957         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1
21958         sync
21959         cancel_lru_locks osc
21960
21961         #define OBD_FAIL_LDLM_OST_LVB            0x31c
21962         do_facet ost1 $LCTL set_param fail_loc=0x31c
21963
21964         # ignore failure
21965         $LFS data_version $DIR/$tdir/$tfile || true
21966
21967         do_facet ost1 $LCTL set_param fail_loc=0
21968         umount_client $MOUNT || error "umount failed"
21969         mount_client $MOUNT || error "mount failed"
21970         stop ost1 || error "cannot stop ost1"
21971         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
21972 }
21973 run_test 232b "failed data version lock should not block umount"
21974
21975 test_233a() {
21976         [ $MDS1_VERSION -ge $(version_code 2.3.64) ] ||
21977                 skip "Need MDS version at least 2.3.64"
21978         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
21979
21980         local fid=$($LFS path2fid $MOUNT)
21981
21982         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
21983                 error "cannot access $MOUNT using its FID '$fid'"
21984 }
21985 run_test 233a "checking that OBF of the FS root succeeds"
21986
21987 test_233b() {
21988         [ $MDS1_VERSION -ge $(version_code 2.5.90) ] ||
21989                 skip "Need MDS version at least 2.5.90"
21990         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
21991
21992         local fid=$($LFS path2fid $MOUNT/.lustre)
21993
21994         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
21995                 error "cannot access $MOUNT/.lustre using its FID '$fid'"
21996
21997         fid=$($LFS path2fid $MOUNT/.lustre/fid)
21998         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
21999                 error "cannot access $MOUNT/.lustre/fid using its FID '$fid'"
22000 }
22001 run_test 233b "checking that OBF of the FS .lustre succeeds"
22002
22003 test_234() {
22004         local p="$TMP/sanityN-$TESTNAME.parameters"
22005         save_lustre_params client "llite.*.xattr_cache" > $p
22006         lctl set_param llite.*.xattr_cache 1 ||
22007                 skip_env "xattr cache is not supported"
22008
22009         mkdir -p $DIR/$tdir || error "mkdir failed"
22010         touch $DIR/$tdir/$tfile || error "touch failed"
22011         # OBD_FAIL_LLITE_XATTR_ENOMEM
22012         $LCTL set_param fail_loc=0x1405
22013         getfattr -n user.attr $DIR/$tdir/$tfile &&
22014                 error "getfattr should have failed with ENOMEM"
22015         $LCTL set_param fail_loc=0x0
22016         rm -rf $DIR/$tdir
22017
22018         restore_lustre_params < $p
22019         rm -f $p
22020 }
22021 run_test 234 "xattr cache should not crash on ENOMEM"
22022
22023 test_235() {
22024         [ $MDS1_VERSION -lt $(version_code 2.4.52) ] &&
22025                 skip "Need MDS version at least 2.4.52"
22026
22027         flock_deadlock $DIR/$tfile
22028         local RC=$?
22029         case $RC in
22030                 0)
22031                 ;;
22032                 124) error "process hangs on a deadlock"
22033                 ;;
22034                 *) error "error executing flock_deadlock $DIR/$tfile"
22035                 ;;
22036         esac
22037 }
22038 run_test 235 "LU-1715: flock deadlock detection does not work properly"
22039
22040 #LU-2935
22041 test_236() {
22042         check_swap_layouts_support
22043
22044         local ref1=/etc/passwd
22045         local ref2=/etc/group
22046         local file1=$DIR/$tdir/f1
22047         local file2=$DIR/$tdir/f2
22048
22049         test_mkdir -c1 $DIR/$tdir
22050         $LFS setstripe -c 1 $file1 || error "cannot setstripe on '$file1': rc = $?"
22051         cp $ref1 $file1 || error "cp $ref1 $file1 failed: rc = $?"
22052         $LFS setstripe -c 2 $file2 || error "cannot setstripe on '$file2': rc = $?"
22053         cp $ref2 $file2 || error "cp $ref2 $file2 failed: rc = $?"
22054         local fd=$(free_fd)
22055         local cmd="exec $fd<>$file2"
22056         eval $cmd
22057         rm $file2
22058         $LFS swap_layouts $file1 /proc/self/fd/${fd} ||
22059                 error "cannot swap layouts of '$file1' and /proc/self/fd/${fd}"
22060         cmd="exec $fd>&-"
22061         eval $cmd
22062         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
22063
22064         #cleanup
22065         rm -rf $DIR/$tdir
22066 }
22067 run_test 236 "Layout swap on open unlinked file"
22068
22069 # LU-4659 linkea consistency
22070 test_238() {
22071         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
22072                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
22073                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
22074                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
22075
22076         touch $DIR/$tfile
22077         ln $DIR/$tfile $DIR/$tfile.lnk
22078         touch $DIR/$tfile.new
22079         mv $DIR/$tfile.new $DIR/$tfile
22080         local fid1=$($LFS path2fid $DIR/$tfile)
22081         local fid2=$($LFS path2fid $DIR/$tfile.lnk)
22082         local path1=$($LFS fid2path $FSNAME "$fid1")
22083         [ $tfile == $path1 ] || error "linkea inconsistent: $tfile $fid1 $path1"
22084         local path2=$($LFS fid2path $FSNAME "$fid2")
22085         [ $tfile.lnk == $path2 ] ||
22086                 error "linkea inconsistent: $tfile.lnk $fid2 $path2!"
22087         rm -f $DIR/$tfile*
22088 }
22089 run_test 238 "Verify linkea consistency"
22090
22091 test_239A() { # was test_239
22092         [ $MDS1_VERSION -lt $(version_code 2.5.60) ] &&
22093                 skip "Need MDS version at least 2.5.60"
22094
22095         local list=$(comma_list $(mdts_nodes))
22096
22097         mkdir -p $DIR/$tdir
22098         createmany -o $DIR/$tdir/f- 5000
22099         unlinkmany $DIR/$tdir/f- 5000
22100         [ $MDS1_VERSION -gt $(version_code 2.10.4) ] &&
22101                 do_nodes $list "lctl set_param -n osp.*.force_sync=1"
22102         changes=$(do_nodes $list "lctl get_param -n osp.*MDT*.sync_changes \
22103                         osp.*MDT*.sync_in_flight" | calc_sum)
22104         [ "$changes" -eq 0 ] || error "$changes not synced"
22105 }
22106 run_test 239A "osp_sync test"
22107
22108 test_239a() { #LU-5297
22109         remote_mds_nodsh && skip "remote MDS with nodsh"
22110
22111         touch $DIR/$tfile
22112         #define OBD_FAIL_OSP_CHECK_INVALID_REC     0x2100
22113         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2100
22114         chgrp $RUNAS_GID $DIR/$tfile
22115         wait_delete_completed
22116 }
22117 run_test 239a "process invalid osp sync record correctly"
22118
22119 test_239b() { #LU-5297
22120         remote_mds_nodsh && skip "remote MDS with nodsh"
22121
22122         touch $DIR/$tfile1
22123         #define OBD_FAIL_OSP_CHECK_ENOMEM     0x2101
22124         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2101
22125         chgrp $RUNAS_GID $DIR/$tfile1
22126         wait_delete_completed
22127         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
22128         touch $DIR/$tfile2
22129         chgrp $RUNAS_GID $DIR/$tfile2
22130         wait_delete_completed
22131 }
22132 run_test 239b "process osp sync record with ENOMEM error correctly"
22133
22134 test_240() {
22135         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22136         remote_mds_nodsh && skip "remote MDS with nodsh"
22137
22138         mkdir -p $DIR/$tdir
22139
22140         $LFS mkdir -i 0 $DIR/$tdir/d0 ||
22141                 error "failed to mkdir $DIR/$tdir/d0 on MDT0"
22142         $LFS mkdir -i 1 $DIR/$tdir/d0/d1 ||
22143                 error "failed to mkdir $DIR/$tdir/d0/d1 on MDT1"
22144
22145         umount_client $MOUNT || error "umount failed"
22146         #define OBD_FAIL_TGT_DELAY_CONDITIONAL   0x713
22147         do_facet mds2 lctl set_param fail_loc=0x713 fail_val=1
22148         mount_client $MOUNT || error "failed to mount client"
22149
22150         echo "stat $DIR/$tdir/d0/d1, should not fail/ASSERT"
22151         stat $DIR/$tdir/d0/d1 || error "fail to stat $DIR/$tdir/d0/d1"
22152 }
22153 run_test 240 "race between ldlm enqueue and the connection RPC (no ASSERT)"
22154
22155 test_241_bio() {
22156         local count=$1
22157         local bsize=$2
22158
22159         for LOOP in $(seq $count); do
22160                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 2>/dev/null
22161                 cancel_lru_locks $OSC || true
22162         done
22163 }
22164
22165 test_241_dio() {
22166         local count=$1
22167         local bsize=$2
22168
22169         for LOOP in $(seq $1); do
22170                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 iflag=direct \
22171                         2>/dev/null
22172         done
22173 }
22174
22175 test_241a() { # was test_241
22176         local bsize=$PAGE_SIZE
22177
22178         (( bsize < 40960 )) && bsize=40960
22179         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
22180         ls -la $DIR/$tfile
22181         cancel_lru_locks $OSC
22182         test_241_bio 1000 $bsize &
22183         PID=$!
22184         test_241_dio 1000 $bsize
22185         wait $PID
22186 }
22187 run_test 241a "bio vs dio"
22188
22189 test_241b() {
22190         local bsize=$PAGE_SIZE
22191
22192         (( bsize < 40960 )) && bsize=40960
22193         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
22194         ls -la $DIR/$tfile
22195         test_241_dio 1000 $bsize &
22196         PID=$!
22197         test_241_dio 1000 $bsize
22198         wait $PID
22199 }
22200 run_test 241b "dio vs dio"
22201
22202 test_242() {
22203         remote_mds_nodsh && skip "remote MDS with nodsh"
22204
22205         mkdir_on_mdt0 $DIR/$tdir
22206         touch $DIR/$tdir/$tfile
22207
22208         #define OBD_FAIL_MDS_READPAGE_PACK      0x105
22209         do_facet mds1 lctl set_param fail_loc=0x105
22210         /bin/ls $DIR/$tdir && error "ls $DIR/$tdir should fail"
22211
22212         do_facet mds1 lctl set_param fail_loc=0
22213         /bin/ls $DIR/$tdir || error "ls $DIR/$tdir failed"
22214 }
22215 run_test 242 "mdt_readpage failure should not cause directory unreadable"
22216
22217 test_243()
22218 {
22219         test_mkdir $DIR/$tdir
22220         group_lock_test -d $DIR/$tdir || error "A group lock test failed"
22221 }
22222 run_test 243 "various group lock tests"
22223
22224 test_244a()
22225 {
22226         test_mkdir $DIR/$tdir
22227         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=35
22228         sendfile_grouplock $DIR/$tdir/$tfile || \
22229                 error "sendfile+grouplock failed"
22230         rm -rf $DIR/$tdir
22231 }
22232 run_test 244a "sendfile with group lock tests"
22233
22234 test_244b()
22235 {
22236         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
22237
22238         local threads=50
22239         local size=$((1024*1024))
22240
22241         test_mkdir $DIR/$tdir
22242         for i in $(seq 1 $threads); do
22243                 local file=$DIR/$tdir/file_$((i / 10))
22244                 $MULTIOP $file OG1234w$size_$((i % 3))w$size_$((i % 4))g1234c &
22245                 local pids[$i]=$!
22246         done
22247         for i in $(seq 1 $threads); do
22248                 wait ${pids[$i]}
22249         done
22250 }
22251 run_test 244b "multi-threaded write with group lock"
22252
22253 test_245a() {
22254         local flagname="multi_mod_rpcs"
22255         local connect_data_name="max_mod_rpcs"
22256         local out
22257
22258         # check if multiple modify RPCs flag is set
22259         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import |
22260                 grep "connect_flags:")
22261         echo "$out"
22262
22263         echo "$out" | grep -qw $flagname
22264         if [ $? -ne 0 ]; then
22265                 echo "connect flag $flagname is not set"
22266                 return
22267         fi
22268
22269         # check if multiple modify RPCs data is set
22270         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import)
22271         echo "$out"
22272
22273         echo "$out" | grep -qw $connect_data_name ||
22274                 error "import should have connect data $connect_data_name"
22275 }
22276 run_test 245a "check mdc connection flag/data: multiple modify RPCs"
22277
22278 test_245b() {
22279         local flagname="multi_mod_rpcs"
22280         local connect_data_name="max_mod_rpcs"
22281         local out
22282
22283         remote_mds_nodsh && skip "remote MDS with nodsh"
22284         [[ $MDSCOUNT -ge 2 ]] || skip "needs >= 2 MDTs"
22285
22286         # check if multiple modify RPCs flag is set
22287         out=$(do_facet mds1 \
22288               $LCTL get_param osp.$FSNAME-MDT0001-osp-MDT0000.import |
22289               grep "connect_flags:")
22290         echo "$out"
22291
22292         [[ "$out" =~ $flagname ]] || skip "connect flag $flagname is not set"
22293
22294         # check if multiple modify RPCs data is set
22295         out=$(do_facet mds1 \
22296               $LCTL get_param osp.$FSNAME-MDT0001-osp-MDT0000.import)
22297
22298         [[ "$out" =~ $connect_data_name ]] ||
22299                 {
22300                         echo "$out"
22301                         error "missing connect data $connect_data_name"
22302                 }
22303 }
22304 run_test 245b "check osp connection flag/data: multiple modify RPCs"
22305
22306 cleanup_247() {
22307         local submount=$1
22308
22309         trap 0
22310         umount_client $submount
22311         rmdir $submount
22312 }
22313
22314 test_247a() {
22315         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
22316                 grep -q subtree ||
22317                 skip_env "Fileset feature is not supported"
22318
22319         local submount=${MOUNT}_$tdir
22320
22321         mkdir $MOUNT/$tdir
22322         mkdir -p $submount || error "mkdir $submount failed"
22323         FILESET="$FILESET/$tdir" mount_client $submount ||
22324                 error "mount $submount failed"
22325         trap "cleanup_247 $submount" EXIT
22326         echo foo > $submount/$tfile || error "write $submount/$tfile failed"
22327         [ $(cat $MOUNT/$tdir/$tfile) = "foo" ] ||
22328                 error "read $MOUNT/$tdir/$tfile failed"
22329         cleanup_247 $submount
22330 }
22331 run_test 247a "mount subdir as fileset"
22332
22333 test_247b() {
22334         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
22335                 skip_env "Fileset feature is not supported"
22336
22337         local submount=${MOUNT}_$tdir
22338
22339         rm -rf $MOUNT/$tdir
22340         mkdir -p $submount || error "mkdir $submount failed"
22341         SKIP_FILESET=1
22342         FILESET="$FILESET/$tdir" mount_client $submount &&
22343                 error "mount $submount should fail"
22344         rmdir $submount
22345 }
22346 run_test 247b "mount subdir that dose not exist"
22347
22348 test_247c() {
22349         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
22350                 skip_env "Fileset feature is not supported"
22351
22352         local submount=${MOUNT}_$tdir
22353
22354         mkdir -p $MOUNT/$tdir/dir1
22355         mkdir -p $submount || error "mkdir $submount failed"
22356         trap "cleanup_247 $submount" EXIT
22357         FILESET="$FILESET/$tdir" mount_client $submount ||
22358                 error "mount $submount failed"
22359         local fid=$($LFS path2fid $MOUNT/)
22360         $LFS fid2path $submount $fid && error "fid2path should fail"
22361         cleanup_247 $submount
22362 }
22363 run_test 247c "running fid2path outside subdirectory root"
22364
22365 test_247d() {
22366         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
22367                 skip "Fileset feature is not supported"
22368
22369         local submount=${MOUNT}_$tdir
22370
22371         mkdir -p $MOUNT/$tdir/dir1
22372         mkdir -p $submount || error "mkdir $submount failed"
22373         FILESET="$FILESET/$tdir" mount_client $submount ||
22374                 error "mount $submount failed"
22375         trap "cleanup_247 $submount" EXIT
22376
22377         local td=$submount/dir1
22378         local fid=$($LFS path2fid $td)
22379         [ -z "$fid" ] && error "path2fid unable to get $td FID"
22380
22381         # check that we get the same pathname back
22382         local rootpath
22383         local found
22384         for rootpath in "$submount" "$submount///" "$submount/dir1"; do
22385                 echo "$rootpath $fid"
22386                 found=$($LFS fid2path $rootpath "$fid")
22387                 [ -n "$found" ] || error "fid2path should succeed"
22388                 [ "$found" == "$td" ] || error "fid2path $found != $td"
22389         done
22390         # check wrong root path format
22391         rootpath=$submount"_wrong"
22392         found=$($LFS fid2path $rootpath "$fid")
22393         [ -z "$found" ] || error "fid2path should fail ($rootpath != $submount)"
22394
22395         cleanup_247 $submount
22396 }
22397 run_test 247d "running fid2path inside subdirectory root"
22398
22399 # LU-8037
22400 test_247e() {
22401         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
22402                 grep -q subtree ||
22403                 skip "Fileset feature is not supported"
22404
22405         local submount=${MOUNT}_$tdir
22406
22407         mkdir $MOUNT/$tdir
22408         mkdir -p $submount || error "mkdir $submount failed"
22409         FILESET="$FILESET/.." mount_client $submount &&
22410                 error "mount $submount should fail"
22411         rmdir $submount
22412 }
22413 run_test 247e "mount .. as fileset"
22414
22415 test_247f() {
22416         (( $MDSCOUNT > 1 )) || skip_env "needs >= 2 MDTs"
22417         (( $MDS1_VERSION >= $(version_code 2.14.50.162) )) ||
22418                 skip "Need at least version 2.14.50.162"
22419         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
22420                 skip "Fileset feature is not supported"
22421
22422         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
22423         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote ||
22424                 error "mkdir remote failed"
22425         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote/subdir ||
22426                 error "mkdir remote/subdir failed"
22427         $LFS mkdir -i 0 -c $MDSCOUNT $DIR/$tdir/striped ||
22428                 error "mkdir striped failed"
22429         mkdir $DIR/$tdir/striped/subdir || error "mkdir striped/subdir failed"
22430
22431         local submount=${MOUNT}_$tdir
22432
22433         mkdir -p $submount || error "mkdir $submount failed"
22434         stack_trap "rmdir $submount"
22435
22436         local dir
22437         local fileset=$FILESET
22438         local mdts=$(comma_list $(mdts_nodes))
22439
22440         do_nodes $mdts "$LCTL set_param mdt.*.enable_remote_subdir_mount=1"
22441         for dir in $tdir/remote $tdir/remote/subdir $tdir/striped \
22442                 $tdir/striped/subdir $tdir/striped/.; do
22443                 FILESET="$fileset/$dir" mount_client $submount ||
22444                         error "mount $dir failed"
22445                 umount_client $submount
22446         done
22447 }
22448 run_test 247f "mount striped or remote directory as fileset"
22449
22450 test_subdir_mount_lock()
22451 {
22452         local testdir=$1
22453         local submount=${MOUNT}_$(basename $testdir)
22454
22455         touch $DIR/$testdir/$tfile || error "touch $tfile failed"
22456
22457         mkdir -p $submount || error "mkdir $submount failed"
22458         stack_trap "rmdir $submount"
22459
22460         FILESET="$fileset/$testdir" mount_client $submount ||
22461                 error "mount $FILESET failed"
22462         stack_trap "umount $submount"
22463
22464         local mdts=$(comma_list $(mdts_nodes))
22465
22466         local nrpcs
22467
22468         stat $submount > /dev/null || error "stat $submount failed"
22469         cancel_lru_locks $MDC
22470         stat $submount > /dev/null || error "stat $submount failed"
22471         stat $submount/$tfile > /dev/null || error "stat $tfile failed"
22472         do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear > /dev/null"
22473         stat $submount/$tfile > /dev/null || error "stat $tfile failed"
22474         nrpcs=$(do_nodes $mdts "lctl get_param -n mdt.*.md_stats" |
22475                 awk '/getattr/ {sum += $2} END {print sum}')
22476
22477         [ -z "$nrpcs" ] || error "$nrpcs extra getattr sent"
22478 }
22479
22480 test_247g() {
22481         (( $MDSCOUNT > 1 )) || skip_env "needs > 1 MDTs"
22482
22483         $LFS mkdir -i 0 -c 4 -H fnv_1a_64 $DIR/$tdir ||
22484                 error "mkdir $tdir failed"
22485         test_subdir_mount_lock $tdir
22486 }
22487 run_test 247g "striped directory submount revalidate ROOT from cache"
22488
22489 test_247h() {
22490         (( $MDSCOUNT > 1 )) || skip_env "needs > 1 MDTs"
22491         (( $MDS1_VERSION >= $(version_code 2.15.51) )) ||
22492                 skip "Need MDS version at least 2.15.51"
22493
22494         $LFS mkdir -i 1 -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
22495         test_subdir_mount_lock $tdir
22496         mkdir_on_mdt -i 0 $DIR/$tdir/$tdir.0 || error "mkdir $tdir.0 failed"
22497         mkdir_on_mdt -i 1 $DIR/$tdir/$tdir.0/$tdir.1 ||
22498                 error "mkdir $tdir.1 failed"
22499         test_subdir_mount_lock $tdir/$tdir.0/$tdir.1
22500 }
22501 run_test 247h "remote directory submount revalidate ROOT from cache"
22502
22503 test_248a() {
22504         local fast_read_sav=$($LCTL get_param -n llite.*.fast_read 2>/dev/null)
22505         [ -z "$fast_read_sav" ] && skip "no fast read support"
22506
22507         # create a large file for fast read verification
22508         dd if=/dev/zero of=$DIR/$tfile bs=1M count=128 > /dev/null 2>&1
22509
22510         # make sure the file is created correctly
22511         $CHECKSTAT -s $((128*1024*1024)) $DIR/$tfile ||
22512                 { rm -f $DIR/$tfile; skip "file creation error"; }
22513
22514         echo "Test 1: verify that fast read is 4 times faster on cache read"
22515
22516         # small read with fast read enabled
22517         $LCTL set_param -n llite.*.fast_read=1
22518         local t_fast=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
22519                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
22520                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
22521         # small read with fast read disabled
22522         $LCTL set_param -n llite.*.fast_read=0
22523         local t_slow=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
22524                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
22525                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
22526
22527         # verify that fast read is 4 times faster for cache read
22528         [ $(bc <<< "4 * $t_fast < $t_slow") -eq 1 ] ||
22529                 error_not_in_vm "fast read was not 4 times faster: " \
22530                            "$t_fast vs $t_slow"
22531
22532         echo "Test 2: verify the performance between big and small read"
22533         $LCTL set_param -n llite.*.fast_read=1
22534
22535         # 1k non-cache read
22536         cancel_lru_locks osc
22537         local t_1k=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
22538                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
22539                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
22540
22541         # 1M non-cache read
22542         cancel_lru_locks osc
22543         local t_1m=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
22544                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
22545                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
22546
22547         # verify that big IO is not 4 times faster than small IO
22548         [ $(bc <<< "4 * $t_1k >= $t_1m") -eq 1 ] ||
22549                 error_not_in_vm "bigger IO is way too fast: $t_1k vs $t_1m"
22550
22551         $LCTL set_param -n llite.*.fast_read=$fast_read_sav
22552         rm -f $DIR/$tfile
22553 }
22554 run_test 248a "fast read verification"
22555
22556 test_248b() {
22557         # Default short_io_bytes=16384, try both smaller and larger sizes.
22558         # Lustre O_DIRECT read and write needs to be a multiple of PAGE_SIZE.
22559         # 6017024 = 2^12*13*113 = 47008*128 = 11752*512 = 4096*1469 = 53248*113
22560         echo "bs=53248 count=113 normal buffered write"
22561         dd if=/dev/urandom of=$TMP/$tfile.0 bs=53248 count=113 ||
22562                 error "dd of initial data file failed"
22563         stack_trap "rm -f $DIR/$tfile.[0-3] $TMP/$tfile.[0-3]" EXIT
22564
22565         echo "bs=47008 count=128 oflag=dsync normal write $tfile.0"
22566         dd if=$TMP/$tfile.0 of=$DIR/$tfile.0 bs=47008 count=128 oflag=dsync ||
22567                 error "dd with sync normal writes failed"
22568         cmp $TMP/$tfile.0 $DIR/$tfile.0 || error "compare $DIR/$tfile.0 failed"
22569
22570         echo "bs=11752 count=512 oflag=dsync small write $tfile.1"
22571         dd if=$TMP/$tfile.0 of=$DIR/$tfile.1 bs=11752 count=512 oflag=dsync ||
22572                 error "dd with sync small writes failed"
22573         cmp $TMP/$tfile.0 $DIR/$tfile.1 || error "compare $DIR/$tfile.1 failed"
22574
22575         cancel_lru_locks osc
22576
22577         # calculate the small O_DIRECT size and count for the client PAGE_SIZE
22578         local num=$((13 * 113 / (PAGE_SIZE / 4096)))
22579         echo "bs=$PAGE_SIZE count=$num iflag=direct small read $tfile.1"
22580         dd if=$DIR/$tfile.1 of=$TMP/$tfile.1 bs=$PAGE_SIZE count=$num \
22581                 iflag=direct || error "dd with O_DIRECT small read failed"
22582         # adjust bytes checked to handle larger PAGE_SIZE for ARM/PPC
22583         cmp --bytes=$((PAGE_SIZE * num)) $TMP/$tfile.0 $TMP/$tfile.1 ||
22584                 error "compare $TMP/$tfile.1 failed"
22585
22586         local save=$($LCTL get_param -n osc.*OST000*.short_io_bytes | head -n 1)
22587         stack_trap "$LCTL set_param osc.$FSNAME-*.short_io_bytes=$save" EXIT
22588
22589         # just to see what the maximum tunable value is, and test parsing
22590         echo "test invalid parameter 2MB"
22591         $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=2M &&
22592                 error "too-large short_io_bytes allowed"
22593         echo "test maximum parameter 512KB"
22594         # if we can set a larger short_io_bytes, run test regardless of version
22595         if ! $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=512K; then
22596                 # older clients may not allow setting it this large, that's OK
22597                 [ $CLIENT_VERSION -ge $(version_code 2.13.50) ] ||
22598                         skip "Need at least client version 2.13.50"
22599                 error "medium short_io_bytes failed"
22600         fi
22601         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
22602         size=$($LCTL get_param -n osc.$FSNAME-OST0000*.short_io_bytes)
22603
22604         echo "test large parameter 64KB"
22605         $LCTL set_param osc.$FSNAME-*.short_io_bytes=65536
22606         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
22607
22608         echo "bs=47008 count=128 oflag=dsync large write $tfile.2"
22609         dd if=$TMP/$tfile.0 of=$DIR/$tfile.2 bs=47008 count=128 oflag=dsync ||
22610                 error "dd with sync large writes failed"
22611         cmp $TMP/$tfile.0 $DIR/$tfile.2 || error "compare $DIR/$tfile.2 failed"
22612
22613         # calculate the large O_DIRECT size and count for the client PAGE_SIZE
22614         local size=$(((4096 * 13 + PAGE_SIZE - 1) / PAGE_SIZE * PAGE_SIZE))
22615         num=$((113 * 4096 / PAGE_SIZE))
22616         echo "bs=$size count=$num oflag=direct large write $tfile.3"
22617         dd if=$TMP/$tfile.0 of=$DIR/$tfile.3 bs=$size count=$num oflag=direct ||
22618                 error "dd with O_DIRECT large writes failed"
22619         cmp --bytes=$((size * num)) $TMP/$tfile.0 $DIR/$tfile.3 ||
22620                 error "compare $DIR/$tfile.3 failed"
22621
22622         cancel_lru_locks osc
22623
22624         echo "bs=$size count=$num iflag=direct large read $tfile.2"
22625         dd if=$DIR/$tfile.2 of=$TMP/$tfile.2 bs=$size count=$num iflag=direct ||
22626                 error "dd with O_DIRECT large read failed"
22627         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.2 ||
22628                 error "compare $TMP/$tfile.2 failed"
22629
22630         echo "bs=$size count=$num iflag=direct large read $tfile.3"
22631         dd if=$DIR/$tfile.3 of=$TMP/$tfile.3 bs=$size count=$num iflag=direct ||
22632                 error "dd with O_DIRECT large read failed"
22633         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.3 ||
22634                 error "compare $TMP/$tfile.3 failed"
22635 }
22636 run_test 248b "test short_io read and write for both small and large sizes"
22637
22638 test_249() { # LU-7890
22639         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
22640                 skip "Need at least version 2.8.54"
22641
22642         rm -f $DIR/$tfile
22643         $LFS setstripe -c 1 $DIR/$tfile
22644         # Offset 2T == 4k * 512M
22645         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 seek=512M ||
22646                 error "dd to 2T offset failed"
22647 }
22648 run_test 249 "Write above 2T file size"
22649
22650 test_250() {
22651         [ "$(facet_fstype ost$(($($LFS getstripe -i $DIR/$tfile) + 1)))" = "zfs" ] \
22652          && skip "no 16TB file size limit on ZFS"
22653
22654         $LFS setstripe -c 1 $DIR/$tfile
22655         # ldiskfs extent file size limit is (16TB - 4KB - 1) bytes
22656         local size=$((16 * 1024 * 1024 * 1024 * 1024 - 4096 - 1))
22657         $TRUNCATE $DIR/$tfile $size || error "truncate $tfile to $size failed"
22658         dd if=/dev/zero of=$DIR/$tfile bs=10 count=1 oflag=append \
22659                 conv=notrunc,fsync && error "append succeeded"
22660         return 0
22661 }
22662 run_test 250 "Write above 16T limit"
22663
22664 test_251() {
22665         $LFS setstripe -c -1 -S 1048576 $DIR/$tfile
22666
22667         #define OBD_FAIL_LLITE_LOST_LAYOUT 0x1407
22668         #Skip once - writing the first stripe will succeed
22669         $LCTL set_param fail_loc=0xa0001407 fail_val=1
22670         $MULTIOP $DIR/$tfile o:O_RDWR:w2097152c 2>&1 | grep -q "short write" &&
22671                 error "short write happened"
22672
22673         $LCTL set_param fail_loc=0xa0001407 fail_val=1
22674         $MULTIOP $DIR/$tfile or2097152c 2>&1 | grep -q "short read" &&
22675                 error "short read happened"
22676
22677         rm -f $DIR/$tfile
22678 }
22679 run_test 251 "Handling short read and write correctly"
22680
22681 test_252() {
22682         remote_mds_nodsh && skip "remote MDS with nodsh"
22683         remote_ost_nodsh && skip "remote OST with nodsh"
22684         if [ "$ost1_FSTYPE" != ldiskfs ] || [ "$mds1_FSTYPE" != ldiskfs ]; then
22685                 skip_env "ldiskfs only test"
22686         fi
22687
22688         local tgt
22689         local dev
22690         local out
22691         local uuid
22692         local num
22693         local gen
22694
22695         # check lr_reader on OST0000
22696         tgt=ost1
22697         dev=$(facet_device $tgt)
22698         out=$(do_facet $tgt $LR_READER $dev)
22699         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
22700         echo "$out"
22701         uuid=$(echo "$out" | grep -i uuid | awk '{ print $2 }')
22702         [ "$uuid" == "$(ostuuid_from_index 0)" ] ||
22703                 error "Invalid uuid returned by $LR_READER on target $tgt"
22704         echo -e "uuid returned by $LR_READER is '$uuid'\n"
22705
22706         # check lr_reader -c on MDT0000
22707         tgt=mds1
22708         dev=$(facet_device $tgt)
22709         if ! do_facet $tgt $LR_READER -h | grep -q OPTIONS; then
22710                 skip "$LR_READER does not support additional options"
22711         fi
22712         out=$(do_facet $tgt $LR_READER -c $dev)
22713         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
22714         echo "$out"
22715         num=$(echo "$out" | grep -c "mdtlov")
22716         [ "$num" -eq $((MDSCOUNT - 1)) ] ||
22717                 error "Invalid number of mdtlov clients returned by $LR_READER"
22718         echo -e "Number of mdtlov clients returned by $LR_READER is '$num'\n"
22719
22720         # check lr_reader -cr on MDT0000
22721         out=$(do_facet $tgt $LR_READER -cr $dev)
22722         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
22723         echo "$out"
22724         echo "$out" | grep -q "^reply_data:$" ||
22725                 error "$LR_READER should have returned 'reply_data' section"
22726         num=$(echo "$out" | grep -c "client_generation")
22727         echo -e "Number of reply data returned by $LR_READER is '$num'\n"
22728 }
22729 run_test 252 "check lr_reader tool"
22730
22731 test_253() {
22732         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22733         remote_mds_nodsh && skip "remote MDS with nodsh"
22734         remote_mgs_nodsh && skip "remote MGS with nodsh"
22735
22736         local ostidx=0
22737         local rc=0
22738         local ost_name=$(ostname_from_index $ostidx)
22739
22740         # on the mdt's osc
22741         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $ost_name)
22742         do_facet $SINGLEMDS $LCTL get_param -n \
22743                 osp.$mdtosc_proc1.reserved_mb_high ||
22744                 skip  "remote MDS does not support reserved_mb_high"
22745
22746         rm -rf $DIR/$tdir
22747         wait_mds_ost_sync
22748         wait_delete_completed
22749         mkdir $DIR/$tdir
22750
22751         pool_add $TESTNAME || error "Pool creation failed"
22752         pool_add_targets $TESTNAME 0 || error "Pool add targets failed"
22753
22754         $LFS setstripe $DIR/$tdir -i $ostidx -c 1 -p $FSNAME.$TESTNAME ||
22755                 error "Setstripe failed"
22756
22757         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M count=10
22758
22759         local wms=$(ost_watermarks_set_enospc $tfile $ostidx |
22760                     grep "watermarks")
22761         stack_trap "ost_watermarks_clear_enospc $tfile $ostidx $wms" EXIT
22762
22763         local oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
22764                         osp.$mdtosc_proc1.prealloc_status)
22765         echo "prealloc_status $oa_status"
22766
22767         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1M count=1 &&
22768                 error "File creation should fail"
22769
22770         #object allocation was stopped, but we still able to append files
22771         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M seek=6 count=5 \
22772                 oflag=append || error "Append failed"
22773
22774         rm -f $DIR/$tdir/$tfile.0
22775
22776         # For this test, we want to delete the files we created to go out of
22777         # space but leave the watermark, so we remain nearly out of space
22778         ost_watermarks_enospc_delete_files $tfile $ostidx
22779
22780         wait_delete_completed
22781
22782         sleep_maxage
22783
22784         for i in $(seq 10 12); do
22785                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$i bs=1M count=1 \
22786                         2>/dev/null || error "File creation failed after rm"
22787         done
22788
22789         oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
22790                         osp.$mdtosc_proc1.prealloc_status)
22791         echo "prealloc_status $oa_status"
22792
22793         if (( oa_status != 0 )); then
22794                 error "Object allocation still disable after rm"
22795         fi
22796 }
22797 run_test 253 "Check object allocation limit"
22798
22799 test_254() {
22800         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22801         remote_mds_nodsh && skip "remote MDS with nodsh"
22802
22803         local mdt=$(facet_svc $SINGLEMDS)
22804
22805         do_facet $SINGLEMDS $LCTL get_param -n mdd.$mdt.changelog_size ||
22806                 skip "MDS does not support changelog_size"
22807
22808         local cl_user
22809
22810         changelog_register || error "changelog_register failed"
22811
22812         changelog_clear 0 || error "changelog_clear failed"
22813
22814         local size1=$(do_facet $SINGLEMDS \
22815                       $LCTL get_param -n mdd.$mdt.changelog_size)
22816         echo "Changelog size $size1"
22817
22818         rm -rf $DIR/$tdir
22819         $LFS mkdir -i 0 $DIR/$tdir
22820         # change something
22821         mkdir -p $DIR/$tdir/pics/2008/zachy
22822         touch $DIR/$tdir/pics/2008/zachy/timestamp
22823         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg
22824         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
22825         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
22826         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
22827         rm $DIR/$tdir/pics/desktop.jpg
22828
22829         local size2=$(do_facet $SINGLEMDS \
22830                       $LCTL get_param -n mdd.$mdt.changelog_size)
22831         echo "Changelog size after work $size2"
22832
22833         (( $size2 > $size1 )) ||
22834                 error "new Changelog size=$size2 less than old size=$size1"
22835 }
22836 run_test 254 "Check changelog size"
22837
22838 ladvise_no_type()
22839 {
22840         local type=$1
22841         local file=$2
22842
22843         lfs ladvise -a invalid $file 2>&1 | grep "Valid types" |
22844                 awk -F: '{print $2}' | grep $type > /dev/null
22845         if [ $? -ne 0 ]; then
22846                 return 0
22847         fi
22848         return 1
22849 }
22850
22851 ladvise_no_ioctl()
22852 {
22853         local file=$1
22854
22855         lfs ladvise -a willread $file > /dev/null 2>&1
22856         if [ $? -eq 0 ]; then
22857                 return 1
22858         fi
22859
22860         lfs ladvise -a willread $file 2>&1 |
22861                 grep "Inappropriate ioctl for device" > /dev/null
22862         if [ $? -eq 0 ]; then
22863                 return 0
22864         fi
22865         return 1
22866 }
22867
22868 percent() {
22869         bc <<<"scale=2; ($1 - $2) * 100 / $2"
22870 }
22871
22872 # run a random read IO workload
22873 # usage: random_read_iops <filename> <filesize> <iosize>
22874 random_read_iops() {
22875         local file=$1
22876         local fsize=$2
22877         local iosize=${3:-4096}
22878
22879         $READS -f $file -s $fsize -b $iosize -n $((fsize / iosize)) -t 60 |
22880                 sed -e '/^$/d' -e 's#.*s, ##' -e 's#MB/s##'
22881 }
22882
22883 drop_file_oss_cache() {
22884         local file="$1"
22885         local nodes="$2"
22886
22887         $LFS ladvise -a dontneed $file 2>/dev/null ||
22888                 do_nodes $nodes "echo 3 > /proc/sys/vm/drop_caches"
22889 }
22890
22891 ladvise_willread_performance()
22892 {
22893         local repeat=10
22894         local average_origin=0
22895         local average_cache=0
22896         local average_ladvise=0
22897
22898         for ((i = 1; i <= $repeat; i++)); do
22899                 echo "Iter $i/$repeat: reading without willread hint"
22900                 cancel_lru_locks osc
22901                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
22902                 local speed_origin=$(random_read_iops $DIR/$tfile $size)
22903                 echo "Iter $i/$repeat: uncached speed: $speed_origin"
22904                 average_origin=$(bc <<<"$average_origin + $speed_origin")
22905
22906                 cancel_lru_locks osc
22907                 local speed_cache=$(random_read_iops $DIR/$tfile $size)
22908                 echo "Iter $i/$repeat: OSS cache speed: $speed_cache"
22909                 average_cache=$(bc <<<"$average_cache + $speed_cache")
22910
22911                 cancel_lru_locks osc
22912                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
22913                 $LFS ladvise -a willread $DIR/$tfile || error "ladvise failed"
22914                 local speed_ladvise=$(random_read_iops $DIR/$tfile $size)
22915                 echo "Iter $i/$repeat: ladvise speed: $speed_ladvise"
22916                 average_ladvise=$(bc <<<"$average_ladvise + $speed_ladvise")
22917         done
22918         average_origin=$(bc <<<"scale=2; $average_origin / $repeat")
22919         average_cache=$(bc <<<"scale=2; $average_cache / $repeat")
22920         average_ladvise=$(bc <<<"scale=2; $average_ladvise / $repeat")
22921
22922         speedup_cache=$(percent $average_cache $average_origin)
22923         speedup_ladvise=$(percent $average_ladvise $average_origin)
22924
22925         echo "Average uncached read: $average_origin"
22926         echo "Average speedup with OSS cached read: " \
22927                 "$average_cache = +$speedup_cache%"
22928         echo "Average speedup with ladvise willread: " \
22929                 "$average_ladvise = +$speedup_ladvise%"
22930
22931         local lowest_speedup=20
22932         if (( ${average_cache%.*} < $lowest_speedup )); then
22933                 echo "Speedup with OSS cached read less than $lowest_speedup%,"\
22934                      " got $average_cache%. Skipping ladvise willread check."
22935                 return 0
22936         fi
22937
22938         # the test won't work on ZFS until it supports 'ladvise dontneed', but
22939         # it is still good to run until then to exercise 'ladvise willread'
22940         ! $LFS ladvise -a dontneed $DIR/$tfile &&
22941                 [ "$ost1_FSTYPE" = "zfs" ] &&
22942                 echo "osd-zfs does not support dontneed or drop_caches" &&
22943                 return 0
22944
22945         lowest_speedup=$(bc <<<"scale=2; $average_cache / 2")
22946         (( ${average_ladvise%.*} > ${lowest_speedup%.*} )) ||
22947                 error_not_in_vm "Speedup with willread is less than " \
22948                         "$lowest_speedup%, got $average_ladvise%"
22949 }
22950
22951 test_255a() {
22952         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
22953                 skip "lustre < 2.8.54 does not support ladvise "
22954         remote_ost_nodsh && skip "remote OST with nodsh"
22955
22956         stack_trap "rm -f $DIR/$tfile"
22957         lfs setstripe -c -1 -i 0 $DIR/$tfile || error "$tfile failed"
22958
22959         ladvise_no_type willread $DIR/$tfile &&
22960                 skip "willread ladvise is not supported"
22961
22962         ladvise_no_ioctl $DIR/$tfile &&
22963                 skip "ladvise ioctl is not supported"
22964
22965         local size_mb=100
22966         local size=$((size_mb * 1048576))
22967         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
22968                 error "dd to $DIR/$tfile failed"
22969
22970         lfs ladvise -a willread $DIR/$tfile ||
22971                 error "Ladvise failed with no range argument"
22972
22973         lfs ladvise -a willread -s 0 $DIR/$tfile ||
22974                 error "Ladvise failed with no -l or -e argument"
22975
22976         lfs ladvise -a willread -e 1 $DIR/$tfile ||
22977                 error "Ladvise failed with only -e argument"
22978
22979         lfs ladvise -a willread -l 1 $DIR/$tfile ||
22980                 error "Ladvise failed with only -l argument"
22981
22982         lfs ladvise -a willread -s 2 -e 1 $DIR/$tfile &&
22983                 error "End offset should not be smaller than start offset"
22984
22985         lfs ladvise -a willread -s 2 -e 2 $DIR/$tfile &&
22986                 error "End offset should not be equal to start offset"
22987
22988         lfs ladvise -a willread -s $size -l 1 $DIR/$tfile ||
22989                 error "Ladvise failed with overflowing -s argument"
22990
22991         lfs ladvise -a willread -s 1 -e $((size + 1)) $DIR/$tfile ||
22992                 error "Ladvise failed with overflowing -e argument"
22993
22994         lfs ladvise -a willread -s 1 -l $size $DIR/$tfile ||
22995                 error "Ladvise failed with overflowing -l argument"
22996
22997         lfs ladvise -a willread -l 1 -e 2 $DIR/$tfile &&
22998                 error "Ladvise succeeded with conflicting -l and -e arguments"
22999
23000         echo "Synchronous ladvise should wait"
23001         local delay=4
23002 #define OBD_FAIL_OST_LADVISE_PAUSE       0x237
23003         do_nodes $(comma_list $(osts_nodes)) \
23004                 $LCTL set_param fail_val=$delay fail_loc=0x237
23005
23006         local start_ts=$SECONDS
23007         lfs ladvise -a willread $DIR/$tfile ||
23008                 error "Ladvise failed with no range argument"
23009         local end_ts=$SECONDS
23010         local inteval_ts=$((end_ts - start_ts))
23011
23012         if [ $inteval_ts -lt $(($delay - 1)) ]; then
23013                 error "Synchronous advice didn't wait reply"
23014         fi
23015
23016         echo "Asynchronous ladvise shouldn't wait"
23017         local start_ts=$SECONDS
23018         lfs ladvise -a willread -b $DIR/$tfile ||
23019                 error "Ladvise failed with no range argument"
23020         local end_ts=$SECONDS
23021         local inteval_ts=$((end_ts - start_ts))
23022
23023         if [ $inteval_ts -gt $(($delay / 2)) ]; then
23024                 error "Asynchronous advice blocked"
23025         fi
23026
23027         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param fail_loc=0
23028         ladvise_willread_performance
23029 }
23030 run_test 255a "check 'lfs ladvise -a willread'"
23031
23032 facet_meminfo() {
23033         local facet=$1
23034         local info=$2
23035
23036         do_facet $facet "cat /proc/meminfo | grep ^${info}:" | awk '{print $2}'
23037 }
23038
23039 test_255b() {
23040         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
23041                 skip "lustre < 2.8.54 does not support ladvise "
23042         remote_ost_nodsh && skip "remote OST with nodsh"
23043
23044         stack_trap "rm -f $DIR/$tfile"
23045         lfs setstripe -c 1 -i 0 $DIR/$tfile
23046
23047         ladvise_no_type dontneed $DIR/$tfile &&
23048                 skip "dontneed ladvise is not supported"
23049
23050         ladvise_no_ioctl $DIR/$tfile &&
23051                 skip "ladvise ioctl is not supported"
23052
23053         ! $LFS ladvise -a dontneed $DIR/$tfile &&
23054                 [ "$ost1_FSTYPE" = "zfs" ] &&
23055                 skip "zfs-osd does not support 'ladvise dontneed'"
23056
23057         local size_mb=100
23058         local size=$((size_mb * 1048576))
23059         # In order to prevent disturbance of other processes, only check 3/4
23060         # of the memory usage
23061         local kibibytes=$((size_mb * 1024 * 3 / 4))
23062
23063         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
23064                 error "dd to $DIR/$tfile failed"
23065
23066         #force write to complete before dropping OST cache & checking memory
23067         sync
23068
23069         local total=$(facet_meminfo ost1 MemTotal)
23070         echo "Total memory: $total KiB"
23071
23072         do_facet ost1 "sync && echo 3 > /proc/sys/vm/drop_caches"
23073         local before_read=$(facet_meminfo ost1 Cached)
23074         echo "Cache used before read: $before_read KiB"
23075
23076         lfs ladvise -a willread $DIR/$tfile ||
23077                 error "Ladvise willread failed"
23078         local after_read=$(facet_meminfo ost1 Cached)
23079         echo "Cache used after read: $after_read KiB"
23080
23081         lfs ladvise -a dontneed $DIR/$tfile ||
23082                 error "Ladvise dontneed again failed"
23083         local no_read=$(facet_meminfo ost1 Cached)
23084         echo "Cache used after dontneed ladvise: $no_read KiB"
23085
23086         if [ $total -lt $((before_read + kibibytes)) ]; then
23087                 echo "Memory is too small, abort checking"
23088                 return 0
23089         fi
23090
23091         if [ $((before_read + kibibytes)) -gt $after_read ]; then
23092                 error "Ladvise willread should use more memory" \
23093                         "than $kibibytes KiB"
23094         fi
23095
23096         if [ $((no_read + kibibytes)) -gt $after_read ]; then
23097                 error "Ladvise dontneed should release more memory" \
23098                         "than $kibibytes KiB"
23099         fi
23100 }
23101 run_test 255b "check 'lfs ladvise -a dontneed'"
23102
23103 test_255c() {
23104         [ $OST1_VERSION -lt $(version_code 2.10.50) ] &&
23105                 skip "lustre < 2.10.50 does not support lockahead"
23106
23107         local ost1_imp=$(get_osc_import_name client ost1)
23108         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
23109                          cut -d'.' -f2)
23110         local count
23111         local new_count
23112         local difference
23113         local i
23114         local rc
23115
23116         test_mkdir -p $DIR/$tdir
23117         $LFS setstripe -i 0 -c 1 $DIR/$tdir
23118
23119         #test 10 returns only success/failure
23120         i=10
23121         lockahead_test -d $DIR/$tdir -t $i -f $tfile
23122         rc=$?
23123         if [ $rc -eq 255 ]; then
23124                 error "Ladvise test${i} failed, ${rc}"
23125         fi
23126
23127         #test 11 counts lock enqueue requests, all others count new locks
23128         i=11
23129         count=$(do_facet ost1 \
23130                 $LCTL get_param -n ost.OSS.ost.stats)
23131         count=$(echo "$count" | grep ldlm_extent_enqueue | awk '{ print $2 }')
23132
23133         lockahead_test -d $DIR/$tdir -t $i -f $tfile
23134         rc=$?
23135         if [ $rc -eq 255 ]; then
23136                 error "Ladvise test${i} failed, ${rc}"
23137         fi
23138
23139         new_count=$(do_facet ost1 \
23140                 $LCTL get_param -n ost.OSS.ost.stats)
23141         new_count=$(echo "$new_count" | grep ldlm_extent_enqueue | \
23142                    awk '{ print $2 }')
23143
23144         difference="$((new_count - count))"
23145         if [ $difference -ne $rc ]; then
23146                 error "Ladvise test${i}, bad enqueue count, returned " \
23147                       "${rc}, actual ${difference}"
23148         fi
23149
23150         for i in $(seq 12 21); do
23151                 # If we do not do this, we run the risk of having too many
23152                 # locks and starting lock cancellation while we are checking
23153                 # lock counts.
23154                 cancel_lru_locks osc
23155
23156                 count=$($LCTL get_param -n \
23157                        ldlm.namespaces.$imp_name.lock_unused_count)
23158
23159                 lockahead_test -d $DIR/$tdir -t $i -f $tfile
23160                 rc=$?
23161                 if [ $rc -eq 255 ]; then
23162                         error "Ladvise test ${i} failed, ${rc}"
23163                 fi
23164
23165                 new_count=$($LCTL get_param -n \
23166                        ldlm.namespaces.$imp_name.lock_unused_count)
23167                 difference="$((new_count - count))"
23168
23169                 # Test 15 output is divided by 100 to map down to valid return
23170                 if [ $i -eq 15 ]; then
23171                         rc="$((rc * 100))"
23172                 fi
23173
23174                 if [ $difference -ne $rc ]; then
23175                         error "Ladvise test ${i}, bad lock count, returned " \
23176                               "${rc}, actual ${difference}"
23177                 fi
23178         done
23179
23180         #test 22 returns only success/failure
23181         i=22
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 run_test 255c "suite of ladvise lockahead tests"
23189
23190 test_256() {
23191         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23192         remote_mds_nodsh && skip "remote MDS with nodsh"
23193         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
23194         changelog_users $SINGLEMDS | grep "^cl" &&
23195                 skip "active changelog user"
23196
23197         local cl_user
23198         local cat_sl
23199         local mdt_dev
23200
23201         mdt_dev=$(facet_device $SINGLEMDS)
23202         echo $mdt_dev
23203
23204         changelog_register || error "changelog_register failed"
23205
23206         rm -rf $DIR/$tdir
23207         mkdir_on_mdt -i$(($(facet_number $SINGLEMDS) - 1)) $DIR/$tdir
23208
23209         changelog_clear 0 || error "changelog_clear failed"
23210
23211         # change something
23212         touch $DIR/$tdir/{1..10}
23213
23214         # stop the MDT
23215         stop $SINGLEMDS || error "Fail to stop MDT"
23216
23217         # remount the MDT
23218         start $SINGLEMDS $(facet_device $SINGLEMDS) $MDS_MOUNT_OPTS ||
23219                 error "Fail to start MDT"
23220
23221         #after mount new plainllog is used
23222         touch $DIR/$tdir/{11..19}
23223         local tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
23224         stack_trap "rm -f $tmpfile"
23225         cat_sl=$(do_facet $SINGLEMDS "sync; \
23226                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
23227                  llog_reader $tmpfile | grep -c type=1064553b")
23228         do_facet $SINGLEMDS llog_reader $tmpfile
23229
23230         [ $cat_sl != 2 ] && error "Changelog catalog has $cat_sl != 2 slots"
23231
23232         changelog_clear 0 || error "changelog_clear failed"
23233
23234         cat_sl=$(do_facet $SINGLEMDS "sync; \
23235                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
23236                  llog_reader $tmpfile | grep -c type=1064553b")
23237
23238         if (( cat_sl == 2 )); then
23239                 error "Empty plain llog was not deleted from changelog catalog"
23240         elif (( cat_sl != 1 )); then
23241                 error "Active plain llog shouldn't be deleted from catalog"
23242         fi
23243 }
23244 run_test 256 "Check llog delete for empty and not full state"
23245
23246 test_257() {
23247         remote_mds_nodsh && skip "remote MDS with nodsh"
23248         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
23249                 skip "Need MDS version at least 2.8.55"
23250
23251         test_mkdir $DIR/$tdir
23252
23253         setfattr -n trusted.name1 -v value1 $DIR/$tdir ||
23254                 error "setfattr -n trusted.name1=value1 $DIR/$tdir failed"
23255         stat $DIR/$tdir
23256
23257 #define OBD_FAIL_MDS_XATTR_REP                  0x161
23258         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
23259         local facet=mds$((mdtidx + 1))
23260         set_nodes_failloc $(facet_active_host $facet) 0x80000161
23261         getfattr -n trusted.name1 $DIR/$tdir 2> /dev/null
23262
23263         stop $facet || error "stop MDS failed"
23264         start $facet $(mdsdevname $((mdtidx + 1))) $MDS_MOUNT_OPTS ||
23265                 error "start MDS fail"
23266         wait_recovery_complete $facet
23267 }
23268 run_test 257 "xattr locks are not lost"
23269
23270 # Verify we take the i_mutex when security requires it
23271 test_258a() {
23272 #define OBD_FAIL_IMUTEX_SEC 0x141c
23273         $LCTL set_param fail_loc=0x141c
23274         touch $DIR/$tfile
23275         chmod u+s $DIR/$tfile
23276         chmod a+rwx $DIR/$tfile
23277         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
23278         RC=$?
23279         if [ $RC -ne 0 ]; then
23280                 error "error, failed to take i_mutex, rc=$?"
23281         fi
23282         rm -f $DIR/$tfile
23283 }
23284 run_test 258a "verify i_mutex security behavior when suid attributes is set"
23285
23286 # Verify we do NOT take the i_mutex in the normal case
23287 test_258b() {
23288 #define OBD_FAIL_IMUTEX_NOSEC 0x141d
23289         $LCTL set_param fail_loc=0x141d
23290         touch $DIR/$tfile
23291         chmod a+rwx $DIR
23292         chmod a+rw $DIR/$tfile
23293         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
23294         RC=$?
23295         if [ $RC -ne 0 ]; then
23296                 error "error, took i_mutex unnecessarily, rc=$?"
23297         fi
23298         rm -f $DIR/$tfile
23299
23300 }
23301 run_test 258b "verify i_mutex security behavior"
23302
23303 test_259() {
23304         local file=$DIR/$tfile
23305         local before
23306         local after
23307
23308         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
23309
23310         stack_trap "rm -f $file" EXIT
23311
23312         wait_delete_completed
23313         before=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
23314         echo "before: $before"
23315
23316         $LFS setstripe -i 0 -c 1 $file
23317         dd if=/dev/zero of=$file bs=1M count=10 || error "couldn't write"
23318         sync_all_data
23319         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
23320         echo "after write: $after"
23321
23322 #define OBD_FAIL_OSD_FAIL_AT_TRUNCATE          0x2301
23323         do_facet ost1 $LCTL set_param fail_loc=0x2301
23324         $TRUNCATE $file 0
23325         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
23326         echo "after truncate: $after"
23327
23328         stop ost1
23329         do_facet ost1 $LCTL set_param fail_loc=0
23330         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
23331         sleep 2
23332         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
23333         echo "after restart: $after"
23334         [ $((after - before)) -ge $(fs_log_size ost1) ] &&
23335                 error "missing truncate?"
23336
23337         return 0
23338 }
23339 run_test 259 "crash at delayed truncate"
23340
23341 test_260() {
23342 #define OBD_FAIL_MDC_CLOSE               0x806
23343         $LCTL set_param fail_loc=0x80000806
23344         touch $DIR/$tfile
23345
23346 }
23347 run_test 260 "Check mdc_close fail"
23348
23349 ### Data-on-MDT sanity tests ###
23350 test_270a() {
23351         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23352                 skip "Need MDS version at least 2.10.55 for DoM"
23353
23354         # create DoM file
23355         local dom=$DIR/$tdir/dom_file
23356         local tmp=$DIR/$tdir/tmp_file
23357
23358         mkdir_on_mdt0 $DIR/$tdir
23359
23360         # basic checks for DoM component creation
23361         $LFS setstripe -E 1024K -E 2048K -L mdt $dom 2>/dev/null &&
23362                 error "Can set MDT layout to non-first entry"
23363
23364         $LFS setstripe -E 1024K -L mdt -E 2048K -L mdt $dom 2>/dev/null &&
23365                 error "Can define multiple entries as MDT layout"
23366
23367         $LFS setstripe -E 1M -L mdt $dom || error "Can't create DoM layout"
23368
23369         [ $($LFS getstripe -L $dom) == "mdt" ] || error "bad pattern"
23370         [ $($LFS getstripe -c $dom) == 0 ] || error "bad stripe count"
23371         [ $($LFS getstripe -S $dom) == 1048576 ] || error "bad stripe size"
23372
23373         local mdtidx=$($LFS getstripe -m $dom)
23374         local mdtname=MDT$(printf %04x $mdtidx)
23375         local facet=mds$((mdtidx + 1))
23376         local space_check=1
23377
23378         # Skip free space checks with ZFS
23379         [ "$(facet_fstype $facet)" == "zfs" ] && space_check=0
23380
23381         # write
23382         sync
23383         local size_tmp=$((65536 * 3))
23384         local mdtfree1=$(do_facet $facet \
23385                          lctl get_param -n osd*.*$mdtname.kbytesfree)
23386
23387         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
23388         # check also direct IO along write
23389         # IO size must be a multiple of PAGE_SIZE on all platforms (ARM=64KB)
23390         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
23391         sync
23392         cmp $tmp $dom || error "file data is different"
23393         [ $(stat -c%s $dom) == $size_tmp ] ||
23394                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
23395         if [ $space_check == 1 ]; then
23396                 local mdtfree2=$(do_facet $facet \
23397                                  lctl get_param -n osd*.*$mdtname.kbytesfree)
23398
23399                 # increase in usage from by $size_tmp
23400                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
23401                         error "MDT free space wrong after write: " \
23402                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
23403         fi
23404
23405         # truncate
23406         local size_dom=10000
23407
23408         $TRUNCATE $dom $size_dom
23409         [ $(stat -c%s $dom) == $size_dom ] ||
23410                 error "bad size after truncate: $(stat -c%s $dom) != $size_dom"
23411         if [ $space_check == 1 ]; then
23412                 mdtfree1=$(do_facet $facet \
23413                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23414                 # decrease in usage from $size_tmp to new $size_dom
23415                 [ $(($mdtfree1 - $mdtfree2)) -ge \
23416                   $(((size_tmp - size_dom) / 1024)) ] ||
23417                         error "MDT free space is wrong after truncate: " \
23418                               "$mdtfree1 >= $mdtfree2 + ($size_tmp - $size_dom) / 1024"
23419         fi
23420
23421         # append
23422         cat $tmp >> $dom
23423         sync
23424         size_dom=$((size_dom + size_tmp))
23425         [ $(stat -c%s $dom) == $size_dom ] ||
23426                 error "bad size after append: $(stat -c%s $dom) != $size_dom"
23427         if [ $space_check == 1 ]; then
23428                 mdtfree2=$(do_facet $facet \
23429                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23430                 # increase in usage by $size_tmp from previous
23431                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
23432                         error "MDT free space is wrong after append: " \
23433                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
23434         fi
23435
23436         # delete
23437         rm $dom
23438         if [ $space_check == 1 ]; then
23439                 mdtfree1=$(do_facet $facet \
23440                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23441                 # decrease in usage by $size_dom from previous
23442                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_dom / 1024)) ] ||
23443                         error "MDT free space is wrong after removal: " \
23444                               "$mdtfree1 >= $mdtfree2 + $size_dom/1024"
23445         fi
23446
23447         # combined striping
23448         $LFS setstripe -E 1024K -L mdt -E EOF $dom ||
23449                 error "Can't create DoM + OST striping"
23450
23451         size_tmp=2031616 # must be a multiple of PAGE_SIZE=65536 on ARM
23452         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
23453         # check also direct IO along write
23454         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
23455         sync
23456         cmp $tmp $dom || error "file data is different"
23457         [ $(stat -c%s $dom) == $size_tmp ] ||
23458                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
23459         rm $dom $tmp
23460
23461         return 0
23462 }
23463 run_test 270a "DoM: basic functionality tests"
23464
23465 test_270b() {
23466         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23467                 skip "Need MDS version at least 2.10.55"
23468
23469         local dom=$DIR/$tdir/dom_file
23470         local max_size=1048576
23471
23472         mkdir -p $DIR/$tdir
23473         $LFS setstripe -E $max_size -L mdt $dom
23474
23475         # truncate over the limit
23476         $TRUNCATE $dom $(($max_size + 1)) &&
23477                 error "successful truncate over the maximum size"
23478         # write over the limit
23479         dd if=/dev/zero of=$dom bs=$max_size seek=1 count=1 &&
23480                 error "successful write over the maximum size"
23481         # append over the limit
23482         dd if=/dev/zero of=$dom bs=$(($max_size - 3)) count=1
23483         echo "12345" >> $dom && error "successful append over the maximum size"
23484         rm $dom
23485
23486         return 0
23487 }
23488 run_test 270b "DoM: maximum size overflow checks for DoM-only file"
23489
23490 test_270c() {
23491         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23492                 skip "Need MDS version at least 2.10.55"
23493
23494         mkdir -p $DIR/$tdir
23495         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
23496
23497         # check files inherit DoM EA
23498         touch $DIR/$tdir/first
23499         [ $($LFS getstripe -L $DIR/$tdir/first) == "mdt" ] ||
23500                 error "bad pattern"
23501         [ $($LFS getstripe -c $DIR/$tdir/first) == 0 ] ||
23502                 error "bad stripe count"
23503         [ $($LFS getstripe -S $DIR/$tdir/first) == 1048576 ] ||
23504                 error "bad stripe size"
23505
23506         # check directory inherits DoM EA and uses it as default
23507         mkdir $DIR/$tdir/subdir
23508         touch $DIR/$tdir/subdir/second
23509         [ $($LFS getstripe -L $DIR/$tdir/subdir/second) == "mdt" ] ||
23510                 error "bad pattern in sub-directory"
23511         [ $($LFS getstripe -c $DIR/$tdir/subdir/second) == 0 ] ||
23512                 error "bad stripe count in sub-directory"
23513         [ $($LFS getstripe -S $DIR/$tdir/subdir/second) == 1048576 ] ||
23514                 error "bad stripe size in sub-directory"
23515         return 0
23516 }
23517 run_test 270c "DoM: DoM EA inheritance tests"
23518
23519 test_270d() {
23520         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23521                 skip "Need MDS version at least 2.10.55"
23522
23523         mkdir -p $DIR/$tdir
23524         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
23525
23526         # inherit default DoM striping
23527         mkdir $DIR/$tdir/subdir
23528         touch $DIR/$tdir/subdir/f1
23529
23530         # change default directory striping
23531         $LFS setstripe -c 1 $DIR/$tdir/subdir
23532         touch $DIR/$tdir/subdir/f2
23533         [ $($LFS getstripe -c $DIR/$tdir/subdir/f2) == 1 ] ||
23534                 error "wrong default striping in file 2"
23535         [ $($LFS getstripe -L $DIR/$tdir/subdir/f2) == "raid0" ] ||
23536                 error "bad pattern in file 2"
23537         return 0
23538 }
23539 run_test 270d "DoM: change striping from DoM to RAID0"
23540
23541 test_270e() {
23542         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23543                 skip "Need MDS version at least 2.10.55"
23544
23545         mkdir -p $DIR/$tdir/dom
23546         mkdir -p $DIR/$tdir/norm
23547         DOMFILES=20
23548         NORMFILES=10
23549         $LFS setstripe -E 1M -L mdt $DIR/$tdir/dom
23550         $LFS setstripe -i 0 -S 2M $DIR/$tdir/norm
23551
23552         createmany -o $DIR/$tdir/dom/dom- $DOMFILES
23553         createmany -o $DIR/$tdir/norm/norm- $NORMFILES
23554
23555         # find DoM files by layout
23556         NUM=$($LFS find -L mdt -type f $DIR/$tdir 2>/dev/null | wc -l)
23557         [ $NUM -eq  $DOMFILES ] ||
23558                 error "lfs find -L: found $NUM, expected $DOMFILES"
23559         echo "Test 1: lfs find 20 DOM files by layout: OK"
23560
23561         # there should be 1 dir with default DOM striping
23562         NUM=$($LFS find -L mdt -type d $DIR/$tdir 2>/dev/null | wc -l)
23563         [ $NUM -eq  1 ] ||
23564                 error "lfs find -L: found $NUM, expected 1 dir"
23565         echo "Test 2: lfs find 1 DOM dir by layout: OK"
23566
23567         # find DoM files by stripe size
23568         NUM=$($LFS find -S -1200K -type f $DIR/$tdir 2>/dev/null | wc -l)
23569         [ $NUM -eq  $DOMFILES ] ||
23570                 error "lfs find -S: found $NUM, expected $DOMFILES"
23571         echo "Test 4: lfs find 20 DOM files by stripe size: OK"
23572
23573         # find files by stripe offset except DoM files
23574         NUM=$($LFS find -i 0 -type f $DIR/$tdir 2>/dev/null | wc -l)
23575         [ $NUM -eq  $NORMFILES ] ||
23576                 error "lfs find -i: found $NUM, expected $NORMFILES"
23577         echo "Test 5: lfs find no DOM files by stripe index: OK"
23578         return 0
23579 }
23580 run_test 270e "DoM: lfs find with DoM files test"
23581
23582 test_270f() {
23583         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23584                 skip "Need MDS version at least 2.10.55"
23585
23586         local mdtname=${FSNAME}-MDT0000-mdtlov
23587         local dom=$DIR/$tdir/dom_file
23588         local dom_limit_saved=$(do_facet mds1 $LCTL get_param -n \
23589                                                 lod.$mdtname.dom_stripesize)
23590         local dom_limit=131072
23591
23592         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=$dom_limit
23593         local dom_current=$(do_facet mds1 $LCTL get_param -n \
23594                                                 lod.$mdtname.dom_stripesize)
23595         [ ${dom_limit} -eq ${dom_current} ] ||
23596                 error "Cannot change per-MDT DoM stripe limit to $dom_limit"
23597
23598         $LFS mkdir -i 0 -c 1 $DIR/$tdir
23599         $LFS setstripe -d $DIR/$tdir
23600         $LFS setstripe -E $dom_limit -L mdt $DIR/$tdir ||
23601                 error "Can't set directory default striping"
23602
23603         # exceed maximum stripe size
23604         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
23605                 error "Can't create file with $((dom_limit * 2)) DoM stripe"
23606         [ $($LFS getstripe -S $dom) -eq $((dom_limit * 2)) ] &&
23607                 error "Able to create DoM component size more than LOD limit"
23608
23609         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
23610         dom_current=$(do_facet mds1 $LCTL get_param -n \
23611                                                 lod.$mdtname.dom_stripesize)
23612         [ 0 -eq ${dom_current} ] ||
23613                 error "Can't set zero DoM stripe limit"
23614         rm $dom
23615
23616         # attempt to create DoM file on server with disabled DoM should
23617         # remove DoM entry from layout and be succeed
23618         $LFS setstripe -E $dom_limit -L mdt -E -1 $dom ||
23619                 error "Can't create DoM file (DoM is disabled)"
23620         [ $($LFS getstripe -L $dom) == "mdt" ] &&
23621                 error "File has DoM component while DoM is disabled"
23622         rm $dom
23623
23624         # attempt to create DoM file with only DoM stripe should return error
23625         $LFS setstripe -E $dom_limit -L mdt $dom &&
23626                 error "Able to create DoM-only file while DoM is disabled"
23627
23628         # too low values to be aligned with smallest stripe size 64K
23629         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=30000
23630         dom_current=$(do_facet mds1 $LCTL get_param -n \
23631                                                 lod.$mdtname.dom_stripesize)
23632         [ 30000 -eq ${dom_current} ] &&
23633                 error "Can set too small DoM stripe limit"
23634
23635         # 64K is a minimal stripe size in Lustre, expect limit of that size
23636         [ 65536 -eq ${dom_current} ] ||
23637                 error "Limit is not set to 64K but ${dom_current}"
23638
23639         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=2147483648
23640         dom_current=$(do_facet mds1 $LCTL get_param -n \
23641                                                 lod.$mdtname.dom_stripesize)
23642         echo $dom_current
23643         [ 2147483648 -eq ${dom_current} ] &&
23644                 error "Can set too large DoM stripe limit"
23645
23646         do_facet mds1 $LCTL set_param -n \
23647                                 lod.$mdtname.dom_stripesize=$((dom_limit * 2))
23648         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
23649                 error "Can't create DoM component size after limit change"
23650         do_facet mds1 $LCTL set_param -n \
23651                                 lod.$mdtname.dom_stripesize=$((dom_limit / 2))
23652         $LFS setstripe -E $dom_limit -L mdt ${dom}_big ||
23653                 error "Can't create DoM file after limit decrease"
23654         [ $($LFS getstripe -S ${dom}_big) -eq $((dom_limit / 2)) ] ||
23655                 error "Can create big DoM component after limit decrease"
23656         touch ${dom}_def ||
23657                 error "Can't create file with old default layout"
23658
23659         do_facet mds1 $LCTL set_param -n lod.*.dom_stripesize=$dom_limit_saved
23660         return 0
23661 }
23662 run_test 270f "DoM: maximum DoM stripe size checks"
23663
23664 test_270g() {
23665         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
23666                 skip "Need MDS version at least 2.13.52"
23667         local dom=$DIR/$tdir/$tfile
23668
23669         $LFS mkdir -i 0 -c 1 $DIR/$tdir
23670         local lodname=${FSNAME}-MDT0000-mdtlov
23671
23672         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
23673         save_lustre_params mds1 "lod.${lodname}.dom_stripesize_max_kb" > $save
23674         save_lustre_params mds1 "lod.${lodname}.dom_threshold_free_mb" >> $save
23675         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
23676
23677         local dom_limit=1024
23678         local dom_threshold="50%"
23679
23680         $LFS setstripe -d $DIR/$tdir
23681         $LFS setstripe -E ${dom_limit}K -L mdt $DIR/$tdir ||
23682                 error "Can't set directory default striping"
23683
23684         do_facet mds1 $LCTL set_param -n \
23685                                 lod.${lodname}.dom_stripesize_max_kb=$dom_limit
23686         # set 0 threshold and create DOM file to change tunable stripesize
23687         do_facet mds1 $LCTL set_param -n lod.${lodname}.dom_threshold_free_mb=0
23688         $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
23689                 error "Failed to create $dom file"
23690         # now tunable dom_cur_stripesize should reach maximum
23691         local dom_current=$(do_facet mds1 $LCTL get_param -n \
23692                                         lod.${lodname}.dom_stripesize_cur_kb)
23693         [[ $dom_current == $dom_limit ]] ||
23694                 error "Current DOM stripesize is not maximum"
23695         rm $dom
23696
23697         # set threshold for further tests
23698         do_facet mds1 $LCTL set_param -n \
23699                         lod.${lodname}.dom_threshold_free_mb=$dom_threshold
23700         echo "DOM threshold is $dom_threshold free space"
23701         local dom_def
23702         local dom_set
23703         # Spoof bfree to exceed threshold
23704         #define OBD_FAIL_MDS_STATFS_SPOOF   0x168
23705         do_facet mds1 $LCTL set_param -n fail_loc=0x0168
23706         for spfree in 40 20 0 15 30 55; do
23707                 do_facet mds1 $LCTL set_param -n fail_val=$spfree
23708                 $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
23709                         error "Failed to create $dom file"
23710                 dom_def=$(do_facet mds1 $LCTL get_param -n \
23711                                         lod.${lodname}.dom_stripesize_cur_kb)
23712                 echo "Free space: ${spfree}%, default DOM stripe: ${dom_def}K"
23713                 [[ $dom_def != $dom_current ]] ||
23714                         error "Default stripe size was not changed"
23715                 if (( spfree > 0 )) ; then
23716                         dom_set=$($LFS getstripe -S $dom)
23717                         (( dom_set == dom_def * 1024 )) ||
23718                                 error "DOM component size is still old"
23719                 else
23720                         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
23721                                 error "DoM component is set with no free space"
23722                 fi
23723                 rm $dom
23724                 dom_current=$dom_def
23725         done
23726 }
23727 run_test 270g "DoM: default DoM stripe size depends on free space"
23728
23729 test_270h() {
23730         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
23731                 skip "Need MDS version at least 2.13.53"
23732
23733         local mdtname=${FSNAME}-MDT0000-mdtlov
23734         local dom=$DIR/$tdir/$tfile
23735         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
23736
23737         save_lustre_params mds1 "lod.*.dom_stripesize" > $save
23738         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
23739
23740         $LFS mkdir -i 0 -c 1 $DIR/$tdir
23741         $LFS setstripe -E 1M -c1  -E -1 -c2 ${dom}_1 ||
23742                 error "can't create OST file"
23743         # mirrored file with DOM entry in the second mirror
23744         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 ${dom}_1 ||
23745                 error "can't create mirror with DoM component"
23746
23747         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
23748
23749         # DOM component in the middle and has other enries in the same mirror,
23750         # should succeed but lost DoM component
23751         $LFS setstripe --copy=${dom}_1 $dom ||
23752                 error "Can't create file from OST|DOM mirror layout"
23753         # check new file has no DoM layout after all
23754         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
23755                 error "File has DoM component while DoM is disabled"
23756 }
23757 run_test 270h "DoM: DoM stripe removal when disabled on server"
23758
23759 test_270i() {
23760         (( $MDS1_VERSION >= $(version_code 2.14.54) )) ||
23761                 skip "Need MDS version at least 2.14.54"
23762
23763         mkdir $DIR/$tdir
23764         # DoM with plain layout
23765         $LFS setstripe -L mdt -S 128k -c -1 $DIR/$tdir &&
23766                 error "default plain layout with DoM must fail"
23767         $LFS setstripe -L mdt -S 128k -c -1 $DIR/$tdir/$tfile &&
23768                 error "setstripe plain file layout with DoM must fail"
23769         $LFS setstripe -E 1M -L mdt -S 128k -c -1 -E eof $DIR/$tdir &&
23770                 error "default DoM layout with bad striping must fail"
23771         $LFS setstripe -E 1M -L mdt -S 128k -c -1 -E eof $DIR/$tdir/$tfile &&
23772                 error "setstripe to DoM layout with bad striping must fail"
23773         return 0
23774 }
23775 run_test 270i "DoM: setting invalid DoM striping should fail"
23776
23777 test_271a() {
23778         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23779                 skip "Need MDS version at least 2.10.55"
23780
23781         local dom=$DIR/$tdir/dom
23782
23783         mkdir -p $DIR/$tdir
23784
23785         $LFS setstripe -E 1024K -L mdt $dom
23786
23787         lctl set_param -n mdc.*.stats=clear
23788         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
23789         cat $dom > /dev/null
23790         local reads=$(lctl get_param -n mdc.*.stats | grep -c ost_read)
23791         [ $reads -eq 0 ] || error "Unexpected $reads READ RPCs"
23792         ls $dom
23793         rm -f $dom
23794 }
23795 run_test 271a "DoM: data is cached for read after write"
23796
23797 test_271b() {
23798         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23799                 skip "Need MDS version at least 2.10.55"
23800
23801         local dom=$DIR/$tdir/dom
23802
23803         mkdir -p $DIR/$tdir
23804
23805         $LFS setstripe -E 1024K -L mdt -E EOF $dom
23806
23807         lctl set_param -n mdc.*.stats=clear
23808         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
23809         cancel_lru_locks mdc
23810         $CHECKSTAT -t file -s 4096 $dom || error "stat #1 fails"
23811         # second stat to check size is cached on client
23812         $CHECKSTAT -t file -s 4096 $dom || error "stat #2 fails"
23813         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
23814         [ $gls -eq 0 ] || error "Unexpected $gls glimpse RPCs"
23815         rm -f $dom
23816 }
23817 run_test 271b "DoM: no glimpse RPC for stat (DoM only file)"
23818
23819 test_271ba() {
23820         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23821                 skip "Need MDS version at least 2.10.55"
23822
23823         local dom=$DIR/$tdir/dom
23824
23825         mkdir -p $DIR/$tdir
23826
23827         $LFS setstripe -E 1024K -L mdt -E EOF $dom
23828
23829         lctl set_param -n mdc.*.stats=clear
23830         lctl set_param -n osc.*.stats=clear
23831         dd if=/dev/zero of=$dom bs=2048K count=1 || return 1
23832         cancel_lru_locks mdc
23833         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
23834         # second stat to check size is cached on client
23835         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
23836         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
23837         [ $gls == 0 ] || error "Unexpected $gls glimpse RPCs"
23838         local gls=$(lctl get_param -n osc.*.stats | grep -c ldlm_glimpse)
23839         [ $gls == 0 ] || error "Unexpected $gls OSC glimpse RPCs"
23840         rm -f $dom
23841 }
23842 run_test 271ba "DoM: no glimpse RPC for stat (combined file)"
23843
23844
23845 get_mdc_stats() {
23846         local mdtidx=$1
23847         local param=$2
23848         local mdt=MDT$(printf %04x $mdtidx)
23849
23850         if [ -z $param ]; then
23851                 lctl get_param -n mdc.*$mdt*.stats
23852         else
23853                 lctl get_param -n mdc.*$mdt*.stats | awk "/$param/"'{print $2}'
23854         fi
23855 }
23856
23857 test_271c() {
23858         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23859                 skip "Need MDS version at least 2.10.55"
23860
23861         local dom=$DIR/$tdir/dom
23862
23863         mkdir -p $DIR/$tdir
23864
23865         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
23866
23867         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
23868         local facet=mds$((mdtidx + 1))
23869
23870         cancel_lru_locks mdc
23871         do_facet $facet lctl set_param -n mdt.*.dom_lock=0
23872         createmany -o $dom 1000
23873         lctl set_param -n mdc.*.stats=clear
23874         smalliomany -w $dom 1000 200
23875         get_mdc_stats $mdtidx
23876         local enq=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
23877         # Each file has 1 open, 1 IO enqueues, total 2000
23878         # but now we have also +1 getxattr for security.capability, total 3000
23879         [ $enq -ge 2000 ] || error "Too few enqueues $enq, expected > 2000"
23880         unlinkmany $dom 1000
23881
23882         cancel_lru_locks mdc
23883         do_facet $facet lctl set_param -n mdt.*.dom_lock=1
23884         createmany -o $dom 1000
23885         lctl set_param -n mdc.*.stats=clear
23886         smalliomany -w $dom 1000 200
23887         local enq_2=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
23888         # Expect to see reduced amount of RPCs by 1000 due to single enqueue
23889         # for OPEN and IO lock.
23890         [ $((enq - enq_2)) -ge 1000 ] ||
23891                 error "Too many enqueues $enq_2, expected about $((enq - 1000))"
23892         unlinkmany $dom 1000
23893         return 0
23894 }
23895 run_test 271c "DoM: IO lock at open saves enqueue RPCs"
23896
23897 cleanup_271def_tests() {
23898         trap 0
23899         rm -f $1
23900 }
23901
23902 test_271d() {
23903         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
23904                 skip "Need MDS version at least 2.10.57"
23905
23906         local dom=$DIR/$tdir/dom
23907         local tmp=$TMP/$tfile
23908         trap "cleanup_271def_tests $tmp" EXIT
23909
23910         mkdir -p $DIR/$tdir
23911
23912         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
23913
23914         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
23915
23916         cancel_lru_locks mdc
23917         dd if=/dev/urandom of=$tmp bs=1000 count=1
23918         dd if=$tmp of=$dom bs=1000 count=1
23919         cancel_lru_locks mdc
23920
23921         cat /etc/hosts >> $tmp
23922         lctl set_param -n mdc.*.stats=clear
23923
23924         # append data to the same file it should update local page
23925         echo "Append to the same page"
23926         cat /etc/hosts >> $dom
23927         local num=$(get_mdc_stats $mdtidx ost_read)
23928         local ra=$(get_mdc_stats $mdtidx req_active)
23929         local rw=$(get_mdc_stats $mdtidx req_waittime)
23930
23931         [ -z $num ] || error "$num READ RPC occured"
23932         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
23933         echo "... DONE"
23934
23935         # compare content
23936         cmp $tmp $dom || error "file miscompare"
23937
23938         cancel_lru_locks mdc
23939         lctl set_param -n mdc.*.stats=clear
23940
23941         echo "Open and read file"
23942         cat $dom > /dev/null
23943         local num=$(get_mdc_stats $mdtidx ost_read)
23944         local ra=$(get_mdc_stats $mdtidx req_active)
23945         local rw=$(get_mdc_stats $mdtidx req_waittime)
23946
23947         [ -z $num ] || error "$num READ RPC occured"
23948         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
23949         echo "... DONE"
23950
23951         # compare content
23952         cmp $tmp $dom || error "file miscompare"
23953
23954         return 0
23955 }
23956 run_test 271d "DoM: read on open (1K file in reply buffer)"
23957
23958 test_271f() {
23959         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
23960                 skip "Need MDS version at least 2.10.57"
23961
23962         local dom=$DIR/$tdir/dom
23963         local tmp=$TMP/$tfile
23964         trap "cleanup_271def_tests $tmp" EXIT
23965
23966         mkdir -p $DIR/$tdir
23967
23968         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
23969
23970         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
23971
23972         cancel_lru_locks mdc
23973         dd if=/dev/urandom of=$tmp bs=265000 count=1
23974         dd if=$tmp of=$dom bs=265000 count=1
23975         cancel_lru_locks mdc
23976         cat /etc/hosts >> $tmp
23977         lctl set_param -n mdc.*.stats=clear
23978
23979         echo "Append to the same page"
23980         cat /etc/hosts >> $dom
23981         local num=$(get_mdc_stats $mdtidx ost_read)
23982         local ra=$(get_mdc_stats $mdtidx req_active)
23983         local rw=$(get_mdc_stats $mdtidx req_waittime)
23984
23985         [ -z $num ] || error "$num READ RPC occured"
23986         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
23987         echo "... DONE"
23988
23989         # compare content
23990         cmp $tmp $dom || error "file miscompare"
23991
23992         cancel_lru_locks mdc
23993         lctl set_param -n mdc.*.stats=clear
23994
23995         echo "Open and read file"
23996         cat $dom > /dev/null
23997         local num=$(get_mdc_stats $mdtidx ost_read)
23998         local ra=$(get_mdc_stats $mdtidx req_active)
23999         local rw=$(get_mdc_stats $mdtidx req_waittime)
24000
24001         [ -z $num ] && num=0
24002         [ $num -eq 1 ] || error "expect 1 READ RPC, $num occured"
24003         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
24004         echo "... DONE"
24005
24006         # compare content
24007         cmp $tmp $dom || error "file miscompare"
24008
24009         return 0
24010 }
24011 run_test 271f "DoM: read on open (200K file and read tail)"
24012
24013 test_271g() {
24014         [[ $($LCTL get_param mdc.*.import) =~ async_discard ]] ||
24015                 skip "Skipping due to old client or server version"
24016
24017         $LFS setstripe -E 1024K -L mdt -E EOF $DIR1/$tfile
24018         # to get layout
24019         $CHECKSTAT -t file $DIR1/$tfile
24020
24021         $MULTIOP $DIR1/$tfile Ow40960_w4096c &
24022         MULTIOP_PID=$!
24023         sleep 1
24024         #define OBD_FAIL_LDLM_CANCEL_BL_CB_RACE
24025         $LCTL set_param fail_loc=0x80000314
24026         rm $DIR1/$tfile || error "Unlink fails"
24027         RC=$?
24028         kill -USR1 $MULTIOP_PID && wait $MULTIOP_PID || error "multiop failure"
24029         [ $RC -eq 0 ] || error "Failed write to stale object"
24030 }
24031 run_test 271g "Discard DoM data vs client flush race"
24032
24033 test_272a() {
24034         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
24035                 skip "Need MDS version at least 2.11.50"
24036
24037         local dom=$DIR/$tdir/dom
24038         mkdir -p $DIR/$tdir
24039
24040         $LFS setstripe -E 256K -L mdt -E -1 -c1 $dom
24041         dd if=/dev/urandom of=$dom bs=512K count=1 ||
24042                 error "failed to write data into $dom"
24043         local old_md5=$(md5sum $dom)
24044
24045         $LFS migrate -E 256K -L mdt -E -1 -c2 $dom ||
24046                 error "failed to migrate to the same DoM component"
24047
24048         local new_md5=$(md5sum $dom)
24049
24050         [ "$old_md5" == "$new_md5" ] ||
24051                 error "md5sum differ: $old_md5, $new_md5"
24052
24053         [ $($LFS getstripe -c $dom) -eq 2 ] ||
24054                 error "bad final stripe count: $($LFS getstripe -c $dom) != 2"
24055 }
24056 run_test 272a "DoM migration: new layout with the same DOM component"
24057
24058 test_272b() {
24059         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
24060                 skip "Need MDS version at least 2.11.50"
24061
24062         local dom=$DIR/$tdir/dom
24063         mkdir -p $DIR/$tdir
24064         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
24065
24066         local mdtidx=$($LFS getstripe -m $dom)
24067         local mdtname=MDT$(printf %04x $mdtidx)
24068         local facet=mds$((mdtidx + 1))
24069
24070         local mdtfree1=$(do_facet $facet \
24071                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24072         dd if=/dev/urandom of=$dom bs=2M count=1 ||
24073                 error "failed to write data into $dom"
24074         local old_md5=$(md5sum $dom)
24075         cancel_lru_locks mdc
24076         local mdtfree1=$(do_facet $facet \
24077                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24078
24079         $LFS migrate -c2 $dom ||
24080                 error "failed to migrate to the new composite layout"
24081         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
24082                 error "MDT stripe was not removed"
24083
24084         cancel_lru_locks mdc
24085         local new_md5=$(md5sum $dom)
24086         [ "$old_md5" == "$new_md5" ] ||
24087                 error "$old_md5 != $new_md5"
24088
24089         # Skip free space checks with ZFS
24090         if [ "$(facet_fstype $facet)" != "zfs" ]; then
24091                 local mdtfree2=$(do_facet $facet \
24092                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24093                 [ $mdtfree2 -gt $mdtfree1 ] ||
24094                         error "MDT space is not freed after migration"
24095         fi
24096         return 0
24097 }
24098 run_test 272b "DoM migration: DOM file to the OST-striped file (plain)"
24099
24100 test_272c() {
24101         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
24102                 skip "Need MDS version at least 2.11.50"
24103
24104         local dom=$DIR/$tdir/$tfile
24105         mkdir -p $DIR/$tdir
24106         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
24107
24108         local mdtidx=$($LFS getstripe -m $dom)
24109         local mdtname=MDT$(printf %04x $mdtidx)
24110         local facet=mds$((mdtidx + 1))
24111
24112         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
24113                 error "failed to write data into $dom"
24114         local old_md5=$(md5sum $dom)
24115         cancel_lru_locks mdc
24116         local mdtfree1=$(do_facet $facet \
24117                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24118
24119         $LFS migrate -E 2M -c1 -E -1 -c2 $dom ||
24120                 error "failed to migrate to the new composite layout"
24121         [ $($LFS getstripe -L $dom) == 'mdt' ] &&
24122                 error "MDT stripe was not removed"
24123
24124         cancel_lru_locks mdc
24125         local new_md5=$(md5sum $dom)
24126         [ "$old_md5" == "$new_md5" ] ||
24127                 error "$old_md5 != $new_md5"
24128
24129         # Skip free space checks with ZFS
24130         if [ "$(facet_fstype $facet)" != "zfs" ]; then
24131                 local mdtfree2=$(do_facet $facet \
24132                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24133                 [ $mdtfree2 -gt $mdtfree1 ] ||
24134                         error "MDS space is not freed after migration"
24135         fi
24136         return 0
24137 }
24138 run_test 272c "DoM migration: DOM file to the OST-striped file (composite)"
24139
24140 test_272d() {
24141         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
24142                 skip "Need MDS version at least 2.12.55"
24143
24144         local dom=$DIR/$tdir/$tfile
24145         mkdir -p $DIR/$tdir
24146         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
24147
24148         local mdtidx=$($LFS getstripe -m $dom)
24149         local mdtname=MDT$(printf %04x $mdtidx)
24150         local facet=mds$((mdtidx + 1))
24151
24152         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
24153                 error "failed to write data into $dom"
24154         local old_md5=$(md5sum $dom)
24155         cancel_lru_locks mdc
24156         local mdtfree1=$(do_facet $facet \
24157                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24158
24159         $LFS mirror extend -N -E 2M -c1 -E -1 -c2 $dom ||
24160                 error "failed mirroring to the new composite layout"
24161         $LFS mirror resync $dom ||
24162                 error "failed mirror resync"
24163         $LFS mirror split --mirror-id 1 -d $dom ||
24164                 error "failed mirror split"
24165
24166         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
24167                 error "MDT stripe was not removed"
24168
24169         cancel_lru_locks mdc
24170         local new_md5=$(md5sum $dom)
24171         [ "$old_md5" == "$new_md5" ] ||
24172                 error "$old_md5 != $new_md5"
24173
24174         # Skip free space checks with ZFS
24175         if [ "$(facet_fstype $facet)" != "zfs" ]; then
24176                 local mdtfree2=$(do_facet $facet \
24177                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24178                 [ $mdtfree2 -gt $mdtfree1 ] ||
24179                         error "MDS space is not freed after DOM mirror deletion"
24180         fi
24181         return 0
24182 }
24183 run_test 272d "DoM mirroring: OST-striped mirror to DOM file"
24184
24185 test_272e() {
24186         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
24187                 skip "Need MDS version at least 2.12.55"
24188
24189         local dom=$DIR/$tdir/$tfile
24190         mkdir -p $DIR/$tdir
24191         $LFS setstripe -c 2 $dom
24192
24193         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
24194                 error "failed to write data into $dom"
24195         local old_md5=$(md5sum $dom)
24196         cancel_lru_locks
24197
24198         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 $dom ||
24199                 error "failed mirroring to the DOM layout"
24200         $LFS mirror resync $dom ||
24201                 error "failed mirror resync"
24202         $LFS mirror split --mirror-id 1 -d $dom ||
24203                 error "failed mirror split"
24204
24205         [[ $($LFS getstripe -L --component-start=0 $dom) == 'mdt' ]] ||
24206                 error "MDT stripe wasn't set"
24207
24208         cancel_lru_locks
24209         local new_md5=$(md5sum $dom)
24210         [ "$old_md5" == "$new_md5" ] ||
24211                 error "$old_md5 != $new_md5"
24212
24213         return 0
24214 }
24215 run_test 272e "DoM mirroring: DOM mirror to the OST-striped file"
24216
24217 test_272f() {
24218         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
24219                 skip "Need MDS version at least 2.12.55"
24220
24221         local dom=$DIR/$tdir/$tfile
24222         mkdir -p $DIR/$tdir
24223         $LFS setstripe -c 2 $dom
24224
24225         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
24226                 error "failed to write data into $dom"
24227         local old_md5=$(md5sum $dom)
24228         cancel_lru_locks
24229
24230         $LFS migrate -E 1M -L mdt -E eof -c2 -v $dom ||
24231                 error "failed migrating to the DOM file"
24232
24233         [[ $($LFS getstripe -L --component-start=0 $dom) == 'mdt' ]] ||
24234                 error "MDT stripe wasn't set"
24235
24236         cancel_lru_locks
24237         local new_md5=$(md5sum $dom)
24238         [ "$old_md5" != "$new_md5" ] &&
24239                 error "$old_md5 != $new_md5"
24240
24241         return 0
24242 }
24243 run_test 272f "DoM migration: OST-striped file to DOM file"
24244
24245 test_273a() {
24246         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
24247                 skip "Need MDS version at least 2.11.50"
24248
24249         # Layout swap cannot be done if either file has DOM component,
24250         # this will never be supported, migration should be used instead
24251
24252         local dom=$DIR/$tdir/$tfile
24253         mkdir -p $DIR/$tdir
24254
24255         $LFS setstripe -c2 ${dom}_plain
24256         $LFS setstripe -E 1M -L mdt -E -1 -c2 ${dom}_dom
24257         $LFS swap_layouts ${dom}_plain ${dom}_dom &&
24258                 error "can swap layout with DoM component"
24259         $LFS swap_layouts ${dom}_dom ${dom}_plain &&
24260                 error "can swap layout with DoM component"
24261
24262         $LFS setstripe -E 1M -c1 -E -1 -c2 ${dom}_comp
24263         $LFS swap_layouts ${dom}_comp ${dom}_dom &&
24264                 error "can swap layout with DoM component"
24265         $LFS swap_layouts ${dom}_dom ${dom}_comp &&
24266                 error "can swap layout with DoM component"
24267         return 0
24268 }
24269 run_test 273a "DoM: layout swapping should fail with DOM"
24270
24271 test_273b() {
24272         mkdir -p $DIR/$tdir
24273         $LFS setstripe -E 1M -L mdt -E -1 -c -1 $DIR/$tdir
24274
24275 #define OBD_FAIL_MDS_COMMITRW_DELAY      0x16b
24276         do_facet mds1 $LCTL set_param fail_loc=0x8000016b fail_val=2
24277
24278         $MULTIOP $DIR/$tdir/$tfile Ouw2097152c
24279 }
24280 run_test 273b "DoM: race writeback and object destroy"
24281
24282 test_273c() {
24283         mkdir -p $DIR/$tdir
24284         $LFS setstripe -E 1M -E-1 -c-1 $DIR/$tdir
24285
24286         #define OBD_FAIL_OFD_COMMITRW_DELAY      0x1e1
24287         do_facet ost1 $LCTL set_param fail_loc=0x800001e1 fail_val=2
24288
24289         $MULTIOP $DIR/$tdir/$tfile Ouw2097152c
24290 }
24291 run_test 273c "race writeback and object destroy"
24292
24293 test_275() {
24294         remote_ost_nodsh && skip "remote OST with nodsh"
24295         [ $OST1_VERSION -lt $(version_code 2.10.57) ] &&
24296                 skip "Need OST version >= 2.10.57"
24297
24298         local file=$DIR/$tfile
24299         local oss
24300
24301         oss=$(comma_list $(osts_nodes))
24302
24303         dd if=/dev/urandom of=$file bs=1M count=2 ||
24304                 error "failed to create a file"
24305         cancel_lru_locks osc
24306
24307         #lock 1
24308         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
24309                 error "failed to read a file"
24310
24311 #define OBD_FAIL_LDLM_PAUSE_CANCEL2      0x31f
24312         $LCTL set_param fail_loc=0x8000031f
24313
24314         cancel_lru_locks osc &
24315         sleep 1
24316
24317 #define OBD_FAIL_LDLM_PROLONG_PAUSE      0x32b
24318         do_nodes $oss $LCTL set_param fail_loc=0x8000032b
24319         #IO takes another lock, but matches the PENDING one
24320         #and places it to the IO RPC
24321         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
24322                 error "failed to read a file with PENDING lock"
24323 }
24324 run_test 275 "Read on a canceled duplicate lock"
24325
24326 test_276() {
24327         remote_ost_nodsh && skip "remote OST with nodsh"
24328         local pid
24329
24330         do_facet ost1 "(while true; do \
24331                 $LCTL get_param obdfilter.*.filesfree > /dev/null 2>&1; \
24332                 done) & pid=\\\$!; echo \\\$pid > $TMP/sanity_276_pid" &
24333         pid=$!
24334
24335         for LOOP in $(seq 20); do
24336                 stop ost1
24337                 start ost1 $(ostdevname 1) $OST_MOUNT_OPTS
24338         done
24339         kill -9 $pid
24340         do_facet ost1 "pid=\\\$(cat $TMP/sanity_276_pid); kill -9 \\\$pid; \
24341                 rm $TMP/sanity_276_pid"
24342 }
24343 run_test 276 "Race between mount and obd_statfs"
24344
24345 test_277() {
24346         $LCTL set_param ldlm.namespaces.*.lru_size=0
24347         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
24348         local cached_mb=$($LCTL get_param llite.*.max_cached_mb |
24349                         grep ^used_mb | awk '{print $2}')
24350         [ $cached_mb -eq 1 ] || error "expected mb 1 got $cached_mb"
24351         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 \
24352                 oflag=direct conv=notrunc
24353         cached_mb=$($LCTL get_param llite.*.max_cached_mb |
24354                         grep ^used_mb | awk '{print $2}')
24355         [ $cached_mb -eq 0 ] || error "expected mb 0 got $cached_mb"
24356 }
24357 run_test 277 "Direct IO shall drop page cache"
24358
24359 test_278() {
24360         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
24361         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
24362         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] &&
24363                 skip "needs the same host for mdt1 mdt2" && return
24364
24365         local pid1
24366         local pid2
24367
24368 #define OBD_FAIL_OBD_STOP_MDS_RACE     0x60b
24369         do_facet mds2 $LCTL set_param fail_loc=0x8000060c
24370         stop mds2 &
24371         pid2=$!
24372
24373         stop mds1
24374
24375         echo "Starting MDTs"
24376         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
24377         wait $pid2
24378 #For the error assertion will happen. lu_env_get_key(..., &mdt_thread_key)
24379 #will return NULL
24380         do_facet mds2 $LCTL set_param fail_loc=0
24381
24382         start mds2 $(mdsdevname 2) $MDS_MOUNT_OPTS
24383         wait_recovery_complete mds2
24384 }
24385 run_test 278 "Race starting MDS between MDTs stop/start"
24386
24387 test_280() {
24388         [ $MGS_VERSION -lt $(version_code 2.13.52) ] &&
24389                 skip "Need MGS version at least 2.13.52"
24390         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24391         combined_mgs_mds || skip "needs combined MGS/MDT"
24392
24393         umount_client $MOUNT
24394 #define OBD_FAIL_MDS_LLOG_UMOUNT_RACE   0x15e
24395         do_facet mgs $LCTL set_param fail_loc=0x8000015e fail_val=0
24396
24397         mount_client $MOUNT &
24398         sleep 1
24399         stop mgs || error "stop mgs failed"
24400         #for a race mgs would crash
24401         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
24402         # make sure we unmount client before remounting
24403         wait
24404         umount_client $MOUNT
24405         mount_client $MOUNT || error "mount client failed"
24406 }
24407 run_test 280 "Race between MGS umount and client llog processing"
24408
24409 cleanup_test_300() {
24410         trap 0
24411         umask $SAVE_UMASK
24412 }
24413 test_striped_dir() {
24414         local mdt_index=$1
24415         local stripe_count
24416         local stripe_index
24417
24418         mkdir -p $DIR/$tdir
24419
24420         SAVE_UMASK=$(umask)
24421         trap cleanup_test_300 RETURN EXIT
24422
24423         $LFS setdirstripe -i $mdt_index -c 2 -H all_char -o 755 \
24424                                                 $DIR/$tdir/striped_dir ||
24425                 error "set striped dir error"
24426
24427         local mode=$(stat -c%a $DIR/$tdir/striped_dir)
24428         [ "$mode" = "755" ] || error "expect 755 got $mode"
24429
24430         $LFS getdirstripe $DIR/$tdir/striped_dir > /dev/null 2>&1 ||
24431                 error "getdirstripe failed"
24432         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir)
24433         if [ "$stripe_count" != "2" ]; then
24434                 error "1:stripe_count is $stripe_count, expect 2"
24435         fi
24436         stripe_count=$($LFS getdirstripe -T $DIR/$tdir/striped_dir)
24437         if [ "$stripe_count" != "2" ]; then
24438                 error "2:stripe_count is $stripe_count, expect 2"
24439         fi
24440
24441         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir)
24442         if [ "$stripe_index" != "$mdt_index" ]; then
24443                 error "stripe_index is $stripe_index, expect $mdt_index"
24444         fi
24445
24446         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
24447                 error "nlink error after create striped dir"
24448
24449         mkdir $DIR/$tdir/striped_dir/a
24450         mkdir $DIR/$tdir/striped_dir/b
24451
24452         stat $DIR/$tdir/striped_dir/a ||
24453                 error "create dir under striped dir failed"
24454         stat $DIR/$tdir/striped_dir/b ||
24455                 error "create dir under striped dir failed"
24456
24457         [ $(stat -c%h $DIR/$tdir/striped_dir) == '4' ] ||
24458                 error "nlink error after mkdir"
24459
24460         rmdir $DIR/$tdir/striped_dir/a
24461         [ $(stat -c%h $DIR/$tdir/striped_dir) == '3' ] ||
24462                 error "nlink error after rmdir"
24463
24464         rmdir $DIR/$tdir/striped_dir/b
24465         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
24466                 error "nlink error after rmdir"
24467
24468         chattr +i $DIR/$tdir/striped_dir
24469         createmany -o $DIR/$tdir/striped_dir/f 10 &&
24470                 error "immutable flags not working under striped dir!"
24471         chattr -i $DIR/$tdir/striped_dir
24472
24473         rmdir $DIR/$tdir/striped_dir ||
24474                 error "rmdir striped dir error"
24475
24476         cleanup_test_300
24477
24478         true
24479 }
24480
24481 test_300a() {
24482         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
24483                 skip "skipped for lustre < 2.7.0"
24484         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24485         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24486
24487         test_striped_dir 0 || error "failed on striped dir on MDT0"
24488         test_striped_dir 1 || error "failed on striped dir on MDT0"
24489 }
24490 run_test 300a "basic striped dir sanity test"
24491
24492 test_300b() {
24493         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
24494                 skip "skipped for lustre < 2.7.0"
24495         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24496         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24497
24498         local i
24499         local mtime1
24500         local mtime2
24501         local mtime3
24502
24503         test_mkdir $DIR/$tdir || error "mkdir fail"
24504         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
24505                 error "set striped dir error"
24506         for i in {0..9}; do
24507                 mtime1=$(stat -c %Y $DIR/$tdir/striped_dir)
24508                 sleep 1
24509                 touch $DIR/$tdir/striped_dir/file_$i || error "touch error $i"
24510                 mtime2=$(stat -c %Y $DIR/$tdir/striped_dir)
24511                 [ $mtime1 -eq $mtime2 ] && error "mtime unchanged after create"
24512                 sleep 1
24513                 rm -f $DIR/$tdir/striped_dir/file_$i || error "unlink error $i"
24514                 mtime3=$(stat -c %Y $DIR/$tdir/striped_dir)
24515                 [ $mtime2 -eq $mtime3 ] && error "mtime unchanged after unlink"
24516         done
24517         true
24518 }
24519 run_test 300b "check ctime/mtime for striped dir"
24520
24521 test_300c() {
24522         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
24523                 skip "skipped for lustre < 2.7.0"
24524         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24525         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24526
24527         local file_count
24528
24529         mkdir_on_mdt0 $DIR/$tdir
24530         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir ||
24531                 error "set striped dir error"
24532
24533         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/striped_dir ||
24534                 error "chown striped dir failed"
24535
24536         $RUNAS createmany -o $DIR/$tdir/striped_dir/f 5000 ||
24537                 error "create 5k files failed"
24538
24539         file_count=$(ls $DIR/$tdir/striped_dir | wc -l)
24540
24541         [ "$file_count" = 5000 ] || error "file count $file_count != 5000"
24542
24543         rm -rf $DIR/$tdir
24544 }
24545 run_test 300c "chown && check ls under striped directory"
24546
24547 test_300d() {
24548         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
24549                 skip "skipped for lustre < 2.7.0"
24550         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24551         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24552
24553         local stripe_count
24554         local file
24555
24556         mkdir -p $DIR/$tdir
24557         $LFS setstripe -c 2 $DIR/$tdir
24558
24559         #local striped directory
24560         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
24561                 error "set striped dir error"
24562         #look at the directories for debug purposes
24563         ls -l $DIR/$tdir
24564         $LFS getdirstripe $DIR/$tdir
24565         ls -l $DIR/$tdir/striped_dir
24566         $LFS getdirstripe $DIR/$tdir/striped_dir
24567         createmany -o $DIR/$tdir/striped_dir/f 10 ||
24568                 error "create 10 files failed"
24569
24570         #remote striped directory
24571         $LFS setdirstripe -i 1 -c 2 $DIR/$tdir/remote_striped_dir ||
24572                 error "set striped dir error"
24573         #look at the directories for debug purposes
24574         ls -l $DIR/$tdir
24575         $LFS getdirstripe $DIR/$tdir
24576         ls -l $DIR/$tdir/remote_striped_dir
24577         $LFS getdirstripe $DIR/$tdir/remote_striped_dir
24578         createmany -o $DIR/$tdir/remote_striped_dir/f 10 ||
24579                 error "create 10 files failed"
24580
24581         for file in $(find $DIR/$tdir); do
24582                 stripe_count=$($LFS getstripe -c $file)
24583                 [ $stripe_count -eq 2 ] ||
24584                         error "wrong stripe $stripe_count for $file"
24585         done
24586
24587         rm -rf $DIR/$tdir
24588 }
24589 run_test 300d "check default stripe under striped directory"
24590
24591 test_300e() {
24592         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24593                 skip "Need MDS version at least 2.7.55"
24594         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24595         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24596
24597         local stripe_count
24598         local file
24599
24600         mkdir -p $DIR/$tdir
24601
24602         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
24603                 error "set striped dir error"
24604
24605         touch $DIR/$tdir/striped_dir/a
24606         touch $DIR/$tdir/striped_dir/b
24607         touch $DIR/$tdir/striped_dir/c
24608
24609         mkdir $DIR/$tdir/striped_dir/dir_a
24610         mkdir $DIR/$tdir/striped_dir/dir_b
24611         mkdir $DIR/$tdir/striped_dir/dir_c
24612
24613         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_a ||
24614                 error "set striped adir under striped dir error"
24615
24616         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_b ||
24617                 error "set striped bdir under striped dir error"
24618
24619         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_c ||
24620                 error "set striped cdir under striped dir error"
24621
24622         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir/dir_b ||
24623                 error "rename dir under striped dir fails"
24624
24625         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir/stp_b ||
24626                 error "rename dir under different stripes fails"
24627
24628         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir/c ||
24629                 error "rename file under striped dir should succeed"
24630
24631         mrename $DIR/$tdir/striped_dir/dir_b $DIR/$tdir/striped_dir/dir_c ||
24632                 error "rename dir under striped dir should succeed"
24633
24634         rm -rf $DIR/$tdir
24635 }
24636 run_test 300e "check rename under striped directory"
24637
24638 test_300f() {
24639         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24640         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24641         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24642                 skip "Need MDS version at least 2.7.55"
24643
24644         local stripe_count
24645         local file
24646
24647         rm -rf $DIR/$tdir
24648         mkdir -p $DIR/$tdir
24649
24650         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
24651                 error "set striped dir error"
24652
24653         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir1 ||
24654                 error "set striped dir error"
24655
24656         touch $DIR/$tdir/striped_dir/a
24657         mkdir $DIR/$tdir/striped_dir/dir_a
24658         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_a ||
24659                 error "create striped dir under striped dir fails"
24660
24661         touch $DIR/$tdir/striped_dir1/b
24662         mkdir $DIR/$tdir/striped_dir1/dir_b
24663         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_b ||
24664                 error "create striped dir under striped dir fails"
24665
24666         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir1/dir_b ||
24667                 error "rename dir under different striped dir should fail"
24668
24669         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir1/stp_b ||
24670                 error "rename striped dir under diff striped dir should fail"
24671
24672         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir1/a ||
24673                 error "rename file under diff striped dirs fails"
24674
24675         rm -rf $DIR/$tdir
24676 }
24677 run_test 300f "check rename cross striped directory"
24678
24679 test_300_check_default_striped_dir()
24680 {
24681         local dirname=$1
24682         local default_count=$2
24683         local default_index=$3
24684         local stripe_count
24685         local stripe_index
24686         local dir_stripe_index
24687         local dir
24688
24689         echo "checking $dirname $default_count $default_index"
24690         $LFS setdirstripe -D -c $default_count -i $default_index \
24691                                 -H all_char $DIR/$tdir/$dirname ||
24692                 error "set default stripe on striped dir error"
24693         stripe_count=$($LFS getdirstripe -D -c $DIR/$tdir/$dirname)
24694         [ $stripe_count -eq $default_count ] ||
24695                 error "expect $default_count get $stripe_count for $dirname"
24696
24697         stripe_index=$($LFS getdirstripe -D -i $DIR/$tdir/$dirname)
24698         [ $stripe_index -eq $default_index ] ||
24699                 error "expect $default_index get $stripe_index for $dirname"
24700
24701         mkdir $DIR/$tdir/$dirname/{test1,test2,test3,test4} ||
24702                                                 error "create dirs failed"
24703
24704         createmany -o $DIR/$tdir/$dirname/f- 10 || error "create files failed"
24705         unlinkmany $DIR/$tdir/$dirname/f- 10    || error "unlink files failed"
24706         for dir in $(find $DIR/$tdir/$dirname/*); do
24707                 stripe_count=$($LFS getdirstripe -c $dir)
24708                 (( $stripe_count == $default_count )) ||
24709                 (( $stripe_count == $MDSCOUNT && $default_count == -1 )) ||
24710                 (( $stripe_count == 0 )) || (( $default_count == 1 )) ||
24711                 error "stripe count $default_count != $stripe_count for $dir"
24712
24713                 stripe_index=$($LFS getdirstripe -i $dir)
24714                 [ $default_index -eq -1 ] ||
24715                         [ $stripe_index -eq $default_index ] ||
24716                         error "$stripe_index != $default_index for $dir"
24717
24718                 #check default stripe
24719                 stripe_count=$($LFS getdirstripe -D -c $dir)
24720                 [ $stripe_count -eq $default_count ] ||
24721                 error "default count $default_count != $stripe_count for $dir"
24722
24723                 stripe_index=$($LFS getdirstripe -D -i $dir)
24724                 [ $stripe_index -eq $default_index ] ||
24725                 error "default index $default_index != $stripe_index for $dir"
24726         done
24727         rmdir $DIR/$tdir/$dirname/* || error "rmdir failed"
24728 }
24729
24730 test_300g() {
24731         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24732         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24733                 skip "Need MDS version at least 2.7.55"
24734
24735         local dir
24736         local stripe_count
24737         local stripe_index
24738
24739         mkdir_on_mdt0 $DIR/$tdir
24740         mkdir $DIR/$tdir/normal_dir
24741
24742         #Checking when client cache stripe index
24743         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
24744         $LFS setdirstripe -D -i1 $DIR/$tdir/striped_dir ||
24745                 error "create striped_dir failed"
24746
24747         $LFS setdirstripe -i0 $DIR/$tdir/striped_dir/dir0 ||
24748                 error "create dir0 fails"
24749         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir0)
24750         [ $stripe_index -eq 0 ] ||
24751                 error "dir0 expect index 0 got $stripe_index"
24752
24753         mkdir $DIR/$tdir/striped_dir/dir1 ||
24754                 error "create dir1 fails"
24755         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir1)
24756         [ $stripe_index -eq 1 ] ||
24757                 error "dir1 expect index 1 got $stripe_index"
24758
24759         #check default stripe count/stripe index
24760         test_300_check_default_striped_dir normal_dir $MDSCOUNT 1
24761         test_300_check_default_striped_dir normal_dir 1 0
24762         test_300_check_default_striped_dir normal_dir -1 1
24763         test_300_check_default_striped_dir normal_dir 2 -1
24764
24765         #delete default stripe information
24766         echo "delete default stripeEA"
24767         $LFS setdirstripe -d $DIR/$tdir/normal_dir ||
24768                 error "set default stripe on striped dir error"
24769
24770         mkdir -p $DIR/$tdir/normal_dir/{test1,test2,test3,test4}
24771         for dir in $(find $DIR/$tdir/normal_dir/*); do
24772                 stripe_count=$($LFS getdirstripe -c $dir)
24773                 [ $stripe_count -eq 0 ] ||
24774                         error "expect 1 get $stripe_count for $dir"
24775         done
24776 }
24777 run_test 300g "check default striped directory for normal directory"
24778
24779 test_300h() {
24780         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24781         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24782                 skip "Need MDS version at least 2.7.55"
24783
24784         local dir
24785         local stripe_count
24786
24787         mkdir $DIR/$tdir
24788         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
24789                 error "set striped dir error"
24790
24791         test_300_check_default_striped_dir striped_dir $MDSCOUNT 1
24792         test_300_check_default_striped_dir striped_dir 1 0
24793         test_300_check_default_striped_dir striped_dir -1 1
24794         test_300_check_default_striped_dir striped_dir 2 -1
24795
24796         #delete default stripe information
24797         $LFS setdirstripe -d $DIR/$tdir/striped_dir ||
24798                 error "set default stripe on striped dir error"
24799
24800         mkdir -p $DIR/$tdir/striped_dir/{test1,test2,test3,test4}
24801         for dir in $(find $DIR/$tdir/striped_dir/*); do
24802                 stripe_count=$($LFS getdirstripe -c $dir)
24803                 [ $stripe_count -eq 0 ] ||
24804                         error "expect 1 get $stripe_count for $dir"
24805         done
24806 }
24807 run_test 300h "check default striped directory for striped directory"
24808
24809 test_300i() {
24810         [[ $PARALLEL == "yes" ]] && skip "skip parallel run"
24811         (( $MDSCOUNT >= 2 )) || skip_env "needs >= 2 MDTs"
24812         (( $MDS1_VERSION >= $(version_code 2.7.55) )) ||
24813                 skip "Need MDS version at least 2.7.55"
24814
24815         local stripe_count
24816         local file
24817
24818         mkdir $DIR/$tdir
24819
24820         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
24821                 error "set striped dir error"
24822
24823         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
24824                 error "create files under striped dir failed"
24825
24826         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir ||
24827                 error "set striped hashdir error"
24828
24829         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir/d0 ||
24830                 error "create dir0 under hash dir failed"
24831         $LFS setdirstripe -i0 -c$MDSCOUNT -H fnv_1a_64 $DIR/$tdir/hashdir/d1 ||
24832                 error "create dir1 under hash dir failed"
24833         $LFS setdirstripe -i0 -c$MDSCOUNT -H crush $DIR/$tdir/hashdir/d2 ||
24834                 error "create dir2 under hash dir failed"
24835
24836         # unfortunately, we need to umount to clear dir layout cache for now
24837         # once we fully implement dir layout, we can drop this
24838         umount_client $MOUNT || error "umount failed"
24839         mount_client $MOUNT || error "mount failed"
24840
24841         $LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir
24842         local dircnt=$($LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir | wc -l)
24843         (( $dircnt == 2 )) || error "lfs find striped dir got $dircnt != 2"
24844
24845         if (( $MDS1_VERSION > $(version_code 2.15.0) )); then
24846                 $LFS mkdir -i0 -c$MDSCOUNT -H crush2 $DIR/$tdir/hashdir/d3 ||
24847                         error "create crush2 dir $tdir/hashdir/d3 failed"
24848                 $LFS find -H crush2 $DIR/$tdir/hashdir
24849                 dircnt=$($LFS find -H crush2 $DIR/$tdir/hashdir | wc -l)
24850                 (( $dircnt == 1 )) || error "find crush2 dir got $dircnt != 1"
24851
24852                 # mkdir with an invalid hash type (hash=fail_val) from client
24853                 # should be replaced on MDS with a valid (default) hash type
24854                 #define OBD_FAIL_LMV_UNKNOWN_STRIPE     0x1901
24855                 $LCTL set_param fail_loc=0x1901 fail_val=99
24856                 $LFS mkdir -c2 $DIR/$tdir/hashdir/d99
24857
24858                 local hash=$($LFS getdirstripe -H $DIR/$tdir/hashdir/d99)
24859                 local expect=$(do_facet mds1 \
24860                         $LCTL get_param -n lod.$FSNAME-MDT0000-mdtlov.mdt_hash)
24861                 [[ $hash == $expect ]] ||
24862                         error "d99 hash '$hash' != expected hash '$expect'"
24863         fi
24864
24865         #set the stripe to be unknown hash type on read
24866         #define OBD_FAIL_LMV_UNKNOWN_STRIPE     0x1901
24867         $LCTL set_param fail_loc=0x1901 fail_val=99
24868         for ((i = 0; i < 10; i++)); do
24869                 $CHECKSTAT -t file $DIR/$tdir/striped_dir/f-$i ||
24870                         error "stat f-$i failed"
24871                 rm $DIR/$tdir/striped_dir/f-$i || error "unlink f-$i failed"
24872         done
24873
24874         touch $DIR/$tdir/striped_dir/f0 &&
24875                 error "create under striped dir with unknown hash should fail"
24876
24877         $LCTL set_param fail_loc=0
24878
24879         umount_client $MOUNT || error "umount failed"
24880         mount_client $MOUNT || error "mount failed"
24881
24882         return 0
24883 }
24884 run_test 300i "client handle unknown hash type striped directory"
24885
24886 test_300j() {
24887         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24888         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24889         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24890                 skip "Need MDS version at least 2.7.55"
24891
24892         local stripe_count
24893         local file
24894
24895         mkdir $DIR/$tdir
24896
24897         #define OBD_FAIL_SPLIT_UPDATE_REC       0x1702
24898         $LCTL set_param fail_loc=0x1702
24899         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
24900                 error "set striped dir error"
24901
24902         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
24903                 error "create files under striped dir failed"
24904
24905         $LCTL set_param fail_loc=0
24906
24907         rm -rf $DIR/$tdir || error "unlink striped dir fails"
24908
24909         return 0
24910 }
24911 run_test 300j "test large update record"
24912
24913 test_300k() {
24914         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24915         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24916         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24917                 skip "Need MDS version at least 2.7.55"
24918
24919         # this test needs a huge transaction
24920         local kb
24921         kb=$(do_facet $SINGLEMDS "$LCTL get_param -n \
24922              osd*.$FSNAME-MDT0000.kbytestotal")
24923         [ $kb -lt $((1024*1024)) ] && skip "MDT0 too small: $kb"
24924
24925         local stripe_count
24926         local file
24927
24928         mkdir $DIR/$tdir
24929
24930         #define OBD_FAIL_LARGE_STRIPE   0x1703
24931         $LCTL set_param fail_loc=0x1703
24932         $LFS setdirstripe -i 0 -c192 $DIR/$tdir/striped_dir ||
24933                 error "set striped dir error"
24934         $LCTL set_param fail_loc=0
24935
24936         $LFS getdirstripe $DIR/$tdir/striped_dir ||
24937                 error "getstripeddir fails"
24938         rm -rf $DIR/$tdir/striped_dir ||
24939                 error "unlink striped dir fails"
24940
24941         return 0
24942 }
24943 run_test 300k "test large striped directory"
24944
24945 test_300l() {
24946         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24947         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24948         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24949                 skip "Need MDS version at least 2.7.55"
24950
24951         local stripe_index
24952
24953         test_mkdir -p $DIR/$tdir/striped_dir
24954         chown $RUNAS_ID $DIR/$tdir/striped_dir ||
24955                         error "chown $RUNAS_ID failed"
24956         $LFS setdirstripe -i 1 -D $DIR/$tdir/striped_dir ||
24957                 error "set default striped dir failed"
24958
24959         #define OBD_FAIL_MDS_STALE_DIR_LAYOUT    0x158
24960         $LCTL set_param fail_loc=0x80000158
24961         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir || error "create dir fails"
24962
24963         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/test_dir)
24964         [ $stripe_index -eq 1 ] ||
24965                 error "expect 1 get $stripe_index for $dir"
24966 }
24967 run_test 300l "non-root user to create dir under striped dir with stale layout"
24968
24969 test_300m() {
24970         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24971         [ $MDSCOUNT -ge 2 ] && skip_env "Only for single MDT"
24972         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24973                 skip "Need MDS version at least 2.7.55"
24974
24975         mkdir -p $DIR/$tdir/striped_dir
24976         $LFS setdirstripe -D -c 1 $DIR/$tdir/striped_dir ||
24977                 error "set default stripes dir error"
24978
24979         mkdir $DIR/$tdir/striped_dir/a || error "mkdir a fails"
24980
24981         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/a)
24982         [ $stripe_count -eq 0 ] ||
24983                         error "expect 0 get $stripe_count for a"
24984
24985         $LFS setdirstripe -D -c 2 $DIR/$tdir/striped_dir ||
24986                 error "set default stripes dir error"
24987
24988         mkdir $DIR/$tdir/striped_dir/b || error "mkdir b fails"
24989
24990         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/b)
24991         [ $stripe_count -eq 0 ] ||
24992                         error "expect 0 get $stripe_count for b"
24993
24994         $LFS setdirstripe -D -c1 -i2 $DIR/$tdir/striped_dir ||
24995                 error "set default stripes dir error"
24996
24997         mkdir $DIR/$tdir/striped_dir/c &&
24998                 error "default stripe_index is invalid, mkdir c should fails"
24999
25000         rm -rf $DIR/$tdir || error "rmdir fails"
25001 }
25002 run_test 300m "setstriped directory on single MDT FS"
25003
25004 cleanup_300n() {
25005         local list=$(comma_list $(mdts_nodes))
25006
25007         trap 0
25008         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
25009 }
25010
25011 test_300n() {
25012         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25013         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25014         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25015                 skip "Need MDS version at least 2.7.55"
25016         remote_mds_nodsh && skip "remote MDS with nodsh"
25017
25018         local stripe_index
25019         local list=$(comma_list $(mdts_nodes))
25020
25021         trap cleanup_300n RETURN EXIT
25022         mkdir -p $DIR/$tdir
25023         chmod 777 $DIR/$tdir
25024         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT \
25025                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
25026                 error "create striped dir succeeds with gid=0"
25027
25028         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
25029         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
25030                 error "create striped dir fails with gid=-1"
25031
25032         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
25033         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D \
25034                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
25035                 error "set default striped dir succeeds with gid=0"
25036
25037
25038         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
25039         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D $DIR/$tdir/striped_dir ||
25040                 error "set default striped dir fails with gid=-1"
25041
25042
25043         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
25044         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir ||
25045                                         error "create test_dir fails"
25046         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir1 ||
25047                                         error "create test_dir1 fails"
25048         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir2 ||
25049                                         error "create test_dir2 fails"
25050         cleanup_300n
25051 }
25052 run_test 300n "non-root user to create dir under striped dir with default EA"
25053
25054 test_300o() {
25055         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25056         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25057         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25058                 skip "Need MDS version at least 2.7.55"
25059
25060         local numfree1
25061         local numfree2
25062
25063         mkdir -p $DIR/$tdir
25064
25065         numfree1=$(lctl get_param -n mdc.*MDT0000*.filesfree)
25066         numfree2=$(lctl get_param -n mdc.*MDT0001*.filesfree)
25067         if [ $numfree1 -lt 66000 ] || [ $numfree2 -lt 66000 ]; then
25068                 skip "not enough free inodes $numfree1 $numfree2"
25069         fi
25070
25071         numfree1=$(lctl get_param -n mdc.*MDT0000-mdc-*.kbytesfree)
25072         numfree2=$(lctl get_param -n mdc.*MDT0001-mdc-*.kbytesfree)
25073         if [ $numfree1 -lt 300000 ] || [ $numfree2 -lt 300000 ]; then
25074                 skip "not enough free space $numfree1 $numfree2"
25075         fi
25076
25077         $LFS setdirstripe -c2 $DIR/$tdir/striped_dir ||
25078                 error "setdirstripe fails"
25079
25080         createmany -d $DIR/$tdir/striped_dir/d 131000 ||
25081                 error "create dirs fails"
25082
25083         $LCTL set_param ldlm.namespaces.*mdc-*.lru_size=0
25084         ls $DIR/$tdir/striped_dir > /dev/null ||
25085                 error "ls striped dir fails"
25086         unlinkmany -d $DIR/$tdir/striped_dir/d 131000 ||
25087                 error "unlink big striped dir fails"
25088 }
25089 run_test 300o "unlink big sub stripe(> 65000 subdirs)"
25090
25091 test_300p() {
25092         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25093         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25094         remote_mds_nodsh && skip "remote MDS with nodsh"
25095
25096         mkdir_on_mdt0 $DIR/$tdir
25097
25098         #define OBD_FAIL_OUT_ENOSPC     0x1704
25099         do_facet mds2 lctl set_param fail_loc=0x80001704
25100         $LFS setdirstripe -i 0 -c2 $DIR/$tdir/bad_striped_dir > /dev/null 2>&1 \
25101                  && error "create striped directory should fail"
25102
25103         [ -e $DIR/$tdir/bad_striped_dir ] && error "striped dir exists"
25104
25105         $LFS setdirstripe -c2 $DIR/$tdir/bad_striped_dir
25106         true
25107 }
25108 run_test 300p "create striped directory without space"
25109
25110 test_300q() {
25111         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25112         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25113
25114         local fd=$(free_fd)
25115         local cmd="exec $fd<$tdir"
25116         cd $DIR
25117         $LFS mkdir -c $MDSCOUNT $tdir || error "create $tdir fails"
25118         eval $cmd
25119         cmd="exec $fd<&-"
25120         trap "eval $cmd" EXIT
25121         cd $tdir || error "cd $tdir fails"
25122         rmdir  ../$tdir || error "rmdir $tdir fails"
25123         mkdir local_dir && error "create dir succeeds"
25124         $LFS setdirstripe -i1 remote_dir && error "create remote dir succeeds"
25125         eval $cmd
25126         return 0
25127 }
25128 run_test 300q "create remote directory under orphan directory"
25129
25130 test_300r() {
25131         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25132                 skip "Need MDS version at least 2.7.55" && return
25133         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
25134
25135         mkdir $DIR/$tdir
25136
25137         $LFS setdirstripe -i 0 -c -1 $DIR/$tdir/striped_dir ||
25138                 error "set striped dir error"
25139
25140         $LFS getdirstripe $DIR/$tdir/striped_dir ||
25141                 error "getstripeddir fails"
25142
25143         local stripe_count
25144         stripe_count=$($LFS getdirstripe $DIR/$tdir/striped_dir |
25145                       awk '/lmv_stripe_count:/ { print $2 }')
25146
25147         [ $MDSCOUNT -ne $stripe_count ] &&
25148                 error "wrong stripe count $stripe_count expected $MDSCOUNT"
25149
25150         rm -rf $DIR/$tdir/striped_dir ||
25151                 error "unlink striped dir fails"
25152 }
25153 run_test 300r "test -1 striped directory"
25154
25155 test_300s_helper() {
25156         local count=$1
25157
25158         local stripe_dir=$DIR/$tdir/striped_dir.$count
25159
25160         $LFS mkdir -c $count $stripe_dir ||
25161                 error "lfs mkdir -c error"
25162
25163         $LFS getdirstripe $stripe_dir ||
25164                 error "lfs getdirstripe fails"
25165
25166         local stripe_count
25167         stripe_count=$($LFS getdirstripe $stripe_dir |
25168                       awk '/lmv_stripe_count:/ { print $2 }')
25169
25170         [ $count -ne $stripe_count ] &&
25171                 error_noexit "bad stripe count $stripe_count expected $count"
25172
25173         local dupe_stripes
25174         dupe_stripes=$($LFS getdirstripe $stripe_dir |
25175                 awk '/0x/ {count[$1] += 1}; END {
25176                         for (idx in count) {
25177                                 if (count[idx]>1) {
25178                                         print "index " idx " count " count[idx]
25179                                 }
25180                         }
25181                 }')
25182
25183         if [[ -n "$dupe_stripes" ]] ; then
25184                 lfs getdirstripe $stripe_dir
25185                 error_noexit "Dupe MDT above: $dupe_stripes "
25186         fi
25187
25188         rm -rf $stripe_dir ||
25189                 error_noexit "unlink $stripe_dir fails"
25190 }
25191
25192 test_300s() {
25193         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25194                 skip "Need MDS version at least 2.7.55" && return
25195         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
25196
25197         mkdir $DIR/$tdir
25198         for count in $(seq 2 $MDSCOUNT); do
25199                 test_300s_helper $count
25200         done
25201 }
25202 run_test 300s "test lfs mkdir -c without -i"
25203
25204 test_300t() {
25205         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
25206                 skip "need MDS 2.14.55 or later"
25207         (( $MDSCOUNT >= 2 )) || skip "needs at least 2 MDTs"
25208
25209         local testdir="$DIR/$tdir/striped_dir"
25210         local dir1=$testdir/dir1
25211         local dir2=$testdir/dir2
25212
25213         mkdir -p $testdir
25214
25215         $LFS setdirstripe -D -c -1 --max-inherit=3 $testdir ||
25216                 error "failed to set default stripe count for $testdir"
25217
25218         mkdir $dir1
25219         local stripe_count=$($LFS getdirstripe -c $dir1)
25220
25221         (( $stripe_count == $MDSCOUNT )) || error "wrong stripe count"
25222
25223         local max_count=$((MDSCOUNT - 1))
25224         local mdts=$(comma_list $(mdts_nodes))
25225
25226         do_nodes $mdts $LCTL set_param lod.*.max_mdt_stripecount=$max_count
25227         stack_trap "do_nodes $mdts $LCTL set_param lod.*.max_mdt_stripecount=0"
25228
25229         mkdir $dir2
25230         stripe_count=$($LFS getdirstripe -c $dir2)
25231
25232         (( $stripe_count == $max_count )) || error "wrong stripe count"
25233 }
25234 run_test 300t "test max_mdt_stripecount"
25235
25236 prepare_remote_file() {
25237         mkdir $DIR/$tdir/src_dir ||
25238                 error "create remote source failed"
25239
25240         cp /etc/hosts $DIR/$tdir/src_dir/a ||
25241                  error "cp to remote source failed"
25242         touch $DIR/$tdir/src_dir/a
25243
25244         $LFS mkdir -i 1 $DIR/$tdir/tgt_dir ||
25245                 error "create remote target dir failed"
25246
25247         touch $DIR/$tdir/tgt_dir/b
25248
25249         mrename $DIR/$tdir/src_dir/a $DIR/$tdir/tgt_dir/b ||
25250                 error "rename dir cross MDT failed!"
25251
25252         $CHECKSTAT -t file $DIR/$tdir/src_dir/a &&
25253                 error "src_child still exists after rename"
25254
25255         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/b ||
25256                 error "missing file(a) after rename"
25257
25258         diff /etc/hosts $DIR/$tdir/tgt_dir/b ||
25259                 error "diff after rename"
25260 }
25261
25262 test_310a() {
25263         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
25264         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25265
25266         local remote_file=$DIR/$tdir/tgt_dir/b
25267
25268         mkdir -p $DIR/$tdir
25269
25270         prepare_remote_file || error "prepare remote file failed"
25271
25272         #open-unlink file
25273         $OPENUNLINK $remote_file $remote_file ||
25274                 error "openunlink $remote_file failed"
25275         $CHECKSTAT -a $remote_file || error "$remote_file exists"
25276 }
25277 run_test 310a "open unlink remote file"
25278
25279 test_310b() {
25280         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
25281         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25282
25283         local remote_file=$DIR/$tdir/tgt_dir/b
25284
25285         mkdir -p $DIR/$tdir
25286
25287         prepare_remote_file || error "prepare remote file failed"
25288
25289         ln $remote_file $DIR/$tfile || error "link failed for remote file"
25290         $MULTIOP $DIR/$tfile Ouc || error "mulitop failed"
25291         $CHECKSTAT -t file $remote_file || error "check file failed"
25292 }
25293 run_test 310b "unlink remote file with multiple links while open"
25294
25295 test_310c() {
25296         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25297         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
25298
25299         local remote_file=$DIR/$tdir/tgt_dir/b
25300
25301         mkdir -p $DIR/$tdir
25302
25303         prepare_remote_file || error "prepare remote file failed"
25304
25305         ln $remote_file $DIR/$tfile || error "link failed for remote file"
25306         multiop_bg_pause $remote_file O_uc ||
25307                         error "mulitop failed for remote file"
25308         MULTIPID=$!
25309         $MULTIOP $DIR/$tfile Ouc
25310         kill -USR1 $MULTIPID
25311         wait $MULTIPID
25312 }
25313 run_test 310c "open-unlink remote file with multiple links"
25314
25315 #LU-4825
25316 test_311() {
25317         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25318         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
25319         [ $MDS1_VERSION -lt $(version_code 2.8.54) ] &&
25320                 skip "lustre < 2.8.54 does not contain LU-4825 fix"
25321         remote_mds_nodsh && skip "remote MDS with nodsh"
25322
25323         local old_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
25324         local mdts=$(comma_list $(mdts_nodes))
25325
25326         mkdir -p $DIR/$tdir
25327         $LFS setstripe -i 0 -c 1 $DIR/$tdir
25328         createmany -o $DIR/$tdir/$tfile. 1000
25329
25330         # statfs data is not real time, let's just calculate it
25331         old_iused=$((old_iused + 1000))
25332
25333         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
25334                         osp.*OST0000*MDT0000.create_count")
25335         local max_count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
25336                                 osp.*OST0000*MDT0000.max_create_count")
25337         do_nodes $mdts "$LCTL set_param -n osp.*OST0000*.max_create_count=0"
25338
25339         $LFS setstripe -i 0 $DIR/$tdir/$tfile || error "setstripe failed"
25340         local index=$($LFS getstripe -i $DIR/$tdir/$tfile)
25341         [ $index -ne 0 ] || error "$tfile stripe index is 0"
25342
25343         unlinkmany $DIR/$tdir/$tfile. 1000
25344
25345         do_nodes $mdts "$LCTL set_param -n \
25346                         osp.*OST0000*.max_create_count=$max_count"
25347         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
25348                 do_nodes $mdts "$LCTL set_param -n \
25349                                 osp.*OST0000*.create_count=$count"
25350         do_nodes $mdts "$LCTL get_param osp.*OST0000*.create_count" |
25351                         grep "=0" && error "create_count is zero"
25352
25353         local new_iused
25354         for i in $(seq 120); do
25355                 new_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
25356                 # system may be too busy to destroy all objs in time, use
25357                 # a somewhat small value to not fail autotest
25358                 [ $((old_iused - new_iused)) -gt 400 ] && break
25359                 sleep 1
25360         done
25361
25362         echo "waited $i sec, old Iused $old_iused, new Iused $new_iused"
25363         [ $((old_iused - new_iused)) -gt 400 ] ||
25364                 error "objs not destroyed after unlink"
25365 }
25366 run_test 311 "disable OSP precreate, and unlink should destroy objs"
25367
25368 zfs_get_objid()
25369 {
25370         local ost=$1
25371         local tf=$2
25372         local fid=($($LFS getstripe $tf | grep 0x))
25373         local seq=${fid[3]#0x}
25374         local objid=${fid[1]}
25375
25376         local vdevdir=$(dirname $(facet_vdevice $ost))
25377         local cmd="$ZDB -e -p $vdevdir -ddddd $(facet_device $ost)"
25378         local zfs_zapid=$(do_facet $ost $cmd |
25379                           grep -w "/O/$seq/d$((objid%32))" -C 5 |
25380                           awk '/Object/{getline; print $1}')
25381         local zfs_objid=$(do_facet $ost $cmd $zfs_zapid |
25382                           awk "/$objid = /"'{printf $3}')
25383
25384         echo $zfs_objid
25385 }
25386
25387 zfs_object_blksz() {
25388         local ost=$1
25389         local objid=$2
25390
25391         local vdevdir=$(dirname $(facet_vdevice $ost))
25392         local cmd="$ZDB -e -p $vdevdir -dddd $(facet_device $ost)"
25393         local blksz=$(do_facet $ost $cmd $objid |
25394                       awk '/dblk/{getline; printf $4}')
25395
25396         case "${blksz: -1}" in
25397                 k|K) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024)) ;;
25398                 m|M) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024*1024)) ;;
25399                 *) ;;
25400         esac
25401
25402         echo $blksz
25403 }
25404
25405 test_312() { # LU-4856
25406         remote_ost_nodsh && skip "remote OST with nodsh"
25407         [[ "$ost1_FSTYPE" == "zfs" ]] || skip "the test only applies to zfs"
25408
25409         local max_blksz=$(do_facet ost1 \
25410                           $ZFS get -p recordsize $(facet_device ost1) |
25411                           awk '!/VALUE/{print $3}')
25412         local tf=$DIR/$tfile
25413
25414         $LFS setstripe -c1 $tf
25415         local facet="ost$(($($LFS getstripe -i $tf) + 1))"
25416
25417         # Get ZFS object id
25418         local zfs_objid=$(zfs_get_objid $facet $tf)
25419         # block size change by sequential overwrite
25420         local bs
25421
25422         for ((bs=$PAGE_SIZE; bs <= max_blksz; bs *= 4)) ; do
25423                 dd if=/dev/zero of=$tf bs=$bs count=1 oflag=sync conv=notrunc
25424
25425                 local blksz=$(zfs_object_blksz $facet $zfs_objid)
25426                 [[ $blksz -eq $bs ]] || error "blksz error: $blksz, expected: $bs"
25427         done
25428         rm -f $tf
25429
25430         $LFS setstripe -c1 $tf
25431         facet="ost$(($($LFS getstripe -i $tf) + 1))"
25432
25433         # block size change by sequential append write
25434         dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=1 oflag=sync conv=notrunc
25435         zfs_objid=$(zfs_get_objid $facet $tf)
25436         local count
25437
25438         for ((count = 1; count < $((max_blksz / PAGE_SIZE)); count *= 2)); do
25439                 dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=$count seek=$count \
25440                         oflag=sync conv=notrunc
25441
25442                 blksz=$(zfs_object_blksz $facet $zfs_objid)
25443                 (( $blksz == 2 * count * PAGE_SIZE )) ||
25444                         error "blksz error, actual $blksz, " \
25445                                 "expected: 2 * $count * $PAGE_SIZE"
25446         done
25447         rm -f $tf
25448
25449         # random write
25450         $LFS setstripe -c1 $tf
25451         facet="ost$(($($LFS getstripe -i $tf) + 1))"
25452         zfs_objid=$(zfs_get_objid $facet $tf)
25453
25454         dd if=/dev/zero of=$tf bs=1K count=1 oflag=sync conv=notrunc
25455         blksz=$(zfs_object_blksz $facet $zfs_objid)
25456         (( blksz == PAGE_SIZE )) ||
25457                 error "blksz error: $blksz, expected: $PAGE_SIZE"
25458
25459         dd if=/dev/zero of=$tf bs=64K count=1 oflag=sync conv=notrunc seek=128
25460         blksz=$(zfs_object_blksz $facet $zfs_objid)
25461         (( blksz == 65536 )) || error "blksz error: $blksz, expected: 64k"
25462
25463         dd if=/dev/zero of=$tf bs=1M count=1 oflag=sync conv=notrunc
25464         blksz=$(zfs_object_blksz $facet $zfs_objid)
25465         (( blksz == 65536 )) || error "rewrite error: $blksz, expected: 64k"
25466 }
25467 run_test 312 "make sure ZFS adjusts its block size by write pattern"
25468
25469 test_313() {
25470         remote_ost_nodsh && skip "remote OST with nodsh"
25471
25472         local file=$DIR/$tfile
25473
25474         rm -f $file
25475         $LFS setstripe -c 1 -i 0 $file || error "setstripe failed"
25476
25477         # define OBD_FAIL_TGT_RCVD_EIO           0x720
25478         do_facet ost1 "$LCTL set_param fail_loc=0x720"
25479         dd if=/dev/zero of=$file bs=$PAGE_SIZE oflag=direct count=1 &&
25480                 error "write should failed"
25481         do_facet ost1 "$LCTL set_param fail_loc=0"
25482         rm -f $file
25483 }
25484 run_test 313 "io should fail after last_rcvd update fail"
25485
25486 test_314() {
25487         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
25488
25489         $LFS setstripe -c 2 -i 0 $DIR/$tfile || error "setstripe failed"
25490         do_facet ost1 "$LCTL set_param fail_loc=0x720"
25491         rm -f $DIR/$tfile
25492         wait_delete_completed
25493         do_facet ost1 "$LCTL set_param fail_loc=0"
25494 }
25495 run_test 314 "OSP shouldn't fail after last_rcvd update failure"
25496
25497 test_315() { # LU-618
25498         [ -f /proc/$$/io ] || skip_env "no IO accounting in kernel"
25499
25500         local file=$DIR/$tfile
25501         rm -f $file
25502
25503         $MULTIOP $file oO_CREAT:O_DIRECT:O_RDWR:w4063232c ||
25504                 error "multiop file write failed"
25505         $MULTIOP $file oO_RDONLY:r4063232_c &
25506         PID=$!
25507
25508         sleep 2
25509
25510         local rbytes=$(awk '/read_bytes/ { print $2 }' /proc/$PID/io)
25511         kill -USR1 $PID
25512
25513         [ $rbytes -gt 4000000 ] || error "read is not accounted ($rbytes)"
25514         rm -f $file
25515 }
25516 run_test 315 "read should be accounted"
25517
25518 test_316() {
25519         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
25520         large_xattr_enabled || skip "ea_inode feature disabled"
25521
25522         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
25523         mkdir $DIR/$tdir/d || error "mkdir $tdir/d failed"
25524         chown nobody $DIR/$tdir/d || error "chown $tdir/d failed"
25525         touch $DIR/$tdir/d/$tfile || error "touch $tdir/d/$tfile failed"
25526
25527         $LFS migrate -m1 $DIR/$tdir/d || error "lfs migrate -m1 failed"
25528 }
25529 run_test 316 "lfs migrate of file with large_xattr enabled"
25530
25531 test_317() {
25532         [ $MDS1_VERSION -lt $(version_code 2.11.53) ] &&
25533                 skip "Need MDS version at least 2.11.53"
25534         if [ "$ost1_FSTYPE" == "zfs" ]; then
25535                 skip "LU-10370: no implementation for ZFS"
25536         fi
25537
25538         local trunc_sz
25539         local grant_blk_size
25540
25541         grant_blk_size=$($LCTL get_param osc.$FSNAME*.import |
25542                         awk '/grant_block_size:/ { print $2; exit; }')
25543         #
25544         # Create File of size 5M. Truncate it to below size's and verify
25545         # blocks count.
25546         #
25547         dd if=/dev/zero of=$DIR/$tfile bs=5M count=1 conv=fsync ||
25548                 error "Create file $DIR/$tfile failed"
25549         stack_trap "rm -f $DIR/$tfile" EXIT
25550
25551         for trunc_sz in 2097152 4097 4000 509 0; do
25552                 $TRUNCATE $DIR/$tfile $trunc_sz ||
25553                         error "truncate $tfile to $trunc_sz failed"
25554                 local sz=$(stat --format=%s $DIR/$tfile)
25555                 local blk=$(stat --format=%b $DIR/$tfile)
25556                 local trunc_blk=$((((trunc_sz + (grant_blk_size - 1) ) /
25557                                      grant_blk_size) * 8))
25558
25559                 if [[ $blk -ne $trunc_blk ]]; then
25560                         $(which stat) $DIR/$tfile
25561                         error "Expected Block $trunc_blk got $blk for $tfile"
25562                 fi
25563
25564                 $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
25565                         error "Expected Size $trunc_sz got $sz for $tfile"
25566         done
25567
25568         #
25569         # sparse file test
25570         # Create file with a hole and write actual 65536 bytes which aligned
25571         # with 4K and 64K PAGE_SIZE. Block count must be 128.
25572         #
25573         local bs=65536
25574         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 seek=5 conv=fsync ||
25575                 error "Create file : $DIR/$tfile"
25576
25577         #
25578         # Truncate to size $trunc_sz bytes. Strip tail blocks and leave only 8
25579         # blocks. The block count must drop to 8.
25580         #
25581         trunc_sz=$(($(stat --format=%s $DIR/$tfile) -
25582                 ((bs - grant_blk_size) + 1)))
25583         $TRUNCATE $DIR/$tfile $trunc_sz ||
25584                 error "truncate $tfile to $trunc_sz failed"
25585
25586         local trunc_bsz=$((grant_blk_size / $(stat --format=%B $DIR/$tfile)))
25587         sz=$(stat --format=%s $DIR/$tfile)
25588         blk=$(stat --format=%b $DIR/$tfile)
25589
25590         if [[ $blk -ne $trunc_bsz ]]; then
25591                 $(which stat) $DIR/$tfile
25592                 error "Expected Block $trunc_bsz got $blk for $tfile"
25593         fi
25594
25595         $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
25596                 error "Expected Size $trunc_sz got $sz for $tfile"
25597 }
25598 run_test 317 "Verify blocks get correctly update after truncate"
25599
25600 test_318() {
25601         local llite_name="llite.$($LFS getname $MOUNT | awk '{print $1}')"
25602         local old_max_active=$($LCTL get_param -n \
25603                             ${llite_name}.max_read_ahead_async_active \
25604                             2>/dev/null)
25605
25606         $LCTL set_param llite.*.max_read_ahead_async_active=256
25607         local max_active=$($LCTL get_param -n \
25608                            ${llite_name}.max_read_ahead_async_active \
25609                            2>/dev/null)
25610         [ $max_active -ne 256 ] && error "expected 256 but got $max_active"
25611
25612         $LCTL set_param llite.*.max_read_ahead_async_active=0 ||
25613                 error "set max_read_ahead_async_active should succeed"
25614
25615         $LCTL set_param llite.*.max_read_ahead_async_active=512
25616         max_active=$($LCTL get_param -n \
25617                      ${llite_name}.max_read_ahead_async_active 2>/dev/null)
25618         [ $max_active -eq 512 ] || error "expected 512 but got $max_active"
25619
25620         # restore @max_active
25621         [ $old_max_active -ne 0 ] && $LCTL set_param \
25622                 llite.*.max_read_ahead_async_active=$old_max_active
25623
25624         local old_threshold=$($LCTL get_param -n \
25625                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
25626         local max_per_file_mb=$($LCTL get_param -n \
25627                 ${llite_name}.max_read_ahead_per_file_mb 2>/dev/null)
25628
25629         local invalid=$(($max_per_file_mb + 1))
25630         $LCTL set_param \
25631                 llite.*.read_ahead_async_file_threshold_mb=$invalid\
25632                         && error "set $invalid should fail"
25633
25634         local valid=$(($invalid - 1))
25635         $LCTL set_param \
25636                 llite.*.read_ahead_async_file_threshold_mb=$valid ||
25637                         error "set $valid should succeed"
25638         local threshold=$($LCTL get_param -n \
25639                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
25640         [ $threshold -eq $valid ] || error \
25641                 "expect threshold $valid got $threshold"
25642         $LCTL set_param \
25643                 llite.*.read_ahead_async_file_threshold_mb=$old_threshold
25644 }
25645 run_test 318 "Verify async readahead tunables"
25646
25647 test_319() {
25648         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
25649
25650         local before=$(date +%s)
25651         local evict
25652         local mdir=$DIR/$tdir
25653         local file=$mdir/xxx
25654
25655         $LFS mkdir -i0 $mdir || error "mkdir $mdir fails"
25656         touch $file
25657
25658 #define OBD_FAIL_LDLM_LOCAL_CANCEL_PAUSE 0x32c
25659         $LCTL set_param fail_val=5 fail_loc=0x8000032c
25660         $LFS migrate -m1 $mdir &
25661
25662         sleep 1
25663         dd if=$file of=/dev/null
25664         wait
25665         evict=$($LCTL get_param mdc.$FSNAME-MDT*.state |
25666           awk -F"[ [,]" '/EVICTED ]$/ { if (mx<$5) {mx=$5;} } END { print mx }')
25667
25668         [ -z "$evict" ] || [[ $evict -le $before ]] || error "eviction happened"
25669 }
25670 run_test 319 "lost lease lock on migrate error"
25671
25672 test_398a() { # LU-4198
25673         local ost1_imp=$(get_osc_import_name client ost1)
25674         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
25675                          cut -d'.' -f2)
25676
25677         $LFS setstripe -c 1 -i 0 $DIR/$tfile
25678         $LCTL set_param ldlm.namespaces.*.lru_size=clear
25679
25680         # request a new lock on client
25681         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
25682
25683         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
25684         local lock_count=$($LCTL get_param -n \
25685                            ldlm.namespaces.$imp_name.lru_size)
25686         [[ $lock_count -eq 0 ]] || error "lock should be cancelled by direct IO"
25687
25688         $LCTL set_param ldlm.namespaces.*-OST0000-osc-ffff*.lru_size=clear
25689
25690         # no lock cached, should use lockless DIO and not enqueue new lock
25691         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
25692         lock_count=$($LCTL get_param -n \
25693                      ldlm.namespaces.$imp_name.lru_size)
25694         [[ $lock_count -eq 0 ]] || error "no lock should be held by direct IO"
25695
25696         $LCTL set_param ldlm.namespaces.*-OST0000-osc-ffff*.lru_size=clear
25697
25698         # no lock cached, should use locked DIO append
25699         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct oflag=append \
25700                 conv=notrunc || error "DIO append failed"
25701         lock_count=$($LCTL get_param -n \
25702                      ldlm.namespaces.*-OST0000-osc-ffff*.lru_size)
25703         [[ $lock_count -ne 0 ]] || error "lock still must be held by DIO append"
25704 }
25705 run_test 398a "direct IO should cancel lock otherwise lockless"
25706
25707 test_398b() { # LU-4198
25708         local before=$(date +%s)
25709         local njobs=4
25710         local size=48
25711
25712         which fio || skip_env "no fio installed"
25713         $LFS setstripe -c -1 -S 1M $DIR/$tfile
25714         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size
25715
25716         # Single page, multiple pages, stripe size, 4*stripe size
25717         for bsize in $(( $PAGE_SIZE )) $(( 4*$PAGE_SIZE )) 1048576 4194304; do
25718                 echo "mix direct rw ${bsize} by fio with $njobs jobs..."
25719                 fio --name=rand-rw --rw=randrw --bs=$bsize --direct=1 \
25720                         --numjobs=$njobs --fallocate=none \
25721                         --iodepth=16 --allow_file_create=0 \
25722                         --size=$((size/njobs))M \
25723                         --filename=$DIR/$tfile &
25724                 bg_pid=$!
25725
25726                 echo "mix buffer rw ${bsize} by fio with $njobs jobs..."
25727                 fio --name=rand-rw --rw=randrw --bs=$bsize \
25728                         --numjobs=$njobs --fallocate=none \
25729                         --iodepth=16 --allow_file_create=0 \
25730                         --size=$((size/njobs))M \
25731                         --filename=$DIR/$tfile || true
25732                 wait $bg_pid
25733         done
25734
25735         evict=$(do_facet client $LCTL get_param \
25736                 osc.$FSNAME-OST*-osc-*/state |
25737             awk -F"[ [,]" '/EVICTED ]$/ { if (t<$5) {t=$5;} } END { print t }')
25738
25739         [ -z "$evict" ] || [[ $evict -le $before ]] ||
25740                 (do_facet client $LCTL get_param \
25741                         osc.$FSNAME-OST*-osc-*/state;
25742                     error "eviction happened: $evict before:$before")
25743
25744         rm -f $DIR/$tfile
25745 }
25746 run_test 398b "DIO and buffer IO race"
25747
25748 test_398c() { # LU-4198
25749         local ost1_imp=$(get_osc_import_name client ost1)
25750         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
25751                          cut -d'.' -f2)
25752
25753         which fio || skip_env "no fio installed"
25754
25755         saved_debug=$($LCTL get_param -n debug)
25756         $LCTL set_param debug=0
25757
25758         local size=$(lctl get_param -n osc.$FSNAME-OST0000*.kbytesavail | head -1)
25759         ((size /= 1024)) # by megabytes
25760         ((size /= 2)) # write half of the OST at most
25761         [ $size -gt 40 ] && size=40 #reduce test time anyway
25762
25763         $LFS setstripe -c 1 $DIR/$tfile
25764
25765         # it seems like ldiskfs reserves more space than necessary if the
25766         # writing blocks are not mapped, so it extends the file firstly
25767         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size && sync
25768         cancel_lru_locks osc
25769
25770         # clear and verify rpc_stats later
25771         $LCTL set_param osc.${FSNAME}-OST0000-osc-ffff*.rpc_stats=clear
25772
25773         local njobs=4
25774         echo "writing ${size}M to OST0 by fio with $njobs jobs..."
25775         fio --name=rand-write --rw=randwrite --bs=$PAGE_SIZE --direct=1 \
25776                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
25777                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
25778                 --filename=$DIR/$tfile
25779         [ $? -eq 0 ] || error "fio write error"
25780
25781         [ $($LCTL get_param -n ldlm.namespaces.$imp_name.lock_count) -eq 0 ] ||
25782                 error "Locks were requested while doing AIO"
25783
25784         # get the percentage of 1-page I/O
25785         pct=$($LCTL get_param osc.${imp_name}.rpc_stats |
25786                 grep -A 1 'pages per rpc' | grep -v 'pages per rpc' |
25787                 awk '{print $7}')
25788         [ $pct -le 50 ] || error "$pct% of I/O are 1-page"
25789
25790         echo "mix rw ${size}M to OST0 by fio with $njobs jobs..."
25791         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
25792                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
25793                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
25794                 --filename=$DIR/$tfile
25795         [ $? -eq 0 ] || error "fio mixed read write error"
25796
25797         echo "AIO with large block size ${size}M"
25798         fio --name=rand-rw --rw=randrw --bs=${size}M --direct=1 \
25799                 --numjobs=1 --fallocate=none --ioengine=libaio \
25800                 --iodepth=16 --allow_file_create=0 --size=${size}M \
25801                 --filename=$DIR/$tfile
25802         [ $? -eq 0 ] || error "fio large block size failed"
25803
25804         rm -f $DIR/$tfile
25805         $LCTL set_param debug="$saved_debug"
25806 }
25807 run_test 398c "run fio to test AIO"
25808
25809 test_398d() { #  LU-13846
25810         which aiocp || skip_env "no aiocp installed"
25811         local aio_file=$DIR/$tfile.aio
25812
25813         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
25814
25815         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=64
25816         aiocp -a $PAGE_SIZE -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file
25817         stack_trap "rm -f $DIR/$tfile $aio_file"
25818
25819         diff $DIR/$tfile $aio_file || error "file diff after aiocp"
25820
25821         # make sure we don't crash and fail properly
25822         aiocp -a 512 -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
25823                 error "aio not aligned with PAGE SIZE should fail"
25824
25825         rm -f $DIR/$tfile $aio_file
25826 }
25827 run_test 398d "run aiocp to verify block size > stripe size"
25828
25829 test_398e() {
25830         dd if=/dev/zero of=$DIR/$tfile bs=1234 count=1
25831         touch $DIR/$tfile.new
25832         dd if=$DIR/$tfile of=$DIR/$tfile.new bs=1M count=1 oflag=direct
25833 }
25834 run_test 398e "O_Direct open cleared by fcntl doesn't cause hang"
25835
25836 test_398f() { #  LU-14687
25837         which aiocp || skip_env "no aiocp installed"
25838         local aio_file=$DIR/$tfile.aio
25839
25840         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
25841
25842         dd if=/dev/zero of=$DIR/$tfile bs=1M count=64
25843         stack_trap "rm -f $DIR/$tfile $aio_file"
25844
25845         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
25846         $LCTL set_param fail_loc=0x1418
25847         # make sure we don't crash and fail properly
25848         aiocp -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
25849                 error "aio with page allocation failure succeeded"
25850         $LCTL set_param fail_loc=0
25851         diff $DIR/$tfile $aio_file
25852         [[ $? != 0 ]] || error "no diff after failed aiocp"
25853 }
25854 run_test 398f "verify aio handles ll_direct_rw_pages errors correctly"
25855
25856 # NB: To get the parallel DIO behavior in LU-13798, there must be > 1
25857 # stripe and i/o size must be > stripe size
25858 # Old style synchronous DIO waits after submitting each chunk, resulting in a
25859 # single RPC in flight.  This test shows async DIO submission is working by
25860 # showing multiple RPCs in flight.
25861 test_398g() { #  LU-13798
25862         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
25863
25864         # We need to do some i/o first to acquire enough grant to put our RPCs
25865         # in flight; otherwise a new connection may not have enough grant
25866         # available
25867         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
25868                 error "parallel dio failed"
25869         stack_trap "rm -f $DIR/$tfile"
25870
25871         # Reduce RPC size to 1M to avoid combination in to larger RPCs
25872         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
25873         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
25874         stack_trap "$LCTL set_param -n $pages_per_rpc"
25875
25876         # Recreate file so it's empty
25877         rm -f $DIR/$tfile
25878         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
25879         #Pause rpc completion to guarantee we see multiple rpcs in flight
25880         #define OBD_FAIL_OST_BRW_PAUSE_BULK
25881         do_facet ost1 $LCTL set_param fail_loc=0x214 fail_val=2
25882         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
25883
25884         # Clear rpc stats
25885         $LCTL set_param osc.*.rpc_stats=c
25886
25887         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
25888                 error "parallel dio failed"
25889         stack_trap "rm -f $DIR/$tfile"
25890
25891         $LCTL get_param osc.*-OST0000-*.rpc_stats
25892         pct=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
25893                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
25894                 grep "8:" | awk '{print $8}')
25895         # We look at the "8 rpcs in flight" field, and verify A) it is present
25896         # and B) it includes all RPCs.  This proves we had 8 RPCs in flight,
25897         # as expected for an 8M DIO to a file with 1M stripes.
25898         [ $pct -eq 100 ] || error "we should see 8 RPCs in flight"
25899
25900         # Verify turning off parallel dio works as expected
25901         # Clear rpc stats
25902         $LCTL set_param osc.*.rpc_stats=c
25903         $LCTL set_param llite.*.parallel_dio=0
25904         stack_trap '$LCTL set_param llite.*.parallel_dio=1'
25905
25906         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
25907                 error "dio with parallel dio disabled failed"
25908
25909         # Ideally, we would see only one RPC in flight here, but there is an
25910         # unavoidable race between i/o completion and RPC in flight counting,
25911         # so while only 1 i/o is in flight at a time, the RPC in flight counter
25912         # will sometimes exceed 1 (3 or 4 is not rare on VM testing).
25913         # So instead we just verify it's always < 8.
25914         $LCTL get_param osc.*-OST0000-*.rpc_stats
25915         ret=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
25916                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
25917                 grep '^$' -B1 | grep . | awk '{print $1}')
25918         [ $ret != "8:" ] ||
25919                 error "we should see fewer than 8 RPCs in flight (saw $ret)"
25920 }
25921 run_test 398g "verify parallel dio async RPC submission"
25922
25923 test_398h() { #  LU-13798
25924         local dio_file=$DIR/$tfile.dio
25925
25926         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
25927
25928         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
25929         stack_trap "rm -f $DIR/$tfile $dio_file"
25930
25931         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct ||
25932                 error "parallel dio failed"
25933         diff $DIR/$tfile $dio_file
25934         [[ $? == 0 ]] || error "file diff after aiocp"
25935 }
25936 run_test 398h "verify correctness of read & write with i/o size >> stripe size"
25937
25938 test_398i() { #  LU-13798
25939         local dio_file=$DIR/$tfile.dio
25940
25941         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
25942
25943         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
25944         stack_trap "rm -f $DIR/$tfile $dio_file"
25945
25946         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
25947         $LCTL set_param fail_loc=0x1418
25948         # make sure we don't crash and fail properly
25949         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct &&
25950                 error "parallel dio page allocation failure succeeded"
25951         diff $DIR/$tfile $dio_file
25952         [[ $? != 0 ]] || error "no diff after failed aiocp"
25953 }
25954 run_test 398i "verify parallel dio handles ll_direct_rw_pages errors correctly"
25955
25956 test_398j() { #  LU-13798
25957         # Stripe size > RPC size but less than i/o size tests split across
25958         # stripes and RPCs for individual i/o op
25959         $LFS setstripe -o 0,0 -S 4M $DIR/$tfile $DIR/$tfile.2
25960
25961         # Reduce RPC size to 1M to guarantee split to multiple RPCs per stripe
25962         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
25963         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
25964         stack_trap "$LCTL set_param -n $pages_per_rpc"
25965
25966         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
25967                 error "parallel dio write failed"
25968         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.2"
25969
25970         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct ||
25971                 error "parallel dio read failed"
25972         diff $DIR/$tfile $DIR/$tfile.2
25973         [[ $? == 0 ]] || error "file diff after parallel dio read"
25974 }
25975 run_test 398j "test parallel dio where stripe size > rpc_size"
25976
25977 test_398k() { #  LU-13798
25978         wait_delete_completed
25979         wait_mds_ost_sync
25980
25981         # 4 stripe file; we will cause out of space on OST0
25982         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
25983
25984         # Fill OST0 (if it's not too large)
25985         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
25986                    head -n1)
25987         if [[ $ORIGFREE -gt $MAXFREE ]]; then
25988                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
25989         fi
25990         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
25991         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
25992                 error "dd should fill OST0"
25993         stack_trap "rm -f $DIR/$tfile.1"
25994
25995         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
25996         err=$?
25997
25998         ls -la $DIR/$tfile
25999         $CHECKSTAT -t file -s 0 $DIR/$tfile ||
26000                 error "file is not 0 bytes in size"
26001
26002         # dd above should not succeed, but don't error until here so we can
26003         # get debug info above
26004         [[ $err != 0 ]] ||
26005                 error "parallel dio write with enospc succeeded"
26006         stack_trap "rm -f $DIR/$tfile"
26007 }
26008 run_test 398k "test enospc on first stripe"
26009
26010 test_398l() { #  LU-13798
26011         wait_delete_completed
26012         wait_mds_ost_sync
26013
26014         # 4 stripe file; we will cause out of space on OST0
26015         # Note the 1M stripe size and the > 1M i/o size mean this ENOSPC
26016         # happens on the second i/o chunk we issue
26017         $LFS setstripe -o 1,0,1,0 -S 1M $DIR/$tfile $DIR/$tfile.2
26018
26019         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=2 oflag=direct
26020         stack_trap "rm -f $DIR/$tfile"
26021
26022         # Fill OST0 (if it's not too large)
26023         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
26024                    head -n1)
26025         if [[ $ORIGFREE -gt $MAXFREE ]]; then
26026                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
26027         fi
26028         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
26029         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
26030                 error "dd should fill OST0"
26031         stack_trap "rm -f $DIR/$tfile.1"
26032
26033         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 oflag=direct
26034         err=$?
26035         stack_trap "rm -f $DIR/$tfile.2"
26036
26037         # Check that short write completed as expected
26038         ls -la $DIR/$tfile.2
26039         $CHECKSTAT -t file -s 1048576 $DIR/$tfile.2 ||
26040                 error "file is not 1M in size"
26041
26042         # dd above should not succeed, but don't error until here so we can
26043         # get debug info above
26044         [[ $err != 0 ]] ||
26045                 error "parallel dio write with enospc succeeded"
26046
26047         # Truncate source file to same length as output file and diff them
26048         $TRUNCATE $DIR/$tfile 1048576
26049         diff $DIR/$tfile $DIR/$tfile.2
26050         [[ $? == 0 ]] || error "data incorrect after short write"
26051 }
26052 run_test 398l "test enospc on intermediate stripe/RPC"
26053
26054 test_398m() { #  LU-13798
26055         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
26056
26057         # Set up failure on OST0, the first stripe:
26058         #define OBD_FAIL_OST_BRW_WRITE_BULK     0x20e
26059         #NB: Fail val is ost # + 1, because we cannot use cfs_fail_val = 0
26060         # OST0 is on ost1, OST1 is on ost2.
26061         # So this fail_val specifies OST0
26062         do_facet ost1 $LCTL set_param fail_loc=0x20e fail_val=1
26063         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
26064
26065         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
26066                 error "parallel dio write with failure on first stripe succeeded"
26067         stack_trap "rm -f $DIR/$tfile"
26068         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
26069
26070         # Place data in file for read
26071         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
26072                 error "parallel dio write failed"
26073
26074         # Fail read on OST0, first stripe
26075         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
26076         do_facet ost1 $LCTL set_param fail_loc=0x20f fail_val=1
26077         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
26078                 error "parallel dio read with error on first stripe succeeded"
26079         rm -f $DIR/$tfile.2
26080         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
26081
26082         # Switch to testing on OST1, second stripe
26083         # Clear file contents, maintain striping
26084         echo > $DIR/$tfile
26085         # Set up failure on OST1, second stripe:
26086         do_facet ost2 $LCTL set_param fail_loc=0x20e fail_val=2
26087         stack_trap "do_facet ost2 $LCTL set_param fail_loc=0"
26088
26089         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
26090                 error "parallel dio write with failure on second stripe succeeded"
26091         stack_trap "rm -f $DIR/$tfile"
26092         do_facet ost2 $LCTL set_param fail_loc=0 fail_val=0
26093
26094         # Place data in file for read
26095         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
26096                 error "parallel dio write failed"
26097
26098         # Fail read on OST1, second stripe
26099         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
26100         do_facet ost2 $LCTL set_param fail_loc=0x20f fail_val=2
26101         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
26102                 error "parallel dio read with error on second stripe succeeded"
26103         rm -f $DIR/$tfile.2
26104         do_facet ost2 $LCTL set_param fail_loc=0 fail_val=0
26105 }
26106 run_test 398m "test RPC failures with parallel dio"
26107
26108 # Parallel submission of DIO should not cause problems for append, but it's
26109 # important to verify.
26110 test_398n() { #  LU-13798
26111         $LFS setstripe -C 2 -S 1M $DIR/$tfile
26112
26113         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 ||
26114                 error "dd to create source file failed"
26115         stack_trap "rm -f $DIR/$tfile"
26116
26117         dd if=$DIR/$tfile of=$DIR/$tfile.1 bs=8M count=8 oflag=direct oflag=append ||
26118                 error "parallel dio write with failure on second stripe succeeded"
26119         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.1"
26120         diff $DIR/$tfile $DIR/$tfile.1
26121         [[ $? == 0 ]] || error "data incorrect after append"
26122
26123 }
26124 run_test 398n "test append with parallel DIO"
26125
26126 test_398o() {
26127         directio rdwr $DIR/$tfile 0 1 1 || error "bad KMS"
26128 }
26129 run_test 398o "right kms with DIO"
26130
26131 test_fake_rw() {
26132         local read_write=$1
26133         if [ "$read_write" = "write" ]; then
26134                 local dd_cmd="dd if=/dev/zero of=$DIR/$tfile"
26135         elif [ "$read_write" = "read" ]; then
26136                 local dd_cmd="dd of=/dev/null if=$DIR/$tfile"
26137         else
26138                 error "argument error"
26139         fi
26140
26141         # turn off debug for performance testing
26142         local saved_debug=$($LCTL get_param -n debug)
26143         $LCTL set_param debug=0
26144
26145         $LFS setstripe -c 1 -i 0 $DIR/$tfile
26146
26147         # get ost1 size - $FSNAME-OST0000
26148         local ost1_avail_size=$($LFS df $DIR | awk /${ost1_svc}/'{ print $4 }')
26149         local blocks=$((ost1_avail_size/2/1024)) # half avail space by megabytes
26150         [ $blocks -gt 1000 ] && blocks=1000 # 1G in maximum
26151
26152         if [ "$read_write" = "read" ]; then
26153                 $TRUNCATE $DIR/$tfile $(expr 1048576 \* $blocks)
26154         fi
26155
26156         local start_time=$(date +%s.%N)
26157         $dd_cmd bs=1M count=$blocks oflag=sync ||
26158                 error "real dd $read_write error"
26159         local duration=$(bc <<< "$(date +%s.%N) - $start_time")
26160
26161         if [ "$read_write" = "write" ]; then
26162                 rm -f $DIR/$tfile
26163         fi
26164
26165         # define OBD_FAIL_OST_FAKE_RW           0x238
26166         do_facet ost1 $LCTL set_param fail_loc=0x238
26167
26168         local start_time=$(date +%s.%N)
26169         $dd_cmd bs=1M count=$blocks oflag=sync ||
26170                 error "fake dd $read_write error"
26171         local duration_fake=$(bc <<< "$(date +%s.%N) - $start_time")
26172
26173         if [ "$read_write" = "write" ]; then
26174                 # verify file size
26175                 cancel_lru_locks osc
26176                 $CHECKSTAT -t file -s $((blocks * 1024 * 1024)) $DIR/$tfile ||
26177                         error "$tfile size not $blocks MB"
26178         fi
26179         do_facet ost1 $LCTL set_param fail_loc=0
26180
26181         echo "fake $read_write $duration_fake vs. normal $read_write" \
26182                 "$duration in seconds"
26183         [ $(bc <<< "$duration_fake < $duration") -eq 1 ] ||
26184                 error_not_in_vm "fake write is slower"
26185
26186         $LCTL set_param -n debug="$saved_debug"
26187         rm -f $DIR/$tfile
26188 }
26189 test_399a() { # LU-7655 for OST fake write
26190         remote_ost_nodsh && skip "remote OST with nodsh"
26191
26192         test_fake_rw write
26193 }
26194 run_test 399a "fake write should not be slower than normal write"
26195
26196 test_399b() { # LU-8726 for OST fake read
26197         remote_ost_nodsh && skip "remote OST with nodsh"
26198         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
26199                 skip_env "ldiskfs only test"
26200         fi
26201
26202         test_fake_rw read
26203 }
26204 run_test 399b "fake read should not be slower than normal read"
26205
26206 test_400a() { # LU-1606, was conf-sanity test_74
26207         if ! which $CC > /dev/null 2>&1; then
26208                 skip_env "$CC is not installed"
26209         fi
26210
26211         local extra_flags=''
26212         local out=$TMP/$tfile
26213         local prefix=/usr/include/lustre
26214         local prog
26215
26216         # Oleg removes .c files in his test rig so test if any c files exist
26217         [[ -n "$(ls -A $LUSTRE_TESTS_API_DIR)" ]] ||
26218                 skip_env "Needed .c test files are missing"
26219
26220         if ! [[ -d $prefix ]]; then
26221                 # Assume we're running in tree and fixup the include path.
26222                 extra_flags+=" -I$LUSTRE/../lnet/include/uapi"
26223                 extra_flags+=" -I$LUSTRE/include/uapi -I$LUSTRE/include"
26224                 extra_flags+=" -L$LUSTRE/utils/.libs"
26225         fi
26226
26227         for prog in $LUSTRE_TESTS_API_DIR/*.c; do
26228                 $CC -Wall -Werror $extra_flags -o $out $prog -llustreapi ||
26229                         error "client api broken"
26230         done
26231         rm -f $out
26232 }
26233 run_test 400a "Lustre client api program can compile and link"
26234
26235 test_400b() { # LU-1606, LU-5011
26236         local header
26237         local out=$TMP/$tfile
26238         local prefix=/usr/include/linux/lustre
26239
26240         # We use a hard coded prefix so that this test will not fail
26241         # when run in tree. There are headers in lustre/include/lustre/
26242         # that are not packaged (like lustre_idl.h) and have more
26243         # complicated include dependencies (like config.h and lnet/types.h).
26244         # Since this test about correct packaging we just skip them when
26245         # they don't exist (see below) rather than try to fixup cppflags.
26246
26247         if ! which $CC > /dev/null 2>&1; then
26248                 skip_env "$CC is not installed"
26249         fi
26250
26251         for header in $prefix/*.h; do
26252                 if ! [[ -f "$header" ]]; then
26253                         continue
26254                 fi
26255
26256                 if [[ "$(basename $header)" == lustre_ioctl.h ]]; then
26257                         continue # lustre_ioctl.h is internal header
26258                 fi
26259
26260                 $CC -Wall -Werror -include $header -c -x c /dev/null -o $out ||
26261                         error "cannot compile '$header'"
26262         done
26263         rm -f $out
26264 }
26265 run_test 400b "packaged headers can be compiled"
26266
26267 test_401a() { #LU-7437
26268         local printf_arg=$(find -printf 2>&1 | grep "unrecognized:")
26269         [ -n "$printf_arg" ] && skip_env "find does not support -printf"
26270
26271         #count the number of parameters by "list_param -R"
26272         local params=$($LCTL list_param -R '*' 2>/dev/null | wc -l)
26273         #count the number of parameters by listing proc files
26274         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
26275         echo "proc_dirs='$proc_dirs'"
26276         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
26277         local procs=$(find -L $proc_dirs -mindepth 1 -printf '%P\n' 2>/dev/null|
26278                       sort -u | wc -l)
26279
26280         [ $params -eq $procs ] ||
26281                 error "found $params parameters vs. $procs proc files"
26282
26283         # test the list_param -D option only returns directories
26284         params=$($LCTL list_param -R -D '*' 2>/dev/null | wc -l)
26285         #count the number of parameters by listing proc directories
26286         procs=$(find -L $proc_dirs -mindepth 1 -type d -printf '%P\n' 2>/dev/null |
26287                 sort -u | wc -l)
26288
26289         [ $params -eq $procs ] ||
26290                 error "found $params parameters vs. $procs proc files"
26291 }
26292 run_test 401a "Verify if 'lctl list_param -R' can list parameters recursively"
26293
26294 test_401b() {
26295         # jobid_var may not allow arbitrary values, so use jobid_name
26296         # if available
26297         if $LCTL list_param jobid_name > /dev/null 2>&1; then
26298                 local testname=jobid_name tmp='testing%p'
26299         else
26300                 local testname=jobid_var tmp=testing
26301         fi
26302
26303         local save=$($LCTL get_param -n $testname)
26304
26305         $LCTL set_param foo=bar $testname=$tmp bar=baz &&
26306                 error "no error returned when setting bad parameters"
26307
26308         local jobid_new=$($LCTL get_param -n foe $testname baz)
26309         [[ "$jobid_new" == "$tmp" ]] || error "jobid tmp $jobid_new != $tmp"
26310
26311         $LCTL set_param -n fog=bam $testname=$save bat=fog
26312         local jobid_old=$($LCTL get_param -n foe $testname bag)
26313         [[ "$jobid_old" == "$save" ]] || error "jobid new $jobid_old != $save"
26314 }
26315 run_test 401b "Verify 'lctl {get,set}_param' continue after error"
26316
26317 test_401c() {
26318         # jobid_var may not allow arbitrary values, so use jobid_name
26319         # if available
26320         if $LCTL list_param jobid_name > /dev/null 2>&1; then
26321                 local testname=jobid_name
26322         else
26323                 local testname=jobid_var
26324         fi
26325
26326         local jobid_var_old=$($LCTL get_param -n $testname)
26327         local jobid_var_new
26328
26329         $LCTL set_param $testname= &&
26330                 error "no error returned for 'set_param a='"
26331
26332         jobid_var_new=$($LCTL get_param -n $testname)
26333         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
26334                 error "$testname was changed by setting without value"
26335
26336         $LCTL set_param $testname &&
26337                 error "no error returned for 'set_param a'"
26338
26339         jobid_var_new=$($LCTL get_param -n $testname)
26340         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
26341                 error "$testname was changed by setting without value"
26342 }
26343 run_test 401c "Verify 'lctl set_param' without value fails in either format."
26344
26345 test_401d() {
26346         # jobid_var may not allow arbitrary values, so use jobid_name
26347         # if available
26348         if $LCTL list_param jobid_name > /dev/null 2>&1; then
26349                 local testname=jobid_name new_value='foo=bar%p'
26350         else
26351                 local testname=jobid_var new_valuie=foo=bar
26352         fi
26353
26354         local jobid_var_old=$($LCTL get_param -n $testname)
26355         local jobid_var_new
26356
26357         $LCTL set_param $testname=$new_value ||
26358                 error "'set_param a=b' did not accept a value containing '='"
26359
26360         jobid_var_new=$($LCTL get_param -n $testname)
26361         [[ "$jobid_var_new" == "$new_value" ]] ||
26362                 error "'set_param a=b' failed on a value containing '='"
26363
26364         # Reset the $testname to test the other format
26365         $LCTL set_param $testname=$jobid_var_old
26366         jobid_var_new=$($LCTL get_param -n $testname)
26367         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
26368                 error "failed to reset $testname"
26369
26370         $LCTL set_param $testname $new_value ||
26371                 error "'set_param a b' did not accept a value containing '='"
26372
26373         jobid_var_new=$($LCTL get_param -n $testname)
26374         [[ "$jobid_var_new" == "$new_value" ]] ||
26375                 error "'set_param a b' failed on a value containing '='"
26376
26377         $LCTL set_param $testname $jobid_var_old
26378         jobid_var_new=$($LCTL get_param -n $testname)
26379         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
26380                 error "failed to reset $testname"
26381 }
26382 run_test 401d "Verify 'lctl set_param' accepts values containing '='"
26383
26384 test_401e() { # LU-14779
26385         $LCTL list_param -R "ldlm.namespaces.MGC*" ||
26386                 error "lctl list_param MGC* failed"
26387         $LCTL get_param "ldlm.namespaces.MGC*" || error "lctl get_param failed"
26388         $LCTL get_param "ldlm.namespaces.MGC*.lru_size" ||
26389                 error "lctl get_param lru_size failed"
26390 }
26391 run_test 401e "verify 'lctl get_param' works with NID in parameter"
26392
26393 test_402() {
26394         [[ $MDS1_VERSION -ge $(version_code 2.7.66) ]] ||
26395         [[ $MDS1_VERSION -ge $(version_code 2.7.18.4) &&
26396                 $MDS1_VERSION -lt $(version_code 2.7.50) ]] ||
26397         [[ $MDS1_VERSION -ge $(version_code 2.7.2) &&
26398                 $MDS1_VERSION -lt $(version_code 2.7.11) ]] ||
26399                 skip "Need MDS version 2.7.2+ or 2.7.18.4+ or 2.7.66+"
26400         remote_mds_nodsh && skip "remote MDS with nodsh"
26401
26402         $LFS setdirstripe -i 0 $DIR/$tdir || error "setdirstripe -i 0 failed"
26403 #define OBD_FAIL_MDS_FLD_LOOKUP 0x15c
26404         do_facet mds1 "lctl set_param fail_loc=0x8000015c"
26405         touch $DIR/$tdir/$tfile && error "touch should fail with ENOENT" ||
26406                 echo "Touch failed - OK"
26407 }
26408 run_test 402 "Return ENOENT to lod_generate_and_set_lovea"
26409
26410 test_403() {
26411         local file1=$DIR/$tfile.1
26412         local file2=$DIR/$tfile.2
26413         local tfile=$TMP/$tfile
26414
26415         rm -f $file1 $file2 $tfile
26416
26417         touch $file1
26418         ln $file1 $file2
26419
26420         # 30 sec OBD_TIMEOUT in ll_getattr()
26421         # right before populating st_nlink
26422         $LCTL set_param fail_loc=0x80001409
26423         stat -c %h $file1 > $tfile &
26424
26425         # create an alias, drop all locks and reclaim the dentry
26426         < $file2
26427         cancel_lru_locks mdc
26428         cancel_lru_locks osc
26429         sysctl -w vm.drop_caches=2
26430
26431         wait
26432
26433         [ $(cat $tfile) -gt 0 ] || error "wrong nlink count: $(cat $tfile)"
26434
26435         rm -f $tfile $file1 $file2
26436 }
26437 run_test 403 "i_nlink should not drop to zero due to aliasing"
26438
26439 test_404() { # LU-6601
26440         [[ $MDS1_VERSION -ge $(version_code 2.8.53) ]] ||
26441                 skip "Need server version newer than 2.8.52"
26442         remote_mds_nodsh && skip "remote MDS with nodsh"
26443
26444         local mosps=$(do_facet $SINGLEMDS $LCTL dl |
26445                 awk '/osp .*-osc-MDT/ { print $4}')
26446
26447         local osp
26448         for osp in $mosps; do
26449                 echo "Deactivate: " $osp
26450                 do_facet $SINGLEMDS $LCTL --device %$osp deactivate
26451                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
26452                         awk -vp=$osp '$4 == p { print $2 }')
26453                 [ $stat = IN ] || {
26454                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
26455                         error "deactivate error"
26456                 }
26457                 echo "Activate: " $osp
26458                 do_facet $SINGLEMDS $LCTL --device %$osp activate
26459                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
26460                         awk -vp=$osp '$4 == p { print $2 }')
26461                 [ $stat = UP ] || {
26462                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
26463                         error "activate error"
26464                 }
26465         done
26466 }
26467 run_test 404 "validate manual {de}activated works properly for OSPs"
26468
26469 test_405() {
26470         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
26471         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] ||
26472                 [ $CLIENT_VERSION -lt $(version_code 2.6.99) ] &&
26473                         skip "Layout swap lock is not supported"
26474
26475         check_swap_layouts_support
26476         check_swap_layout_no_dom $DIR
26477
26478         test_mkdir $DIR/$tdir
26479         swap_lock_test -d $DIR/$tdir ||
26480                 error "One layout swap locked test failed"
26481 }
26482 run_test 405 "Various layout swap lock tests"
26483
26484 test_406() {
26485         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26486         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
26487         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
26488         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26489         [ $MDS1_VERSION -lt $(version_code 2.8.50) ] &&
26490                 skip "Need MDS version at least 2.8.50"
26491
26492         local def_stripe_size=$($LFS getstripe -S $MOUNT)
26493         local test_pool=$TESTNAME
26494
26495         pool_add $test_pool || error "pool_add failed"
26496         pool_add_targets $test_pool 0 $(($OSTCOUNT - 1)) 1 ||
26497                 error "pool_add_targets failed"
26498
26499         save_layout_restore_at_exit $MOUNT
26500
26501         # parent set default stripe count only, child will stripe from both
26502         # parent and fs default
26503         $LFS setstripe -c 1 -i 1 -S $((def_stripe_size * 2)) -p $test_pool $MOUNT ||
26504                 error "setstripe $MOUNT failed"
26505         $LFS mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
26506         $LFS setstripe -c $OSTCOUNT $DIR/$tdir || error "setstripe $tdir failed"
26507         for i in $(seq 10); do
26508                 local f=$DIR/$tdir/$tfile.$i
26509                 touch $f || error "touch failed"
26510                 local count=$($LFS getstripe -c $f)
26511                 [ $count -eq $OSTCOUNT ] ||
26512                         error "$f stripe count $count != $OSTCOUNT"
26513                 local offset=$($LFS getstripe -i $f)
26514                 [ $offset -eq 1 ] || error "$f stripe offset $offset != 1"
26515                 local size=$($LFS getstripe -S $f)
26516                 [ $size -eq $((def_stripe_size * 2)) ] ||
26517                         error "$f stripe size $size != $((def_stripe_size * 2))"
26518                 local pool=$($LFS getstripe -p $f)
26519                 [ $pool == $test_pool ] || error "$f pool $pool != $test_pool"
26520         done
26521
26522         # change fs default striping, delete parent default striping, now child
26523         # will stripe from new fs default striping only
26524         $LFS setstripe -c 1 -S $def_stripe_size -i 0 $MOUNT ||
26525                 error "change $MOUNT default stripe failed"
26526         $LFS setstripe -c 0 $DIR/$tdir ||
26527                 error "delete $tdir default stripe failed"
26528         for i in $(seq 11 20); do
26529                 local f=$DIR/$tdir/$tfile.$i
26530                 touch $f || error "touch $f failed"
26531                 local count=$($LFS getstripe -c $f)
26532                 [ $count -eq 1 ] || error "$f stripe count $count != 1"
26533                 local offset=$($LFS getstripe -i $f)
26534                 [ $offset -eq 0 ] || error "$f stripe offset $offset != 0"
26535                 local size=$($LFS getstripe -S $f)
26536                 [ $size -eq $def_stripe_size ] ||
26537                         error "$f stripe size $size != $def_stripe_size"
26538                 local pool=$($LFS getstripe -p $f)
26539                 [ $pool == $test_pool ] || error "$f pool $pool isn't set"
26540         done
26541
26542         unlinkmany $DIR/$tdir/$tfile. 1 20
26543
26544         local f=$DIR/$tdir/$tfile
26545         pool_remove_all_targets $test_pool $f
26546         pool_remove $test_pool $f
26547 }
26548 run_test 406 "DNE support fs default striping"
26549
26550 test_407() {
26551         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26552         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
26553                 skip "Need MDS version at least 2.8.55"
26554         remote_mds_nodsh && skip "remote MDS with nodsh"
26555
26556         $LFS mkdir -i 0 -c 1 $DIR/$tdir.0 ||
26557                 error "$LFS mkdir -i 0 -c 1 $tdir.0 failed"
26558         $LFS mkdir -i 1 -c 1 $DIR/$tdir.1 ||
26559                 error "$LFS mkdir -i 1 -c 1 $tdir.1 failed"
26560         touch $DIR/$tdir.0/$tfile.0 || error "touch $tdir.0/$tfile.0 failed"
26561
26562         #define OBD_FAIL_DT_TXN_STOP    0x2019
26563         for idx in $(seq $MDSCOUNT); do
26564                 do_facet mds$idx "lctl set_param fail_loc=0x2019"
26565         done
26566         $LFS mkdir -c 2 $DIR/$tdir && error "$LFS mkdir -c 2 $tdir should fail"
26567         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1/$tfile.1 &&
26568                 error "mv $tdir.0/$tfile.0 $tdir.1/$tfile.1 should fail"
26569         true
26570 }
26571 run_test 407 "transaction fail should cause operation fail"
26572
26573 test_408() {
26574         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
26575
26576         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
26577         lctl set_param fail_loc=0x8000040a
26578         # let ll_prepare_partial_page() fail
26579         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 conv=notrunc || true
26580
26581         rm -f $DIR/$tfile
26582
26583         # create at least 100 unused inodes so that
26584         # shrink_icache_memory(0) should not return 0
26585         touch $DIR/$tfile-{0..100}
26586         rm -f $DIR/$tfile-{0..100}
26587         sync
26588
26589         echo 2 > /proc/sys/vm/drop_caches
26590 }
26591 run_test 408 "drop_caches should not hang due to page leaks"
26592
26593 test_409()
26594 {
26595         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
26596
26597         mkdir -p $DIR/$tdir || error "(0) Fail to mkdir"
26598         $LFS mkdir -i 1 -c 2 $DIR/$tdir/foo || error "(1) Fail to mkdir"
26599         touch $DIR/$tdir/guard || error "(2) Fail to create"
26600
26601         local PREFIX=$(str_repeat 'A' 128)
26602         echo "Create 1K hard links start at $(date)"
26603         createmany -l $DIR/$tdir/guard $DIR/$tdir/foo/${PREFIX}_ 1000 ||
26604                 error "(3) Fail to hard link"
26605
26606         echo "Links count should be right although linkEA overflow"
26607         stat $DIR/$tdir/guard || error "(4) Fail to stat"
26608         local linkcount=$(stat --format=%h $DIR/$tdir/guard)
26609         [ $linkcount -eq 1001 ] ||
26610                 error "(5) Unexpected hard links count: $linkcount"
26611
26612         echo "List all links start at $(date)"
26613         ls -l $DIR/$tdir/foo > /dev/null ||
26614                 error "(6) Fail to list $DIR/$tdir/foo"
26615
26616         echo "Unlink hard links start at $(date)"
26617         unlinkmany $DIR/$tdir/foo/${PREFIX}_ 1000 ||
26618                 error "(7) Fail to unlink"
26619         echo "Unlink hard links finished at $(date)"
26620 }
26621 run_test 409 "Large amount of cross-MDTs hard links on the same file"
26622
26623 test_410()
26624 {
26625         [[ $CLIENT_VERSION -lt $(version_code 2.9.59) ]] &&
26626                 skip "Need client version at least 2.9.59"
26627         [ -f $LUSTRE/tests/kernel/kinode.ko ] ||
26628                 skip "Need MODULES build"
26629
26630         # Create a file, and stat it from the kernel
26631         local testfile=$DIR/$tfile
26632         touch $testfile
26633
26634         local run_id=$RANDOM
26635         local my_ino=$(stat --format "%i" $testfile)
26636
26637         # Try to insert the module. This will always fail as the
26638         # module is designed to not be inserted.
26639         insmod $LUSTRE/tests/kernel/kinode.ko run_id=$run_id fname=$testfile \
26640             &> /dev/null
26641
26642         # Anything but success is a test failure
26643         dmesg | grep -q \
26644             "lustre_kinode_$run_id: inode numbers are identical: $my_ino" ||
26645             error "no inode match"
26646 }
26647 run_test 410 "Test inode number returned from kernel thread"
26648
26649 cleanup_test411_cgroup() {
26650         trap 0
26651         rmdir "$1"
26652 }
26653
26654 test_411() {
26655         local cg_basedir=/sys/fs/cgroup/memory
26656         # LU-9966
26657         test -f "$cg_basedir/memory.kmem.limit_in_bytes" ||
26658                 skip "no setup for cgroup"
26659
26660         dd if=/dev/zero of=$DIR/$tfile bs=1M count=100 conv=fsync ||
26661                 error "test file creation failed"
26662         cancel_lru_locks osc
26663
26664         # Create a very small memory cgroup to force a slab allocation error
26665         local cgdir=$cg_basedir/osc_slab_alloc
26666         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
26667         trap "cleanup_test411_cgroup $cgdir" EXIT
26668         echo 2M > $cgdir/memory.kmem.limit_in_bytes
26669         echo 1M > $cgdir/memory.limit_in_bytes
26670
26671         # Should not LBUG, just be killed by oom-killer
26672         # dd will return 0 even allocation failure in some environment.
26673         # So don't check return value
26674         bash -c "echo \$$ > $cgdir/tasks && dd if=$DIR/$tfile of=/dev/null"
26675         cleanup_test411_cgroup $cgdir
26676
26677         return 0
26678 }
26679 run_test 411 "Slab allocation error with cgroup does not LBUG"
26680
26681 test_412() {
26682         (( $MDSCOUNT > 1 )) || skip_env "needs >= 2 MDTs"
26683         (( $MDS1_VERSION >= $(version_code 2.10.55) )) ||
26684                 skip "Need server version at least 2.10.55"
26685
26686         $LFS mkdir -i $((MDSCOUNT - 1)),$((MDSCOUNT - 2)) $DIR/$tdir ||
26687                 error "mkdir failed"
26688         $LFS getdirstripe $DIR/$tdir
26689         local stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
26690         [ $stripe_index -eq $((MDSCOUNT - 1)) ] ||
26691                 error "expect $((MDSCOUT - 1)) get $stripe_index"
26692         local stripe_count=$($LFS getdirstripe -T $DIR/$tdir)
26693         [ $stripe_count -eq 2 ] ||
26694                 error "expect 2 get $stripe_count"
26695
26696         (( $MDS1_VERSION >= $(version_code 2.14.55) )) || return 0
26697
26698         local index
26699         local index2
26700
26701         # subdirs should be on the same MDT as parent
26702         for i in $(seq 0 $((MDSCOUNT - 1))); do
26703                 $LFS mkdir -i $i $DIR/$tdir/mdt$i || error "mkdir mdt$i failed"
26704                 mkdir $DIR/$tdir/mdt$i/sub || error "mkdir sub failed"
26705                 index=$($LFS getstripe -m $DIR/$tdir/mdt$i/sub)
26706                 (( index == i )) || error "mdt$i/sub on MDT$index"
26707         done
26708
26709         # stripe offset -1, ditto
26710         for i in {1..10}; do
26711                 $LFS mkdir -i -1 $DIR/$tdir/qos$i || error "mkdir qos$i failed"
26712                 index=$($LFS getstripe -m $DIR/$tdir/qos$i)
26713                 mkdir $DIR/$tdir/qos$i/sub || error "mkdir sub failed"
26714                 index2=$($LFS getstripe -m $DIR/$tdir/qos$i/sub)
26715                 (( index == index2 )) ||
26716                         error "qos$i on MDT$index, sub on MDT$index2"
26717         done
26718
26719         local testdir=$DIR/$tdir/inherit
26720
26721         $LFS mkdir -i 1 --max-inherit=3 $testdir || error "mkdir inherit failed"
26722         # inherit 2 levels
26723         for i in 1 2; do
26724                 testdir=$testdir/s$i
26725                 mkdir $testdir || error "mkdir $testdir failed"
26726                 index=$($LFS getstripe -m $testdir)
26727                 (( index == 1 )) ||
26728                         error "$testdir on MDT$index"
26729         done
26730
26731         # not inherit any more
26732         testdir=$testdir/s3
26733         mkdir $testdir || error "mkdir $testdir failed"
26734         getfattr -d -m dmv $testdir | grep dmv &&
26735                 error "default LMV set on $testdir" || true
26736 }
26737 run_test 412 "mkdir on specific MDTs"
26738
26739 TEST413_COUNT=${TEST413_COUNT:-200}
26740
26741 #
26742 # set_maxage() is used by test_413 only.
26743 # This is a helper function to set maxage. Does not return any value.
26744 # Input: maxage to set
26745 #
26746 set_maxage() {
26747         local lmv_qos_maxage
26748         local lod_qos_maxage
26749         local new_maxage=$1
26750
26751         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
26752         $LCTL set_param lmv.*.qos_maxage=$new_maxage
26753         stack_trap "$LCTL set_param \
26754                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null"
26755         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
26756                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
26757         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
26758                 lod.*.mdt_qos_maxage=$new_maxage
26759         stack_trap "do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
26760                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null"
26761 }
26762
26763 generate_uneven_mdts() {
26764         local threshold=$1
26765         local ffree
26766         local bavail
26767         local max
26768         local min
26769         local max_index
26770         local min_index
26771         local tmp
26772         local i
26773
26774         echo
26775         echo "Check for uneven MDTs: "
26776
26777         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
26778         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
26779         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
26780
26781         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
26782         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
26783         max_index=0
26784         min_index=0
26785         for ((i = 1; i < ${#ffree[@]}; i++)); do
26786                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
26787                 if [ $tmp -gt $max ]; then
26788                         max=$tmp
26789                         max_index=$i
26790                 fi
26791                 if [ $tmp -lt $min ]; then
26792                         min=$tmp
26793                         min_index=$i
26794                 fi
26795         done
26796
26797         (( min > 0 )) || skip "low space on MDT$min_index"
26798         (( ${ffree[min_index]} > 0 )) ||
26799                 skip "no free files on MDT$min_index"
26800         (( ${ffree[min_index]} < 10000000 )) ||
26801                 skip "too many free files on MDT$min_index"
26802
26803         # Check if we need to generate uneven MDTs
26804         local diff=$(((max - min) * 100 / min))
26805         local testdirp=$DIR/$tdir-fillmdt # parent fill folder
26806         local testdir # individual folder within $testdirp
26807         local start
26808         local cmd
26809
26810         # fallocate is faster to consume space on MDT, if available
26811         if check_fallocate_supported mds$((min_index + 1)); then
26812                 cmd="fallocate -l 128K "
26813         else
26814                 cmd="dd if=/dev/zero bs=128K count=1 of="
26815         fi
26816
26817         echo "using cmd $cmd"
26818         for (( i = 0; diff < threshold; i++ )); do
26819                 testdir=${testdirp}/$i
26820                 [ -d $testdir ] && continue
26821
26822                 (( i % 10 > 0 )) || { $LFS df; $LFS df -i; }
26823
26824                 mkdir -p $testdirp
26825                 # generate uneven MDTs, create till $threshold% diff
26826                 echo -n "weight diff=$diff% must be > $threshold% ..."
26827                 echo "Fill MDT$min_index with $TEST413_COUNT files: loop $i"
26828                 $LFS mkdir -i $min_index $testdir ||
26829                         error "mkdir $testdir failed"
26830                 $LFS setstripe -E 1M -L mdt $testdir ||
26831                         error "setstripe $testdir failed"
26832                 start=$SECONDS
26833                 for (( f = 0; f < TEST413_COUNT; f++ )); do
26834                         $cmd$testdir/f.$f &> /dev/null || error "$cmd $f failed"
26835                 done
26836                 sync; sleep 1; sync
26837
26838                 # wait for QOS to update
26839                 (( SECONDS < start + 2 )) && sleep $((start + 2 - SECONDS))
26840
26841                 ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-*.filesfree))
26842                 bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-*.kbytesavail))
26843                 max=$(((${ffree[max_index]} >> 8) *
26844                         (${bavail[max_index]} * bsize >> 16)))
26845                 min=$(((${ffree[min_index]} >> 8) *
26846                         (${bavail[min_index]} * bsize >> 16)))
26847                 (( min > 0 )) || skip "low space on MDT$min_index"
26848                 diff=$(((max - min) * 100 / min))
26849         done
26850
26851         echo "MDT filesfree available: ${ffree[*]}"
26852         echo "MDT blocks available: ${bavail[*]}"
26853         echo "weight diff=$diff%"
26854 }
26855
26856 test_qos_mkdir() {
26857         local mkdir_cmd=$1
26858         local stripe_count=$2
26859         local mdts=$(comma_list $(mdts_nodes))
26860
26861         local testdir
26862         local lmv_qos_prio_free
26863         local lmv_qos_threshold_rr
26864         local lod_qos_prio_free
26865         local lod_qos_threshold_rr
26866         local total
26867         local count
26868         local i
26869
26870         # @total is total directories created if it's testing plain
26871         # directories, otherwise it's total stripe object count for
26872         # striped directories test.
26873         # remote/striped directory unlinking is slow on zfs and may
26874         # timeout, test with fewer directories
26875         [ "$mds1_FSTYPE" = "zfs" ] && total=120 || total=240
26876
26877         lmv_qos_prio_free=$($LCTL get_param -n lmv.*.qos_prio_free | head -n1)
26878         lmv_qos_prio_free=${lmv_qos_prio_free%%%}
26879         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
26880                 head -n1)
26881         lmv_qos_threshold_rr=${lmv_qos_threshold_rr%%%}
26882         stack_trap "$LCTL set_param \
26883                 lmv.*.qos_prio_free=$lmv_qos_prio_free > /dev/null"
26884         stack_trap "$LCTL set_param \
26885                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null"
26886
26887         lod_qos_prio_free=$(do_facet mds1 $LCTL get_param -n \
26888                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_prio_free | head -n1)
26889         lod_qos_prio_free=${lod_qos_prio_free%%%}
26890         lod_qos_threshold_rr=$(do_facet mds1 $LCTL get_param -n \
26891                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_threshold_rr | head -n1)
26892         lod_qos_threshold_rr=${lod_qos_threshold_rr%%%}
26893         stack_trap "do_nodes $mdts $LCTL set_param \
26894                 lod.*.mdt_qos_prio_free=$lod_qos_prio_free > /dev/null"
26895         stack_trap "do_nodes $mdts $LCTL set_param \
26896                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null"
26897
26898         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
26899         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=100 > /dev/null
26900
26901         testdir=$DIR/$tdir-s$stripe_count/rr
26902
26903         local stripe_index=$($LFS getstripe -m $testdir)
26904         local test_mkdir_rr=true
26905
26906         getfattr -d -m dmv -e hex $testdir | grep dmv
26907         if (( $? == 0 && $MDS1_VERSION >= $(version_code 2.14.51) )); then
26908                 echo "defstripe: '$($LFS getdirstripe -D $testdir)'"
26909                 (( $($LFS getdirstripe -D --max-inherit-rr $testdir) == 0 )) &&
26910                         test_mkdir_rr=false
26911         fi
26912
26913         echo
26914         $test_mkdir_rr &&
26915                 echo "Mkdir (stripe_count $stripe_count) roundrobin:" ||
26916                 echo "Mkdir (stripe_count $stripe_count) on stripe $stripe_index"
26917
26918         stack_trap "unlinkmany -d $testdir/subdir $((total / stripe_count))"
26919         for (( i = 0; i < total / stripe_count; i++ )); do
26920                 eval $mkdir_cmd $testdir/subdir$i ||
26921                         error "$mkdir_cmd subdir$i failed"
26922         done
26923
26924         for (( i = 0; i < $MDSCOUNT; i++ )); do
26925                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
26926                 echo "$count directories created on MDT$i"
26927                 if $test_mkdir_rr; then
26928                         (( count == total / stripe_count / MDSCOUNT )) ||
26929                                 error "subdirs are not evenly distributed"
26930                 elif (( i == stripe_index )); then
26931                         (( count == total / stripe_count )) ||
26932                                 error "$count subdirs created on MDT$i"
26933                 else
26934                         (( count == 0 )) ||
26935                                 error "$count subdirs created on MDT$i"
26936                 fi
26937
26938                 if $test_mkdir_rr && [ $stripe_count -gt 1 ]; then
26939                         count=$($LFS getdirstripe $testdir/* |
26940                                 grep -c -P "^\s+$i\t")
26941                         echo "$count stripes created on MDT$i"
26942                         # deviation should < 5% of average
26943                         delta=$((count - total / MDSCOUNT))
26944                         (( ${delta#-} <= total / MDSCOUNT / 20 )) ||
26945                                 error "stripes are not evenly distributed"
26946                 fi
26947         done
26948
26949         echo
26950         echo "Check for uneven MDTs: "
26951
26952         local ffree
26953         local bavail
26954         local max
26955         local min
26956         local max_index
26957         local min_index
26958         local tmp
26959
26960         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
26961         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
26962         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
26963
26964         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
26965         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
26966         max_index=0
26967         min_index=0
26968         for ((i = 1; i < ${#ffree[@]}; i++)); do
26969                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
26970                 if [ $tmp -gt $max ]; then
26971                         max=$tmp
26972                         max_index=$i
26973                 fi
26974                 if [ $tmp -lt $min ]; then
26975                         min=$tmp
26976                         min_index=$i
26977                 fi
26978         done
26979         echo "stripe_count=$stripe_count min_idx=$min_index max_idx=$max_index"
26980
26981         (( min > 0 )) || skip "low space on MDT$min_index"
26982         (( ${ffree[min_index]} < 10000000 )) ||
26983                 skip "too many free files on MDT$min_index"
26984
26985         generate_uneven_mdts 120
26986
26987         echo "MDT filesfree available: ${ffree[*]}"
26988         echo "MDT blocks available: ${bavail[*]}"
26989         echo "weight diff=$(((max - min) * 100 / min))%"
26990         echo
26991         echo "Mkdir (stripe_count $stripe_count) with balanced space usage:"
26992
26993         $LCTL set_param lmv.*.qos_threshold_rr=0 > /dev/null
26994         $LCTL set_param lmv.*.qos_prio_free=100 > /dev/null
26995         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=0 > /dev/null
26996         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_prio_free=100 > /dev/null
26997         # decrease statfs age, so that it can be updated in time
26998         $LCTL set_param lmv.*.qos_maxage=1 > /dev/null
26999         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_maxage=1 > /dev/null
27000
27001         sleep 1
27002
27003         testdir=$DIR/$tdir-s$stripe_count/qos
27004
27005         stack_trap "unlinkmany -d $testdir/subdir $((total / stripe_count))"
27006         for (( i = 0; i < total / stripe_count; i++ )); do
27007                 eval $mkdir_cmd $testdir/subdir$i ||
27008                         error "$mkdir_cmd subdir$i failed"
27009         done
27010
27011         max=0
27012         for (( i = 0; i < $MDSCOUNT; i++ )); do
27013                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
27014                 (( count > max )) && max=$count
27015                 echo "$count directories created on MDT$i : curmax=$max"
27016         done
27017
27018         min=$($LFS getdirstripe -i $testdir/* | grep -c "^$min_index$")
27019
27020         # D-value should > 10% of average
27021         (( max - min > total / stripe_count / MDSCOUNT / 10 )) ||
27022                 error "subdirs shouldn't be evenly distributed: $max - $min <= $((total / stripe_count / MDSCOUNT / 10))"
27023
27024         # ditto for stripes
27025         if (( stripe_count > 1 )); then
27026                 max=0
27027                 for (( i = 0; i < $MDSCOUNT; i++ )); do
27028                         count=$($LFS getdirstripe $testdir/* |
27029                                 grep -c -P "^\s+$i\t")
27030                         (( count > max )) && max=$count
27031                         echo "$count stripes created on MDT$i"
27032                 done
27033
27034                 min=$($LFS getdirstripe $testdir/* |
27035                         grep -c -P "^\s+$min_index\t")
27036                 (( max - min > total / MDSCOUNT / 10 )) ||
27037                         error "stripes shouldn't be evenly distributed: $max - $min <= $((total / MDSCOUNT / 10))"
27038         fi
27039 }
27040
27041 most_full_mdt() {
27042         local ffree
27043         local bavail
27044         local bsize
27045         local min
27046         local min_index
27047         local tmp
27048
27049         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
27050         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
27051         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
27052
27053         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
27054         min_index=0
27055         for ((i = 1; i < ${#ffree[@]}; i++)); do
27056                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
27057                 (( tmp < min )) && min=$tmp && min_index=$i
27058         done
27059
27060         echo -n $min_index
27061 }
27062
27063 test_413a() {
27064         [ $MDSCOUNT -lt 2 ] &&
27065                 skip "We need at least 2 MDTs for this test"
27066
27067         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
27068                 skip "Need server version at least 2.12.52"
27069
27070         local stripe_max=$((MDSCOUNT - 1))
27071         local stripe_count
27072
27073         # let caller set maxage for latest result
27074         set_maxage 1
27075
27076         # fill MDT unevenly
27077         generate_uneven_mdts 120
27078
27079         # test 4-stripe directory at most, otherwise it's too slow
27080         # We are being very defensive. Although Autotest uses 4 MDTs.
27081         # We make sure stripe_max does not go over 4.
27082         (( stripe_max > 4 )) && stripe_max=4
27083         # unlinking striped directory is slow on zfs, and may timeout, only test
27084         # plain directory
27085         [ "$mds1_FSTYPE" == "zfs" ] && stripe_max=1
27086         for stripe_count in $(seq 1 $stripe_max); do
27087                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
27088                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
27089                 $LFS mkdir -i $(most_full_mdt) $DIR/$tdir-s$stripe_count/qos ||
27090                         error "mkdir failed"
27091                 test_qos_mkdir "$LFS mkdir -i -1 -c $stripe_count" $stripe_count
27092         done
27093 }
27094 run_test 413a "QoS mkdir with 'lfs mkdir -i -1'"
27095
27096 test_413b() {
27097         [ $MDSCOUNT -lt 2 ] &&
27098                 skip "We need at least 2 MDTs for this test"
27099
27100         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
27101                 skip "Need server version at least 2.12.52"
27102
27103         local stripe_max=$((MDSCOUNT - 1))
27104         local testdir
27105         local stripe_count
27106
27107         # let caller set maxage for latest result
27108         set_maxage 1
27109
27110         # fill MDT unevenly
27111         generate_uneven_mdts 120
27112
27113         # test 4-stripe directory at most, otherwise it's too slow
27114         # We are being very defensive. Although Autotest uses 4 MDTs.
27115         # We make sure stripe_max does not go over 4.
27116         (( stripe_max > 4 )) && stripe_max=4
27117         [ "$mds1_FSTYPE" == "zfs" ] && stripe_max=1
27118         for stripe_count in $(seq 1 $stripe_max); do
27119                 testdir=$DIR/$tdir-s$stripe_count
27120                 mkdir $testdir || error "mkdir $testdir failed"
27121                 mkdir $testdir/rr || error "mkdir rr failed"
27122                 $LFS mkdir -i $(most_full_mdt) $testdir/qos ||
27123                         error "mkdir qos failed"
27124                 $LFS setdirstripe -D -c $stripe_count --max-inherit-rr 2 \
27125                         $testdir/rr || error "setdirstripe rr failed"
27126                 $LFS setdirstripe -D -c $stripe_count $testdir/qos ||
27127                         error "setdirstripe failed"
27128                 test_qos_mkdir "mkdir" $stripe_count
27129         done
27130 }
27131 run_test 413b "QoS mkdir under dir whose default LMV starting MDT offset is -1"
27132
27133 test_413c() {
27134         (( $MDSCOUNT >= 2 )) ||
27135                 skip "We need at least 2 MDTs for this test"
27136
27137         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
27138                 skip "Need server version at least 2.14.51"
27139
27140         local testdir
27141         local inherit
27142         local inherit_rr
27143         local lmv_qos_maxage
27144         local lod_qos_maxage
27145
27146         # let caller set maxage for latest result
27147         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
27148         $LCTL set_param lmv.*.qos_maxage=1
27149         stack_trap "$LCTL set_param \
27150                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null" RETURN
27151         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
27152                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
27153         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
27154                 lod.*.mdt_qos_maxage=1
27155         stack_trap "do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
27156                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null" RETURN
27157
27158         # fill MDT unevenly
27159         generate_uneven_mdts 120
27160
27161         testdir=$DIR/${tdir}-s1
27162         mkdir $testdir || error "mkdir $testdir failed"
27163         mkdir $testdir/rr || error "mkdir rr failed"
27164         $LFS mkdir -i $(most_full_mdt) $testdir/qos || error "mkdir qos failed"
27165         # default max_inherit is -1, default max_inherit_rr is 0
27166         $LFS setdirstripe -D -c 1 $testdir/rr ||
27167                 error "setdirstripe rr failed"
27168         $LFS setdirstripe -D -c 1 -i -1 -X 2 --max-inherit-rr 1 $testdir/qos ||
27169                 error "setdirstripe qos failed"
27170         test_qos_mkdir "mkdir" 1
27171
27172         mkdir $testdir/rr/level1 || error "mkdir rr/level1 failed"
27173         inherit=$($LFS getdirstripe -D -X $testdir/rr/level1)
27174         (( $inherit == -1 )) || error "rr/level1 inherit $inherit != -1"
27175         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/rr/level1)
27176         (( $inherit_rr == 0 )) || error "rr/level1 inherit-rr $inherit_rr != 0"
27177
27178         mkdir $testdir/qos/level1 || error "mkdir qos/level1 failed"
27179         inherit=$($LFS getdirstripe -D -X $testdir/qos/level1)
27180         (( $inherit == 1 )) || error "qos/level1 inherit $inherit != 1"
27181         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/qos/level1)
27182         (( $inherit_rr == 0 )) || error "qos/level1 inherit-rr $inherit_rr != 0"
27183         mkdir $testdir/qos/level1/level2 || error "mkdir level2 failed"
27184         getfattr -d -m dmv -e hex $testdir/qos/level1/level2 | grep dmv &&
27185                 error "level2 shouldn't have default LMV" || true
27186 }
27187 run_test 413c "mkdir with default LMV max inherit rr"
27188
27189 test_413d() {
27190         (( MDSCOUNT >= 2 )) ||
27191                 skip "We need at least 2 MDTs for this test"
27192
27193         (( MDS1_VERSION >= $(version_code 2.14.51) )) ||
27194                 skip "Need server version at least 2.14.51"
27195
27196         local lmv_qos_threshold_rr
27197
27198         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
27199                 head -n1)
27200         stack_trap "$LCTL set_param \
27201                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null" EXIT
27202
27203         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
27204         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
27205         getfattr -d -m dmv -e hex $DIR/$tdir | grep dmv &&
27206                 error "$tdir shouldn't have default LMV"
27207         createmany -d $DIR/$tdir/sub $((100 * MDSCOUNT)) ||
27208                 error "mkdir sub failed"
27209
27210         local count=$($LFS getstripe -m $DIR/$tdir/* | grep -c ^0)
27211
27212         (( count == 100 )) || error "$count subdirs on MDT0"
27213 }
27214 run_test 413d "inherit ROOT default LMV"
27215
27216 test_413e() {
27217         (( MDSCOUNT >= 2 )) ||
27218                 skip "We need at least 2 MDTs for this test"
27219         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
27220                 skip "Need server version at least 2.14.55"
27221
27222         local testdir=$DIR/$tdir
27223         local tmpfile=$TMP/temp.setdirstripe.stderr.$$
27224         local max_inherit
27225         local sub_max_inherit
27226
27227         mkdir -p $testdir || error "failed to create $testdir"
27228
27229         # set default max-inherit to -1 if stripe count is 0 or 1
27230         $LFS setdirstripe -D -c 1 $testdir ||
27231                 error "failed to set default LMV"
27232         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
27233         (( max_inherit == -1 )) ||
27234                 error "wrong max_inherit value $max_inherit"
27235
27236         # set default max_inherit to a fixed value if stripe count is not 0 or 1
27237         $LFS setdirstripe -D -c -1 $testdir ||
27238                 error "failed to set default LMV"
27239         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
27240         (( max_inherit > 0 )) ||
27241                 error "wrong max_inherit value $max_inherit"
27242
27243         # and the subdir will decrease the max_inherit by 1
27244         mkdir -p $testdir/subdir-1 || error "failed to make subdir"
27245         sub_max_inherit=$($LFS getdirstripe -D --max-inherit $testdir/subdir-1)
27246         (( sub_max_inherit == max_inherit - 1)) ||
27247                 error "wrong max-inherit of subdir $sub_max_inherit"
27248
27249         # check specified --max-inherit and warning message
27250         stack_trap "rm -f $tmpfile"
27251         $LFS setdirstripe -D -c 2 --max-inherit=-1 $testdir 2> $tmpfile ||
27252                 error "failed to set default LMV"
27253         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
27254         (( max_inherit == -1 )) ||
27255                 error "wrong max_inherit value $max_inherit"
27256
27257         # check the warning messages
27258         if ! [[ $(cat $tmpfile) =~ "max-inherit=" ]]; then
27259                 error "failed to detect warning string"
27260         fi
27261 }
27262 run_test 413e "check default max-inherit value"
27263
27264 test_fs_dmv_inherit()
27265 {
27266         local testdir=$DIR/$tdir
27267
27268         local count
27269         local inherit
27270         local inherit_rr
27271
27272         for i in 1 2; do
27273                 mkdir $testdir || error "mkdir $testdir failed"
27274                 count=$($LFS getdirstripe -D -c $testdir)
27275                 (( count == 1 )) ||
27276                         error "$testdir default LMV count mismatch $count != 1"
27277                 inherit=$($LFS getdirstripe -D -X $testdir)
27278                 (( inherit == 3 - i )) ||
27279                         error "$testdir default LMV max-inherit $inherit != $((3 - i))"
27280                 inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir)
27281                 (( inherit_rr == 3 - i )) ||
27282                         error "$testdir default LMV max-inherit-rr $inherit_rr != $((3 - i))"
27283                 testdir=$testdir/sub
27284         done
27285
27286         mkdir $testdir || error "mkdir $testdir failed"
27287         count=$($LFS getdirstripe -D -c $testdir)
27288         (( count == 0 )) ||
27289                 error "$testdir default LMV count not zero: $count"
27290 }
27291
27292 test_413f() {
27293         (( MDSCOUNT >= 2 )) || skip "We need at least 2 MDTs for this test"
27294
27295         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
27296                 skip "Need server version at least 2.14.55"
27297
27298         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
27299                 error "dump $DIR default LMV failed"
27300         stack_trap "setfattr --restore=$TMP/dmv.ea"
27301
27302         $LFS setdirstripe -D -i -1 -c 1 -X 3 --max-inherit-rr 3 $DIR ||
27303                 error "set $DIR default LMV failed"
27304
27305         test_fs_dmv_inherit
27306 }
27307 run_test 413f "lfs getdirstripe -D list ROOT default LMV if it's not set on dir"
27308
27309 test_413g() {
27310         (( MDSCOUNT >= 2 )) || skip "We need at least 2 MDTs for this test"
27311
27312         mkdir -p $DIR/$tdir/l2/l3/l4 || error "mkdir $tdir/l1/l2/l3 failed"
27313         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
27314                 error "dump $DIR default LMV failed"
27315         stack_trap "setfattr --restore=$TMP/dmv.ea"
27316
27317         $LFS setdirstripe -D -i -1 -c 1 -X 3 --max-inherit-rr 3 $DIR ||
27318                 error "set $DIR default LMV failed"
27319
27320         FILESET="$FILESET/$tdir/l2/l3/l4" mount_client $MOUNT2 ||
27321                 error "mount $MOUNT2 failed"
27322         stack_trap "umount_client $MOUNT2"
27323
27324         local saved_DIR=$DIR
27325
27326         export DIR=$MOUNT2
27327
27328         stack_trap "export DIR=$saved_DIR"
27329
27330         # first check filesystem-wide default LMV inheritance
27331         test_fs_dmv_inherit || error "incorrect fs default LMV inheritance"
27332
27333         # then check subdirs are spread to all MDTs
27334         createmany -d $DIR/s $((MDSCOUNT * 100)) || error "createmany failed"
27335
27336         local count=$($LFS getstripe -m $DIR/s* | sort -u | wc -l)
27337
27338         (( $count == $MDSCOUNT )) || error "dirs are spread to $count MDTs"
27339 }
27340 run_test 413g "enforce ROOT default LMV on subdir mount"
27341
27342 test_413h() {
27343         (( MDSCOUNT >= 2 )) ||
27344                 skip "We need at least 2 MDTs for this test"
27345
27346         (( MDS1_VERSION >= $(version_code 2.15.50.6) )) ||
27347                 skip "Need server version at least 2.15.50.6"
27348
27349         local lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
27350
27351         stack_trap "$LCTL set_param \
27352                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null"
27353         $LCTL set_param lmv.*.qos_maxage=1
27354
27355         local depth=5
27356         local rr_depth=4
27357         local dir=$DIR/$tdir/l1/l2/l3/l4/l5
27358         local count=$((MDSCOUNT * 20))
27359
27360         generate_uneven_mdts 50
27361
27362         mkdir -p $dir || error "mkdir $dir failed"
27363         stack_trap "rm -rf $dir"
27364         $LFS setdirstripe -D -c 1 -i -1 --max-inherit=$depth \
27365                 --max-inherit-rr=$rr_depth $dir
27366
27367         for ((d=0; d < depth + 2; d++)); do
27368                 log "dir=$dir:"
27369                 for ((sub=0; sub < count; sub++)); do
27370                         mkdir $dir/d$sub
27371                 done
27372                 $LFS getdirstripe -i $dir/d* | sort | uniq -c | sort -nr
27373                 local num=($($LFS getdirstripe -i $dir/d* | sort | uniq -c))
27374                 # subdirs within $rr_depth should be created round-robin
27375                 if (( d < rr_depth )); then
27376                         (( ${num[0]} != count )) ||
27377                                 error "all objects created on MDT ${num[1]}"
27378                 fi
27379
27380                 dir=$dir/d0
27381         done
27382 }
27383 run_test 413h "don't stick to parent for round-robin dirs"
27384
27385 test_413i() {
27386         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
27387
27388         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
27389                 skip "Need server version at least 2.14.55"
27390
27391         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
27392                 error "dump $DIR default LMV failed"
27393         stack_trap "setfattr --restore=$TMP/dmv.ea"
27394
27395         local testdir=$DIR/$tdir
27396         local def_max_rr=1
27397         local def_max=3
27398         local count
27399
27400         $LFS setdirstripe -D -i-1 -c1 --max-inherit=$def_max \
27401                 --max-inherit-rr=$def_max_rr $DIR ||
27402                 error "set $DIR default LMV failed"
27403
27404         for i in $(seq 2 3); do
27405                 def_max=$((def_max - 1))
27406                 (( def_max_rr == 0 )) || def_max_rr=$((def_max_rr - 1))
27407
27408                 mkdir $testdir
27409                 # RR is decremented and keeps zeroed once exhausted
27410                 count=$($LFS getdirstripe -D --max-inherit-rr $testdir)
27411                 (( count == def_max_rr )) ||
27412                         error_noexit "$testdir: max-inherit-rr $count != $def_max_rr"
27413
27414                 # max-inherit is decremented
27415                 count=$($LFS getdirstripe -D --max-inherit $testdir)
27416                 (( count == def_max )) ||
27417                         error_noexit "$testdir: max-inherit $count != $def_max"
27418
27419                 testdir=$testdir/d$i
27420         done
27421
27422         # d3 is the last inherited from ROOT, no inheritance anymore
27423         # i.e. no the default layout anymore
27424         mkdir -p $testdir/d4/d5
27425         count=$($LFS getdirstripe -D --max-inherit $testdir)
27426         (( count == -1 )) ||
27427                 error_noexit "$testdir: max-inherit $count != -1"
27428
27429         local p_count=$($LFS getdirstripe -i $testdir)
27430
27431         for i in $(seq 4 5); do
27432                 testdir=$testdir/d$i
27433
27434                 # the root default layout is not applied once exhausted
27435                 count=$($LFS getdirstripe -i $testdir)
27436                 (( count == p_count )) ||
27437                         error_noexit "$testdir: stripe-offset $count != parent offset $p_count"
27438         done
27439
27440         $LFS setdirstripe -i 0 $DIR/d2
27441         count=$($LFS getdirstripe -D --max-inherit $DIR/d2)
27442         (( count == -1 )) ||
27443                 error_noexit "$DIR/d2: max-inherit non-striped default $count != -1"
27444 }
27445 run_test 413i "check default layout inheritance"
27446
27447 test_413z() {
27448         local pids=""
27449         local subdir
27450         local pid
27451
27452         for subdir in $(\ls -1 -d $DIR/d413*-fillmdt/*); do
27453                 unlinkmany $subdir/f. $TEST413_COUNT &
27454                 pids="$pids $!"
27455         done
27456
27457         for pid in $pids; do
27458                 wait $pid
27459         done
27460
27461         true
27462 }
27463 run_test 413z "413 test cleanup"
27464
27465 test_414() {
27466 #define OBD_FAIL_PTLRPC_BULK_ATTACH      0x521
27467         $LCTL set_param fail_loc=0x80000521
27468         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
27469         rm -f $DIR/$tfile
27470 }
27471 run_test 414 "simulate ENOMEM in ptlrpc_register_bulk()"
27472
27473 test_415() {
27474         [[ $PARALLEL == "yes" ]] && skip "skip parallel run"
27475         (( $MDS1_VERSION >= $(version_code 2.11.52) )) ||
27476                 skip "Need server version at least 2.11.52"
27477
27478         # LU-11102
27479         local total=500
27480         local max=120
27481
27482         # this test may be slow on ZFS
27483         [[ "$mds1_FSTYPE" == "zfs" ]] && total=50
27484
27485         # though this test is designed for striped directory, let's test normal
27486         # directory too since lock is always saved as CoS lock.
27487         test_mkdir $DIR/$tdir || error "mkdir $tdir"
27488         createmany -o $DIR/$tdir/$tfile. $total || error "createmany"
27489         stack_trap "unlinkmany $DIR/$tdir/$tfile. $total || true"
27490         # if looping with ONLY_REPEAT, wait for previous deletions to finish
27491         wait_delete_completed_mds
27492
27493         # run a loop without concurrent touch to measure rename duration.
27494         # only for test debug/robustness, NOT part of COS functional test.
27495         local start_time=$SECONDS
27496         for ((i = 0; i < total; i++)); do
27497                 mrename $DIR/$tdir/$tfile.$i $DIR/$tdir/$tfile-new.$i \
27498                         > /dev/null
27499         done
27500         local baseline=$((SECONDS - start_time))
27501         echo "rename $total files without 'touch' took $baseline sec"
27502
27503         (
27504                 while true; do
27505                         touch $DIR/$tdir
27506                 done
27507         ) &
27508         local setattr_pid=$!
27509
27510         # rename files back to original name so unlinkmany works
27511         start_time=$SECONDS
27512         for ((i = 0; i < total; i++)); do
27513                 mrename $DIR/$tdir/$tfile-new.$i $DIR/$tdir/$tfile.$i\
27514                         > /dev/null
27515         done
27516         local duration=$((SECONDS - start_time))
27517
27518         kill -9 $setattr_pid
27519
27520         echo "rename $total files with 'touch' took $duration sec"
27521         (( max > 2 * baseline )) || max=$((2 * baseline + 5))
27522         (( duration <= max )) ||
27523                 error_not_in_vm "rename took $duration > $max sec"
27524 }
27525 run_test 415 "lock revoke is not missing"
27526
27527 test_416() {
27528         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
27529                 skip "Need server version at least 2.11.55"
27530
27531         # define OBD_FAIL_OSD_TXN_START    0x19a
27532         do_facet mds1 lctl set_param fail_loc=0x19a
27533
27534         lfs mkdir -c $MDSCOUNT $DIR/$tdir
27535
27536         true
27537 }
27538 run_test 416 "transaction start failure won't cause system hung"
27539
27540 cleanup_417() {
27541         trap 0
27542         do_nodes $(comma_list $(mdts_nodes)) \
27543                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=1"
27544         do_nodes $(comma_list $(mdts_nodes)) \
27545                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=1"
27546         do_nodes $(comma_list $(mdts_nodes)) \
27547                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=1"
27548 }
27549
27550 test_417() {
27551         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
27552         [[ $MDS1_VERSION -lt $(version_code 2.11.56) ]] &&
27553                 skip "Need MDS version at least 2.11.56"
27554
27555         trap cleanup_417 RETURN EXIT
27556
27557         $LFS mkdir -i 1 $DIR/$tdir.1 || error "create remote dir $tdir.1 failed"
27558         do_nodes $(comma_list $(mdts_nodes)) \
27559                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=0"
27560         $LFS migrate -m 0 $DIR/$tdir.1 &&
27561                 error "migrate dir $tdir.1 should fail"
27562
27563         do_nodes $(comma_list $(mdts_nodes)) \
27564                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=0"
27565         $LFS mkdir -i 1 $DIR/$tdir.2 &&
27566                 error "create remote dir $tdir.2 should fail"
27567
27568         do_nodes $(comma_list $(mdts_nodes)) \
27569                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=0"
27570         $LFS mkdir -c 2 $DIR/$tdir.3 &&
27571                 error "create striped dir $tdir.3 should fail"
27572         true
27573 }
27574 run_test 417 "disable remote dir, striped dir and dir migration"
27575
27576 # Checks that the outputs of df [-i] and lfs df [-i] match
27577 #
27578 # usage: check_lfs_df <blocks | inodes> <mountpoint>
27579 check_lfs_df() {
27580         local dir=$2
27581         local inodes
27582         local df_out
27583         local lfs_df_out
27584         local count
27585         local passed=false
27586
27587         # blocks or inodes
27588         [ "$1" == "blocks" ] && inodes= || inodes="-i"
27589
27590         for count in {1..100}; do
27591                 do_nodes "$CLIENTS" \
27592                         $LCTL set_param ldlm.namespaces.*.lru_size=clear
27593                 sync; sleep 0.2
27594
27595                 # read the lines of interest
27596                 df_out=($(df -P $inodes $dir | tail -n +2)) ||
27597                         error "df $inodes $dir | tail -n +2 failed"
27598                 lfs_df_out=($($LFS df $inodes $dir | grep summary:)) ||
27599                         error "lfs df $inodes $dir | grep summary: failed"
27600
27601                 # skip first substrings of each output as they are different
27602                 # "<NID>:/<fsname>" for df, "filesystem_summary:" for lfs df
27603                 # compare the two outputs
27604                 passed=true
27605                 #  skip "available" on MDT until LU-13997 is fixed.
27606                 #for i in {1..5}; do
27607                 for i in 1 2 4 5; do
27608                         [ "${df_out[i]}" != "${lfs_df_out[i]}" ] && passed=false
27609                 done
27610                 $passed && break
27611         done
27612
27613         if ! $passed; then
27614                 df -P $inodes $dir
27615                 echo
27616                 lfs df $inodes $dir
27617                 error "df and lfs df $1 output mismatch: "      \
27618                       "df ${inodes}: ${df_out[*]}, "            \
27619                       "lfs df ${inodes}: ${lfs_df_out[*]}"
27620         fi
27621 }
27622
27623 test_418() {
27624         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27625
27626         local dir=$DIR/$tdir
27627         local numfiles=$((RANDOM % 4096 + 2))
27628         local numblocks=$((RANDOM % 256 + 1))
27629
27630         wait_delete_completed
27631         test_mkdir $dir
27632
27633         # check block output
27634         check_lfs_df blocks $dir
27635         # check inode output
27636         check_lfs_df inodes $dir
27637
27638         # create a single file and retest
27639         echo "Creating a single file and testing"
27640         createmany -o $dir/$tfile- 1 &>/dev/null ||
27641                 error "creating 1 file in $dir failed"
27642         check_lfs_df blocks $dir
27643         check_lfs_df inodes $dir
27644
27645         # create a random number of files
27646         echo "Creating $((numfiles - 1)) files and testing"
27647         createmany -o $dir/$tfile- 1 $((numfiles - 1)) &>/dev/null ||
27648                 error "creating $((numfiles - 1)) files in $dir failed"
27649
27650         # write a random number of blocks to the first test file
27651         echo "Writing $numblocks 4K blocks and testing"
27652         dd if=/dev/urandom of=$dir/${tfile}-0 bs=4K conv=fsync \
27653                 count=$numblocks &>/dev/null ||
27654                 error "dd to $dir/${tfile}-0 failed"
27655
27656         # retest
27657         check_lfs_df blocks $dir
27658         check_lfs_df inodes $dir
27659
27660         unlinkmany $dir/$tfile- $numfiles &>/dev/null ||
27661                 error "unlinking $numfiles files in $dir failed"
27662 }
27663 run_test 418 "df and lfs df outputs match"
27664
27665 test_419()
27666 {
27667         local dir=$DIR/$tdir
27668
27669         mkdir -p $dir
27670         touch $dir/file
27671
27672         cancel_lru_locks mdc
27673
27674         #OBD_FAIL_LLITE_OPEN_BY_NAME    0x1410
27675         $LCTL set_param fail_loc=0x1410
27676         cat $dir/file
27677         $LCTL set_param fail_loc=0
27678         rm -rf $dir
27679 }
27680 run_test 419 "Verify open file by name doesn't crash kernel"
27681
27682 test_420()
27683 {
27684         [[ $MDS1_VERSION -ge $(version_code 2.12.53) ]] ||
27685                 skip "Need MDS version at least 2.12.53"
27686
27687         local SAVE_UMASK=$(umask)
27688         local dir=$DIR/$tdir
27689         local uname=$(getent passwd $RUNAS_ID | cut -d: -f1)
27690
27691         mkdir -p $dir
27692         umask 0000
27693         mkdir -m03777 $dir/testdir
27694         ls -dn $dir/testdir
27695         # Need to remove trailing '.' when SELinux is enabled
27696         local dirperms=$(ls -dn $dir/testdir |
27697                          awk '{ sub(/\.$/, "", $1); print $1}')
27698         [ $dirperms == "drwxrwsrwt" ] ||
27699                 error "incorrect perms on $dir/testdir"
27700
27701         su - $uname -c "PATH=$LUSTRE/tests:\$PATH; \
27702                 openfile -f O_RDONLY:O_CREAT -m 02755 $dir/testdir/testfile"
27703         ls -n $dir/testdir/testfile
27704         local fileperms=$(ls -n $dir/testdir/testfile |
27705                           awk '{ sub(/\.$/, "", $1); print $1}')
27706         [ $fileperms == "-rwxr-xr-x" ] ||
27707                 error "incorrect perms on $dir/testdir/testfile"
27708
27709         umask $SAVE_UMASK
27710 }
27711 run_test 420 "clear SGID bit on non-directories for non-members"
27712
27713 test_421a() {
27714         local cnt
27715         local fid1
27716         local fid2
27717
27718         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
27719                 skip "Need MDS version at least 2.12.54"
27720
27721         test_mkdir $DIR/$tdir
27722         createmany -o $DIR/$tdir/f 3
27723         cnt=$(ls -1 $DIR/$tdir | wc -l)
27724         [ $cnt != 3 ] && error "unexpected #files: $cnt"
27725
27726         fid1=$(lfs path2fid $DIR/$tdir/f1)
27727         fid2=$(lfs path2fid $DIR/$tdir/f2)
27728         $LFS rmfid $DIR $fid1 $fid2 || error "rmfid failed"
27729
27730         stat $DIR/$tdir/f1 && error "f1 still visible on the client"
27731         stat $DIR/$tdir/f2 && error "f2 still visible on the client"
27732
27733         cnt=$(ls -1 $DIR/$tdir | wc -l)
27734         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
27735
27736         rm -f $DIR/$tdir/f3 || error "can't remove f3"
27737         createmany -o $DIR/$tdir/f 3
27738         cnt=$(ls -1 $DIR/$tdir | wc -l)
27739         [ $cnt != 3 ] && error "unexpected #files: $cnt"
27740
27741         fid1=$(lfs path2fid $DIR/$tdir/f1)
27742         fid2=$(lfs path2fid $DIR/$tdir/f2)
27743         echo "remove using fsname $FSNAME"
27744         $LFS rmfid $FSNAME $fid1 $fid2 || error "rmfid with fsname failed"
27745
27746         cnt=$(ls -1 $DIR/$tdir | wc -l)
27747         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
27748 }
27749 run_test 421a "simple rm by fid"
27750
27751 test_421b() {
27752         local cnt
27753         local FID1
27754         local FID2
27755
27756         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
27757                 skip "Need MDS version at least 2.12.54"
27758
27759         test_mkdir $DIR/$tdir
27760         createmany -o $DIR/$tdir/f 3
27761         multiop_bg_pause $DIR/$tdir/f1 o_c || error "multiop failed to start"
27762         MULTIPID=$!
27763
27764         FID1=$(lfs path2fid $DIR/$tdir/f1)
27765         FID2=$(lfs path2fid $DIR/$tdir/f2)
27766         $LFS rmfid $DIR $FID1 $FID2 && error "rmfid didn't fail"
27767
27768         kill -USR1 $MULTIPID
27769         wait
27770
27771         cnt=$(ls $DIR/$tdir | wc -l)
27772         [ $cnt == 2 ] || error "unexpected #files after: $cnt"
27773 }
27774 run_test 421b "rm by fid on open file"
27775
27776 test_421c() {
27777         local cnt
27778         local FIDS
27779
27780         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
27781                 skip "Need MDS version at least 2.12.54"
27782
27783         test_mkdir $DIR/$tdir
27784         createmany -o $DIR/$tdir/f 3
27785         touch $DIR/$tdir/$tfile
27786         createmany -l$DIR/$tdir/$tfile $DIR/$tdir/h 180
27787         cnt=$(ls -1 $DIR/$tdir | wc -l)
27788         [ $cnt != 184 ] && error "unexpected #files: $cnt"
27789
27790         FID1=$(lfs path2fid $DIR/$tdir/$tfile)
27791         $LFS rmfid $DIR $FID1 || error "rmfid failed"
27792
27793         cnt=$(ls $DIR/$tdir | wc -l)
27794         [ $cnt == 3 ] || error "unexpected #files after: $cnt"
27795 }
27796 run_test 421c "rm by fid against hardlinked files"
27797
27798 test_421d() {
27799         local cnt
27800         local FIDS
27801
27802         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
27803                 skip "Need MDS version at least 2.12.54"
27804
27805         test_mkdir $DIR/$tdir
27806         createmany -o $DIR/$tdir/f 4097
27807         cnt=$(ls -1 $DIR/$tdir | wc -l)
27808         [ $cnt != 4097 ] && error "unexpected #files: $cnt"
27809
27810         FIDS=$(lfs path2fid $DIR/$tdir/f* | sed "s/[/][^:]*://g")
27811         $LFS rmfid $DIR $FIDS || error "rmfid failed"
27812
27813         cnt=$(ls $DIR/$tdir | wc -l)
27814         rm -rf $DIR/$tdir
27815         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
27816 }
27817 run_test 421d "rmfid en masse"
27818
27819 test_421e() {
27820         local cnt
27821         local FID
27822
27823         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
27824         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
27825                 skip "Need MDS version at least 2.12.54"
27826
27827         mkdir -p $DIR/$tdir
27828         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
27829         createmany -o $DIR/$tdir/striped_dir/f 512
27830         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
27831         [ $cnt != 512 ] && error "unexpected #files: $cnt"
27832
27833         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
27834                 sed "s/[/][^:]*://g")
27835         $LFS rmfid $DIR $FIDS || error "rmfid failed"
27836
27837         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
27838         rm -rf $DIR/$tdir
27839         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
27840 }
27841 run_test 421e "rmfid in DNE"
27842
27843 test_421f() {
27844         local cnt
27845         local FID
27846
27847         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
27848                 skip "Need MDS version at least 2.12.54"
27849
27850         test_mkdir $DIR/$tdir
27851         touch $DIR/$tdir/f
27852         cnt=$(ls -1 $DIR/$tdir | wc -l)
27853         [ $cnt != 1 ] && error "unexpected #files: $cnt"
27854
27855         FID=$(lfs path2fid $DIR/$tdir/f)
27856         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (1)"
27857         # rmfid should fail
27858         cnt=$(ls -1 $DIR/$tdir | wc -l)
27859         [ $cnt != 1 ] && error "unexpected #files after (2): $cnt"
27860
27861         chmod a+rw $DIR/$tdir
27862         ls -la $DIR/$tdir
27863         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (2)"
27864         # rmfid should fail
27865         cnt=$(ls -1 $DIR/$tdir | wc -l)
27866         [ $cnt != 1 ] && error "unexpected #files after (3): $cnt"
27867
27868         rm -f $DIR/$tdir/f
27869         $RUNAS touch $DIR/$tdir/f
27870         FID=$(lfs path2fid $DIR/$tdir/f)
27871         echo "rmfid as root"
27872         $LFS rmfid $DIR $FID || error "rmfid as root failed"
27873         cnt=$(ls -1 $DIR/$tdir | wc -l)
27874         [ $cnt == 0 ] || error "unexpected #files after (4): $cnt"
27875
27876         rm -f $DIR/$tdir/f
27877         $RUNAS touch $DIR/$tdir/f
27878         cnt=$(ls -1 $DIR/$tdir | wc -l)
27879         [ $cnt != 1 ] && error "unexpected #files (4): $cnt"
27880         FID=$(lfs path2fid $DIR/$tdir/f)
27881         # rmfid w/o user_fid2path mount option should fail
27882         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail(3)"
27883         cnt=$(ls -1 $DIR/$tdir | wc -l)
27884         [ $cnt == 1 ] || error "unexpected #files after (5): $cnt"
27885
27886         tmpdir=$(mktemp -d /tmp/lustre-XXXXXX)
27887         stack_trap "rmdir $tmpdir"
27888         mount_client $tmpdir "$MOUNT_OPTS,user_fid2path" ||
27889                 error "failed to mount client'"
27890         stack_trap "umount_client $tmpdir"
27891
27892         $RUNAS $LFS rmfid $tmpdir $FID || error "rmfid failed"
27893         # rmfid should succeed
27894         cnt=$(ls -1 $tmpdir/$tdir | wc -l)
27895         [ $cnt == 0 ] || error "unexpected #files after (6): $cnt"
27896
27897         # rmfid shouldn't allow to remove files due to dir's permission
27898         chmod a+rwx $tmpdir/$tdir
27899         touch $tmpdir/$tdir/f
27900         ls -la $tmpdir/$tdir
27901         FID=$(lfs path2fid $tmpdir/$tdir/f)
27902         $RUNAS $LFS rmfid $tmpdir $FID && error "rmfid didn't fail"
27903         return 0
27904 }
27905 run_test 421f "rmfid checks permissions"
27906
27907 test_421g() {
27908         local cnt
27909         local FIDS
27910
27911         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
27912         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
27913                 skip "Need MDS version at least 2.12.54"
27914
27915         mkdir -p $DIR/$tdir
27916         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
27917         createmany -o $DIR/$tdir/striped_dir/f 512
27918         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
27919         [ $cnt != 512 ] && error "unexpected #files: $cnt"
27920
27921         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
27922                 sed "s/[/][^:]*://g")
27923
27924         rm -f $DIR/$tdir/striped_dir/f1*
27925         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
27926         removed=$((512 - cnt))
27927
27928         # few files have been just removed, so we expect
27929         # rmfid to fail on their fids
27930         errors=$($LFS rmfid $DIR $FIDS 2>&1 | wc -l)
27931         [ $removed != $errors ] && error "$errors != $removed"
27932
27933         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
27934         rm -rf $DIR/$tdir
27935         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
27936 }
27937 run_test 421g "rmfid to return errors properly"
27938
27939 test_421h() {
27940         local mount_other
27941         local mount_ret
27942         local rmfid_ret
27943         local old_fid
27944         local fidA
27945         local fidB
27946         local fidC
27947         local fidD
27948
27949         (( MDS1_VERSION >= $(version_code 2.15.53) )) ||
27950                 skip "Need MDS version at least 2.15.53"
27951
27952         test_mkdir $DIR/$tdir
27953         test_mkdir $DIR/$tdir/subdir
27954         touch $DIR/$tdir/subdir/file0
27955         old_fid=$(lfs path2fid $DIR/$tdir/subdir/file0 | sed "s/[/][^:]*://g")
27956         echo File $DIR/$tdir/subdir/file0 FID $old_fid
27957         rm -f $DIR/$tdir/subdir/file0
27958         touch $DIR/$tdir/subdir/fileA
27959         fidA=$(lfs path2fid $DIR/$tdir/subdir/fileA | sed "s/[/][^:]*://g")
27960         echo File $DIR/$tdir/subdir/fileA FID $fidA
27961         touch $DIR/$tdir/subdir/fileB
27962         fidB=$(lfs path2fid $DIR/$tdir/subdir/fileB | sed "s/[/][^:]*://g")
27963         echo File $DIR/$tdir/subdir/fileB FID $fidB
27964         ln $DIR/$tdir/subdir/fileB $DIR/$tdir/subdir/fileB_hl
27965         touch $DIR/$tdir/subdir/fileC
27966         fidC=$(lfs path2fid $DIR/$tdir/subdir/fileC | sed "s/[/][^:]*://g")
27967         echo File $DIR/$tdir/subdir/fileC FID $fidC
27968         ln $DIR/$tdir/subdir/fileC $DIR/$tdir/fileC
27969         touch $DIR/$tdir/fileD
27970         fidD=$(lfs path2fid $DIR/$tdir/fileD | sed "s/[/][^:]*://g")
27971         echo File $DIR/$tdir/fileD FID $fidD
27972
27973         # mount another client mount point with subdirectory mount
27974         export FILESET=/$tdir/subdir
27975         mount_other=${MOUNT}_other
27976         mount_client $mount_other ${MOUNT_OPTS}
27977         mount_ret=$?
27978         export FILESET=""
27979         (( mount_ret == 0 )) || error "mount $mount_other failed"
27980
27981         echo Removing FIDs:
27982         echo $LFS rmfid $mount_other $old_fid $fidA $fidD $fidB $fidC
27983         $LFS rmfid $mount_other $old_fid $fidA $fidD $fidB $fidC
27984         rmfid_ret=$?
27985
27986         umount_client $mount_other || error "umount $mount_other failed"
27987
27988         (( rmfid_ret != 0 )) || error "rmfid should have failed"
27989
27990         # fileA should have been deleted
27991         stat $DIR/$tdir/subdir/fileA && error "fileA not deleted"
27992
27993         # fileB should have been deleted
27994         stat $DIR/$tdir/subdir/fileB && error "fileB not deleted"
27995
27996         # fileC should not have been deleted, fid also exists outside of fileset
27997         stat $DIR/$tdir/subdir/fileC || error "fileC deleted"
27998
27999         # fileD should not have been deleted, it exists outside of fileset
28000         stat $DIR/$tdir/fileD || error "fileD deleted"
28001 }
28002 run_test 421h "rmfid with fileset mount"
28003
28004 test_422() {
28005         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d1
28006         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d2
28007         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d3
28008         dd if=/dev/zero of=$DIR/$tdir/d1/file1 bs=1k count=1
28009         dd if=/dev/zero of=$DIR/$tdir/d2/file1 bs=1k count=1
28010
28011         local amc=$(at_max_get client)
28012         local amo=$(at_max_get mds1)
28013         local timeout=`lctl get_param -n timeout`
28014
28015         at_max_set 0 client
28016         at_max_set 0 mds1
28017
28018 #define OBD_FAIL_PTLRPC_PAUSE_REQ        0x50a
28019         do_facet mds1 $LCTL set_param fail_loc=0x8000050a \
28020                         fail_val=$(((2*timeout + 10)*1000))
28021         touch $DIR/$tdir/d3/file &
28022         sleep 2
28023 #define OBD_FAIL_TGT_REPLY_DATA_RACE     0x722
28024         do_facet mds1 $LCTL set_param fail_loc=0x80000722 \
28025                         fail_val=$((2*timeout + 5))
28026         mv $DIR/$tdir/d1/file1 $DIR/$tdir/d1/file2 &
28027         local pid=$!
28028         sleep 1
28029         kill -9 $pid
28030         sleep $((2 * timeout))
28031         echo kill $pid
28032         kill -9 $pid
28033         lctl mark touch
28034         touch $DIR/$tdir/d2/file3
28035         touch $DIR/$tdir/d2/file4
28036         touch $DIR/$tdir/d2/file5
28037
28038         wait
28039         at_max_set $amc client
28040         at_max_set $amo mds1
28041
28042         # LU-12838 - verify the ptlrpc thread watchdog is not always throttled
28043         do_facet mds1 "dmesg | grep 'Dumping the stack trace for debugging'" ||
28044                 error "Watchdog is always throttled"
28045 }
28046 run_test 422 "kill a process with RPC in progress"
28047
28048 stat_test() {
28049     df -h $MOUNT &
28050     df -h $MOUNT &
28051     df -h $MOUNT &
28052     df -h $MOUNT &
28053     df -h $MOUNT &
28054     df -h $MOUNT &
28055 }
28056
28057 test_423() {
28058     local _stats
28059     # ensure statfs cache is expired
28060     sleep 2;
28061
28062     _stats=$(stat_test | grep $MOUNT | sort -u | wc -l)
28063     [[ ${_stats} -ne 1 ]] && error "statfs wrong"
28064
28065     return 0
28066 }
28067 run_test 423 "statfs should return a right data"
28068
28069 test_424() {
28070 #define OBD_FAIL_PTLRPC_BULK_REPLY_ATTACH      0x522 | CFS_FAIL_ONCE
28071         $LCTL set_param fail_loc=0x80000522
28072         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
28073         rm -f $DIR/$tfile
28074 }
28075 run_test 424 "simulate ENOMEM in ptl_send_rpc bulk reply ME attach"
28076
28077 test_425() {
28078         test_mkdir -c -1 $DIR/$tdir
28079         $LFS setstripe -c -1 $DIR/$tdir
28080
28081         lru_resize_disable "" 100
28082         stack_trap "lru_resize_enable" EXIT
28083
28084         sleep 5
28085
28086         for i in $(seq $((MDSCOUNT * 125))); do
28087                 local t=$DIR/$tdir/$tfile_$i
28088
28089                 dd if=/dev/zero of=$t bs=4K count=1 > /dev/null 2>&1 ||
28090                         error_noexit "Create file $t"
28091         done
28092         stack_trap "rm -rf $DIR/$tdir" EXIT
28093
28094         for oscparam in $($LCTL list_param ldlm.namespaces.*osc-[-0-9a-f]*); do
28095                 local lru_size=$($LCTL get_param -n $oscparam.lru_size)
28096                 local lock_count=$($LCTL get_param -n $oscparam.lock_count)
28097
28098                 [ $lock_count -le $lru_size ] ||
28099                         error "osc lock count $lock_count > lru size $lru_size"
28100         done
28101
28102         for mdcparam in $($LCTL list_param ldlm.namespaces.*mdc-*); do
28103                 local lru_size=$($LCTL get_param -n $mdcparam.lru_size)
28104                 local lock_count=$($LCTL get_param -n $mdcparam.lock_count)
28105
28106                 [ $lock_count -le $lru_size ] ||
28107                         error "mdc lock count $lock_count > lru size $lru_size"
28108         done
28109 }
28110 run_test 425 "lock count should not exceed lru size"
28111
28112 test_426() {
28113         splice-test -r $DIR/$tfile
28114         splice-test -rd $DIR/$tfile
28115         splice-test $DIR/$tfile
28116         splice-test -d $DIR/$tfile
28117 }
28118 run_test 426 "splice test on Lustre"
28119
28120 test_427() {
28121         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
28122         (( $MDS1_VERSION >= $(version_code 2.12.4) )) ||
28123                 skip "Need MDS version at least 2.12.4"
28124         local log
28125
28126         mkdir $DIR/$tdir
28127         mkdir $DIR/$tdir/1
28128         mkdir $DIR/$tdir/2
28129         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/1/dir
28130         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/2/dir2
28131
28132         $LFS getdirstripe $DIR/$tdir/1/dir
28133
28134         #first setfattr for creating updatelog
28135         setfattr -n user.attr0 -v "some text" $DIR/$tdir/1/dir
28136
28137 #define OBD_FAIL_OUT_OBJECT_MISS        0x1708
28138         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param fail_loc=0x80001708
28139         setfattr -n user.attr1 -v "some text" $DIR/$tdir/1/dir &
28140         setfattr -n user.attr2 -v "another attr"  $DIR/$tdir/2/dir2 &
28141
28142         sleep 2
28143         fail mds2
28144         wait_recovery_complete mds2 $((2*TIMEOUT))
28145
28146         log=$(do_facet mds1 dmesg | tac | sed "/${TESTNAME//_/ }/,$ d")
28147         echo $log | grep "get update log failed" &&
28148                 error "update log corruption is detected" || true
28149 }
28150 run_test 427 "Failed DNE2 update request shouldn't corrupt updatelog"
28151
28152 test_428() {
28153         [ $PARALLEL == "yes" ] && skip "skip parallel run"
28154         local cache_limit=$CACHE_MAX
28155
28156         stack_trap "$LCTL set_param -n llite.*.max_cached_mb=$cache_limit"
28157         $LCTL set_param -n llite.*.max_cached_mb=64
28158
28159         mkdir $DIR/$tdir
28160         $LFS setstripe -c 1 $DIR/$tdir
28161         eval touch $DIR/$tdir/$tfile.{1..$OSTCOUNT}
28162         stack_trap "rm -f $DIR/$tdir/$tfile.*"
28163         #test write
28164         for f in $(seq 4); do
28165                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$f bs=128M count=1 &
28166         done
28167         wait
28168
28169         cancel_lru_locks osc
28170         # Test read
28171         for f in $(seq 4); do
28172                 dd if=$DIR/$tdir/$tfile.$f of=/dev/null bs=128M count=1 &
28173         done
28174         wait
28175 }
28176 run_test 428 "large block size IO should not hang"
28177
28178 test_429() { # LU-7915 / LU-10948
28179         local ll_opencache_threshold_count="llite.*.opencache_threshold_count"
28180         local testfile=$DIR/$tfile
28181         local mdc_rpcstats="mdc.$FSNAME-MDT0000-*.stats"
28182         local new_flag=1
28183         local first_rpc
28184         local second_rpc
28185         local third_rpc
28186
28187         $LCTL get_param $ll_opencache_threshold_count ||
28188                 skip "client does not have opencache parameter"
28189
28190         set_opencache $new_flag
28191         stack_trap "restore_opencache"
28192         [ $($LCTL get_param -n $ll_opencache_threshold_count) == $new_flag ] ||
28193                 error "enable opencache failed"
28194         touch $testfile
28195         # drop MDC DLM locks
28196         cancel_lru_locks mdc
28197         # clear MDC RPC stats counters
28198         $LCTL set_param $mdc_rpcstats=clear
28199
28200         # According to the current implementation, we need to run 3 times
28201         # open & close file to verify if opencache is enabled correctly.
28202         # 1st, RPCs are sent for lookup/open and open handle is released on
28203         #      close finally.
28204         # 2nd, RPC is sent for open, MDS_OPEN_LOCK is fetched automatically,
28205         #      so open handle won't be released thereafter.
28206         # 3rd, No RPC is sent out.
28207         $MULTIOP $testfile oc || error "multiop failed"
28208         first_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
28209         echo "1st: $first_rpc RPCs in flight"
28210
28211         $MULTIOP $testfile oc || error "multiop failed"
28212         second_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
28213         echo "2nd: $second_rpc RPCs in flight"
28214
28215         $MULTIOP $testfile oc || error "multiop failed"
28216         third_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
28217         echo "3rd: $third_rpc RPCs in flight"
28218
28219         #verify no MDC RPC is sent
28220         [[ $second_rpc == $third_rpc ]] || error "MDC RPC is still sent"
28221 }
28222 run_test 429 "verify if opencache flag on client side does work"
28223
28224 lseek_test_430() {
28225         local offset
28226         local file=$1
28227
28228         # data at [200K, 400K)
28229         dd if=/dev/urandom of=$file bs=256K count=1 seek=1 ||
28230                 error "256K->512K dd fails"
28231         # data at [2M, 3M)
28232         dd if=/dev/urandom of=$file bs=1M count=1 seek=2 ||
28233                 error "2M->3M dd fails"
28234         # data at [4M, 5M)
28235         dd if=/dev/urandom of=$file bs=1M count=1 seek=4 ||
28236                 error "4M->5M dd fails"
28237         echo "Data at 256K...512K, 2M...3M and 4M...5M"
28238         # start at first component hole #1
28239         printf "Seeking hole from 1000 ... "
28240         offset=$(lseek_test -l 1000 $file)
28241         echo $offset
28242         [[ $offset == 1000 ]] || error "offset $offset != 1000"
28243         printf "Seeking data from 1000 ... "
28244         offset=$(lseek_test -d 1000 $file)
28245         echo $offset
28246         [[ $offset == 262144 ]] || error "offset $offset != 262144"
28247
28248         # start at first component data block
28249         printf "Seeking hole from 300000 ... "
28250         offset=$(lseek_test -l 300000 $file)
28251         echo $offset
28252         [[ $offset == 524288 ]] || error "offset $offset != 524288"
28253         printf "Seeking data from 300000 ... "
28254         offset=$(lseek_test -d 300000 $file)
28255         echo $offset
28256         [[ $offset == 300000 ]] || error "offset $offset != 300000"
28257
28258         # start at the first component but beyond end of object size
28259         printf "Seeking hole from 1000000 ... "
28260         offset=$(lseek_test -l 1000000 $file)
28261         echo $offset
28262         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
28263         printf "Seeking data from 1000000 ... "
28264         offset=$(lseek_test -d 1000000 $file)
28265         echo $offset
28266         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
28267
28268         # start at second component stripe 2 (empty file)
28269         printf "Seeking hole from 1500000 ... "
28270         offset=$(lseek_test -l 1500000 $file)
28271         echo $offset
28272         [[ $offset == 1500000 ]] || error "offset $offset != 1500000"
28273         printf "Seeking data from 1500000 ... "
28274         offset=$(lseek_test -d 1500000 $file)
28275         echo $offset
28276         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
28277
28278         # start at second component stripe 1 (all data)
28279         printf "Seeking hole from 3000000 ... "
28280         offset=$(lseek_test -l 3000000 $file)
28281         echo $offset
28282         [[ $offset == 3145728 ]] || error "offset $offset != 3145728"
28283         printf "Seeking data from 3000000 ... "
28284         offset=$(lseek_test -d 3000000 $file)
28285         echo $offset
28286         [[ $offset == 3000000 ]] || error "offset $offset != 3000000"
28287
28288         dd if=/dev/urandom of=$file bs=640K count=1 seek=1 ||
28289                 error "2nd dd fails"
28290         echo "Add data block at 640K...1280K"
28291
28292         # start at before new data block, in hole
28293         printf "Seeking hole from 600000 ... "
28294         offset=$(lseek_test -l 600000 $file)
28295         echo $offset
28296         [[ $offset == 600000 ]] || error "offset $offset != 600000"
28297         printf "Seeking data from 600000 ... "
28298         offset=$(lseek_test -d 600000 $file)
28299         echo $offset
28300         [[ $offset == 655360 ]] || error "offset $offset != 655360"
28301
28302         # start at the first component new data block
28303         printf "Seeking hole from 1000000 ... "
28304         offset=$(lseek_test -l 1000000 $file)
28305         echo $offset
28306         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
28307         printf "Seeking data from 1000000 ... "
28308         offset=$(lseek_test -d 1000000 $file)
28309         echo $offset
28310         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
28311
28312         # start at second component stripe 2, new data
28313         printf "Seeking hole from 1200000 ... "
28314         offset=$(lseek_test -l 1200000 $file)
28315         echo $offset
28316         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
28317         printf "Seeking data from 1200000 ... "
28318         offset=$(lseek_test -d 1200000 $file)
28319         echo $offset
28320         [[ $offset == 1200000 ]] || error "offset $offset != 1200000"
28321
28322         # start beyond file end
28323         printf "Using offset > filesize ... "
28324         lseek_test -l 4000000 $file && error "lseek should fail"
28325         printf "Using offset > filesize ... "
28326         lseek_test -d 4000000 $file && error "lseek should fail"
28327
28328         printf "Done\n\n"
28329 }
28330
28331 test_430a() {
28332         $LCTL get_param mdc.*.import | grep -q 'connect_flags:.*seek' ||
28333                 skip "MDT does not support SEEK_HOLE"
28334
28335         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
28336                 skip "OST does not support SEEK_HOLE"
28337
28338         local file=$DIR/$tdir/$tfile
28339
28340         mkdir -p $DIR/$tdir
28341
28342         $LFS setstripe -E 1M -L mdt -E eof -c2 $file
28343         # OST stripe #1 will have continuous data at [1M, 3M)
28344         # OST stripe #2 is empty
28345         echo "Component #1: 1M DoM, component #2: EOF, 2 stripes 1M"
28346         lseek_test_430 $file
28347         rm $file
28348         $LFS setstripe -E 1M -c2 -S 64K -E 10M -c2 -S 1M $file
28349         echo "Component #1: 1M, 2 stripes 64K, component #2: EOF, 2 stripes 1M"
28350         lseek_test_430 $file
28351         rm $file
28352         $LFS setstripe -c2 -S 512K $file
28353         echo "Two stripes, stripe size 512K"
28354         lseek_test_430 $file
28355         rm $file
28356         # FLR with stale mirror
28357         $LFS setstripe -N -E 512K -c1 -S 64K -E eof -c2 -S 512K \
28358                        -N -c2 -S 1M $file
28359         echo "Mirrored file:"
28360         echo "Component #1: 512K, stripe 64K, component #2: EOF, 2 stripes 512K"
28361         echo "Plain 2 stripes 1M"
28362         lseek_test_430 $file
28363         rm $file
28364 }
28365 run_test 430a "lseek: SEEK_DATA/SEEK_HOLE basic functionality"
28366
28367 test_430b() {
28368         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
28369                 skip "OST does not support SEEK_HOLE"
28370
28371         local offset
28372         local file=$DIR/$tdir/$tfile
28373
28374         mkdir -p $DIR/$tdir
28375         # Empty layout lseek should fail
28376         $MCREATE $file
28377         # seek from 0
28378         printf "Seeking hole from 0 ... "
28379         lseek_test -l 0 $file && error "lseek should fail"
28380         printf "Seeking data from 0 ... "
28381         lseek_test -d 0 $file && error "lseek should fail"
28382         rm $file
28383
28384         # 1M-hole file
28385         $LFS setstripe -E 1M -c2 -E eof $file
28386         $TRUNCATE $file 1048576
28387         printf "Seeking hole from 1000000 ... "
28388         offset=$(lseek_test -l 1000000 $file)
28389         echo $offset
28390         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
28391         printf "Seeking data from 1000000 ... "
28392         lseek_test -d 1000000 $file && error "lseek should fail"
28393         rm $file
28394
28395         # full component followed by non-inited one
28396         $LFS setstripe -E 1M -c2 -E eof $file
28397         dd if=/dev/urandom of=$file bs=1M count=1
28398         printf "Seeking hole from 1000000 ... "
28399         offset=$(lseek_test -l 1000000 $file)
28400         echo $offset
28401         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
28402         printf "Seeking hole from 1048576 ... "
28403         lseek_test -l 1048576 $file && error "lseek should fail"
28404         # init second component and truncate back
28405         echo "123" >> $file
28406         $TRUNCATE $file 1048576
28407         printf "Seeking hole from 1000000 ... "
28408         offset=$(lseek_test -l 1000000 $file)
28409         echo $offset
28410         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
28411         printf "Seeking hole from 1048576 ... "
28412         lseek_test -l 1048576 $file && error "lseek should fail"
28413         # boundary checks for big values
28414         dd if=/dev/urandom of=$file.10g bs=1 count=1 seek=10G
28415         offset=$(lseek_test -d 0 $file.10g)
28416         [[ $offset == 10737418240 ]] || error "offset $offset != 10737418240"
28417         dd if=/dev/urandom of=$file.100g bs=1 count=1 seek=100G
28418         offset=$(lseek_test -d 0 $file.100g)
28419         [[ $offset == 107374182400 ]] || error "offset $offset != 107374182400"
28420         return 0
28421 }
28422 run_test 430b "lseek: SEEK_DATA/SEEK_HOLE special cases"
28423
28424 test_430c() {
28425         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
28426                 skip "OST does not support SEEK_HOLE"
28427
28428         local file=$DIR/$tdir/$tfile
28429         local start
28430
28431         mkdir -p $DIR/$tdir
28432         stack_trap "rm -f $file $file.tmp"
28433         dd if=/dev/urandom of=$file bs=1k count=1 seek=5M || error "dd failed"
28434
28435         # cp version 8.33+ prefers lseek over fiemap
28436         local ver=$(cp --version | awk '{ print $4; exit; }')
28437
28438         echo "cp $ver installed"
28439         if (( $(version_code $ver) >= $(version_code 8.33) )); then
28440                 start=$SECONDS
28441                 time cp -v $file $file.tmp || error "cp $file failed"
28442                 (( SECONDS - start < 5 )) || {
28443                         strace cp $file $file.tmp |&
28444                                 grep -E "open|read|seek|FIEMAP" |
28445                                 grep -A 100 $file
28446                         error "cp: too long runtime $((SECONDS - start))"
28447                 }
28448         else
28449                 echo "cp test skipped due to $ver < 8.33"
28450         fi
28451
28452         # tar version 1.29+ supports SEEK_HOLE/DATA
28453         ver=$(tar --version | awk '{ print $4; exit; }')
28454         echo "tar $ver installed"
28455         if (( $(version_code $ver) >= $(version_code 1.29) )); then
28456                 start=$SECONDS
28457                 time tar cvf $file.tmp --sparse $file || error "tar $file error"
28458                 (( SECONDS - start < 5 )) || {
28459                         strace tar cf $file.tmp --sparse $file |&
28460                                 grep -E "open|read|seek|FIEMAP" |
28461                                 grep -A 100 $file
28462                         error "tar: too long runtime $((SECONDS - start))"
28463                 }
28464         else
28465                 echo "tar test skipped due to $ver < 1.29"
28466         fi
28467 }
28468 run_test 430c "lseek: external tools check"
28469
28470 test_431() { # LU-14187
28471         local file=$DIR/$tdir/$tfile
28472
28473         mkdir -p $DIR/$tdir
28474         $LFS setstripe -c 1 -i 0 $file || error "lfs setstripe failed"
28475         dd if=/dev/urandom of=$file bs=4k count=1
28476         dd if=/dev/urandom of=$file bs=4k count=1 seek=10 conv=notrunc
28477         dd if=/dev/urandom of=$file bs=4k count=1 seek=12 conv=notrunc
28478         #define OBD_FAIL_OST_RESTART_IO 0x251
28479         do_facet ost1 "$LCTL set_param fail_loc=0x251"
28480         $LFS setstripe -c 1 -i 0 $file.0 || error "lfs setstripe failed"
28481         cp $file $file.0
28482         cancel_lru_locks
28483         sync_all_data
28484         echo 3 > /proc/sys/vm/drop_caches
28485         diff  $file $file.0 || error "data diff"
28486 }
28487 run_test 431 "Restart transaction for IO"
28488
28489 cleanup_test_432() {
28490         do_facet mgs $LCTL nodemap_activate 0
28491         wait_nm_sync active
28492 }
28493
28494 test_432() {
28495         local tmpdir=$TMP/dir432
28496
28497         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
28498                 skip "Need MDS version at least 2.14.52"
28499
28500         stack_trap cleanup_test_432 EXIT
28501         mkdir $DIR/$tdir
28502         mkdir $tmpdir
28503
28504         do_facet mgs $LCTL nodemap_activate 1
28505         wait_nm_sync active
28506         do_facet mgs $LCTL nodemap_modify --name default \
28507                 --property admin --value 1
28508         do_facet mgs $LCTL nodemap_modify --name default \
28509                 --property trusted --value 1
28510         cancel_lru_locks mdc
28511         wait_nm_sync default admin_nodemap
28512         wait_nm_sync default trusted_nodemap
28513
28514         if [ $(mv $tmpdir $DIR/$tdir/ 2>&1 |
28515                grep -ci "Operation not permitted") -ne 0 ]; then
28516                 error "mv $tmpdir $DIR/$tdir/ hits 'Operation not permitted'"
28517         fi
28518 }
28519 run_test 432 "mv dir from outside Lustre"
28520
28521 test_433() {
28522         [ $PARALLEL == "yes" ] && skip "skip parallel run"
28523
28524         [[ -n "$($LCTL list_param llite.*.inode_cache 2>/dev/null)" ]] ||
28525                 skip "inode cache not supported"
28526
28527         $LCTL set_param llite.*.inode_cache=0
28528         stack_trap "$LCTL set_param llite.*.inode_cache=1"
28529
28530         local count=256
28531         local before
28532         local after
28533
28534         cancel_lru_locks mdc
28535         test_mkdir $DIR/$tdir || error "mkdir $tdir"
28536         createmany -m $DIR/$tdir/f $count
28537         createmany -d $DIR/$tdir/d $count
28538         ls -l $DIR/$tdir > /dev/null
28539         stack_trap "rm -rf $DIR/$tdir"
28540
28541         before=$(num_objects)
28542         cancel_lru_locks mdc
28543         after=$(num_objects)
28544
28545         # sometimes even @before is less than 2 * count
28546         while (( before - after < count )); do
28547                 sleep 1
28548                 after=$(num_objects)
28549                 wait=$((wait + 1))
28550                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
28551                 if (( wait > 60 )); then
28552                         error "inode slab grew from $before to $after"
28553                 fi
28554         done
28555
28556         echo "lustre_inode_cache $before objs before lock cancel, $after after"
28557 }
28558 run_test 433 "ldlm lock cancel releases dentries and inodes"
28559
28560 test_434() {
28561         local file
28562         local getxattr_count
28563         local mdc_stat_param="mdc.$FSNAME-MDT0000*.md_stats"
28564         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
28565
28566         [[ $(getenforce) == "Disabled" ]] ||
28567                 skip "lsm selinux module have to be disabled for this test"
28568
28569         test_mkdir -i 0 -c1 $DIR/$tdir/ ||
28570                 error "fail to create $DIR/$tdir/ on MDT0000"
28571
28572         touch $DIR/$tdir/$tfile-{001..100}
28573
28574         # disable the xattr cache
28575         save_lustre_params client "llite.*.xattr_cache" > $p
28576         lctl set_param llite.*.xattr_cache=0
28577         stack_trap "restore_lustre_params < $p; rm -f $p" EXIT
28578
28579         # clear clients mdc stats
28580         clear_stats $mdc_stat_param ||
28581                 error "fail to clear stats on mdc MDT0000"
28582
28583         for file in $DIR/$tdir/$tfile-{001..100}; do
28584                 getfattr -n security.selinux $file |&
28585                         grep -q "Operation not supported" ||
28586                         error "getxattr on security.selinux should return EOPNOTSUPP"
28587         done
28588
28589         getxattr_count=$(calc_stats $mdc_stat_param "getxattr")
28590         (( getxattr_count < 100 )) ||
28591                 error "client sent $getxattr_count getxattr RPCs to the MDS"
28592 }
28593 run_test 434 "Client should not send RPCs for security.selinux with SElinux disabled"
28594
28595 test_440() {
28596         if [[ -f $LUSTRE/scripts/bash-completion/lustre ]]; then
28597                 source $LUSTRE/scripts/bash-completion/lustre
28598         elif [[ -f /usr/share/bash-completion/completions/lustre ]]; then
28599                 source /usr/share/bash-completion/completions/lustre
28600         else
28601                 skip "bash completion scripts not found"
28602         fi
28603
28604         local lctl_completions
28605         local lfs_completions
28606
28607         lctl_completions=$(_lustre_cmds lctl)
28608         if [[ ! $lctl_completions =~ "get_param" ]]; then
28609                 error "lctl bash completion failed"
28610         fi
28611
28612         lfs_completions=$(_lustre_cmds lfs)
28613         if [[ ! $lfs_completions =~ "setstripe" ]]; then
28614                 error "lfs bash completion failed"
28615         fi
28616 }
28617 run_test 440 "bash completion for lfs, lctl"
28618
28619 prep_801() {
28620         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
28621         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
28622                 skip "Need server version at least 2.9.55"
28623
28624         start_full_debug_logging
28625 }
28626
28627 post_801() {
28628         stop_full_debug_logging
28629 }
28630
28631 barrier_stat() {
28632         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
28633                 local st=$(do_facet mgs $LCTL barrier_stat $FSNAME |
28634                            awk '/The barrier for/ { print $7 }')
28635                 echo $st
28636         else
28637                 local st=$(do_facet mgs $LCTL barrier_stat -s $FSNAME)
28638                 echo \'$st\'
28639         fi
28640 }
28641
28642 barrier_expired() {
28643         local expired
28644
28645         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
28646                 expired=$(do_facet mgs $LCTL barrier_stat $FSNAME |
28647                           awk '/will be expired/ { print $7 }')
28648         else
28649                 expired=$(do_facet mgs $LCTL barrier_stat -t $FSNAME)
28650         fi
28651
28652         echo $expired
28653 }
28654
28655 test_801a() {
28656         prep_801
28657
28658         echo "Start barrier_freeze at: $(date)"
28659         #define OBD_FAIL_BARRIER_DELAY          0x2202
28660         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
28661         # Do not reduce barrier time - See LU-11873
28662         do_facet mgs $LCTL barrier_freeze $FSNAME 20 &
28663
28664         sleep 2
28665         local b_status=$(barrier_stat)
28666         echo "Got barrier status at: $(date)"
28667         [ "$b_status" = "'freezing_p1'" ] ||
28668                 error "(1) unexpected barrier status $b_status"
28669
28670         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
28671         wait
28672         b_status=$(barrier_stat)
28673         [ "$b_status" = "'frozen'" ] ||
28674                 error "(2) unexpected barrier status $b_status"
28675
28676         local expired=$(barrier_expired)
28677         echo "sleep $((expired + 3)) seconds, then the barrier will be expired"
28678         sleep $((expired + 3))
28679
28680         b_status=$(barrier_stat)
28681         [ "$b_status" = "'expired'" ] ||
28682                 error "(3) unexpected barrier status $b_status"
28683
28684         # Do not reduce barrier time - See LU-11873
28685         do_facet mgs $LCTL barrier_freeze $FSNAME 20 ||
28686                 error "(4) fail to freeze barrier"
28687
28688         b_status=$(barrier_stat)
28689         [ "$b_status" = "'frozen'" ] ||
28690                 error "(5) unexpected barrier status $b_status"
28691
28692         echo "Start barrier_thaw at: $(date)"
28693         #define OBD_FAIL_BARRIER_DELAY          0x2202
28694         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
28695         do_facet mgs $LCTL barrier_thaw $FSNAME &
28696
28697         sleep 2
28698         b_status=$(barrier_stat)
28699         echo "Got barrier status at: $(date)"
28700         [ "$b_status" = "'thawing'" ] ||
28701                 error "(6) unexpected barrier status $b_status"
28702
28703         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
28704         wait
28705         b_status=$(barrier_stat)
28706         [ "$b_status" = "'thawed'" ] ||
28707                 error "(7) unexpected barrier status $b_status"
28708
28709         #define OBD_FAIL_BARRIER_FAILURE        0x2203
28710         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2203
28711         do_facet mgs $LCTL barrier_freeze $FSNAME
28712
28713         b_status=$(barrier_stat)
28714         [ "$b_status" = "'failed'" ] ||
28715                 error "(8) unexpected barrier status $b_status"
28716
28717         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
28718         do_facet mgs $LCTL barrier_thaw $FSNAME
28719
28720         post_801
28721 }
28722 run_test 801a "write barrier user interfaces and stat machine"
28723
28724 test_801b() {
28725         prep_801
28726
28727         mkdir $DIR/$tdir || error "(1) fail to mkdir"
28728         createmany -d $DIR/$tdir/d 6 || error "(2) fail to mkdir"
28729         touch $DIR/$tdir/d2/f10 || error "(3) fail to touch"
28730         touch $DIR/$tdir/d3/f11 || error "(4) fail to touch"
28731         touch $DIR/$tdir/d4/f12 || error "(5) fail to touch"
28732
28733         cancel_lru_locks mdc
28734
28735         # 180 seconds should be long enough
28736         do_facet mgs $LCTL barrier_freeze $FSNAME 180
28737
28738         local b_status=$(barrier_stat)
28739         [ "$b_status" = "'frozen'" ] ||
28740                 error "(6) unexpected barrier status $b_status"
28741
28742         mkdir $DIR/$tdir/d0/d10 &
28743         mkdir_pid=$!
28744
28745         touch $DIR/$tdir/d1/f13 &
28746         touch_pid=$!
28747
28748         ln $DIR/$tdir/d2/f10 $DIR/$tdir/d2/f14 &
28749         ln_pid=$!
28750
28751         mv $DIR/$tdir/d3/f11 $DIR/$tdir/d3/f15 &
28752         mv_pid=$!
28753
28754         rm -f $DIR/$tdir/d4/f12 &
28755         rm_pid=$!
28756
28757         stat $DIR/$tdir/d5 || error "(7) stat should succeed"
28758
28759         # To guarantee taht the 'stat' is not blocked
28760         b_status=$(barrier_stat)
28761         [ "$b_status" = "'frozen'" ] ||
28762                 error "(8) unexpected barrier status $b_status"
28763
28764         # let above commands to run at background
28765         sleep 5
28766
28767         ps -p $mkdir_pid || error "(9) mkdir should be blocked"
28768         ps -p $touch_pid || error "(10) touch should be blocked"
28769         ps -p $ln_pid || error "(11) link should be blocked"
28770         ps -p $mv_pid || error "(12) rename should be blocked"
28771         ps -p $rm_pid || error "(13) unlink should be blocked"
28772
28773         b_status=$(barrier_stat)
28774         [ "$b_status" = "'frozen'" ] ||
28775                 error "(14) unexpected barrier status $b_status"
28776
28777         do_facet mgs $LCTL barrier_thaw $FSNAME
28778         b_status=$(barrier_stat)
28779         [ "$b_status" = "'thawed'" ] ||
28780                 error "(15) unexpected barrier status $b_status"
28781
28782         wait $mkdir_pid || error "(16) mkdir should succeed"
28783         wait $touch_pid || error "(17) touch should succeed"
28784         wait $ln_pid || error "(18) link should succeed"
28785         wait $mv_pid || error "(19) rename should succeed"
28786         wait $rm_pid || error "(20) unlink should succeed"
28787
28788         post_801
28789 }
28790 run_test 801b "modification will be blocked by write barrier"
28791
28792 test_801c() {
28793         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
28794
28795         prep_801
28796
28797         stop mds2 || error "(1) Fail to stop mds2"
28798
28799         do_facet mgs $LCTL barrier_freeze $FSNAME 30
28800
28801         local b_status=$(barrier_stat)
28802         [ "$b_status" = "'expired'" ] || [ "$b_status" = "'failed'" ] || {
28803                 do_facet mgs $LCTL barrier_thaw $FSNAME
28804                 error "(2) unexpected barrier status $b_status"
28805         }
28806
28807         do_facet mgs $LCTL barrier_rescan $FSNAME ||
28808                 error "(3) Fail to rescan barrier bitmap"
28809
28810         # Do not reduce barrier time - See LU-11873
28811         do_facet mgs $LCTL barrier_freeze $FSNAME 20
28812
28813         b_status=$(barrier_stat)
28814         [ "$b_status" = "'frozen'" ] ||
28815                 error "(4) unexpected barrier status $b_status"
28816
28817         do_facet mgs $LCTL barrier_thaw $FSNAME
28818         b_status=$(barrier_stat)
28819         [ "$b_status" = "'thawed'" ] ||
28820                 error "(5) unexpected barrier status $b_status"
28821
28822         local devname=$(mdsdevname 2)
28823
28824         start mds2 $devname $MDS_MOUNT_OPTS || error "(6) Fail to start mds2"
28825
28826         do_facet mgs $LCTL barrier_rescan $FSNAME ||
28827                 error "(7) Fail to rescan barrier bitmap"
28828
28829         post_801
28830 }
28831 run_test 801c "rescan barrier bitmap"
28832
28833 test_802b() {
28834         [ $PARALLEL == "yes" ] && skip "skip parallel run"
28835         remote_mds_nodsh && skip "remote MDS with nodsh"
28836
28837         do_facet $SINGLEMDS $LCTL get_param mdt.*.readonly ||
28838                 skip "readonly option not available"
28839
28840         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "(1) fail to mkdir"
28841
28842         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
28843                 error "(2) Fail to copy"
28844
28845         # write back all cached data before setting MDT to readonly
28846         cancel_lru_locks
28847         sync_all_data
28848
28849         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=1
28850         stack_trap "do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0" EXIT
28851
28852         echo "Modify should be refused"
28853         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
28854
28855         echo "Read should be allowed"
28856         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
28857                 error "(7) Read should succeed under ro mode"
28858
28859         # disable readonly
28860         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0
28861 }
28862 run_test 802b "be able to set MDTs to readonly"
28863
28864 test_803a() {
28865         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
28866         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
28867                 skip "MDS needs to be newer than 2.10.54"
28868
28869         mkdir_on_mdt0 $DIR/$tdir
28870         # Create some objects on all MDTs to trigger related logs objects
28871         for idx in $(seq $MDSCOUNT); do
28872                 $LFS mkdir -c $MDSCOUNT -i $((idx % $MDSCOUNT)) \
28873                         $DIR/$tdir/dir${idx} ||
28874                         error "Fail to create $DIR/$tdir/dir${idx}"
28875         done
28876
28877         wait_delete_completed # ensure old test cleanups are finished
28878         sleep 3
28879         echo "before create:"
28880         $LFS df -i $MOUNT
28881         local before_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
28882
28883         for i in {1..10}; do
28884                 $LFS mkdir -c 1 -i 1 $DIR/$tdir/foo$i ||
28885                         error "Fail to create $DIR/$tdir/foo$i"
28886         done
28887
28888         # sync ZFS-on-MDS to refresh statfs data
28889         wait_zfs_commit mds1
28890         sleep 3
28891         echo "after create:"
28892         $LFS df -i $MOUNT
28893         local after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
28894
28895         # allow for an llog to be cleaned up during the test
28896         [ $after_used -ge $((before_used + 10 - 1)) ] ||
28897                 error "before ($before_used) + 10 > after ($after_used)"
28898
28899         for i in {1..10}; do
28900                 rm -rf $DIR/$tdir/foo$i ||
28901                         error "Fail to remove $DIR/$tdir/foo$i"
28902         done
28903
28904         # sync ZFS-on-MDS to refresh statfs data
28905         wait_zfs_commit mds1
28906         wait_delete_completed
28907         sleep 3 # avoid MDT return cached statfs
28908         echo "after unlink:"
28909         $LFS df -i $MOUNT
28910         after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
28911
28912         # allow for an llog to be created during the test
28913         [ $after_used -le $((before_used + 1)) ] ||
28914                 error "after ($after_used) > before ($before_used) + 1"
28915 }
28916 run_test 803a "verify agent object for remote object"
28917
28918 test_803b() {
28919         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
28920         [ $MDS1_VERSION -lt $(version_code 2.13.56) ] &&
28921                 skip "MDS needs to be newer than 2.13.56"
28922         [ $PARALLEL == "yes" ] && skip "skip parallel run"
28923
28924         for i in $(seq 0 $((MDSCOUNT - 1))); do
28925                 $LFS mkdir -i $i $DIR/$tdir.$i || error "mkdir $tdir.$i"
28926         done
28927
28928         local before=0
28929         local after=0
28930
28931         local tmp
28932
28933         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
28934         for i in $(seq 0 $((MDSCOUNT - 1))); do
28935                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
28936                         awk '/getattr/ { print $2 }')
28937                 before=$((before + tmp))
28938         done
28939         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
28940         for i in $(seq 0 $((MDSCOUNT - 1))); do
28941                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
28942                         awk '/getattr/ { print $2 }')
28943                 after=$((after + tmp))
28944         done
28945
28946         [ $before -eq $after ] || error "getattr count $before != $after"
28947 }
28948 run_test 803b "remote object can getattr from cache"
28949
28950 test_804() {
28951         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
28952         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
28953                 skip "MDS needs to be newer than 2.10.54"
28954         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
28955
28956         mkdir -p $DIR/$tdir
28957         $LFS mkdir -c 1 -i 1 $DIR/$tdir/dir0 ||
28958                 error "Fail to create $DIR/$tdir/dir0"
28959
28960         local fid=$($LFS path2fid $DIR/$tdir/dir0)
28961         local dev=$(mdsdevname 2)
28962
28963         do_facet mds2 "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
28964                 grep ${fid} || error "NOT found agent entry for dir0"
28965
28966         $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir/dir1 ||
28967                 error "Fail to create $DIR/$tdir/dir1"
28968
28969         touch $DIR/$tdir/dir1/foo0 ||
28970                 error "Fail to create $DIR/$tdir/dir1/foo0"
28971         fid=$($LFS path2fid $DIR/$tdir/dir1/foo0)
28972         local rc=0
28973
28974         for idx in $(seq $MDSCOUNT); do
28975                 dev=$(mdsdevname $idx)
28976                 do_facet mds${idx} \
28977                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
28978                         grep ${fid} && rc=$idx
28979         done
28980
28981         mv $DIR/$tdir/dir1/foo0 $DIR/$tdir/dir1/foo1 ||
28982                 error "Fail to rename foo0 to foo1"
28983         if [ $rc -eq 0 ]; then
28984                 for idx in $(seq $MDSCOUNT); do
28985                         dev=$(mdsdevname $idx)
28986                         do_facet mds${idx} \
28987                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
28988                         grep ${fid} && rc=$idx
28989                 done
28990         fi
28991
28992         mv $DIR/$tdir/dir1/foo1 $DIR/$tdir/dir1/foo2 ||
28993                 error "Fail to rename foo1 to foo2"
28994         if [ $rc -eq 0 ]; then
28995                 for idx in $(seq $MDSCOUNT); do
28996                         dev=$(mdsdevname $idx)
28997                         do_facet mds${idx} \
28998                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
28999                         grep ${fid} && rc=$idx
29000                 done
29001         fi
29002
29003         [ $rc -ne 0 ] || error "NOT found agent entry for foo"
29004
29005         ln $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir0/guard ||
29006                 error "Fail to link to $DIR/$tdir/dir1/foo2"
29007         mv $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir1/foo0 ||
29008                 error "Fail to rename foo2 to foo0"
29009         unlink $DIR/$tdir/dir1/foo0 ||
29010                 error "Fail to unlink $DIR/$tdir/dir1/foo0"
29011         rm -rf $DIR/$tdir/dir0 ||
29012                 error "Fail to rm $DIR/$tdir/dir0"
29013
29014         for idx in $(seq $MDSCOUNT); do
29015                 rc=0
29016
29017                 stop mds${idx}
29018                 dev=$(mdsdevname $idx)
29019                 run_e2fsck $(facet_active_host mds$idx) $dev -n ||
29020                         rc=$?
29021                 start mds${idx} $dev $MDS_MOUNT_OPTS ||
29022                         error "mount mds$idx failed"
29023                 df $MOUNT > /dev/null 2>&1
29024
29025                 # e2fsck should not return error
29026                 [ $rc -eq 0 ] ||
29027                         error "e2fsck detected error on MDT${idx}: rc=$rc"
29028         done
29029 }
29030 run_test 804 "verify agent entry for remote entry"
29031
29032 cleanup_805() {
29033         do_facet $SINGLEMDS zfs set quota=$old $fsset
29034         unlinkmany $DIR/$tdir/f- 1000000
29035         trap 0
29036 }
29037
29038 test_805() {
29039         local zfs_version=$(do_facet mds1 cat /sys/module/zfs/version)
29040         [ "$mds1_FSTYPE" != "zfs" ] && skip "ZFS specific test"
29041         [ $(version_code $zfs_version) -lt $(version_code 0.7.2) ] &&
29042                 skip "netfree not implemented before 0.7"
29043         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
29044                 skip "Need MDS version at least 2.10.57"
29045
29046         local fsset
29047         local freekb
29048         local usedkb
29049         local old
29050         local quota
29051         local pref="osd-zfs.$FSNAME-MDT0000."
29052
29053         # limit available space on MDS dataset to meet nospace issue
29054         # quickly. then ZFS 0.7.2 can use reserved space if asked
29055         # properly (using netfree flag in osd_declare_destroy()
29056         fsset=$(do_facet $SINGLEMDS lctl get_param -n $pref.mntdev)
29057         old=$(do_facet $SINGLEMDS zfs get -H quota $fsset | \
29058                 gawk '{print $3}')
29059         freekb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytesfree)
29060         usedkb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytestotal)
29061         let "usedkb=usedkb-freekb"
29062         let "freekb=freekb/2"
29063         if let "freekb > 5000"; then
29064                 let "freekb=5000"
29065         fi
29066         do_facet $SINGLEMDS zfs set quota=$(((usedkb+freekb)*1024)) $fsset
29067         trap cleanup_805 EXIT
29068         mkdir_on_mdt0 $DIR/$tdir
29069         $LFS setstripe -E 1M -c2 -E 4M -c2 -E -1 -c2 $DIR/$tdir ||
29070                 error "Can't set PFL layout"
29071         createmany -m $DIR/$tdir/f- 1000000 && error "ENOSPC wasn't met"
29072         rm -rf $DIR/$tdir || error "not able to remove"
29073         do_facet $SINGLEMDS zfs set quota=$old $fsset
29074         trap 0
29075 }
29076 run_test 805 "ZFS can remove from full fs"
29077
29078 # Size-on-MDS test
29079 check_lsom_data()
29080 {
29081         local file=$1
29082         local expect=$(stat -c %s $file)
29083
29084         check_lsom_size $1 $expect
29085
29086         local blocks=$($LFS getsom -b $file)
29087         expect=$(stat -c %b $file)
29088         [[ $blocks == $expect ]] ||
29089                 error "$file expected blocks: $expect, got: $blocks"
29090 }
29091
29092 check_lsom_size()
29093 {
29094         local size
29095         local expect=$2
29096
29097         cancel_lru_locks mdc
29098
29099         size=$($LFS getsom -s $1)
29100         [[ $size == $expect ]] ||
29101                 error "$file expected size: $expect, got: $size"
29102 }
29103
29104 test_806() {
29105         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
29106                 skip "Need MDS version at least 2.11.52"
29107
29108         local bs=1048576
29109
29110         $LFS setstripe -c-1 $DIR/$tfile || error "setstripe $tfile failed"
29111
29112         disable_opencache
29113         stack_trap "restore_opencache"
29114
29115         # single-threaded write
29116         echo "Test SOM for single-threaded write"
29117         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 ||
29118                 error "write $tfile failed"
29119         check_lsom_size $DIR/$tfile $bs
29120
29121         local num=32
29122         local size=$(($num * $bs))
29123         local offset=0
29124         local i
29125
29126         echo "Test SOM for single client multi-threaded($num) write"
29127         $TRUNCATE $DIR/$tfile 0
29128         for ((i = 0; i < $num; i++)); do
29129                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
29130                 local pids[$i]=$!
29131                 offset=$((offset + $bs))
29132         done
29133         for (( i=0; i < $num; i++ )); do
29134                 wait ${pids[$i]}
29135         done
29136         check_lsom_size $DIR/$tfile $size
29137
29138         $TRUNCATE $DIR/$tfile 0
29139         for ((i = 0; i < $num; i++)); do
29140                 offset=$((offset - $bs))
29141                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
29142                 local pids[$i]=$!
29143         done
29144         for (( i=0; i < $num; i++ )); do
29145                 wait ${pids[$i]}
29146         done
29147         check_lsom_size $DIR/$tfile $size
29148
29149         # multi-client writes
29150         num=$(get_node_count ${CLIENTS//,/ })
29151         size=$(($num * $bs))
29152         offset=0
29153         i=0
29154
29155         echo "Test SOM for multi-client ($num) writes"
29156         $TRUNCATE $DIR/$tfile 0
29157         for client in ${CLIENTS//,/ }; do
29158                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
29159                 local pids[$i]=$!
29160                 i=$((i + 1))
29161                 offset=$((offset + $bs))
29162         done
29163         for (( i=0; i < $num; i++ )); do
29164                 wait ${pids[$i]}
29165         done
29166         check_lsom_size $DIR/$tfile $offset
29167
29168         i=0
29169         $TRUNCATE $DIR/$tfile 0
29170         for client in ${CLIENTS//,/ }; do
29171                 offset=$((offset - $bs))
29172                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
29173                 local pids[$i]=$!
29174                 i=$((i + 1))
29175         done
29176         for (( i=0; i < $num; i++ )); do
29177                 wait ${pids[$i]}
29178         done
29179         check_lsom_size $DIR/$tfile $size
29180
29181         # verify SOM blocks count
29182         echo "Verify SOM block count"
29183         $TRUNCATE $DIR/$tfile 0
29184         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w$((bs))YSc ||
29185                 error "failed to write file $tfile with fdatasync and fstat"
29186         check_lsom_data $DIR/$tfile
29187
29188         $TRUNCATE $DIR/$tfile 0
29189         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w$((bs * 2))Yc ||
29190                 error "failed to write file $tfile with fdatasync"
29191         check_lsom_data $DIR/$tfile
29192
29193         $TRUNCATE $DIR/$tfile 0
29194         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:O_SYNC:w$((bs * 3))c ||
29195                 error "failed to write file $tfile with sync IO"
29196         check_lsom_data $DIR/$tfile
29197
29198         # verify truncate
29199         echo "Test SOM for truncate"
29200         # use ftruncate to sync blocks on close request
29201         $MULTIOP $DIR/$tfile oO_WRONLY:T16384c
29202         check_lsom_size $DIR/$tfile 16384
29203         check_lsom_data $DIR/$tfile
29204
29205         $TRUNCATE $DIR/$tfile 1234
29206         check_lsom_size $DIR/$tfile 1234
29207         # sync blocks on the MDT
29208         $MULTIOP $DIR/$tfile oc
29209         check_lsom_data $DIR/$tfile
29210 }
29211 run_test 806 "Verify Lazy Size on MDS"
29212
29213 test_807() {
29214         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
29215         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
29216                 skip "Need MDS version at least 2.11.52"
29217
29218         # Registration step
29219         changelog_register || error "changelog_register failed"
29220         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
29221         changelog_users $SINGLEMDS | grep -q $cl_user ||
29222                 error "User $cl_user not found in changelog_users"
29223
29224         rm -rf $DIR/$tdir || error "rm $tdir failed"
29225         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
29226         touch $DIR/$tdir/trunc || error "touch $tdir/trunc failed"
29227         $TRUNCATE $DIR/$tdir/trunc 1024 || error "truncate $tdir/trunc failed"
29228         $TRUNCATE $DIR/$tdir/trunc 1048576 ||
29229                 error "truncate $tdir/trunc failed"
29230
29231         local bs=1048576
29232         echo "Test SOM for single-threaded write with fsync"
29233         dd if=/dev/zero of=$DIR/$tdir/single_dd bs=$bs count=1 ||
29234                 error "write $tfile failed"
29235         sync;sync;sync
29236
29237         # multi-client wirtes
29238         local num=$(get_node_count ${CLIENTS//,/ })
29239         local offset=0
29240         local i=0
29241
29242         echo "Test SOM for multi-client ($num) writes"
29243         touch $DIR/$tfile || error "touch $tfile failed"
29244         $TRUNCATE $DIR/$tfile 0
29245         for client in ${CLIENTS//,/ }; do
29246                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
29247                 local pids[$i]=$!
29248                 i=$((i + 1))
29249                 offset=$((offset + $bs))
29250         done
29251         for (( i=0; i < $num; i++ )); do
29252                 wait ${pids[$i]}
29253         done
29254
29255         do_rpc_nodes "$CLIENTS" cancel_lru_locks osc
29256         do_nodes "$CLIENTS" "sync ; sleep 5 ; sync"
29257         $LSOM_SYNC -u $cl_user -m $FSNAME-MDT0000 $MOUNT
29258         check_lsom_data $DIR/$tdir/trunc
29259         check_lsom_data $DIR/$tdir/single_dd
29260         check_lsom_data $DIR/$tfile
29261
29262         rm -rf $DIR/$tdir
29263         # Deregistration step
29264         changelog_deregister || error "changelog_deregister failed"
29265 }
29266 run_test 807 "verify LSOM syncing tool"
29267
29268 check_som_nologged()
29269 {
29270         local lines=$($LFS changelog $FSNAME-MDT0000 |
29271                 grep 'x=trusted.som' | wc -l)
29272         [ $lines -ne 0 ] && error "trusted.som xattr is logged in Changelogs"
29273 }
29274
29275 test_808() {
29276         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
29277                 skip "Need MDS version at least 2.11.55"
29278
29279         # Registration step
29280         changelog_register || error "changelog_register failed"
29281
29282         touch $DIR/$tfile || error "touch $tfile failed"
29283         check_som_nologged
29284
29285         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=1 ||
29286                 error "write $tfile failed"
29287         check_som_nologged
29288
29289         $TRUNCATE $DIR/$tfile 1234
29290         check_som_nologged
29291
29292         $TRUNCATE $DIR/$tfile 1048576
29293         check_som_nologged
29294
29295         # Deregistration step
29296         changelog_deregister || error "changelog_deregister failed"
29297 }
29298 run_test 808 "Check trusted.som xattr not logged in Changelogs"
29299
29300 check_som_nodata()
29301 {
29302         $LFS getsom $1
29303         [[ $? -eq 61 ]] || error "DoM-only file $1 has SOM xattr"
29304 }
29305
29306 test_809() {
29307         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
29308                 skip "Need MDS version at least 2.11.56"
29309
29310         $LFS setstripe -E 1M -L mdt $DIR/$tfile ||
29311                 error "failed to create DoM-only file $DIR/$tfile"
29312         touch $DIR/$tfile || error "touch $tfile failed"
29313         check_som_nodata $DIR/$tfile
29314
29315         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 ||
29316                 error "write $tfile failed"
29317         check_som_nodata $DIR/$tfile
29318
29319         $TRUNCATE $DIR/$tfile 1234
29320         check_som_nodata $DIR/$tfile
29321
29322         $TRUNCATE $DIR/$tfile 4097
29323         check_som_nodata $DIR/$file
29324 }
29325 run_test 809 "Verify no SOM xattr store for DoM-only files"
29326
29327 test_810() {
29328         [ $PARALLEL == "yes" ] && skip "skip parallel run"
29329         $GSS && skip_env "could not run with gss"
29330         [[ $OST1_VERSION -gt $(version_code 2.12.58) ]] ||
29331                 skip "OST < 2.12.58 doesn't align checksum"
29332
29333         set_checksums 1
29334         stack_trap "set_checksums $ORIG_CSUM" EXIT
29335         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
29336
29337         local csum
29338         local before
29339         local after
29340         for csum in $CKSUM_TYPES; do
29341                 #define OBD_FAIL_OSC_NO_GRANT   0x411
29342                 $LCTL set_param osc.*.checksum_type=$csum fail_loc=0x411
29343                 for i in "10240 0" "10000 0" "4000 1" "500 1"; do
29344                         eval set -- $i
29345                         dd if=/dev/urandom of=$DIR/$tfile bs=$1 count=2 seek=$2
29346                         before=$(md5sum $DIR/$tfile)
29347                         $LCTL set_param ldlm.namespaces.*osc*.lru_size=clear
29348                         after=$(md5sum $DIR/$tfile)
29349                         [ "$before" == "$after" ] ||
29350                                 error "$csum: $before != $after bs=$1 seek=$2"
29351                 done
29352         done
29353 }
29354 run_test 810 "partial page writes on ZFS (LU-11663)"
29355
29356 test_812a() {
29357         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
29358                 skip "OST < 2.12.51 doesn't support this fail_loc"
29359
29360         $LFS setstripe -c 1 -i 0 $DIR/$tfile
29361         # ensure ost1 is connected
29362         stat $DIR/$tfile >/dev/null || error "can't stat"
29363         wait_osc_import_state client ost1 FULL
29364         # no locks, no reqs to let the connection idle
29365         cancel_lru_locks osc
29366
29367         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
29368 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
29369         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
29370         wait_osc_import_state client ost1 CONNECTING
29371         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
29372
29373         stat $DIR/$tfile >/dev/null || error "can't stat file"
29374 }
29375 run_test 812a "do not drop reqs generated when imp is going to idle (LU-11951)"
29376
29377 test_812b() { # LU-12378
29378         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
29379                 skip "OST < 2.12.51 doesn't support this fail_loc"
29380
29381         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "setstripe failed"
29382         # ensure ost1 is connected
29383         stat $DIR/$tfile >/dev/null || error "can't stat"
29384         wait_osc_import_state client ost1 FULL
29385         # no locks, no reqs to let the connection idle
29386         cancel_lru_locks osc
29387
29388         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
29389 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
29390         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
29391         wait_osc_import_state client ost1 CONNECTING
29392         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
29393
29394         $LFS quota -u 0 $DIR/ || error "lfs quota should succeed"
29395         wait_osc_import_state client ost1 IDLE
29396 }
29397 run_test 812b "do not drop no resend request for idle connect"
29398
29399 test_812c() {
29400         local old
29401
29402         old=$($LCTL get_param -n osc.*.idle_timeout | head -n 1)
29403
29404         $LFS setstripe -c 1 -o 0 $DIR/$tfile
29405         $LFS getstripe $DIR/$tfile
29406         $LCTL set_param osc.*.idle_timeout=10
29407         stack_trap "$LCTL set_param osc.*.idle_timeout=$old" EXIT
29408         # ensure ost1 is connected
29409         stat $DIR/$tfile >/dev/null || error "can't stat"
29410         wait_osc_import_state client ost1 FULL
29411         # no locks, no reqs to let the connection idle
29412         cancel_lru_locks osc
29413
29414 #define OBD_FAIL_PTLRPC_IDLE_RACE        0x533
29415         $LCTL set_param fail_loc=0x80000533
29416         sleep 15
29417         dd if=/dev/zero of=$DIR/$tfile count=1 conv=sync || error "dd failed"
29418 }
29419 run_test 812c "idle import vs lock enqueue race"
29420
29421 test_813() {
29422         local file_heat_sav=$($LCTL get_param -n llite.*.file_heat 2>/dev/null)
29423         [ -z "$file_heat_sav" ] && skip "no file heat support"
29424
29425         local readsample
29426         local writesample
29427         local readbyte
29428         local writebyte
29429         local readsample1
29430         local writesample1
29431         local readbyte1
29432         local writebyte1
29433
29434         local period_second=$($LCTL get_param -n llite.*.heat_period_second)
29435         local decay_pct=$($LCTL get_param -n llite.*.heat_decay_percentage)
29436
29437         $LCTL set_param -n llite.*.file_heat=1
29438         echo "Turn on file heat"
29439         echo "Period second: $period_second, Decay percentage: $decay_pct"
29440
29441         echo "QQQQ" > $DIR/$tfile
29442         echo "QQQQ" > $DIR/$tfile
29443         echo "QQQQ" > $DIR/$tfile
29444         cat $DIR/$tfile > /dev/null
29445         cat $DIR/$tfile > /dev/null
29446         cat $DIR/$tfile > /dev/null
29447         cat $DIR/$tfile > /dev/null
29448
29449         local out=$($LFS heat_get $DIR/$tfile)
29450
29451         $LFS heat_get $DIR/$tfile
29452         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
29453         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
29454         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
29455         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
29456
29457         [ $readsample -le 4 ] || error "read sample ($readsample) is wrong"
29458         [ $writesample -le 3 ] || error "write sample ($writesample) is wrong"
29459         [ $readbyte -le 20 ] || error "read bytes ($readbyte) is wrong"
29460         [ $writebyte -le 15 ] || error "write bytes ($writebyte) is wrong"
29461
29462         sleep $((period_second + 3))
29463         echo "Sleep $((period_second + 3)) seconds..."
29464         # The recursion formula to calculate the heat of the file f is as
29465         # follow:
29466         # Hi+1(f) = (1-P)*Hi(f)+ P*Ci
29467         # Where Hi is the heat value in the period between time points i*I and
29468         # (i+1)*I; Ci is the access count in the period; the symbol P refers
29469         # to the weight of Ci.
29470         out=$($LFS heat_get $DIR/$tfile)
29471         $LFS heat_get $DIR/$tfile
29472         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
29473         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
29474         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
29475         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
29476
29477         [ $(bc <<< "$readsample <= 4 * $decay_pct / 100") -eq 1 ] ||
29478                 error "read sample ($readsample) is wrong"
29479         [ $(bc <<< "$writesample <= 3 * $decay_pct / 100") -eq 1 ] ||
29480                 error "write sample ($writesample) is wrong"
29481         [ $(bc <<< "$readbyte <= 20 * $decay_pct / 100") -eq 1 ] ||
29482                 error "read bytes ($readbyte) is wrong"
29483         [ $(bc <<< "$writebyte <= 15 * $decay_pct / 100") -eq 1 ] ||
29484                 error "write bytes ($writebyte) is wrong"
29485
29486         echo "QQQQ" > $DIR/$tfile
29487         echo "QQQQ" > $DIR/$tfile
29488         echo "QQQQ" > $DIR/$tfile
29489         cat $DIR/$tfile > /dev/null
29490         cat $DIR/$tfile > /dev/null
29491         cat $DIR/$tfile > /dev/null
29492         cat $DIR/$tfile > /dev/null
29493
29494         sleep $((period_second + 3))
29495         echo "Sleep $((period_second + 3)) seconds..."
29496
29497         out=$($LFS heat_get $DIR/$tfile)
29498         $LFS heat_get $DIR/$tfile
29499         readsample1=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
29500         writesample1=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
29501         readbyte1=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
29502         writebyte1=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
29503
29504         [ $(bc <<< "$readsample1 <= ($readsample * (100 - $decay_pct) + \
29505                 4 * $decay_pct) / 100") -eq 1 ] ||
29506                 error "read sample ($readsample1) is wrong"
29507         [ $(bc <<< "$writesample1 <= ($writesample * (100 - $decay_pct) + \
29508                 3 * $decay_pct) / 100") -eq 1 ] ||
29509                 error "write sample ($writesample1) is wrong"
29510         [ $(bc <<< "$readbyte1 <= ($readbyte * (100 - $decay_pct) + \
29511                 20 * $decay_pct) / 100") -eq 1 ] ||
29512                 error "read bytes ($readbyte1) is wrong"
29513         [ $(bc <<< "$writebyte1 <= ($writebyte * (100 - $decay_pct) + \
29514                 15 * $decay_pct) / 100") -eq 1 ] ||
29515                 error "write bytes ($writebyte1) is wrong"
29516
29517         echo "Turn off file heat for the file $DIR/$tfile"
29518         $LFS heat_set -o $DIR/$tfile
29519
29520         echo "QQQQ" > $DIR/$tfile
29521         echo "QQQQ" > $DIR/$tfile
29522         echo "QQQQ" > $DIR/$tfile
29523         cat $DIR/$tfile > /dev/null
29524         cat $DIR/$tfile > /dev/null
29525         cat $DIR/$tfile > /dev/null
29526         cat $DIR/$tfile > /dev/null
29527
29528         out=$($LFS heat_get $DIR/$tfile)
29529         $LFS heat_get $DIR/$tfile
29530         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
29531         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
29532         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
29533         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
29534
29535         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
29536         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
29537         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
29538         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
29539
29540         echo "Trun on file heat for the file $DIR/$tfile"
29541         $LFS heat_set -O $DIR/$tfile
29542
29543         echo "QQQQ" > $DIR/$tfile
29544         echo "QQQQ" > $DIR/$tfile
29545         echo "QQQQ" > $DIR/$tfile
29546         cat $DIR/$tfile > /dev/null
29547         cat $DIR/$tfile > /dev/null
29548         cat $DIR/$tfile > /dev/null
29549         cat $DIR/$tfile > /dev/null
29550
29551         out=$($LFS heat_get $DIR/$tfile)
29552         $LFS heat_get $DIR/$tfile
29553         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
29554         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
29555         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
29556         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
29557
29558         [ $readsample -gt 0 ] || error "read sample ($readsample) is wrong"
29559         [ $writesample -gt 0 ] || error "write sample ($writesample) is wrong"
29560         [ $readbyte -gt 0 ] || error "read bytes ($readbyte) is wrong"
29561         [ $writebyte -gt 0 ] || error "write bytes ($writebyte) is wrong"
29562
29563         $LFS heat_set -c $DIR/$tfile
29564         $LCTL set_param -n llite.*.file_heat=0
29565         echo "Turn off file heat support for the Lustre filesystem"
29566
29567         echo "QQQQ" > $DIR/$tfile
29568         echo "QQQQ" > $DIR/$tfile
29569         echo "QQQQ" > $DIR/$tfile
29570         cat $DIR/$tfile > /dev/null
29571         cat $DIR/$tfile > /dev/null
29572         cat $DIR/$tfile > /dev/null
29573         cat $DIR/$tfile > /dev/null
29574
29575         out=$($LFS heat_get $DIR/$tfile)
29576         $LFS heat_get $DIR/$tfile
29577         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
29578         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
29579         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
29580         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
29581
29582         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
29583         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
29584         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
29585         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
29586
29587         $LCTL set_param -n llite.*.file_heat=$file_heat_sav
29588         rm -f $DIR/$tfile
29589 }
29590 run_test 813 "File heat verfication"
29591
29592 test_814()
29593 {
29594         dd of=$DIR/$tfile seek=128 bs=1k < /dev/null
29595         echo -n y >> $DIR/$tfile
29596         cp --sparse=always $DIR/$tfile $DIR/${tfile}.cp || error "copy failed"
29597         diff $DIR/$tfile $DIR/${tfile}.cp || error "files should be same"
29598 }
29599 run_test 814 "sparse cp works as expected (LU-12361)"
29600
29601 test_815()
29602 {
29603         writeme -b 100 $DIR/$tfile || error "write 100 bytes failed"
29604         writeme -b 0 $DIR/$tfile || error "write 0 byte failed"
29605 }
29606 run_test 815 "zero byte tiny write doesn't hang (LU-12382)"
29607
29608 test_816() {
29609         local ost1_imp=$(get_osc_import_name client ost1)
29610         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
29611                          cut -d'.' -f2)
29612
29613         $LFS setstripe -c 1 -i 0 $DIR/$tfile
29614         # ensure ost1 is connected
29615
29616         stat $DIR/$tfile >/dev/null || error "can't stat"
29617         wait_osc_import_state client ost1 FULL
29618         # no locks, no reqs to let the connection idle
29619         cancel_lru_locks osc
29620         lru_resize_disable osc
29621         local before
29622         local now
29623         before=$($LCTL get_param -n \
29624                  ldlm.namespaces.$imp_name.lru_size)
29625
29626         wait_osc_import_state client ost1 IDLE
29627         dd if=/dev/null of=$DIR/$tfile bs=1k count=1 conv=sync
29628         now=$($LCTL get_param -n \
29629               ldlm.namespaces.$imp_name.lru_size)
29630         [ $before == $now ] || error "lru_size changed $before != $now"
29631 }
29632 run_test 816 "do not reset lru_resize on idle reconnect"
29633
29634 cleanup_817() {
29635         umount $tmpdir
29636         exportfs -u localhost:$DIR/nfsexp
29637         rm -rf $DIR/nfsexp
29638 }
29639
29640 test_817() {
29641         systemctl restart nfs-server.service || skip "failed to restart nfsd"
29642
29643         mkdir -p $DIR/nfsexp
29644         exportfs -orw,no_root_squash localhost:$DIR/nfsexp ||
29645                 error "failed to export nfs"
29646
29647         tmpdir=$(mktemp -d /tmp/nfs-XXXXXX)
29648         stack_trap cleanup_817 EXIT
29649
29650         mount -t nfs -orw localhost:$DIR/nfsexp $tmpdir ||
29651                 error "failed to mount nfs to $tmpdir"
29652
29653         cp /bin/true $tmpdir
29654         $DIR/nfsexp/true || error "failed to execute 'true' command"
29655 }
29656 run_test 817 "nfsd won't cache write lock for exec file"
29657
29658 test_818() {
29659         test_mkdir -i0 -c1 $DIR/$tdir
29660         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
29661         $LFS setstripe -c1 -i1 $DIR/$tdir/$tfile
29662         stop $SINGLEMDS
29663
29664         # restore osp-syn threads
29665         stack_trap "fail $SINGLEMDS"
29666
29667         #define OBD_FAIL_OSP_CANT_PROCESS_LLOG          0x2105
29668         do_facet $SINGLEMDS lctl set_param fail_loc=0x80002105
29669         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
29670                 error "start $SINGLEMDS failed"
29671         rm -rf $DIR/$tdir
29672
29673         local testid=$(echo $TESTNAME | tr '_' ' ')
29674
29675         do_facet mds1 dmesg | tac | sed "/$testid/,$ d" |
29676                 grep "run LFSCK" || error "run LFSCK is not suggested"
29677 }
29678 run_test 818 "unlink with failed llog"
29679
29680 test_819a() {
29681         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
29682         cancel_lru_locks osc
29683         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
29684         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
29685         dd if=$DIR/$tfile of=/dev/null bs=1M count=1
29686         rm -f $TDIR/$tfile
29687 }
29688 run_test 819a "too big niobuf in read"
29689
29690 test_819b() {
29691         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
29692         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
29693         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
29694         cancel_lru_locks osc
29695         sleep 1
29696         rm -f $TDIR/$tfile
29697 }
29698 run_test 819b "too big niobuf in write"
29699
29700
29701 function test_820_start_ost() {
29702         sleep 5
29703
29704         for num in $(seq $OSTCOUNT); do
29705                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS
29706         done
29707 }
29708
29709 test_820() {
29710         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
29711
29712         mkdir $DIR/$tdir
29713         umount_client $MOUNT || error "umount failed"
29714         for num in $(seq $OSTCOUNT); do
29715                 stop ost$num
29716         done
29717
29718         # mount client with no active OSTs
29719         # so that the client can't initialize max LOV EA size
29720         # from OSC notifications
29721         mount_client $MOUNT || error "mount failed"
29722         # delay OST starting to keep this 0 max EA size for a while
29723         test_820_start_ost &
29724
29725         # create a directory on MDS2
29726         test_mkdir -i 1 -c1 $DIR/$tdir/mds2 ||
29727                 error "Failed to create directory"
29728         # open intent should update default EA size
29729         # see mdc_update_max_ea_from_body()
29730         # notice this is the very first RPC to MDS2
29731         out=$(cp /etc/services $DIR/$tdir/mds2 2>&1)
29732         ret=$?
29733         echo $out
29734         # With SSK, this situation can lead to -EPERM being returned.
29735         # In that case, simply retry.
29736         if [ $ret -ne 0 ] && $SHARED_KEY; then
29737                 if echo "$out" | grep -q "not permitted"; then
29738                         cp /etc/services $DIR/$tdir/mds2
29739                         ret=$?
29740                 fi
29741         fi
29742         [ $ret -eq 0 ] || error "Failed to copy files to mds$n"
29743 }
29744 run_test 820 "update max EA from open intent"
29745
29746 test_823() {
29747         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
29748         local OST_MAX_PRECREATE=20000
29749
29750         (( $MDS1_VERSION >= $(version_code 2.14.56) )) ||
29751                 skip "Need MDS version at least 2.14.56"
29752
29753         save_lustre_params mds1 \
29754                 "osp.$FSNAME-OST*-osc-MDT0000.max_create_count" > $p
29755         do_facet $SINGLEMDS "$LCTL set_param -n \
29756                 osp.$FSNAME-OST*MDT0000.max_create_count=0"
29757         do_facet $SINGLEMDS "$LCTL set_param -n \
29758                 osp.$FSNAME-OST0000*MDT0000.max_create_count=$OST_MAX_PRECREATE"
29759
29760         stack_trap "restore_lustre_params < $p; rm $p"
29761
29762         do_facet $SINGLEMDS "$LCTL set_param -n \
29763                 osp.$FSNAME-OST*-osc-MDT*.create_count=100200"
29764
29765         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
29766                       osp.$FSNAME-OST0000*MDT0000.create_count")
29767         local max=$(do_facet $SINGLEMDS "$LCTL get_param -n \
29768                     osp.$FSNAME-OST0000*MDT0000.max_create_count")
29769         local expect_count=$(((($max/2)/256) * 256))
29770
29771         log "setting create_count to 100200:"
29772         log " -result- count: $count with max: $max, expecting: $expect_count"
29773
29774         [[ $count -eq expect_count ]] ||
29775                 error "Create count not set to max precreate."
29776 }
29777 run_test 823 "Setting create_count > OST_MAX_PRECREATE is lowered to maximum"
29778
29779 test_831() {
29780         [[ $MDS1_VERSION -lt $(version_code 2.14.56) ]] &&
29781                 skip "Need MDS version 2.14.56"
29782
29783         local sync_changes=$(do_facet $SINGLEMDS \
29784                 $LCTL get_param -n osp.$FSNAME-OST0000-osc-MDT0000.sync_changes)
29785
29786         [ "$sync_changes" -gt 100 ] &&
29787                 skip "Sync changes $sync_changes > 100 already"
29788
29789         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
29790
29791         $LFS mkdir -i 0 $DIR/$tdir
29792         $LFS setstripe -c 1 -i 0 $DIR/$tdir
29793
29794         save_lustre_params mds1 \
29795                 "osp.$FSNAME-OST*-osc-MDT0000.max_sync_changes" > $p
29796         save_lustre_params mds1 \
29797                 "osp.$FSNAME-OST*-osc-MDT0000.max_rpcs_in_progress" >> $p
29798
29799         do_facet mds1 "$LCTL set_param -n \
29800                 osp.$FSNAME-OST*-osc-MDT0000.max_sync_changes=100 \
29801                 osp.$FSNAME-OST*-osc-MDT0000.max_rpcs_in_progress=128"
29802         stack_trap "restore_lustre_params < $p" EXIT
29803
29804         createmany -o $DIR/$tdir/f- 1000
29805         unlinkmany $DIR/$tdir/f- 1000 &
29806         local UNLINK_PID=$!
29807
29808         while sleep 1; do
29809                 sync_changes=$(do_facet mds1 \
29810                 $LCTL get_param -n osp.$FSNAME-OST0000-osc-MDT0000.sync_changes)
29811                 # the check in the code is racy, fail the test
29812                 # if the value above the limit by 10.
29813                 [ $sync_changes -gt 110 ] && {
29814                         kill -2 $UNLINK_PID
29815                         wait
29816                         error "osp changes throttling failed, $sync_changes>110"
29817                 }
29818                 kill -0 $UNLINK_PID 2> /dev/null || break
29819         done
29820         wait
29821 }
29822 run_test 831 "throttling unlink/setattr queuing on OSP"
29823
29824 test_832() {
29825         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
29826         (( $MDS1_VERSION >= $(version_code 2.15.52) )) ||
29827                 skip "Need MDS version 2.15.52+"
29828         is_rmentry_supported || skip "rm_entry not supported"
29829
29830         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
29831         mkdir $DIR/$tdir/local_dir || error "mkdir local_dir failed"
29832         mkdir_on_mdt -i 1 $DIR/$tdir/remote_dir ||
29833                 error "mkdir remote_dir failed"
29834         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/striped_dir ||
29835                 error "mkdir striped_dir failed"
29836         touch $DIR/$tdir/file || error "touch file failed"
29837         $LFS rm_entry $DIR/$tdir/* || error "lfs rm_entry $tdir/* failed"
29838         [ -z "$(ls -A $DIR/$tdir)" ] || error "$tdir not empty"
29839 }
29840 run_test 832 "lfs rm_entry"
29841
29842 #
29843 # tests that do cleanup/setup should be run at the end
29844 #
29845
29846 test_900() {
29847         [ $PARALLEL == "yes" ] && skip "skip parallel run"
29848         local ls
29849
29850         #define OBD_FAIL_MGC_PAUSE_PROCESS_LOG   0x903
29851         $LCTL set_param fail_loc=0x903
29852
29853         cancel_lru_locks MGC
29854
29855         FAIL_ON_ERROR=true cleanup
29856         FAIL_ON_ERROR=true setup
29857 }
29858 run_test 900 "umount should not race with any mgc requeue thread"
29859
29860 # LUS-6253/LU-11185
29861 test_901() {
29862         local old
29863         local count
29864         local oldc
29865         local newc
29866         local olds
29867         local news
29868         [ $PARALLEL == "yes" ] && skip "skip parallel run"
29869
29870         # some get_param have a bug to handle dot in param name
29871         cancel_lru_locks MGC
29872         old=$(mount -t lustre | wc -l)
29873         # 1 config+sptlrpc
29874         # 2 params
29875         # 3 nodemap
29876         # 4 IR
29877         old=$((old * 4))
29878         oldc=0
29879         count=0
29880         while [ $old -ne $oldc ]; do
29881                 oldc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
29882                 sleep 1
29883                 ((count++))
29884                 if [ $count -ge $TIMEOUT ]; then
29885                         error "too large timeout"
29886                 fi
29887         done
29888         umount_client $MOUNT || error "umount failed"
29889         mount_client $MOUNT || error "mount failed"
29890         cancel_lru_locks MGC
29891         newc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
29892
29893         [ $oldc -lt $newc ] && error "mgc lock leak ($oldc != $newc)"
29894
29895         return 0
29896 }
29897 run_test 901 "don't leak a mgc lock on client umount"
29898
29899 # LU-13377
29900 test_902() {
29901         [ $CLIENT_VERSION -lt $(version_code 2.13.52) ] &&
29902                 skip "client does not have LU-13377 fix"
29903         #define OBD_FAIL_LLITE_SHORT_COMMIT 0x1415
29904         $LCTL set_param fail_loc=0x1415
29905         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
29906         cancel_lru_locks osc
29907         rm -f $DIR/$tfile
29908 }
29909 run_test 902 "test short write doesn't hang lustre"
29910
29911 # LU-14711
29912 test_903() {
29913         $LFS setstripe -i 0 -c 1 $DIR/$tfile $DIR/${tfile}-2
29914         echo "blah" > $DIR/${tfile}-2
29915         dd if=/dev/zero of=$DIR/$tfile bs=1M count=6 conv=fsync
29916         #define OBD_FAIL_OSC_SLOW_PAGE_EVICT 0x417
29917         $LCTL set_param fail_loc=0x417 fail_val=20
29918
29919         mv $DIR/${tfile}-2 $DIR/$tfile # Destroys the big object
29920         sleep 1 # To start the destroy
29921         wait_destroy_complete 150 || error "Destroy taking too long"
29922         cat $DIR/$tfile > /dev/null || error "Evicted"
29923 }
29924 run_test 903 "Test long page discard does not cause evictions"
29925
29926 test_904() {
29927         [ "$mds1_FSTYPE" == "ldiskfs" ] || skip "ldiskfs only test"
29928         do_facet mds1 $DEBUGFS -R features $(mdsdevname 1) |
29929                 grep -q project || skip "skip project quota not supported"
29930
29931         local testfile="$DIR/$tdir/$tfile"
29932         local xattr="trusted.projid"
29933         local projid
29934         local mdts=$(comma_list $(mdts_nodes))
29935         local saved=$(do_facet mds1 $LCTL get_param -n \
29936                 osd-ldiskfs.*MDT0000.enable_projid_xattr)
29937
29938         do_nodes $mdts $LCTL set_param osd-ldiskfs.*MDT*.enable_projid_xattr=0
29939         stack_trap "do_nodes $mdts $LCTL set_param \
29940                 osd-ldiskfs.*MDT*.enable_projid_xattr=$saved"
29941
29942         mkdir -p $DIR/$tdir
29943         touch $testfile
29944         #hide projid xattr on server
29945         $LFS project -p 1 $testfile ||
29946                 error "set $testfile project id failed"
29947         getfattr -m - $testfile | grep $xattr &&
29948                 error "do not show trusted.projid when disabled on server"
29949         do_nodes $mdts $LCTL set_param osd-ldiskfs.*MDT*.enable_projid_xattr=1
29950         #should be hidden when projid is 0
29951         $LFS project -p 0 $testfile ||
29952                 error "set $testfile project id failed"
29953         getfattr -m - $testfile | grep $xattr &&
29954                 error "do not show trusted.projid with project ID 0"
29955
29956         #still can getxattr explicitly
29957         projid=$(getfattr -n $xattr $testfile |
29958                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
29959         [ $projid == "0" ] ||
29960                 error "projid expected 0 not $projid"
29961
29962         #set the projid via setxattr
29963         setfattr -n $xattr -v "1000" $testfile ||
29964                 error "setattr failed with $?"
29965         projid=($($LFS project $testfile))
29966         [ ${projid[0]} == "1000" ] ||
29967                 error "projid expected 1000 not $projid"
29968
29969         #check the new projid via getxattr
29970         $LFS project -p 1001 $testfile ||
29971                 error "set $testfile project id failed"
29972         getfattr -m - $testfile | grep $xattr ||
29973                 error "should show trusted.projid when project ID != 0"
29974         projid=$(getfattr -n $xattr $testfile |
29975                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
29976         [ $projid == "1001" ] ||
29977                 error "projid expected 1001 not $projid"
29978
29979         #try to set invalid projid
29980         setfattr -n $xattr -v "4294967295" $testfile &&
29981                 error "set invalid projid should fail"
29982
29983         #remove the xattr means setting projid to 0
29984         setfattr -x $xattr $testfile ||
29985                 error "setfattr failed with $?"
29986         projid=($($LFS project $testfile))
29987         [ ${projid[0]} == "0" ] ||
29988                 error "projid expected 0 not $projid"
29989
29990         #should be hidden when parent has inherit flag and same projid
29991         $LFS project -srp 1002 $DIR/$tdir ||
29992                 error "set $tdir project id failed"
29993         getfattr -m - $testfile | grep $xattr &&
29994                 error "do not show trusted.projid with inherit flag"
29995
29996         #still can getxattr explicitly
29997         projid=$(getfattr -n $xattr $testfile |
29998                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
29999         [ $projid == "1002" ] ||
30000                 error "projid expected 1002 not $projid"
30001 }
30002 run_test 904 "virtual project ID xattr"
30003
30004 # LU-8582
30005 test_905() {
30006         (( $OST1_VERSION >= $(version_code 2.8.54) )) ||
30007                 skip "lustre < 2.8.54 does not support ladvise"
30008
30009         remote_ost_nodsh && skip "remote OST with nodsh"
30010         $LFS setstripe -c -1 -i 0 $DIR/$tfile || error "setstripe failed"
30011
30012         $LFS ladvise -a willread $DIR/$tfile || error "ladvise does not work"
30013
30014         #define OBD_FAIL_OST_OPCODE 0x253
30015         # OST_LADVISE = 21
30016         do_facet ost1 "$LCTL set_param fail_val=21 fail_loc=0x0253"
30017         $LFS ladvise -a willread $DIR/$tfile &&
30018                 error "unexpected success of ladvise with fault injection"
30019         $LFS ladvise -a willread $DIR/$tfile |&
30020                 grep -q "Operation not supported"
30021         (( $? == 0 )) || error "unexpected stderr of ladvise with fault injection"
30022 }
30023 run_test 905 "bad or new opcode should not stuck client"
30024
30025 test_906() {
30026         grep -q io_uring_setup /proc/kallsyms ||
30027                 skip "Client OS does not support io_uring I/O engine"
30028         io_uring_probe || skip "kernel does not support io_uring fully"
30029         which fio || skip_env "no fio installed"
30030         fio --enghelp | grep -q io_uring ||
30031                 skip_env "fio does not support io_uring I/O engine"
30032
30033         local file=$DIR/$tfile
30034         local ioengine="io_uring"
30035         local numjobs=2
30036         local size=50M
30037
30038         fio --name=seqwrite --ioengine=$ioengine        \
30039                 --bs=$PAGE_SIZE --direct=1 --numjobs=$numjobs   \
30040                 --iodepth=64 --size=$size --filename=$file --rw=write ||
30041                 error "fio seqwrite $file failed"
30042
30043         fio --name=seqread --ioengine=$ioengine \
30044                 --bs=$PAGE_SIZE --direct=1 --numjobs=$numjobs   \
30045                 --iodepth=64 --size=$size --filename=$file --rw=read ||
30046                 error "fio seqread $file failed"
30047
30048         rm -f $file || error "rm -f $file failed"
30049 }
30050 run_test 906 "Simple test for io_uring I/O engine via fio"
30051
30052 complete $SECONDS
30053 [ -f $EXT2_DEV ] && rm $EXT2_DEV || true
30054 check_and_cleanup_lustre
30055 if [ "$I_MOUNTED" != "yes" ]; then
30056         lctl set_param debug="$OLDDEBUG" 2> /dev/null || true
30057 fi
30058 exit_status