Whamcloud - gitweb
LU-15934 tests: add a test case for update llog
[fs/lustre-release.git] / lustre / tests / sanity.sh
1 #!/bin/bash
2 #
3 # Run select tests by setting ONLY, or as arguments to the script.
4 # Skip specific tests by setting EXCEPT.
5 #
6 # e.g. ONLY="22 23" or ONLY="`seq 32 39`" or EXCEPT="31"
7 set -e
8
9 ONLY=${ONLY:-"$*"}
10
11 # Check Grants after these tests
12 GRANT_CHECK_LIST="$GRANT_CHECK_LIST 42a 42b 42c 42d 42e 63a 63b 64a 64b 64c 64d"
13
14 OSC=${OSC:-"osc"}
15
16 CC=${CC:-cc}
17 CREATETEST=${CREATETEST:-createtest}
18 LVERIFY=${LVERIFY:-ll_dirstripe_verify}
19 OPENFILE=${OPENFILE:-openfile}
20 OPENUNLINK=${OPENUNLINK:-openunlink}
21 READS=${READS:-"reads"}
22 MUNLINK=${MUNLINK:-munlink}
23 SOCKETSERVER=${SOCKETSERVER:-socketserver}
24 SOCKETCLIENT=${SOCKETCLIENT:-socketclient}
25 MEMHOG=${MEMHOG:-memhog}
26 DIRECTIO=${DIRECTIO:-directio}
27 ACCEPTOR_PORT=${ACCEPTOR_PORT:-988}
28 DEF_STRIPE_COUNT=-1
29 CHECK_GRANT=${CHECK_GRANT:-"yes"}
30 GRANT_CHECK_LIST=${GRANT_CHECK_LIST:-""}
31
32 TRACE=${TRACE:-""}
33 LUSTRE=${LUSTRE:-$(dirname $0)/..}
34 LUSTRE_TESTS_API_DIR=${LUSTRE_TESTS_API_DIR:-${LUSTRE}/tests/clientapi}
35 . $LUSTRE/tests/test-framework.sh
36 init_test_env "$@"
37
38 init_logging
39
40 ALWAYS_EXCEPT="$SANITY_EXCEPT "
41 always_except LU-9693  42a 42c
42 always_except LU-6493  42b
43 always_except LU-16515 118c 118d
44 always_except LU-8411  407
45
46 if $SHARED_KEY; then
47         always_except LU-14181 64e 64f
48 fi
49
50 # skip the grant tests for ARM until they are fixed
51 if [[ $(uname -m) = aarch64 ]]; then
52         always_except LU-11671 45
53 fi
54
55 # skip nfs tests on kernels >= 4.12.0 until they are fixed
56 if [ $LINUX_VERSION_CODE -ge $(version_code 4.12.0) ]; then
57         always_except LU-12661 817
58 fi
59 # skip cgroup tests on RHEL8.1 kernels until they are fixed
60 if (( $LINUX_VERSION_CODE >= $(version_code 4.18.0) &&
61       $LINUX_VERSION_CODE <  $(version_code 5.4.0) )); then
62         always_except LU-13063 411
63 fi
64
65 # skip basic ops on file with foreign LOV tests on 5.16.0+ kernels
66 # until the filemap_read() issue is fixed
67 if (( $LINUX_VERSION_CODE >= $(version_code 5.16.0) )); then
68         always_except LU-16101 27J
69 fi
70
71 #                                  5              12     8   12  15   (min)"
72 [[ "$SLOW" = "no" ]] && EXCEPT_SLOW="27m 60i 64b 68 71 135 136 230d 300o"
73
74 if [[ "$mds1_FSTYPE" == "zfs" ]]; then
75         #                                               13    (min)"
76         [[ "$SLOW" == "no" ]] && EXCEPT_SLOW="$EXCEPT_SLOW 51b"
77 fi
78
79 if [[ "$ost1_FSTYPE" = "zfs" ]]; then
80         always_except LU-1941 130b 130c 130d 130e 130f 130g
81         always_except LU-9054 312
82 fi
83
84 proc_regexp="/{proc,sys}/{fs,sys,kernel/debug}/{lustre,lnet}/"
85
86 # Get the SLES distro version
87 #
88 # Returns a version string that should only be used in comparing
89 # strings returned by version_code()
90 sles_version_code()
91 {
92         local version=$(grep VERSION_ID /etc/os-release | cut -d'"' -f2)
93
94         # All SuSE Linux versions have one decimal. version_code expects two
95         local sles_version=$version.0
96         version_code $sles_version
97 }
98
99 # Check if we are running on Ubuntu or SLES so we can make decisions on
100 # what tests to run
101 if [ -r /etc/SuSE-release ] || [ -r /etc/SUSE-brand ]; then
102         sles_version=$(sles_version_code)
103         [ $sles_version -lt $(version_code 11.4.0) ] &&
104                 always_except LU-4341 170
105
106         [ $sles_version -lt $(version_code 12.0.0) ] &&
107                 always_except LU-3703 234
108
109         [ $sles_version -ge $(version_code 15.4.0) ] &&
110                 always_except LU-16101 27J
111 elif [ -r /etc/os-release ]; then
112         if grep -qi ubuntu /etc/os-release; then
113                 ubuntu_version=$(version_code $(sed -n -e 's/"//g' \
114                                                 -e 's/^VERSION=//p' \
115                                                 /etc/os-release |
116                                                 awk '{ print $1 }'))
117
118                 if [[ $ubuntu_version -gt $(version_code 16.0.0) ]]; then
119                         always_except LU-10366 410
120                 fi
121         fi
122 fi
123
124 build_test_filter
125 FAIL_ON_ERROR=false
126
127 cleanup() {
128         echo -n "cln.."
129         pgrep ll_sa > /dev/null && { echo "There are ll_sa thread not exit!"; exit 20; }
130         cleanupall ${FORCE} $* || { echo "FAILed to clean up"; exit 20; }
131 }
132 setup() {
133         echo -n "mnt.."
134         load_modules
135         setupall || exit 10
136         echo "done"
137 }
138
139 check_swap_layouts_support()
140 {
141         $LCTL get_param -n llite.*.sbi_flags | grep -q layout ||
142                 skip "Does not support layout lock."
143 }
144
145 check_swap_layout_no_dom()
146 {
147         local FOLDER=$1
148         local SUPP=$(lfs getstripe $FOLDER | grep "pattern:       mdt" | wc -l)
149         [ $SUPP -eq 0 ] || skip "layout swap does not support DOM files so far"
150 }
151
152 check_and_setup_lustre
153 DIR=${DIR:-$MOUNT}
154 assert_DIR
155
156 MAXFREE=${MAXFREE:-$((300000 * $OSTCOUNT))}
157
158 [ -f $DIR/d52a/foo ] && chattr -a $DIR/d52a/foo
159 [ -f $DIR/d52b/foo ] && chattr -i $DIR/d52b/foo
160 rm -rf $DIR/[Rdfs][0-9]*
161
162 # $RUNAS_ID may get set incorrectly somewhere else
163 [ $UID -eq 0 -a $RUNAS_ID -eq 0 ] &&
164         error "\$RUNAS_ID set to 0, but \$UID is also 0!"
165
166 check_runas_id $RUNAS_ID $RUNAS_GID $RUNAS
167
168 if [ "${ONLY}" = "MOUNT" ] ; then
169         echo "Lustre is up, please go on"
170         exit
171 fi
172
173 echo "preparing for tests involving mounts"
174 EXT2_DEV=${EXT2_DEV:-$TMP/SANITY.LOOP}
175 touch $EXT2_DEV
176 mke2fs -j -F $EXT2_DEV 8000 > /dev/null
177 echo # add a newline after mke2fs.
178
179 umask 077
180
181 OLDDEBUG=$(lctl get_param -n debug 2> /dev/null)
182
183 # ensure all internal functions know we want full debug
184 export PTLDEBUG=all
185 lctl set_param debug=$PTLDEBUG 2> /dev/null || true
186
187 test_0a() {
188         touch $DIR/$tfile
189         $CHECKSTAT -t file $DIR/$tfile || error "$tfile is not a file"
190         rm $DIR/$tfile
191         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
192 }
193 run_test 0a "touch; rm ====================="
194
195 test_0b() {
196         chmod 0755 $DIR || error "chmod 0755 $DIR failed"
197         $CHECKSTAT -p 0755 $DIR || error "$DIR permission is not 0755"
198 }
199 run_test 0b "chmod 0755 $DIR ============================="
200
201 test_0c() {
202         $LCTL get_param mdc.*.import | grep "state: FULL" ||
203                 error "import not FULL"
204         $LCTL get_param mdc.*.import | grep "target: $FSNAME-MDT" ||
205                 error "bad target"
206 }
207 run_test 0c "check import proc"
208
209 test_0d() { # LU-3397
210         [ $MGS_VERSION -lt $(version_code 2.10.57) ] &&
211                 skip "proc exports not supported before 2.10.57"
212
213         local mgs_exp="mgs.MGS.exports"
214         local client_uuid=$($LCTL get_param -n mgc.*.uuid)
215         local exp_client_nid
216         local exp_client_version
217         local exp_val
218         local imp_val
219         local temp_imp=$DIR/$tfile.import
220         local temp_exp=$DIR/$tfile.export
221
222         # save mgc import file to $temp_imp
223         $LCTL get_param mgc.*.import | tee $temp_imp
224         # Check if client uuid is found in MGS export
225         for exp_client_nid in $(do_facet mgs $LCTL get_param -N $mgs_exp.*); do
226                 [ $(do_facet mgs $LCTL get_param -n $exp_client_nid.uuid) == \
227                         $client_uuid ] &&
228                         break;
229         done
230         # save mgs export file to $temp_exp
231         do_facet mgs $LCTL get_param $exp_client_nid.export | tee $temp_exp
232
233         # Compare the value of field "connect_flags"
234         imp_val=$(grep "connect_flags" $temp_imp)
235         exp_val=$(grep "connect_flags" $temp_exp)
236         [ "$exp_val" == "$imp_val" ] ||
237                 error "export flags '$exp_val' != import flags '$imp_val'"
238
239         # Compare client versions.  Only compare top-3 fields for compatibility
240         exp_client_version=$(awk '/target_version:/ { print $2 }' $temp_exp)
241         exp_val=$(version_code $(cut -d. -f1,2,3 <<<$exp_client_version))
242         imp_val=$(version_code $(lustre_build_version client | cut -d. -f1,2,3))
243         [ "$exp_val" == "$imp_val" ] ||
244                 error "exp version '$exp_client_version'($exp_val) != " \
245                         "'$(lustre_build_version client)'($imp_val)"
246 }
247 run_test 0d "check export proc ============================="
248
249 test_0e() { # LU-13417
250         (( $MDSCOUNT > 1 )) ||
251                 skip "We need at least 2 MDTs for this test"
252
253         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
254                 skip "Need server version at least 2.14.51"
255
256         local default_lmv_count=$($LFS getdirstripe -D -c $MOUNT)
257         local default_lmv_index=$($LFS getdirstripe -D -i $MOUNT)
258
259         [ $default_lmv_count -eq 1 ] ||
260                 error "$MOUNT default stripe count $default_lmv_count"
261
262         [ $default_lmv_index -eq -1 ] ||
263                 error "$MOUNT default stripe index $default_lmv_index"
264
265         mkdir $MOUNT/$tdir.1 || error "mkdir $MOUNT/$tdir.1 failed"
266         mkdir $MOUNT/$tdir.2 || error "mkdir $MOUNT/$tdir.2 failed"
267
268         local mdt_index1=$($LFS getdirstripe -i $MOUNT/$tdir.1)
269         local mdt_index2=$($LFS getdirstripe -i $MOUNT/$tdir.2)
270
271         [ $mdt_index1 -eq $mdt_index2 ] &&
272                 error "directories are on the same MDT $mdt_index1=$mdt_index2"
273
274         rmdir $MOUNT/$tdir.1 $MOUNT/$tdir.2
275 }
276 run_test 0e "Enable DNE MDT balancing for mkdir in the ROOT"
277
278 test_1() {
279         test_mkdir $DIR/$tdir
280         test_mkdir $DIR/$tdir/d2
281         mkdir $DIR/$tdir/d2 && error "we expect EEXIST, but not returned"
282         $CHECKSTAT -t dir $DIR/$tdir/d2 || error "$tdir/d2 is not a dir"
283         rmdir $DIR/$tdir/d2
284         rmdir $DIR/$tdir
285         $CHECKSTAT -a $DIR/$tdir || error "$tdir was not removed"
286 }
287 run_test 1 "mkdir; remkdir; rmdir"
288
289 test_2() {
290         test_mkdir $DIR/$tdir
291         touch $DIR/$tdir/$tfile || error "touch $tdir/$tfile failed"
292         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "$tdir/$tfile not a file"
293         rm -r $DIR/$tdir
294         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$file is not removed"
295 }
296 run_test 2 "mkdir; touch; rmdir; check file"
297
298 test_3() {
299         test_mkdir $DIR/$tdir
300         $CHECKSTAT -t dir $DIR/$tdir || error "$tdir is not a directory"
301         touch $DIR/$tdir/$tfile
302         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "$tdir/$tfile not a file"
303         rm -r $DIR/$tdir
304         $CHECKSTAT -a $DIR/$tdir || error "$tdir is not removed"
305 }
306 run_test 3 "mkdir; touch; rmdir; check dir"
307
308 # LU-4471 - failed rmdir on remote directories still removes directory on MDT0
309 test_4() {
310         test_mkdir -i 1 $DIR/$tdir
311
312         touch $DIR/$tdir/$tfile ||
313                 error "Create file under remote directory failed"
314
315         rmdir $DIR/$tdir &&
316                 error "Expect error removing in-use dir $DIR/$tdir"
317
318         test -d $DIR/$tdir || error "Remote directory disappeared"
319
320         rm -rf $DIR/$tdir || error "remove remote dir error"
321 }
322 run_test 4 "mkdir; touch dir/file; rmdir; checkdir (expect error)"
323
324 test_5() {
325         test_mkdir $DIR/$tdir
326         test_mkdir $DIR/$tdir/d2
327         chmod 0707 $DIR/$tdir/d2 || error "chmod 0707 $tdir/d2 failed"
328         $CHECKSTAT -t dir -p 0707 $DIR/$tdir/d2 || error "$tdir/d2 not mode 707"
329         $CHECKSTAT -t dir $DIR/$tdir/d2 || error "$tdir/d2 is not a directory"
330 }
331 run_test 5 "mkdir .../d5 .../d5/d2; chmod .../d5/d2"
332
333 test_6a() {
334         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
335         chmod 0666 $DIR/$tfile || error "chmod 0666 $tfile failed"
336         $CHECKSTAT -t file -p 0666 -u \#$UID $DIR/$tfile ||
337                 error "$tfile does not have perm 0666 or UID $UID"
338         $RUNAS chmod 0444 $DIR/$tfile && error "chmod $tfile worked on UID $UID"
339         $CHECKSTAT -t file -p 0666 -u \#$UID $DIR/$tfile ||
340                 error "$tfile should be 0666 and owned by UID $UID"
341 }
342 run_test 6a "touch f6a; chmod f6a; $RUNAS chmod f6a (should return error) =="
343
344 test_6c() {
345         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
346
347         touch $DIR/$tfile
348         chown $RUNAS_ID $DIR/$tfile || error "chown $RUNAS_ID $file failed"
349         $CHECKSTAT -t file -u \#$RUNAS_ID $DIR/$tfile ||
350                 error "$tfile should be owned by UID $RUNAS_ID"
351         $RUNAS chown $UID $DIR/$tfile && error "chown $UID $file succeeded"
352         $CHECKSTAT -t file -u \#$RUNAS_ID $DIR/$tfile ||
353                 error "$tfile should be owned by UID $RUNAS_ID"
354 }
355 run_test 6c "touch f6c; chown f6c; $RUNAS chown f6c (should return error) =="
356
357 test_6e() {
358         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
359
360         touch $DIR/$tfile
361         chgrp $RUNAS_ID $DIR/$tfile || error "chgrp $RUNAS_ID $file failed"
362         $CHECKSTAT -t file -u \#$UID -g \#$RUNAS_ID $DIR/$tfile ||
363                 error "$tfile should be owned by GID $UID"
364         $RUNAS chgrp $UID $DIR/$tfile && error "chgrp $UID $file succeeded"
365         $CHECKSTAT -t file -u \#$UID -g \#$RUNAS_ID $DIR/$tfile ||
366                 error "$tfile should be owned by UID $UID and GID $RUNAS_ID"
367 }
368 run_test 6e "touch+chgrp $tfile; $RUNAS chgrp $tfile (should return error)"
369
370 test_6g() {
371         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
372
373         test_mkdir $DIR/$tdir
374         chmod 777 $DIR/$tdir || error "chmod 0777 $tdir failed"
375         $RUNAS mkdir $DIR/$tdir/d || error "mkdir $tdir/d failed"
376         chmod g+s $DIR/$tdir/d || error "chmod g+s $tdir/d failed"
377         test_mkdir $DIR/$tdir/d/subdir
378         $CHECKSTAT -g \#$RUNAS_GID $DIR/$tdir/d/subdir ||
379                 error "$tdir/d/subdir should be GID $RUNAS_GID"
380         if [[ $MDSCOUNT -gt 1 ]]; then
381                 # check remote dir sgid inherite
382                 $LFS mkdir -i 0 $DIR/$tdir.local ||
383                         error "mkdir $tdir.local failed"
384                 chmod g+s $DIR/$tdir.local ||
385                         error "chmod $tdir.local failed"
386                 chgrp $RUNAS_GID $DIR/$tdir.local ||
387                         error "chgrp $tdir.local failed"
388                 $LFS mkdir -i 1 $DIR/$tdir.local/$tdir.remote ||
389                         error "mkdir $tdir.remote failed"
390                 $CHECKSTAT -g \#$RUNAS_GID $DIR/$tdir.local/$tdir.remote ||
391                         error "$tdir.remote should be owned by $UID.$RUNAS_ID"
392                 $CHECKSTAT -p 02755 $DIR/$tdir.local/$tdir.remote ||
393                         error "$tdir.remote should be mode 02755"
394         fi
395 }
396 run_test 6g "verify new dir in sgid dir inherits group"
397
398 test_6h() { # bug 7331
399         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
400
401         touch $DIR/$tfile || error "touch failed"
402         chown $RUNAS_ID:$RUNAS_GID $DIR/$tfile || error "initial chown failed"
403         $RUNAS -G$RUNAS_GID chown $RUNAS_ID:0 $DIR/$tfile &&
404                 error "chown $RUNAS_ID:0 $tfile worked as GID $RUNAS_GID"
405         $CHECKSTAT -t file -u \#$RUNAS_ID -g \#$RUNAS_GID $DIR/$tfile ||
406                 error "$tdir/$tfile should be UID $RUNAS_UID GID $RUNAS_GID"
407 }
408 run_test 6h "$RUNAS chown RUNAS_ID.0 .../$tfile (should return error)"
409
410 test_7a() {
411         test_mkdir $DIR/$tdir
412         $MCREATE $DIR/$tdir/$tfile
413         chmod 0666 $DIR/$tdir/$tfile
414         $CHECKSTAT -t file -p 0666 $DIR/$tdir/$tfile ||
415                 error "$tdir/$tfile should be mode 0666"
416 }
417 run_test 7a "mkdir .../d7; mcreate .../d7/f; chmod .../d7/f ===="
418
419 test_7b() {
420         if [ ! -d $DIR/$tdir ]; then
421                 test_mkdir $DIR/$tdir
422         fi
423         $MCREATE $DIR/$tdir/$tfile
424         echo -n foo > $DIR/$tdir/$tfile
425         [ "$(cat $DIR/$tdir/$tfile)" = "foo" ] || error "$tdir/$tfile not 'foo'"
426         $CHECKSTAT -t file -s 3 $DIR/$tdir/$tfile || error "$tfile size not 3"
427 }
428 run_test 7b "mkdir .../d7; mcreate d7/f2; echo foo > d7/f2 ====="
429
430 test_8() {
431         test_mkdir $DIR/$tdir
432         touch $DIR/$tdir/$tfile
433         chmod 0666 $DIR/$tdir/$tfile
434         $CHECKSTAT -t file -p 0666 $DIR/$tdir/$tfile ||
435                 error "$tfile mode not 0666"
436 }
437 run_test 8 "mkdir .../d8; touch .../d8/f; chmod .../d8/f ======="
438
439 test_9() {
440         test_mkdir $DIR/$tdir
441         test_mkdir $DIR/$tdir/d2
442         test_mkdir $DIR/$tdir/d2/d3
443         $CHECKSTAT -t dir $DIR/$tdir/d2/d3 || error "$tdir/d2/d3 not a dir"
444 }
445 run_test 9 "mkdir .../d9 .../d9/d2 .../d9/d2/d3 ================"
446
447 test_10() {
448         test_mkdir $DIR/$tdir
449         test_mkdir $DIR/$tdir/d2
450         touch $DIR/$tdir/d2/$tfile
451         $CHECKSTAT -t file $DIR/$tdir/d2/$tfile ||
452                 error "$tdir/d2/$tfile not a file"
453 }
454 run_test 10 "mkdir .../d10 .../d10/d2; touch .../d10/d2/f ======"
455
456 test_11() {
457         test_mkdir $DIR/$tdir
458         test_mkdir $DIR/$tdir/d2
459         chmod 0666 $DIR/$tdir/d2
460         chmod 0705 $DIR/$tdir/d2
461         $CHECKSTAT -t dir -p 0705 $DIR/$tdir/d2 ||
462                 error "$tdir/d2 mode not 0705"
463 }
464 run_test 11 "mkdir .../d11 d11/d2; chmod .../d11/d2 ============"
465
466 test_12() {
467         test_mkdir $DIR/$tdir
468         touch $DIR/$tdir/$tfile
469         chmod 0666 $DIR/$tdir/$tfile
470         chmod 0654 $DIR/$tdir/$tfile
471         $CHECKSTAT -t file -p 0654 $DIR/$tdir/$tfile ||
472                 error "$tdir/d2 mode not 0654"
473 }
474 run_test 12 "touch .../d12/f; chmod .../d12/f .../d12/f ========"
475
476 test_13() {
477         test_mkdir $DIR/$tdir
478         dd if=/dev/zero of=$DIR/$tdir/$tfile count=10
479         >  $DIR/$tdir/$tfile
480         $CHECKSTAT -t file -s 0 $DIR/$tdir/$tfile ||
481                 error "$tdir/$tfile size not 0 after truncate"
482 }
483 run_test 13 "creat .../d13/f; dd .../d13/f; > .../d13/f ========"
484
485 test_14() {
486         test_mkdir $DIR/$tdir
487         touch $DIR/$tdir/$tfile
488         rm $DIR/$tdir/$tfile
489         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$tfile not removed"
490 }
491 run_test 14 "touch .../d14/f; rm .../d14/f; rm .../d14/f ======="
492
493 test_15() {
494         test_mkdir $DIR/$tdir
495         touch $DIR/$tdir/$tfile
496         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}_2
497         $CHECKSTAT -t file $DIR/$tdir/${tfile}_2 ||
498                 error "$tdir/${tfile_2} not a file after rename"
499         rm $DIR/$tdir/${tfile}_2 || error "unlink failed after rename"
500 }
501 run_test 15 "touch .../d15/f; mv .../d15/f .../d15/f2 =========="
502
503 test_16() {
504         test_mkdir $DIR/$tdir
505         touch $DIR/$tdir/$tfile
506         rm -rf $DIR/$tdir/$tfile
507         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$tfile not removed"
508 }
509 run_test 16 "touch .../d16/f; rm -rf .../d16/f"
510
511 test_17a() {
512         test_mkdir $DIR/$tdir
513         touch $DIR/$tdir/$tfile
514         ln -s $DIR/$tdir/$tfile $DIR/$tdir/l-exist
515         ls -l $DIR/$tdir
516         $CHECKSTAT -l $DIR/$tdir/$tfile $DIR/$tdir/l-exist ||
517                 error "$tdir/l-exist not a symlink"
518         $CHECKSTAT -f -t f $DIR/$tdir/l-exist ||
519                 error "$tdir/l-exist not referencing a file"
520         rm -f $DIR/$tdir/l-exist
521         $CHECKSTAT -a $DIR/$tdir/l-exist || error "$tdir/l-exist not removed"
522 }
523 run_test 17a "symlinks: create, remove (real)"
524
525 test_17b() {
526         test_mkdir $DIR/$tdir
527         ln -s no-such-file $DIR/$tdir/l-dangle
528         ls -l $DIR/$tdir
529         $CHECKSTAT -l no-such-file $DIR/$tdir/l-dangle ||
530                 error "$tdir/l-dangle not referencing no-such-file"
531         $CHECKSTAT -fa $DIR/$tdir/l-dangle ||
532                 error "$tdir/l-dangle not referencing non-existent file"
533         rm -f $DIR/$tdir/l-dangle
534         $CHECKSTAT -a $DIR/$tdir/l-dangle || error "$tdir/l-dangle not removed"
535 }
536 run_test 17b "symlinks: create, remove (dangling)"
537
538 test_17c() { # bug 3440 - don't save failed open RPC for replay
539         test_mkdir $DIR/$tdir
540         ln -s foo $DIR/$tdir/$tfile
541         cat $DIR/$tdir/$tfile && error "opened non-existent symlink" || true
542 }
543 run_test 17c "symlinks: open dangling (should return error)"
544
545 test_17d() {
546         test_mkdir $DIR/$tdir
547         ln -s foo $DIR/$tdir/$tfile
548         touch $DIR/$tdir/$tfile || error "creating to new symlink"
549 }
550 run_test 17d "symlinks: create dangling"
551
552 test_17e() {
553         test_mkdir $DIR/$tdir
554         local foo=$DIR/$tdir/$tfile
555         ln -s $foo $foo || error "create symlink failed"
556         ls -l $foo || error "ls -l failed"
557         ls $foo && error "ls not failed" || true
558 }
559 run_test 17e "symlinks: create recursive symlink (should return error)"
560
561 test_17f() {
562         test_mkdir $DIR/$tdir
563         ln -s 1234567890/2234567890/3234567890/4234567890 $DIR/$tdir/111
564         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890 $DIR/$tdir/222
565         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890 $DIR/$tdir/333
566         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890 $DIR/$tdir/444
567         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890/c234567890/d234567890/f234567890 $DIR/$tdir/555
568         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890/c234567890/d234567890/f234567890/aaaaaaaaaa/bbbbbbbbbb/cccccccccc/dddddddddd/eeeeeeeeee/ffffffffff/ $DIR/$tdir/666
569         ls -l  $DIR/$tdir
570 }
571 run_test 17f "symlinks: long and very long symlink name"
572
573 # str_repeat(S, N) generate a string that is string S repeated N times
574 str_repeat() {
575         local s=$1
576         local n=$2
577         local ret=''
578         while [ $((n -= 1)) -ge 0 ]; do
579                 ret=$ret$s
580         done
581         echo $ret
582 }
583
584 # Long symlinks and LU-2241
585 test_17g() {
586         test_mkdir $DIR/$tdir
587         local TESTS="59 60 61 4094 4095"
588
589         # Fix for inode size boundary in 2.1.4
590         [ $MDS1_VERSION -lt $(version_code 2.1.4) ] &&
591                 TESTS="4094 4095"
592
593         # Patch not applied to 2.2 or 2.3 branches
594         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
595         [ $MDS1_VERSION -le $(version_code 2.3.55) ] &&
596                 TESTS="4094 4095"
597
598         for i in $TESTS; do
599                 local SYMNAME=$(str_repeat 'x' $i)
600                 ln -s $SYMNAME $DIR/$tdir/f$i || error "failed $i-char symlink"
601                 readlink $DIR/$tdir/f$i || error "failed $i-char readlink"
602         done
603 }
604 run_test 17g "symlinks: really long symlink name and inode boundaries"
605
606 test_17h() { #bug 17378
607         [ $PARALLEL == "yes" ] && skip "skip parallel run"
608         remote_mds_nodsh && skip "remote MDS with nodsh"
609
610         local mdt_idx
611
612         test_mkdir $DIR/$tdir
613         mdt_idx=$($LFS getdirstripe -i $DIR/$tdir)
614         $LFS setstripe -c -1 $DIR/$tdir
615         #define OBD_FAIL_MDS_LOV_PREP_CREATE 0x141
616         do_facet mds$((mdt_idx + 1)) lctl set_param fail_loc=0x80000141
617         touch $DIR/$tdir/$tfile || true
618 }
619 run_test 17h "create objects: lov_free_memmd() doesn't lbug"
620
621 test_17i() { #bug 20018
622         [ $PARALLEL == "yes" ] && skip "skip parallel run"
623         remote_mds_nodsh && skip "remote MDS with nodsh"
624
625         local foo=$DIR/$tdir/$tfile
626         local mdt_idx
627
628         test_mkdir -c1 $DIR/$tdir
629         mdt_idx=$($LFS getdirstripe -i $DIR/$tdir)
630         ln -s $foo $foo || error "create symlink failed"
631 #define OBD_FAIL_MDS_READLINK_EPROTO     0x143
632         do_facet mds$((mdt_idx + 1)) lctl set_param fail_loc=0x80000143
633         ls -l $foo && error "error not detected"
634         return 0
635 }
636 run_test 17i "don't panic on short symlink (should return error)"
637
638 test_17k() { #bug 22301
639         [ $PARALLEL == "yes" ] && skip "skip parallel run"
640         [[ -z "$(which rsync 2>/dev/null)" ]] &&
641                 skip "no rsync command"
642         rsync --help | grep -q xattr ||
643                 skip_env "$(rsync --version | head -n1) does not support xattrs"
644         test_mkdir $DIR/$tdir
645         test_mkdir $DIR/$tdir.new
646         touch $DIR/$tdir/$tfile
647         ln -s $DIR/$tdir/$tfile $DIR/$tdir/$tfile.lnk
648         rsync -av -X $DIR/$tdir/ $DIR/$tdir.new ||
649                 error "rsync failed with xattrs enabled"
650 }
651 run_test 17k "symlinks: rsync with xattrs enabled"
652
653 test_17l() { # LU-279
654         [[ -z "$(which getfattr 2>/dev/null)" ]] &&
655                 skip "no getfattr command"
656
657         test_mkdir $DIR/$tdir
658         touch $DIR/$tdir/$tfile
659         ln -s $DIR/$tdir/$tfile $DIR/$tdir/$tfile.lnk
660         for path in "$DIR/$tdir" "$DIR/$tdir/$tfile" "$DIR/$tdir/$tfile.lnk"; do
661                 # -h to not follow symlinks. -m '' to list all the xattrs.
662                 # grep to remove first line: '# file: $path'.
663                 for xattr in `getfattr -hm '' $path 2>/dev/null | grep -v '^#'`;
664                 do
665                         lgetxattr_size_check $path $xattr ||
666                                 error "lgetxattr_size_check $path $xattr failed"
667                 done
668         done
669 }
670 run_test 17l "Ensure lgetxattr's returned xattr size is consistent"
671
672 # LU-1540
673 test_17m() {
674         [ $PARALLEL == "yes" ] && skip "skip parallel run"
675         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
676         remote_mds_nodsh && skip "remote MDS with nodsh"
677         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
678         [ $MDS1_VERSION -le $(version_code 2.2.93) ] &&
679                 skip "MDS 2.2.0-2.2.93 do not NUL-terminate symlinks"
680
681         local short_sym="0123456789"
682         local wdir=$DIR/$tdir
683         local i
684
685         test_mkdir $wdir
686         long_sym=$short_sym
687         # create a long symlink file
688         for ((i = 0; i < 4; ++i)); do
689                 long_sym=${long_sym}${long_sym}
690         done
691
692         echo "create 512 short and long symlink files under $wdir"
693         for ((i = 0; i < 256; ++i)); do
694                 ln -sf ${long_sym}"a5a5" $wdir/long-$i
695                 ln -sf ${short_sym}"a5a5" $wdir/short-$i
696         done
697
698         echo "erase them"
699         rm -f $wdir/*
700         sync
701         wait_delete_completed
702
703         echo "recreate the 512 symlink files with a shorter string"
704         for ((i = 0; i < 512; ++i)); do
705                 # rewrite the symlink file with a shorter string
706                 ln -sf ${long_sym} $wdir/long-$i || error "long_sym failed"
707                 ln -sf ${short_sym} $wdir/short-$i || error "short_sym failed"
708         done
709
710         local mds_index=$(($($LFS getstripe -m $wdir) + 1))
711
712         echo "stop and checking mds${mds_index}:"
713         # e2fsck should not return error
714         stop mds${mds_index}
715         local devname=$(mdsdevname $mds_index)
716         run_e2fsck $(facet_active_host mds${mds_index}) $devname -n
717         rc=$?
718
719         start mds${mds_index} $devname $MDS_MOUNT_OPTS ||
720                 error "start mds${mds_index} failed"
721         df $MOUNT > /dev/null 2>&1
722         [ $rc -eq 0 ] ||
723                 error "e2fsck detected error for short/long symlink: rc=$rc"
724         rm -f $wdir/*
725 }
726 run_test 17m "run e2fsck against MDT which contains short/long symlink"
727
728 check_fs_consistency_17n() {
729         local mdt_index
730         local rc=0
731
732         # create/unlink in 17n only change 2 MDTs(MDT1/MDT2),
733         # so it only check MDT1/MDT2 instead of all of MDTs.
734         for mdt_index in 1 2; do
735                 # e2fsck should not return error
736                 stop mds${mdt_index}
737                 local devname=$(mdsdevname $mdt_index)
738                 run_e2fsck $(facet_active_host mds$mdt_index) $devname -n ||
739                         rc=$((rc + $?))
740
741                 start mds${mdt_index} $devname $MDS_MOUNT_OPTS ||
742                         error "mount mds$mdt_index failed"
743                 df $MOUNT > /dev/null 2>&1
744         done
745         return $rc
746 }
747
748 test_17n() {
749         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
750         [ $PARALLEL == "yes" ] && skip "skip parallel run"
751         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
752         remote_mds_nodsh && skip "remote MDS with nodsh"
753         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
754         [ $MDS1_VERSION -le $(version_code 2.2.93) ] &&
755                 skip "MDS 2.2.0-2.2.93 do not NUL-terminate symlinks"
756
757         local i
758
759         test_mkdir $DIR/$tdir
760         for ((i=0; i<10; i++)); do
761                 $LFS mkdir -i1 -c2 $DIR/$tdir/remote_dir_${i} ||
762                         error "create remote dir error $i"
763                 createmany -o $DIR/$tdir/remote_dir_${i}/f 10 ||
764                         error "create files under remote dir failed $i"
765         done
766
767         check_fs_consistency_17n ||
768                 error "e2fsck report error after create files under remote dir"
769
770         for ((i = 0; i < 10; i++)); do
771                 rm -rf $DIR/$tdir/remote_dir_${i} ||
772                         error "destroy remote dir error $i"
773         done
774
775         check_fs_consistency_17n ||
776                 error "e2fsck report error after unlink files under remote dir"
777
778         [ $MDS1_VERSION -lt $(version_code 2.4.50) ] &&
779                 skip "lustre < 2.4.50 does not support migrate mv"
780
781         for ((i = 0; i < 10; i++)); do
782                 mkdir -p $DIR/$tdir/remote_dir_${i}
783                 createmany -o $DIR/$tdir/remote_dir_${i}/f 10 ||
784                         error "create files under remote dir failed $i"
785                 $LFS migrate --mdt-index 1 $DIR/$tdir/remote_dir_${i} ||
786                         error "migrate remote dir error $i"
787         done
788         check_fs_consistency_17n || error "e2fsck report error after migration"
789
790         for ((i = 0; i < 10; i++)); do
791                 rm -rf $DIR/$tdir/remote_dir_${i} ||
792                         error "destroy remote dir error $i"
793         done
794
795         check_fs_consistency_17n || error "e2fsck report error after unlink"
796 }
797 run_test 17n "run e2fsck against master/slave MDT which contains remote dir"
798
799 test_17o() {
800         remote_mds_nodsh && skip "remote MDS with nodsh"
801         [ $MDS1_VERSION -lt $(version_code 2.3.64) ] &&
802                 skip "Need MDS version at least 2.3.64"
803
804         local wdir=$DIR/${tdir}o
805         local mdt_index
806         local rc=0
807
808         test_mkdir $wdir
809         touch $wdir/$tfile
810         mdt_index=$($LFS getstripe -m $wdir/$tfile)
811         mdt_index=$((mdt_index + 1))
812
813         cancel_lru_locks mdc
814         #fail mds will wait the failover finish then set
815         #following fail_loc to avoid interfer the recovery process.
816         fail mds${mdt_index}
817
818         #define OBD_FAIL_OSD_LMA_INCOMPAT 0x194
819         do_facet mds${mdt_index} lctl set_param fail_loc=0x194
820         ls -l $wdir/$tfile && rc=1
821         do_facet mds${mdt_index} lctl set_param fail_loc=0
822         [[ $rc -eq 0 ]] || error "stat file should fail"
823 }
824 run_test 17o "stat file with incompat LMA feature"
825
826 test_18() {
827         touch $DIR/$tfile || error "Failed to touch $DIR/$tfile: $?"
828         ls $DIR || error "Failed to ls $DIR: $?"
829 }
830 run_test 18 "touch .../f ; ls ... =============================="
831
832 test_19a() {
833         touch $DIR/$tfile
834         ls -l $DIR
835         rm $DIR/$tfile
836         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
837 }
838 run_test 19a "touch .../f19 ; ls -l ... ; rm .../f19 ==========="
839
840 test_19b() {
841         ls -l $DIR/$tfile && error "ls -l $tfile failed"|| true
842 }
843 run_test 19b "ls -l .../f19 (should return error) =============="
844
845 test_19c() {
846         [ $RUNAS_ID -eq $UID ] &&
847                 skip_env "RUNAS_ID = UID = $UID -- skipping"
848
849         $RUNAS touch $DIR/$tfile && error "create non-root file failed" || true
850 }
851 run_test 19c "$RUNAS touch .../f19 (should return error) =="
852
853 test_19d() {
854         cat $DIR/f19 && error || true
855 }
856 run_test 19d "cat .../f19 (should return error) =============="
857
858 test_20() {
859         touch $DIR/$tfile
860         rm $DIR/$tfile
861         touch $DIR/$tfile
862         rm $DIR/$tfile
863         touch $DIR/$tfile
864         rm $DIR/$tfile
865         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
866 }
867 run_test 20 "touch .../f ; ls -l ..."
868
869 test_21() {
870         test_mkdir $DIR/$tdir
871         [ -f $DIR/$tdir/dangle ] && rm -f $DIR/$tdir/dangle
872         ln -s dangle $DIR/$tdir/link
873         echo foo >> $DIR/$tdir/link
874         cat $DIR/$tdir/dangle
875         $CHECKSTAT -t link $DIR/$tdir/link || error "$tdir/link not a link"
876         $CHECKSTAT -f -t file $DIR/$tdir/link ||
877                 error "$tdir/link not linked to a file"
878 }
879 run_test 21 "write to dangling link"
880
881 test_22() {
882         local wdir=$DIR/$tdir
883         test_mkdir $wdir
884         chown $RUNAS_ID:$RUNAS_GID $wdir
885         (cd $wdir || error "cd $wdir failed";
886                 $RUNAS tar cf - /etc/hosts /etc/sysconfig/network |
887                 $RUNAS tar xf -)
888         ls -lR $wdir/etc || error "ls -lR $wdir/etc failed"
889         $CHECKSTAT -t dir $wdir/etc || error "checkstat -t dir failed"
890         $CHECKSTAT -u \#$RUNAS_ID -g \#$RUNAS_GID $wdir/etc ||
891                 error "checkstat -u failed"
892 }
893 run_test 22 "unpack tar archive as non-root user"
894
895 # was test_23
896 test_23a() {
897         test_mkdir $DIR/$tdir
898         local file=$DIR/$tdir/$tfile
899
900         openfile -f O_CREAT:O_EXCL $file || error "$file create failed"
901         openfile -f O_CREAT:O_EXCL $file &&
902                 error "$file recreate succeeded" || true
903 }
904 run_test 23a "O_CREAT|O_EXCL in subdir"
905
906 test_23b() { # bug 18988
907         test_mkdir $DIR/$tdir
908         local file=$DIR/$tdir/$tfile
909
910         rm -f $file
911         echo foo > $file || error "write filed"
912         echo bar >> $file || error "append filed"
913         $CHECKSTAT -s 8 $file || error "wrong size"
914         rm $file
915 }
916 run_test 23b "O_APPEND check"
917
918 # LU-9409, size with O_APPEND and tiny writes
919 test_23c() {
920         local file=$DIR/$tfile
921
922         # single dd
923         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800
924         $CHECKSTAT -s 6400 $file || error "wrong size, expected 6400"
925         rm -f $file
926
927         # racing tiny writes
928         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800 &
929         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800 &
930         wait
931         $CHECKSTAT -s 12800 $file || error "wrong size, expected 12800"
932         rm -f $file
933
934         #racing tiny & normal writes
935         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=4096 count=4 &
936         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=100 &
937         wait
938         $CHECKSTAT -s 17184 $file || error "wrong size, expected 17184"
939         rm -f $file
940
941         #racing tiny & normal writes 2, ugly numbers
942         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=4099 count=11 &
943         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=17 count=173 &
944         wait
945         $CHECKSTAT -s 48030 $file || error "wrong size, expected 48030"
946         rm -f $file
947 }
948 run_test 23c "O_APPEND size checks for tiny writes"
949
950 # LU-11069 file offset is correct after appending writes
951 test_23d() {
952         local file=$DIR/$tfile
953         local offset
954
955         echo CentaurHauls > $file
956         offset=$($MULTIOP $file oO_WRONLY:O_APPEND:w13Zp)
957         if ((offset != 26)); then
958                 error "wrong offset, expected 26, got '$offset'"
959         fi
960 }
961 run_test 23d "file offset is correct after appending writes"
962
963 # rename sanity
964 test_24a() {
965         echo '-- same directory rename'
966         test_mkdir $DIR/$tdir
967         touch $DIR/$tdir/$tfile.1
968         mv $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
969         $CHECKSTAT -t file $DIR/$tdir/$tfile.2 || error "$tfile.2 not a file"
970 }
971 run_test 24a "rename file to non-existent target"
972
973 test_24b() {
974         test_mkdir $DIR/$tdir
975         touch $DIR/$tdir/$tfile.{1,2}
976         mv $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
977         $CHECKSTAT -a $DIR/$tdir/$tfile.1 || error "$tfile.1 exists"
978         $CHECKSTAT -t file $DIR/$tdir/$tfile.2 || error "$tfile.2 not a file"
979 }
980 run_test 24b "rename file to existing target"
981
982 test_24c() {
983         test_mkdir $DIR/$tdir
984         test_mkdir $DIR/$tdir/d$testnum.1
985         mv $DIR/$tdir/d$testnum.1 $DIR/$tdir/d$testnum.2
986         $CHECKSTAT -a $DIR/$tdir/d$testnum.1 || error "d$testnum.1 exists"
987         $CHECKSTAT -t dir $DIR/$tdir/d$testnum.2 || error "d$testnum.2 not dir"
988 }
989 run_test 24c "rename directory to non-existent target"
990
991 test_24d() {
992         test_mkdir -c1 $DIR/$tdir
993         test_mkdir -c1 $DIR/$tdir/d$testnum.1
994         test_mkdir -c1 $DIR/$tdir/d$testnum.2
995         mrename $DIR/$tdir/d$testnum.1 $DIR/$tdir/d$testnum.2
996         $CHECKSTAT -a $DIR/$tdir/d$testnum.1 || error "d$testnum.1 exists"
997         $CHECKSTAT -t dir $DIR/$tdir/d$testnum.2 || error "d$testnum.2 not dir"
998 }
999 run_test 24d "rename directory to existing target"
1000
1001 test_24e() {
1002         echo '-- cross directory renames --'
1003         test_mkdir $DIR/R5a
1004         test_mkdir $DIR/R5b
1005         touch $DIR/R5a/f
1006         mv $DIR/R5a/f $DIR/R5b/g
1007         $CHECKSTAT -a $DIR/R5a/f || error "$DIR/R5a/f exists"
1008         $CHECKSTAT -t file $DIR/R5b/g || error "$DIR/R5b/g not file type"
1009 }
1010 run_test 24e "touch .../R5a/f; rename .../R5a/f .../R5b/g ======"
1011
1012 test_24f() {
1013         test_mkdir $DIR/R6a
1014         test_mkdir $DIR/R6b
1015         touch $DIR/R6a/f $DIR/R6b/g
1016         mv $DIR/R6a/f $DIR/R6b/g
1017         $CHECKSTAT -a $DIR/R6a/f || error "$DIR/R6a/f exists"
1018         $CHECKSTAT -t file $DIR/R6b/g || error "$DIR/R6b/g not file type"
1019 }
1020 run_test 24f "touch .../R6a/f R6b/g; mv .../R6a/f .../R6b/g ===="
1021
1022 test_24g() {
1023         test_mkdir $DIR/R7a
1024         test_mkdir $DIR/R7b
1025         test_mkdir $DIR/R7a/d
1026         mv $DIR/R7a/d $DIR/R7b/e
1027         $CHECKSTAT -a $DIR/R7a/d || error "$DIR/R7a/d exists"
1028         $CHECKSTAT -t dir $DIR/R7b/e || error "$DIR/R7b/e not dir type"
1029 }
1030 run_test 24g "mkdir .../R7{a,b}/d; mv .../R7a/d .../R7b/e ======"
1031
1032 test_24h() {
1033         test_mkdir -c1 $DIR/R8a
1034         test_mkdir -c1 $DIR/R8b
1035         test_mkdir -c1 $DIR/R8a/d
1036         test_mkdir -c1 $DIR/R8b/e
1037         mrename $DIR/R8a/d $DIR/R8b/e
1038         $CHECKSTAT -a $DIR/R8a/d || error "$DIR/R8a/d exists"
1039         $CHECKSTAT -t dir $DIR/R8b/e || error "$DIR/R8b/e not dir type"
1040 }
1041 run_test 24h "mkdir .../R8{a,b}/{d,e}; rename .../R8a/d .../R8b/e"
1042
1043 test_24i() {
1044         echo "-- rename error cases"
1045         test_mkdir $DIR/R9
1046         test_mkdir $DIR/R9/a
1047         touch $DIR/R9/f
1048         mrename $DIR/R9/f $DIR/R9/a
1049         $CHECKSTAT -t file $DIR/R9/f || error "$DIR/R9/f not file type"
1050         $CHECKSTAT -t dir  $DIR/R9/a || error "$DIR/R9/a not dir type"
1051         $CHECKSTAT -a $DIR/R9/a/f || error "$DIR/R9/a/f exists"
1052 }
1053 run_test 24i "rename file to dir error: touch f ; mkdir a ; rename f a"
1054
1055 test_24j() {
1056         test_mkdir $DIR/R10
1057         mrename $DIR/R10/f $DIR/R10/g
1058         $CHECKSTAT -t dir $DIR/R10 || error "$DIR/R10 not dir type"
1059         $CHECKSTAT -a $DIR/R10/f || error "$DIR/R10/f exists"
1060         $CHECKSTAT -a $DIR/R10/g || error "$DIR/R10/g exists"
1061 }
1062 run_test 24j "source does not exist ============================"
1063
1064 test_24k() {
1065         test_mkdir $DIR/R11a
1066         test_mkdir $DIR/R11a/d
1067         touch $DIR/R11a/f
1068         mv $DIR/R11a/f $DIR/R11a/d
1069         $CHECKSTAT -a $DIR/R11a/f || error "$DIR/R11a/f exists"
1070         $CHECKSTAT -t file $DIR/R11a/d/f || error "$DIR/R11a/d/f not file type"
1071 }
1072 run_test 24k "touch .../R11a/f; mv .../R11a/f .../R11a/d ======="
1073
1074 # bug 2429 - rename foo foo foo creates invalid file
1075 test_24l() {
1076         f="$DIR/f24l"
1077         $MULTIOP $f OcNs || error "rename of ${f} to itself failed"
1078 }
1079 run_test 24l "Renaming a file to itself ========================"
1080
1081 test_24m() {
1082         f="$DIR/f24m"
1083         $MULTIOP $f OcLN ${f}2 ${f}2 || error "link ${f}2 ${f}2 failed"
1084         # on ext3 this does not remove either the source or target files
1085         # though the "expected" operation would be to remove the source
1086         $CHECKSTAT -t file ${f} || error "${f} missing"
1087         $CHECKSTAT -t file ${f}2 || error "${f}2 missing"
1088 }
1089 run_test 24m "Renaming a file to a hard link to itself ========="
1090
1091 test_24n() {
1092     f="$DIR/f24n"
1093     # this stats the old file after it was renamed, so it should fail
1094     touch ${f}
1095     $CHECKSTAT ${f} || error "${f} missing"
1096     mv ${f} ${f}.rename
1097     $CHECKSTAT ${f}.rename || error "${f}.rename missing"
1098     $CHECKSTAT -a ${f} || error "${f} exists"
1099 }
1100 run_test 24n "Statting the old file after renaming (Posix rename 2)"
1101
1102 test_24o() {
1103         test_mkdir $DIR/$tdir
1104         rename_many -s random -v -n 10 $DIR/$tdir
1105 }
1106 run_test 24o "rename of files during htree split"
1107
1108 test_24p() {
1109         test_mkdir $DIR/R12a
1110         test_mkdir $DIR/R12b
1111         DIRINO=`ls -lid $DIR/R12a | awk '{ print $1 }'`
1112         mrename $DIR/R12a $DIR/R12b
1113         $CHECKSTAT -a $DIR/R12a || error "$DIR/R12a exists"
1114         $CHECKSTAT -t dir $DIR/R12b || error "$DIR/R12b not dir type"
1115         DIRINO2=`ls -lid $DIR/R12b | awk '{ print $1 }'`
1116         [ "$DIRINO" = "$DIRINO2" ] || error "R12a $DIRINO != R12b $DIRINO2"
1117 }
1118 run_test 24p "mkdir .../R12{a,b}; rename .../R12a .../R12b"
1119
1120 cleanup_multiop_pause() {
1121         trap 0
1122         kill -USR1 $MULTIPID
1123 }
1124
1125 test_24q() {
1126         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1127
1128         test_mkdir $DIR/R13a
1129         test_mkdir $DIR/R13b
1130         local DIRINO=$(ls -lid $DIR/R13a | awk '{ print $1 }')
1131         multiop_bg_pause $DIR/R13b D_c || error "multiop failed to start"
1132         MULTIPID=$!
1133
1134         trap cleanup_multiop_pause EXIT
1135         mrename $DIR/R13a $DIR/R13b
1136         $CHECKSTAT -a $DIR/R13a || error "R13a still exists"
1137         $CHECKSTAT -t dir $DIR/R13b || error "R13b does not exist"
1138         local DIRINO2=$(ls -lid $DIR/R13b | awk '{ print $1 }')
1139         [ "$DIRINO" = "$DIRINO2" ] || error "R13a $DIRINO != R13b $DIRINO2"
1140         cleanup_multiop_pause
1141         wait $MULTIPID || error "multiop close failed"
1142 }
1143 run_test 24q "mkdir .../R13{a,b}; open R13b rename R13a R13b ==="
1144
1145 test_24r() { #bug 3789
1146         test_mkdir $DIR/R14a
1147         test_mkdir $DIR/R14a/b
1148         mrename $DIR/R14a $DIR/R14a/b && error "rename to subdir worked!"
1149         $CHECKSTAT -t dir $DIR/R14a || error "$DIR/R14a missing"
1150         $CHECKSTAT -t dir $DIR/R14a/b || error "$DIR/R14a/b missing"
1151 }
1152 run_test 24r "mkdir .../R14a/b; rename .../R14a .../R14a/b ====="
1153
1154 test_24s() {
1155         test_mkdir $DIR/R15a
1156         test_mkdir $DIR/R15a/b
1157         test_mkdir $DIR/R15a/b/c
1158         mrename $DIR/R15a $DIR/R15a/b/c && error "rename to sub-subdir worked!"
1159         $CHECKSTAT -t dir $DIR/R15a || error "$DIR/R15a missing"
1160         $CHECKSTAT -t dir $DIR/R15a/b/c || error "$DIR/R15a/b/c missing"
1161 }
1162 run_test 24s "mkdir .../R15a/b/c; rename .../R15a .../R15a/b/c ="
1163
1164 test_24t() {
1165         test_mkdir $DIR/R16a
1166         test_mkdir $DIR/R16a/b
1167         test_mkdir $DIR/R16a/b/c
1168         mrename $DIR/R16a/b/c $DIR/R16a && error "rename to sub-subdir worked!"
1169         $CHECKSTAT -t dir $DIR/R16a || error "$DIR/R16a missing"
1170         $CHECKSTAT -t dir $DIR/R16a/b/c || error "$DIR/R16a/b/c missing"
1171 }
1172 run_test 24t "mkdir .../R16a/b/c; rename .../R16a/b/c .../R16a ="
1173
1174 test_24u() { # bug12192
1175         $MULTIOP $DIR/$tfile C2w$((2048 * 1024))c || error "multiop failed"
1176         $CHECKSTAT -s $((2048 * 1024)) $DIR/$tfile || error "wrong file size"
1177 }
1178 run_test 24u "create stripe file"
1179
1180 simple_cleanup_common() {
1181         local createmany=$1
1182         local rc=0
1183
1184         [[ -z "$DIR" || -z "$tdir" || ! -d "$DIR/$tdir" ]] && return 0
1185
1186         local start=$SECONDS
1187
1188         [[ -n "$createmany" ]] && unlinkmany $DIR/$tdir/$tfile $createmany
1189         rm -rf $DIR/$tdir || error "cleanup $DIR/$tdir failed"
1190         rc=$?
1191         wait_delete_completed
1192         echo "cleanup time $((SECONDS - start))"
1193         return $rc
1194 }
1195
1196 max_pages_per_rpc() {
1197         local mdtname="$(printf "MDT%04x" ${1:-0})"
1198         $LCTL get_param -n mdc.*$mdtname*.max_pages_per_rpc
1199 }
1200
1201 test_24v() {
1202         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1203
1204         local nrfiles=${COUNT:-100000}
1205         local fname="$DIR/$tdir/$tfile"
1206
1207         # Performance issue on ZFS see LU-4072 (c.f. LU-2887)
1208         [ "$mds1_FSTYPE" = "zfs" ] && nrfiles=${COUNT:-10000}
1209
1210         test_mkdir "$(dirname $fname)"
1211         # assume MDT0000 has the fewest inodes
1212         local stripes=$($LFS getdirstripe -c $(dirname $fname))
1213         local free_inodes=$(($(mdt_free_inodes 0) * ${stripes/#0/1}))
1214         [[ $free_inodes -lt $nrfiles ]] && nrfiles=$free_inodes
1215
1216         stack_trap "simple_cleanup_common $nrfiles"
1217
1218         createmany -m "$fname" $nrfiles
1219
1220         cancel_lru_locks mdc
1221         lctl set_param mdc.*.stats clear
1222
1223         # was previously test_24D: LU-6101
1224         # readdir() returns correct number of entries after cursor reload
1225         local num_ls=$(ls $DIR/$tdir | wc -l)
1226         local num_uniq=$(ls $DIR/$tdir | sort -u | wc -l)
1227         local num_all=$(ls -a $DIR/$tdir | wc -l)
1228         if [ $num_ls -ne $nrfiles ] || [ $num_uniq -ne $nrfiles ] ||
1229                 [ $num_all -ne $((nrfiles + 2)) ]; then
1230                         error "Expected $nrfiles files, got $num_ls " \
1231                                 "($num_uniq unique $num_all .&..)"
1232         fi
1233         # LU-5 large readdir
1234         # dirent_size = 32 bytes for sizeof(struct lu_dirent) +
1235         #               N bytes for name (len($nrfiles) rounded to 8 bytes) +
1236         #               8 bytes for luda_type (4 bytes rounded to 8 bytes)
1237         # take into account of overhead in lu_dirpage header and end mark in
1238         # each page, plus one in rpc_num calculation.
1239         local dirent_size=$((32 + (${#tfile} | 7) + 1 + 8))
1240         local page_entries=$(((PAGE_SIZE - 24) / dirent_size))
1241         local mdt_idx=$($LFS getdirstripe -i $(dirname $fname))
1242         local rpc_pages=$(max_pages_per_rpc $mdt_idx)
1243         local rpc_max=$((nrfiles / (page_entries * rpc_pages) + stripes))
1244         local mds_readpage=$(calc_stats mdc.*.stats mds_readpage)
1245         echo "readpages: $mds_readpage rpc_max: $rpc_max-2/+1"
1246         (( $mds_readpage >= $rpc_max - 2 && $mds_readpage <= $rpc_max + 1)) ||
1247                 error "large readdir doesn't take effect: " \
1248                       "$mds_readpage should be about $rpc_max"
1249 }
1250 run_test 24v "list large directory (test hash collision, b=17560)"
1251
1252 test_24w() { # bug21506
1253         SZ1=234852
1254         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=4096 || return 1
1255         dd if=/dev/zero bs=$SZ1 count=1 >> $DIR/$tfile || return 2
1256         dd if=$DIR/$tfile of=$DIR/${tfile}_left bs=1M skip=4097 || return 3
1257         SZ2=`ls -l $DIR/${tfile}_left | awk '{print $5}'`
1258         [[ "$SZ1" -eq "$SZ2" ]] ||
1259                 error "Error reading at the end of the file $tfile"
1260 }
1261 run_test 24w "Reading a file larger than 4Gb"
1262
1263 test_24x() {
1264         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1265         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1266         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1267                 skip "Need MDS version at least 2.7.56"
1268
1269         local MDTIDX=1
1270         local remote_dir=$DIR/$tdir/remote_dir
1271
1272         test_mkdir $DIR/$tdir
1273         $LFS mkdir -i $MDTIDX $remote_dir ||
1274                 error "create remote directory failed"
1275
1276         test_mkdir $DIR/$tdir/src_dir
1277         touch $DIR/$tdir/src_file
1278         test_mkdir $remote_dir/tgt_dir
1279         touch $remote_dir/tgt_file
1280
1281         mrename $DIR/$tdir/src_dir $remote_dir/tgt_dir ||
1282                 error "rename dir cross MDT failed!"
1283
1284         mrename $DIR/$tdir/src_file $remote_dir/tgt_file ||
1285                 error "rename file cross MDT failed!"
1286
1287         touch $DIR/$tdir/ln_file
1288         ln $DIR/$tdir/ln_file $remote_dir/ln_name ||
1289                 error "ln file cross MDT failed"
1290
1291         rm -rf $DIR/$tdir || error "Can not delete directories"
1292 }
1293 run_test 24x "cross MDT rename/link"
1294
1295 test_24y() {
1296         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1297         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1298
1299         local remote_dir=$DIR/$tdir/remote_dir
1300         local mdtidx=1
1301
1302         test_mkdir $DIR/$tdir
1303         $LFS mkdir -i $mdtidx $remote_dir ||
1304                 error "create remote directory failed"
1305
1306         test_mkdir $remote_dir/src_dir
1307         touch $remote_dir/src_file
1308         test_mkdir $remote_dir/tgt_dir
1309         touch $remote_dir/tgt_file
1310
1311         mrename $remote_dir/src_dir $remote_dir/tgt_dir ||
1312                 error "rename subdir in the same remote dir failed!"
1313
1314         mrename $remote_dir/src_file $remote_dir/tgt_file ||
1315                 error "rename files in the same remote dir failed!"
1316
1317         ln $remote_dir/tgt_file $remote_dir/tgt_file1 ||
1318                 error "link files in the same remote dir failed!"
1319
1320         rm -rf $DIR/$tdir || error "Can not delete directories"
1321 }
1322 run_test 24y "rename/link on the same dir should succeed"
1323
1324 test_24z() {
1325         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1326         [[ $MDS1_VERSION -lt $(version_code 2.12.51) ]] &&
1327                 skip "Need MDS version at least 2.12.51"
1328
1329         local index
1330
1331         for index in 0 1; do
1332                 $LFS mkdir -i $index $DIR/$tdir.$index || error "mkdir failed"
1333                 touch $DIR/$tdir.0/$tfile.$index || error "touch failed"
1334         done
1335
1336         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1 || error "mv $tfile.0 failed"
1337
1338         index=$($LFS getstripe -m $DIR/$tdir.1/$tfile.0)
1339         [ $index -eq 0 ] || error "$tfile.0 is on MDT$index"
1340
1341         local mdts=$(comma_list $(mdts_nodes))
1342
1343         do_nodes $mdts $LCTL set_param mdt.*.enable_remote_rename=0
1344         stack_trap "do_nodes $mdts $LCTL \
1345                 set_param mdt.*.enable_remote_rename=1" EXIT
1346
1347         mv $DIR/$tdir.0/$tfile.1 $DIR/$tdir.1 || error "mv $tfile.1 failed"
1348
1349         index=$($LFS getstripe -m $DIR/$tdir.1/$tfile.1)
1350         [ $index -eq 1 ] || error "$tfile.1 is on MDT$index"
1351 }
1352 run_test 24z "cross-MDT rename is done as cp"
1353
1354 test_24A() { # LU-3182
1355         local NFILES=5000
1356
1357         test_mkdir $DIR/$tdir
1358         stack_trap "simple_cleanup_common $NFILES"
1359         createmany -m $DIR/$tdir/$tfile $NFILES
1360         local t=$(ls $DIR/$tdir | wc -l)
1361         local u=$(ls $DIR/$tdir | sort -u | wc -l)
1362         local v=$(ls -ai $DIR/$tdir | sort -u | wc -l)
1363
1364         (( $t == $NFILES && $u == $NFILES && $v == NFILES + 2 )) ||
1365                 error "Expected $NFILES files, got $t ($u unique $v .&..)"
1366 }
1367 run_test 24A "readdir() returns correct number of entries."
1368
1369 test_24B() { # LU-4805
1370         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1371
1372         local count
1373
1374         test_mkdir $DIR/$tdir
1375         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir/ ||
1376                 error "create striped dir failed"
1377
1378         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1379         [ $count -eq 2 ] || error "Expected 2, got $count"
1380
1381         touch $DIR/$tdir/striped_dir/a
1382
1383         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1384         [ $count -eq 3 ] || error "Expected 3, got $count"
1385
1386         touch $DIR/$tdir/striped_dir/.f
1387
1388         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1389         [ $count -eq 4 ] || error "Expected 4, got $count"
1390
1391         rm -rf $DIR/$tdir || error "Can not delete directories"
1392 }
1393 run_test 24B "readdir for striped dir return correct number of entries"
1394
1395 test_24C() {
1396         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1397
1398         mkdir $DIR/$tdir
1399         mkdir $DIR/$tdir/d0
1400         mkdir $DIR/$tdir/d1
1401
1402         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/d0/striped_dir ||
1403                 error "create striped dir failed"
1404
1405         cd $DIR/$tdir/d0/striped_dir
1406
1407         local d0_ino=$(ls -i -l -a $DIR/$tdir | grep "d0" | awk '{print $1}')
1408         local d1_ino=$(ls -i -l -a $DIR/$tdir | grep "d1" | awk '{print $1}')
1409         local parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1410
1411         [ "$d0_ino" = "$parent_ino" ] ||
1412                 error ".. wrong, expect $d0_ino, get $parent_ino"
1413
1414         mv $DIR/$tdir/d0/striped_dir $DIR/$tdir/d1/ ||
1415                 error "mv striped dir failed"
1416
1417         parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1418
1419         [ "$d1_ino" = "$parent_ino" ] ||
1420                 error ".. wrong after mv, expect $d1_ino, get $parent_ino"
1421 }
1422 run_test 24C "check .. in striped dir"
1423
1424 test_24E() {
1425         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
1426         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1427
1428         mkdir -p $DIR/$tdir
1429         mkdir $DIR/$tdir/src_dir
1430         $LFS mkdir -i 1 $DIR/$tdir/src_dir/src_child ||
1431                 error "create remote source failed"
1432
1433         touch $DIR/$tdir/src_dir/src_child/a
1434
1435         $LFS mkdir -i 2 $DIR/$tdir/tgt_dir ||
1436                 error "create remote target dir failed"
1437
1438         $LFS mkdir -i 3 $DIR/$tdir/tgt_dir/tgt_child ||
1439                 error "create remote target child failed"
1440
1441         mrename $DIR/$tdir/src_dir/src_child $DIR/$tdir/tgt_dir/tgt_child ||
1442                 error "rename dir cross MDT failed!"
1443
1444         find $DIR/$tdir
1445
1446         $CHECKSTAT -t dir $DIR/$tdir/src_dir/src_child &&
1447                 error "src_child still exists after rename"
1448
1449         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/tgt_child/a ||
1450                 error "missing file(a) after rename"
1451
1452         rm -rf $DIR/$tdir || error "Can not delete directories"
1453 }
1454 run_test 24E "cross MDT rename/link"
1455
1456 test_24F () {
1457         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
1458
1459         local repeats=1000
1460         [ "$SLOW" = "no" ] && repeats=100
1461
1462         mkdir -p $DIR/$tdir
1463
1464         echo "$repeats repeats"
1465         for ((i = 0; i < repeats; i++)); do
1466                 $LFS mkdir -i0 -c2 $DIR/$tdir/test || error "mkdir fails"
1467                 touch $DIR/$tdir/test/a || error "touch fails"
1468                 mkdir $DIR/$tdir/test/b || error "mkdir fails"
1469                 rm -rf $DIR/$tdir/test || error "rmdir fails"
1470         done
1471
1472         true
1473 }
1474 run_test 24F "hash order vs readdir (LU-11330)"
1475
1476 test_24G () {
1477         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
1478
1479         local ino1
1480         local ino2
1481
1482         $LFS mkdir -i 0 $DIR/$tdir-0 || error "mkdir $tdir-0"
1483         $LFS mkdir -i 1 $DIR/$tdir-1 || error "mkdir $tdir-1"
1484         touch $DIR/$tdir-0/f1 || error "touch f1"
1485         ln -s $DIR/$tdir-0/f1 $DIR/$tdir-0/s1 || error "ln s1"
1486         ino1=$(stat -c%i $DIR/$tdir-0/s1)
1487         mv $DIR/$tdir-0/s1 $DIR/$tdir-1 || error "mv s1"
1488         ino2=$(stat -c%i $DIR/$tdir-1/s1)
1489         [ $ino1 -ne $ino2 ] || error "s1 should be migrated"
1490 }
1491 run_test 24G "migrate symlink in rename"
1492
1493 test_24H() {
1494         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
1495         [[ $(hostname) != $(facet_active_host mds2) ]] ||
1496                 skip "MDT1 should be on another node"
1497
1498         test_mkdir -i 1 -c 1 $DIR/$tdir
1499 #define OBD_FAIL_FLD_QUERY_REQ           0x1103
1500         do_facet mds2 $LCTL set_param fail_loc=0x80001103
1501         touch $DIR/$tdir/$tfile || error "touch failed"
1502 }
1503 run_test 24H "repeat FLD_QUERY rpc"
1504
1505 test_25a() {
1506         echo '== symlink sanity ============================================='
1507
1508         test_mkdir $DIR/d25
1509         ln -s d25 $DIR/s25
1510         touch $DIR/s25/foo ||
1511                 error "File creation in symlinked directory failed"
1512 }
1513 run_test 25a "create file in symlinked directory ==============="
1514
1515 test_25b() {
1516         [ ! -d $DIR/d25 ] && test_25a
1517         $CHECKSTAT -t file $DIR/s25/foo || error "$DIR/s25/foo not file type"
1518 }
1519 run_test 25b "lookup file in symlinked directory ==============="
1520
1521 test_26a() {
1522         test_mkdir $DIR/d26
1523         test_mkdir $DIR/d26/d26-2
1524         ln -s d26/d26-2 $DIR/s26
1525         touch $DIR/s26/foo || error "File creation failed"
1526 }
1527 run_test 26a "multiple component symlink ======================="
1528
1529 test_26b() {
1530         test_mkdir -p $DIR/$tdir/d26-2
1531         ln -s $tdir/d26-2/foo $DIR/s26-2
1532         touch $DIR/s26-2 || error "File creation failed"
1533 }
1534 run_test 26b "multiple component symlink at end of lookup ======"
1535
1536 test_26c() {
1537         test_mkdir $DIR/d26.2
1538         touch $DIR/d26.2/foo
1539         ln -s d26.2 $DIR/s26.2-1
1540         ln -s s26.2-1 $DIR/s26.2-2
1541         ln -s s26.2-2 $DIR/s26.2-3
1542         chmod 0666 $DIR/s26.2-3/foo
1543 }
1544 run_test 26c "chain of symlinks"
1545
1546 # recursive symlinks (bug 439)
1547 test_26d() {
1548         ln -s d26-3/foo $DIR/d26-3
1549 }
1550 run_test 26d "create multiple component recursive symlink"
1551
1552 test_26e() {
1553         [ ! -h $DIR/d26-3 ] && test_26d
1554         rm $DIR/d26-3
1555 }
1556 run_test 26e "unlink multiple component recursive symlink"
1557
1558 # recursive symlinks (bug 7022)
1559 test_26f() {
1560         test_mkdir $DIR/$tdir
1561         test_mkdir $DIR/$tdir/$tfile
1562         cd $DIR/$tdir/$tfile           || error "cd $DIR/$tdir/$tfile failed"
1563         test_mkdir -p lndir/bar1
1564         test_mkdir $DIR/$tdir/$tfile/$tfile
1565         cd $tfile                || error "cd $tfile failed"
1566         ln -s .. dotdot          || error "ln dotdot failed"
1567         ln -s dotdot/lndir lndir || error "ln lndir failed"
1568         cd $DIR/$tdir                 || error "cd $DIR/$tdir failed"
1569         output=`ls $tfile/$tfile/lndir/bar1`
1570         [ "$output" = bar1 ] && error "unexpected output"
1571         rm -r $tfile             || error "rm $tfile failed"
1572         $CHECKSTAT -a $DIR/$tfile || error "$tfile not gone"
1573 }
1574 run_test 26f "rm -r of a directory which has recursive symlink"
1575
1576 test_27a() {
1577         test_mkdir $DIR/$tdir
1578         $LFS getstripe $DIR/$tdir
1579         $LFS setstripe -c 1 $DIR/$tdir/$tfile || error "setstripe failed"
1580         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1581         cp /etc/hosts $DIR/$tdir/$tfile || error "Can't copy to one stripe file"
1582 }
1583 run_test 27a "one stripe file"
1584
1585 test_27b() {
1586         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1587
1588         test_mkdir $DIR/$tdir
1589         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1590         $LFS getstripe -c $DIR/$tdir/$tfile
1591         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
1592                 error "two-stripe file doesn't have two stripes"
1593
1594         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1595 }
1596 run_test 27b "create and write to two stripe file"
1597
1598 # 27c family tests specific striping, setstripe -o
1599 test_27ca() {
1600         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1601         test_mkdir -p $DIR/$tdir
1602         local osts="1"
1603
1604         $LFS setstripe -o $osts $DIR/$tdir/$tfile  || error "setstripe failed"
1605         $LFS getstripe -i $DIR/$tdir/$tfile
1606         [ $($LFS getstripe -i $DIR/$tdir/$tfile ) -eq $osts ] ||
1607                 error "stripe not on specified OST"
1608
1609         dd if=/dev/zero of=$DIR/$tdir/$tfile  bs=1M count=4 || error "dd failed"
1610 }
1611 run_test 27ca "one stripe on specified OST"
1612
1613 test_27cb() {
1614         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1615         test_mkdir -p $DIR/$tdir
1616         local osts="1,0"
1617         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1618         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1619         echo "$getstripe"
1620
1621         # Strip getstripe output to a space separated list of OSTs
1622         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1623                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1624         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1625                 error "stripes not on specified OSTs"
1626
1627         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1628 }
1629 run_test 27cb "two stripes on specified OSTs"
1630
1631 test_27cc() {
1632         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1633         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1634                 skip "server does not support overstriping"
1635
1636         test_mkdir -p $DIR/$tdir
1637         local osts="0,0"
1638         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1639         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1640         echo "$getstripe"
1641
1642         # Strip getstripe output to a space separated list of OSTs
1643         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1644                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1645         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1646                 error "stripes not on specified OSTs"
1647
1648         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1649 }
1650 run_test 27cc "two stripes on the same OST"
1651
1652 test_27cd() {
1653         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1654         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1655                 skip "server does not support overstriping"
1656         test_mkdir -p $DIR/$tdir
1657         local osts="0,1,1,0"
1658         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1659         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1660         echo "$getstripe"
1661
1662         # Strip getstripe output to a space separated list of OSTs
1663         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1664                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1665         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1666                 error "stripes not on specified OSTs"
1667
1668         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1669 }
1670 run_test 27cd "four stripes on two OSTs"
1671
1672 test_27ce() {
1673         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
1674                 skip_env "too many osts, skipping"
1675         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1676                 skip "server does not support overstriping"
1677         # We do one more stripe than we have OSTs
1678         [ $OSTCOUNT -lt 159 ] || large_xattr_enabled ||
1679                 skip_env "ea_inode feature disabled"
1680
1681         test_mkdir -p $DIR/$tdir
1682         local osts=""
1683         for i in $(seq 0 $OSTCOUNT);
1684         do
1685                 osts=$osts"0"
1686                 if [ $i -ne $OSTCOUNT ]; then
1687                         osts=$osts","
1688                 fi
1689         done
1690         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1691         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1692         echo "$getstripe"
1693
1694         # Strip getstripe output to a space separated list of OSTs
1695         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1696                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1697         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1698                 error "stripes not on specified OSTs"
1699
1700         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1701 }
1702 run_test 27ce "more stripes than OSTs with -o"
1703
1704 test_27cf() {
1705         local osp_proc="osp.$FSNAME-OST0000-osc-MDT000*.active"
1706         local pid=0
1707
1708         test_mkdir -p $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
1709         do_facet $SINGLEMDS "$LCTL set_param -n $osp_proc=0"
1710         stack_trap "do_facet $SINGLEMDS $LCTL set_param -n $osp_proc=1" EXIT
1711         wait_update_facet $SINGLEMDS "$LCTL get_param -n $osp_proc | grep 1" ||
1712                 error "failed to set $osp_proc=0"
1713
1714         $LFS setstripe -o 0 $DIR/$tdir/$tfile &
1715         pid=$!
1716         sleep 1
1717         do_facet $SINGLEMDS "$LCTL set_param -n $osp_proc=1"
1718         wait_update_facet $SINGLEMDS "$LCTL get_param -n $osp_proc | grep 0" ||
1719                 error "failed to set $osp_proc=1"
1720         wait $pid
1721         [[ $pid -ne 0 ]] ||
1722                 error "should return error due to $osp_proc=0"
1723 }
1724 run_test 27cf "'setstripe -o' on inactive OSTs should return error"
1725
1726 test_27cg() {
1727         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1728                 skip "server does not support overstriping"
1729         [[ $mds1_FSTYPE != "ldiskfs" ]] && skip_env "ldiskfs only test"
1730         large_xattr_enabled || skip_env "ea_inode feature disabled"
1731
1732         local osts="0"
1733
1734         for ((i=1;i<1000;i++)); do
1735                 osts+=",$((i % OSTCOUNT))"
1736         done
1737
1738         local mdts=$(comma_list $(mdts_nodes))
1739         local before=$(do_nodes $mdts \
1740                 "$LCTL get_param -n osd-ldiskfs.*MDT*.stats" |
1741                 awk '/many credits/{print $3}' |
1742                 calc_sum)
1743
1744         $LFS setstripe -o $osts $DIR/$tfile || error "setstripe failed"
1745         $LFS getstripe $DIR/$tfile | grep stripe
1746
1747         rm -f $DIR/$tfile || error "can't unlink"
1748
1749         after=$(do_nodes $mdts \
1750                 "$LCTL get_param -n osd-ldiskfs.*MDT*.stats" |
1751                 awk '/many credits/{print $3}' |
1752                 calc_sum)
1753
1754         (( before == after )) ||
1755                 error "too many credits happened: $after > $before"
1756 }
1757 run_test 27cg "1000 shouldn't cause too many credits"
1758
1759 test_27d() {
1760         test_mkdir $DIR/$tdir
1761         $LFS setstripe -c 0 -i -1 -S 0 $DIR/$tdir/$tfile ||
1762                 error "setstripe failed"
1763         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1764         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1765 }
1766 run_test 27d "create file with default settings"
1767
1768 test_27e() {
1769         # LU-5839 adds check for existed layout before setting it
1770         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1771                 skip "Need MDS version at least 2.7.56"
1772
1773         test_mkdir $DIR/$tdir
1774         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1775         $LFS setstripe -c 2 $DIR/$tdir/$tfile && error "setstripe worked twice"
1776         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1777 }
1778 run_test 27e "setstripe existing file (should return error)"
1779
1780 test_27f() {
1781         test_mkdir $DIR/$tdir
1782         $LFS setstripe -S 100 -i 0 -c 1 $DIR/$tdir/$tfile &&
1783                 error "$LFS setstripe $DIR/$tdir/$tfile failed"
1784         $CHECKSTAT -t file $DIR/$tdir/$tfile &&
1785                 error "$CHECKSTAT -t file $DIR/$tdir/$tfile should fail"
1786         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1787         $LFS getstripe $DIR/$tdir/$tfile || error "$LFS getstripe failed"
1788 }
1789 run_test 27f "setstripe with bad stripe size (should return error)"
1790
1791 test_27g() {
1792         test_mkdir $DIR/$tdir
1793         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1794         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "no stripe info" ||
1795                 error "$DIR/$tdir/$tfile has object"
1796 }
1797 run_test 27g "$LFS getstripe with no objects"
1798
1799 test_27ga() {
1800         test_mkdir $DIR/$tdir
1801         touch $DIR/$tdir/$tfile || error "touch failed"
1802         ln -s bogus $DIR/$tdir/$tfile.2 || error "ln failed"
1803         $LFS getstripe -m $DIR/$tdir/$tfile $DIR/$tdir/$tfile.2
1804         local rc=$?
1805         (( rc == 2 )) || error "getstripe did not return ENOENT"
1806 }
1807 run_test 27ga "$LFS getstripe with missing file (should return error)"
1808
1809 test_27i() {
1810         test_mkdir $DIR/$tdir
1811         touch $DIR/$tdir/$tfile || error "touch failed"
1812         [[ $($LFS getstripe -c $DIR/$tdir/$tfile) -gt 0 ]] ||
1813                 error "missing objects"
1814 }
1815 run_test 27i "$LFS getstripe with some objects"
1816
1817 test_27j() {
1818         test_mkdir $DIR/$tdir
1819         $LFS setstripe -i $OSTCOUNT $DIR/$tdir/$tfile &&
1820                 error "setstripe failed" || true
1821 }
1822 run_test 27j "setstripe with bad stripe offset (should return error)"
1823
1824 test_27k() { # bug 2844
1825         test_mkdir $DIR/$tdir
1826         local file=$DIR/$tdir/$tfile
1827         local ll_max_blksize=$((4 * 1024 * 1024))
1828         $LFS setstripe -S 67108864 $file || error "setstripe failed"
1829         local blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1830         [ $blksize -le $ll_max_blksize ] || error "1:$blksize > $ll_max_blksize"
1831         dd if=/dev/zero of=$file bs=4k count=1
1832         blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1833         [ $blksize -le $ll_max_blksize ] || error "2:$blksize > $ll_max_blksize"
1834 }
1835 run_test 27k "limit i_blksize for broken user apps"
1836
1837 test_27l() {
1838         mcreate $DIR/$tfile || error "creating file"
1839         $RUNAS $LFS setstripe -c 1 $DIR/$tfile &&
1840                 error "setstripe should have failed" || true
1841 }
1842 run_test 27l "check setstripe permissions (should return error)"
1843
1844 test_27m() {
1845         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1846
1847         [ -n "$RCLIENTS" -o -n "$MOUNT_2" ] &&
1848                 skip_env "multiple clients -- skipping"
1849
1850         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
1851                    head -n1)
1852         if [[ $ORIGFREE -gt $MAXFREE ]]; then
1853                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
1854         fi
1855         stack_trap simple_cleanup_common
1856         test_mkdir $DIR/$tdir
1857         $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.1
1858         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1024 count=$MAXFREE &&
1859                 error "dd should fill OST0"
1860         i=2
1861         while $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.$i; do
1862                 i=$((i + 1))
1863                 [ $i -gt 256 ] && break
1864         done
1865         i=$((i + 1))
1866         touch $DIR/$tdir/$tfile.$i
1867         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1868             awk '{print $1}'| grep -w "0") ] &&
1869                 error "OST0 was full but new created file still use it"
1870         i=$((i + 1))
1871         touch $DIR/$tdir/$tfile.$i
1872         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1873             awk '{print $1}'| grep -w "0") ] &&
1874                 error "OST0 was full but new created file still use it" || true
1875 }
1876 run_test 27m "create file while OST0 was full"
1877
1878 # OSCs keep a NOSPC flag that will be reset after ~5s (qos_maxage)
1879 # if the OST isn't full anymore.
1880 reset_enospc() {
1881         local ostidx=${1:-""}
1882         local delay
1883         local ready
1884         local get_prealloc
1885
1886         local list=$(comma_list $(osts_nodes))
1887         [ "$ostidx" ] && list=$(facet_host ost$((ostidx + 1)))
1888
1889         do_nodes $list lctl set_param fail_loc=0
1890         wait_delete_completed   # initiate all OST_DESTROYs from MDS to OST
1891         delay=$(do_facet $SINGLEMDS lctl get_param -n lov.*.qos_maxage |
1892                 awk '{print $1 * 2;exit;}')
1893         get_prealloc="$LCTL get_param -n osc.*MDT*.prealloc_status |
1894                         grep -v \"^0$\""
1895         wait_update_facet $SINGLEMDS "$get_prealloc" "" $delay
1896 }
1897
1898 test_27n() {
1899         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1900         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1901         remote_mds_nodsh && skip "remote MDS with nodsh"
1902         remote_ost_nodsh && skip "remote OST with nodsh"
1903
1904         reset_enospc
1905         rm -f $DIR/$tdir/$tfile
1906         exhaust_precreations 0 0x80000215
1907         $LFS setstripe -c -1 $DIR/$tdir || error "setstripe failed"
1908         touch $DIR/$tdir/$tfile || error "touch failed"
1909         $LFS getstripe $DIR/$tdir/$tfile
1910         reset_enospc
1911 }
1912 run_test 27n "create file with some full OSTs"
1913
1914 test_27o() {
1915         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1916         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1917         remote_mds_nodsh && skip "remote MDS with nodsh"
1918         remote_ost_nodsh && skip "remote OST with nodsh"
1919
1920         reset_enospc
1921         rm -f $DIR/$tdir/$tfile
1922         exhaust_all_precreations 0x215
1923
1924         touch $DIR/$tdir/$tfile && error "able to create $DIR/$tdir/$tfile"
1925
1926         reset_enospc
1927         rm -rf $DIR/$tdir/*
1928 }
1929 run_test 27o "create file with all full OSTs (should error)"
1930
1931 function create_and_checktime() {
1932         local fname=$1
1933         local loops=$2
1934         local i
1935
1936         for ((i=0; i < $loops; i++)); do
1937                 local start=$SECONDS
1938                 multiop $fname-$i Oc
1939                 ((SECONDS-start < TIMEOUT)) ||
1940                         error "creation took " $((SECONDS-$start)) && return 1
1941         done
1942 }
1943
1944 test_27oo() {
1945         local mdts=$(comma_list $(mdts_nodes))
1946
1947         [ $MDS1_VERSION -lt $(version_code 2.13.57) ] &&
1948                 skip "Need MDS version at least 2.13.57"
1949
1950         local f0=$DIR/${tfile}-0
1951         local f1=$DIR/${tfile}-1
1952
1953         wait_delete_completed
1954
1955         # refill precreated objects
1956         $LFS setstripe -i0 -c1 $f0
1957
1958         saved=$(do_facet mds1 $LCTL get_param -n lov.*0000*.qos_threshold_rr)
1959         # force QoS allocation policy
1960         do_nodes $mdts $LCTL set_param lov.*.qos_threshold_rr=0%
1961         stack_trap "do_nodes $mdts $LCTL set_param \
1962                 lov.*.qos_threshold_rr=$saved" EXIT
1963         sleep_maxage
1964
1965         # one OST is unavailable, but still have few objects preallocated
1966         stop ost1
1967         stack_trap "start ost1 $(ostdevname 1) $OST_MOUNT_OPTS; \
1968                 rm -rf $f1 $DIR/$tdir*" EXIT
1969
1970         for ((i=0; i < 7; i++)); do
1971                 mkdir $DIR/$tdir$i || error "can't create dir"
1972                 $LFS setstripe -c$((OSTCOUNT-1)) $DIR/$tdir$i ||
1973                         error "can't set striping"
1974         done
1975         for ((i=0; i < 7; i++)); do
1976                 create_and_checktime $DIR/$tdir$i/$tfile 100 &
1977         done
1978         wait
1979 }
1980 run_test 27oo "don't let few threads to reserve too many objects"
1981
1982 test_27p() {
1983         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1984         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1985         remote_mds_nodsh && skip "remote MDS with nodsh"
1986         remote_ost_nodsh && skip "remote OST with nodsh"
1987
1988         reset_enospc
1989         rm -f $DIR/$tdir/$tfile
1990         test_mkdir $DIR/$tdir
1991
1992         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1993         $TRUNCATE $DIR/$tdir/$tfile 80000000 || error "truncate failed"
1994         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
1995
1996         exhaust_precreations 0 0x80000215
1997         echo foo >> $DIR/$tdir/$tfile || error "append failed"
1998         $CHECKSTAT -s 80000004 $DIR/$tdir/$tfile || error "checkstat failed"
1999         $LFS getstripe $DIR/$tdir/$tfile
2000
2001         reset_enospc
2002 }
2003 run_test 27p "append to a truncated file with some full OSTs"
2004
2005 test_27q() {
2006         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2007         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2008         remote_mds_nodsh && skip "remote MDS with nodsh"
2009         remote_ost_nodsh && skip "remote OST with nodsh"
2010
2011         reset_enospc
2012         rm -f $DIR/$tdir/$tfile
2013
2014         mkdir_on_mdt0 $DIR/$tdir
2015         $MCREATE $DIR/$tdir/$tfile || error "mcreate $DIR/$tdir/$tfile failed"
2016         $TRUNCATE $DIR/$tdir/$tfile 80000000 ||
2017                 error "truncate $DIR/$tdir/$tfile failed"
2018         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
2019
2020         exhaust_all_precreations 0x215
2021
2022         echo foo >> $DIR/$tdir/$tfile && error "append succeeded"
2023         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat 2 failed"
2024
2025         reset_enospc
2026 }
2027 run_test 27q "append to truncated file with all OSTs full (should error)"
2028
2029 test_27r() {
2030         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2031         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2032         remote_mds_nodsh && skip "remote MDS with nodsh"
2033         remote_ost_nodsh && skip "remote OST with nodsh"
2034
2035         reset_enospc
2036         rm -f $DIR/$tdir/$tfile
2037         exhaust_precreations 0 0x80000215
2038
2039         $LFS setstripe -i 0 -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
2040
2041         reset_enospc
2042 }
2043 run_test 27r "stripe file with some full OSTs (shouldn't LBUG) ="
2044
2045 test_27s() { # bug 10725
2046         test_mkdir $DIR/$tdir
2047         local stripe_size=$((4096 * 1024 * 1024))       # 2^32
2048         local stripe_count=0
2049         [ $OSTCOUNT -eq 1 ] || stripe_count=2
2050         $LFS setstripe -S $stripe_size -c $stripe_count $DIR/$tdir &&
2051                 error "stripe width >= 2^32 succeeded" || true
2052
2053 }
2054 run_test 27s "lsm_xfersize overflow (should error) (bug 10725)"
2055
2056 test_27t() { # bug 10864
2057         WDIR=$(pwd)
2058         WLFS=$(which lfs)
2059         cd $DIR
2060         touch $tfile
2061         $WLFS getstripe $tfile
2062         cd $WDIR
2063 }
2064 run_test 27t "check that utils parse path correctly"
2065
2066 test_27u() { # bug 4900
2067         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2068         remote_mds_nodsh && skip "remote MDS with nodsh"
2069
2070         local index
2071         local list=$(comma_list $(mdts_nodes))
2072
2073 #define OBD_FAIL_MDS_OSC_PRECREATE      0x139
2074         do_nodes $list $LCTL set_param fail_loc=0x139
2075         test_mkdir -p $DIR/$tdir
2076         stack_trap "simple_cleanup_common 1000"
2077         createmany -o $DIR/$tdir/$tfile 1000
2078         do_nodes $list $LCTL set_param fail_loc=0
2079
2080         TLOG=$TMP/$tfile.getstripe
2081         $LFS getstripe $DIR/$tdir > $TLOG
2082         OBJS=$(awk -vobj=0 '($1 == 0) { obj += 1 } END { print obj; }' $TLOG)
2083         [[ $OBJS -gt 0 ]] &&
2084                 error "$OBJS objects created on OST-0. See $TLOG" ||
2085                 rm -f $TLOG
2086 }
2087 run_test 27u "skip object creation on OSC w/o objects"
2088
2089 test_27v() { # bug 4900
2090         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2091         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2092         remote_mds_nodsh && skip "remote MDS with nodsh"
2093         remote_ost_nodsh && skip "remote OST with nodsh"
2094
2095         exhaust_all_precreations 0x215
2096         reset_enospc
2097
2098         $LFS setstripe -c 1 $DIR/$tdir         # 1 stripe / file
2099
2100         touch $DIR/$tdir/$tfile
2101         #define OBD_FAIL_TGT_DELAY_PRECREATE     0x705
2102         # all except ost1
2103         for (( i=1; i < OSTCOUNT; i++ )); do
2104                 do_facet ost$i lctl set_param fail_loc=0x705
2105         done
2106         local START=`date +%s`
2107         createmany -o $DIR/$tdir/$tfile 32
2108
2109         local FINISH=`date +%s`
2110         local TIMEOUT=`lctl get_param -n timeout`
2111         local PROCESS=$((FINISH - START))
2112         [ $PROCESS -ge $((TIMEOUT / 2)) ] && \
2113                error "$FINISH - $START >= $TIMEOUT / 2"
2114         sleep $((TIMEOUT / 2 - PROCESS))
2115         reset_enospc
2116 }
2117 run_test 27v "skip object creation on slow OST"
2118
2119 test_27w() { # bug 10997
2120         test_mkdir $DIR/$tdir
2121         $LFS setstripe -S 65536 $DIR/$tdir/f0 || error "setstripe failed"
2122         [ $($LFS getstripe -S $DIR/$tdir/f0) -ne 65536 ] &&
2123                 error "stripe size $size != 65536" || true
2124         [ $($LFS getstripe -d $DIR/$tdir | grep -c "stripe_count") -eq 0 ] &&
2125                 error "$LFS getstripe -d $DIR/$tdir no 'stripe_count'" || true
2126 }
2127 run_test 27w "check $LFS setstripe -S and getstrip -d options"
2128
2129 test_27wa() {
2130         [[ $OSTCOUNT -lt 2 ]] &&
2131                 skip_env "skipping multiple stripe count/offset test"
2132
2133         test_mkdir $DIR/$tdir
2134         for i in $(seq 1 $OSTCOUNT); do
2135                 offset=$((i - 1))
2136                 $LFS setstripe -c $i -i $offset $DIR/$tdir/f$i ||
2137                         error "setstripe -c $i -i $offset failed"
2138                 count=$($LFS getstripe -c $DIR/$tdir/f$i)
2139                 index=$($LFS getstripe -i $DIR/$tdir/f$i)
2140                 [ $count -ne $i ] && error "stripe count $count != $i" || true
2141                 [ $index -ne $offset ] &&
2142                         error "stripe offset $index != $offset" || true
2143         done
2144 }
2145 run_test 27wa "check $LFS setstripe -c -i options"
2146
2147 test_27x() {
2148         remote_ost_nodsh && skip "remote OST with nodsh"
2149         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2150         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2151
2152         OFFSET=$(($OSTCOUNT - 1))
2153         OSTIDX=0
2154         local OST=$(ostname_from_index $OSTIDX)
2155
2156         test_mkdir $DIR/$tdir
2157         $LFS setstripe -c 1 $DIR/$tdir  # 1 stripe per file
2158         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 1
2159         sleep_maxage
2160         createmany -o $DIR/$tdir/$tfile $OSTCOUNT
2161         for i in $(seq 0 $OFFSET); do
2162                 [ $($LFS getstripe $DIR/$tdir/$tfile$i | grep -A 10 obdidx |
2163                         awk '{print $1}' | grep -w "$OSTIDX") ] &&
2164                 error "OST0 was degraded but new created file still use it"
2165         done
2166         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 0
2167 }
2168 run_test 27x "create files while OST0 is degraded"
2169
2170 test_27y() {
2171         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2172         remote_mds_nodsh && skip "remote MDS with nodsh"
2173         remote_ost_nodsh && skip "remote OST with nodsh"
2174         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2175
2176         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS $FSNAME-OST0000)
2177         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
2178                 osp.$mdtosc.prealloc_last_id)
2179         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
2180                 osp.$mdtosc.prealloc_next_id)
2181         local fcount=$((last_id - next_id))
2182         [[ $fcount -eq 0 ]] && skip "not enough space on OST0"
2183         [[ $fcount -gt $OSTCOUNT ]] && fcount=$OSTCOUNT
2184
2185         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
2186                          awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
2187         local OST_DEACTIVE_IDX=-1
2188         local OSC
2189         local OSTIDX
2190         local OST
2191
2192         for OSC in $MDS_OSCS; do
2193                 OST=$(osc_to_ost $OSC)
2194                 OSTIDX=$(index_from_ostuuid $OST)
2195                 if [ $OST_DEACTIVE_IDX == -1 ]; then
2196                         OST_DEACTIVE_IDX=$OSTIDX
2197                 fi
2198                 if [ $OSTIDX != $OST_DEACTIVE_IDX ]; then
2199                         echo $OSC "is Deactivated:"
2200                         do_facet $SINGLEMDS lctl --device  %$OSC deactivate
2201                 fi
2202         done
2203
2204         OSTIDX=$(index_from_ostuuid $OST)
2205         test_mkdir $DIR/$tdir
2206         $LFS setstripe -c 1 $DIR/$tdir      # 1 stripe / file
2207
2208         for OSC in $MDS_OSCS; do
2209                 OST=$(osc_to_ost $OSC)
2210                 OSTIDX=$(index_from_ostuuid $OST)
2211                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2212                         echo $OST "is degraded:"
2213                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2214                                                 obdfilter.$OST.degraded=1
2215                 fi
2216         done
2217
2218         sleep_maxage
2219         createmany -o $DIR/$tdir/$tfile $fcount
2220
2221         for OSC in $MDS_OSCS; do
2222                 OST=$(osc_to_ost $OSC)
2223                 OSTIDX=$(index_from_ostuuid $OST)
2224                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2225                         echo $OST "is recovered from degraded:"
2226                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2227                                                 obdfilter.$OST.degraded=0
2228                 else
2229                         do_facet $SINGLEMDS lctl --device %$OSC activate
2230                 fi
2231         done
2232
2233         # all osp devices get activated, hence -1 stripe count restored
2234         local stripe_count=0
2235
2236         # sleep 2*lod_qos_maxage seconds waiting for lod qos to notice osp
2237         # devices get activated.
2238         sleep_maxage
2239         $LFS setstripe -c -1 $DIR/$tfile
2240         stripe_count=$($LFS getstripe -c $DIR/$tfile)
2241         rm -f $DIR/$tfile
2242         [ $stripe_count -ne $OSTCOUNT ] &&
2243                 error "Of $OSTCOUNT OSTs, only $stripe_count is available"
2244         return 0
2245 }
2246 run_test 27y "create files while OST0 is degraded and the rest inactive"
2247
2248 check_seq_oid()
2249 {
2250         log "check file $1"
2251
2252         lmm_count=$($LFS getstripe -c $1)
2253         lmm_seq=$($LFS getstripe -v $1 | awk '/lmm_seq/ { print $2 }')
2254         lmm_oid=$($LFS getstripe -v $1 | awk '/lmm_object_id/ { print $2 }')
2255
2256         local old_ifs="$IFS"
2257         IFS=$'[:]'
2258         fid=($($LFS path2fid $1))
2259         IFS="$old_ifs"
2260
2261         log "FID seq ${fid[1]}, oid ${fid[2]} ver ${fid[3]}"
2262         log "LOV seq $lmm_seq, oid $lmm_oid, count: $lmm_count"
2263
2264         # compare lmm_seq and lu_fid->f_seq
2265         [ $lmm_seq = ${fid[1]} ] || { error "SEQ mismatch"; return 1; }
2266         # compare lmm_object_id and lu_fid->oid
2267         [ $lmm_oid = ${fid[2]} ] || { error "OID mismatch"; return 2; }
2268
2269         # check the trusted.fid attribute of the OST objects of the file
2270         local have_obdidx=false
2271         local stripe_nr=0
2272         $LFS getstripe $1 | while read obdidx oid hex seq; do
2273                 # skip lines up to and including "obdidx"
2274                 [ -z "$obdidx" ] && break
2275                 [ "$obdidx" = "obdidx" ] && have_obdidx=true && continue
2276                 $have_obdidx || continue
2277
2278                 local ost=$((obdidx + 1))
2279                 local dev=$(ostdevname $ost)
2280                 local oid_hex
2281
2282                 log "want: stripe:$stripe_nr ost:$obdidx oid:$oid/$hex seq:$seq"
2283
2284                 seq=$(echo $seq | sed -e "s/^0x//g")
2285                 if [ $seq == 0 ] || [ $(facet_fstype ost$ost) == zfs ]; then
2286                         oid_hex=$(echo $oid)
2287                 else
2288                         oid_hex=$(echo $hex | sed -e "s/^0x//g")
2289                 fi
2290                 local obj_file="O/$seq/d$((oid %32))/$oid_hex"
2291
2292                 local ff=""
2293                 #
2294                 # Don't unmount/remount the OSTs if we don't need to do that.
2295                 # LU-2577 changes filter_fid to be smaller, so debugfs needs
2296                 # update too, until that use mount/ll_decode_filter_fid/mount.
2297                 # Re-enable when debugfs will understand new filter_fid.
2298                 #
2299                 if [ $(facet_fstype ost$ost) == ldiskfs ]; then
2300                         ff=$(do_facet ost$ost "$DEBUGFS -c -R 'stat $obj_file' \
2301                                 $dev 2>/dev/null" | grep "parent=")
2302                 fi
2303                 if [ -z "$ff" ]; then
2304                         stop ost$ost
2305                         mount_fstype ost$ost
2306                         ff=$(do_facet ost$ost $LL_DECODE_FILTER_FID \
2307                                 $(facet_mntpt ost$ost)/$obj_file)
2308                         unmount_fstype ost$ost
2309                         start ost$ost $dev $OST_MOUNT_OPTS
2310                         clients_up
2311                 fi
2312
2313                 [ -z "$ff" ] && error "$obj_file: no filter_fid info"
2314
2315                 echo "$ff" | sed -e 's#.*objid=#got: objid=#'
2316
2317                 # /mnt/O/0/d23/23: objid=23 seq=0 parent=[0x200000400:0x1e:0x1]
2318                 # fid: objid=23 seq=0 parent=[0x200000400:0x1e:0x0] stripe=1
2319                 #
2320                 # fid: parent=[0x200000400:0x1e:0x0] stripe=1 stripe_count=2 \
2321                 #       stripe_size=1048576 component_id=1 component_start=0 \
2322                 #       component_end=33554432
2323                 local ff_parent=$(sed -e 's/.*parent=.//' <<<$ff)
2324                 local ff_pseq=$(cut -d: -f1 <<<$ff_parent)
2325                 local ff_poid=$(cut -d: -f2 <<<$ff_parent)
2326                 local ff_pstripe
2327                 if grep -q 'stripe=' <<<$ff; then
2328                         ff_pstripe=$(sed -e 's/.*stripe=//' -e 's/ .*//' <<<$ff)
2329                 else
2330                         # $LL_DECODE_FILTER_FID does not print "stripe="; look
2331                         # into f_ver in this case.  See comment on ff_parent.
2332                         ff_pstripe=$(cut -d: -f3 <<<$ff_parent | sed -e 's/]//')
2333                 fi
2334
2335                 # compare lmm_seq and filter_fid->ff_parent.f_seq
2336                 [ $ff_pseq = $lmm_seq ] ||
2337                         error "FF parent SEQ $ff_pseq != $lmm_seq"
2338                 # compare lmm_object_id and filter_fid->ff_parent.f_oid
2339                 [ $ff_poid = $lmm_oid ] ||
2340                         error "FF parent OID $ff_poid != $lmm_oid"
2341                 (($ff_pstripe == $stripe_nr)) ||
2342                         error "FF stripe $ff_pstripe != $stripe_nr"
2343
2344                 stripe_nr=$((stripe_nr + 1))
2345                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2346                         continue
2347                 if grep -q 'stripe_count=' <<<$ff; then
2348                         local ff_scnt=$(sed -e 's/.*stripe_count=//' \
2349                                             -e 's/ .*//' <<<$ff)
2350                         [ $lmm_count = $ff_scnt ] ||
2351                                 error "FF stripe count $lmm_count != $ff_scnt"
2352                 fi
2353         done
2354 }
2355
2356 test_27z() {
2357         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2358         remote_ost_nodsh && skip "remote OST with nodsh"
2359
2360         test_mkdir $DIR/$tdir
2361         $LFS setstripe -c 1 -i 0 -S 64k $DIR/$tdir/$tfile-1 ||
2362                 { error "setstripe -c -1 failed"; return 1; }
2363         # We need to send a write to every object to get parent FID info set.
2364         # This _should_ also work for setattr, but does not currently.
2365         # touch $DIR/$tdir/$tfile-1 ||
2366         dd if=/dev/zero of=$DIR/$tdir/$tfile-1 bs=1M count=1 ||
2367                 { error "dd $tfile-1 failed"; return 2; }
2368         $LFS setstripe -c -1 -i $((OSTCOUNT - 1)) -S 1M $DIR/$tdir/$tfile-2 ||
2369                 { error "setstripe -c -1 failed"; return 3; }
2370         dd if=/dev/zero of=$DIR/$tdir/$tfile-2 bs=1M count=$OSTCOUNT ||
2371                 { error "dd $tfile-2 failed"; return 4; }
2372
2373         # make sure write RPCs have been sent to OSTs
2374         sync; sleep 5; sync
2375
2376         check_seq_oid $DIR/$tdir/$tfile-1 || return 5
2377         check_seq_oid $DIR/$tdir/$tfile-2 || return 6
2378 }
2379 run_test 27z "check SEQ/OID on the MDT and OST filesystems"
2380
2381 test_27A() { # b=19102
2382         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2383
2384         save_layout_restore_at_exit $MOUNT
2385         $LFS setstripe -c 0 -i -1 -S 0 $MOUNT
2386         wait_update $HOSTNAME "$LFS getstripe -c $MOUNT | sed 's/  *//g'" "1" 20 ||
2387                 error "stripe count $($LFS getstripe -c $MOUNT) != 1"
2388         local default_size=$($LFS getstripe -S $MOUNT)
2389         local default_offset=$($LFS getstripe -i $MOUNT)
2390         local dsize=$(do_facet $SINGLEMDS \
2391                 "$LCTL get_param -n lod.$(facet_svc $SINGLEMDS)*.stripesize")
2392         [ $default_size -eq $dsize ] ||
2393                 error "stripe size $default_size != $dsize"
2394         [ $default_offset -eq -1 ] ||
2395                 error "stripe offset $default_offset != -1"
2396 }
2397 run_test 27A "check filesystem-wide default LOV EA values"
2398
2399 test_27B() { # LU-2523
2400         test_mkdir $DIR/$tdir
2401         rm -f $DIR/$tdir/f0 $DIR/$tdir/f1
2402         touch $DIR/$tdir/f0
2403         # open f1 with O_LOV_DELAY_CREATE
2404         # rename f0 onto f1
2405         # call setstripe ioctl on open file descriptor for f1
2406         # close
2407         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:nB1c \
2408                 $DIR/$tdir/f0
2409
2410         rm -f $DIR/$tdir/f1
2411         # open f1 with O_LOV_DELAY_CREATE
2412         # unlink f1
2413         # call setstripe ioctl on open file descriptor for f1
2414         # close
2415         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:uB1c
2416
2417         # Allow multiop to fail in imitation of NFS's busted semantics.
2418         true
2419 }
2420 run_test 27B "call setstripe on open unlinked file/rename victim"
2421
2422 # 27C family tests full striping and overstriping
2423 test_27Ca() { #LU-2871
2424         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2425
2426         declare -a ost_idx
2427         local index
2428         local found
2429         local i
2430         local j
2431
2432         test_mkdir $DIR/$tdir
2433         cd $DIR/$tdir
2434         for i in $(seq 0 $((OSTCOUNT - 1))); do
2435                 # set stripe across all OSTs starting from OST$i
2436                 $LFS setstripe -i $i -c -1 $tfile$i
2437                 # get striping information
2438                 ost_idx=($($LFS getstripe $tfile$i |
2439                          tail -n $((OSTCOUNT + 1)) | awk '{print $1}'))
2440                 echo "OST Index: ${ost_idx[*]}"
2441
2442                 # check the layout
2443                 [ ${#ost_idx[@]} -eq $OSTCOUNT ] ||
2444                         error "${#ost_idx[@]} != $OSTCOUNT"
2445
2446                 for index in $(seq 0 $((OSTCOUNT - 1))); do
2447                         found=0
2448                         for j in "${ost_idx[@]}"; do
2449                                 if [ $index -eq $j ]; then
2450                                         found=1
2451                                         break
2452                                 fi
2453                         done
2454                         [ $found = 1 ] ||
2455                                 error "Can not find $index in ${ost_idx[*]}"
2456                 done
2457         done
2458 }
2459 run_test 27Ca "check full striping across all OSTs"
2460
2461 test_27Cb() {
2462         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2463                 skip "server does not support overstriping"
2464         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2465                 skip_env "too many osts, skipping"
2466
2467         test_mkdir -p $DIR/$tdir
2468         local setcount=$(($OSTCOUNT * 2))
2469         [ $setcount -lt 160 ] || large_xattr_enabled ||
2470                 skip_env "ea_inode feature disabled"
2471
2472         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2473                 error "setstripe failed"
2474
2475         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2476         [ $count -eq $setcount ] ||
2477                 error "stripe count $count, should be $setcount"
2478
2479         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2480                 error "overstriped should be set in pattern"
2481
2482         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2483                 error "dd failed"
2484 }
2485 run_test 27Cb "more stripes than OSTs with -C"
2486
2487 test_27Cc() {
2488         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2489                 skip "server does not support overstriping"
2490         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2491
2492         test_mkdir -p $DIR/$tdir
2493         local setcount=$(($OSTCOUNT - 1))
2494
2495         [ $setcount -lt 160 ] || large_xattr_enabled ||
2496                 skip_env "ea_inode feature disabled"
2497
2498         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2499                 error "setstripe failed"
2500
2501         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2502         [ $count -eq $setcount ] ||
2503                 error "stripe count $count, should be $setcount"
2504
2505         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" &&
2506                 error "overstriped should not be set in pattern"
2507
2508         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2509                 error "dd failed"
2510 }
2511 run_test 27Cc "fewer stripes than OSTs does not set overstriping"
2512
2513 test_27Cd() {
2514         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2515                 skip "server does not support overstriping"
2516         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2517         large_xattr_enabled || skip_env "ea_inode feature disabled"
2518
2519         force_new_seq_all
2520
2521         test_mkdir -p $DIR/$tdir
2522         local setcount=$LOV_MAX_STRIPE_COUNT
2523
2524         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2525                 error "setstripe failed"
2526
2527         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2528         [ $count -eq $setcount ] ||
2529                 error "stripe count $count, should be $setcount"
2530
2531         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2532                 error "overstriped should be set in pattern"
2533
2534         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2535                 error "dd failed"
2536
2537         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2538 }
2539 run_test 27Cd "test maximum stripe count"
2540
2541 test_27Ce() {
2542         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2543                 skip "server does not support overstriping"
2544         test_mkdir -p $DIR/$tdir
2545
2546         pool_add $TESTNAME || error "Pool creation failed"
2547         pool_add_targets $TESTNAME 0 || error "pool_add_targets failed"
2548
2549         local setcount=8
2550
2551         $LFS setstripe  -C $setcount -p "$TESTNAME" $DIR/$tdir/$tfile ||
2552                 error "setstripe failed"
2553
2554         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2555         [ $count -eq $setcount ] ||
2556                 error "stripe count $count, should be $setcount"
2557
2558         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2559                 error "overstriped should be set in pattern"
2560
2561         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2562                 error "dd failed"
2563
2564         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2565 }
2566 run_test 27Ce "test pool with overstriping"
2567
2568 test_27Cf() {
2569         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2570                 skip "server does not support overstriping"
2571         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2572                 skip_env "too many osts, skipping"
2573
2574         test_mkdir -p $DIR/$tdir
2575
2576         local setcount=$(($OSTCOUNT * 2))
2577         [ $setcount -lt 160 ] || large_xattr_enabled ||
2578                 skip_env "ea_inode feature disabled"
2579
2580         $LFS setstripe  -C $setcount $DIR/$tdir/ ||
2581                 error "setstripe failed"
2582
2583         echo 1 > $DIR/$tdir/$tfile
2584
2585         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2586         [ $count -eq $setcount ] ||
2587                 error "stripe count $count, should be $setcount"
2588
2589         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2590                 error "overstriped should be set in pattern"
2591
2592         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2593                 error "dd failed"
2594
2595         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2596 }
2597 run_test 27Cf "test default inheritance with overstriping"
2598
2599 test_27Cg() {
2600         $LFS setstripe -o 0,$OSTCOUNT $DIR/$tfile
2601         [ $? -ne 0 ] || error "must be an error for not existent OST#"
2602 }
2603 run_test 27Cg "test setstripe with wrong OST idx"
2604
2605 test_27D() {
2606         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2607         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2608         remote_mds_nodsh && skip "remote MDS with nodsh"
2609
2610         local POOL=${POOL:-testpool}
2611         local first_ost=0
2612         local last_ost=$(($OSTCOUNT - 1))
2613         local ost_step=1
2614         local ost_list=$(seq $first_ost $ost_step $last_ost)
2615         local ost_range="$first_ost $last_ost $ost_step"
2616
2617         test_mkdir $DIR/$tdir
2618         pool_add $POOL || error "pool_add failed"
2619         pool_add_targets $POOL $ost_range || error "pool_add_targets failed"
2620
2621         local skip27D
2622         [ $MDS1_VERSION -lt $(version_code 2.8.55) ] &&
2623                 skip27D+="-s 29"
2624         [ $MDS1_VERSION -lt $(version_code 2.9.55) ] ||
2625                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2626                         skip27D+=" -s 30,31"
2627         [[ ! $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ||
2628           $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2629                 skip27D+=" -s 32,33"
2630         [[ $MDS_VERSION -lt $(version_code $SEL_VER) ]] &&
2631                 skip27D+=" -s 34"
2632         llapi_layout_test -d$DIR/$tdir -p$POOL -o$OSTCOUNT $skip27D ||
2633                 error "llapi_layout_test failed"
2634
2635         destroy_test_pools || error "destroy test pools failed"
2636 }
2637 run_test 27D "validate llapi_layout API"
2638
2639 # Verify that default_easize is increased from its initial value after
2640 # accessing a widely striped file.
2641 test_27E() {
2642         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2643         [ $CLIENT_VERSION -lt $(version_code 2.5.57) ] &&
2644                 skip "client does not have LU-3338 fix"
2645
2646         # 72 bytes is the minimum space required to store striping
2647         # information for a file striped across one OST:
2648         # (sizeof(struct lov_user_md_v3) +
2649         #  sizeof(struct lov_user_ost_data_v1))
2650         local min_easize=72
2651         $LCTL set_param -n llite.*.default_easize $min_easize ||
2652                 error "lctl set_param failed"
2653         local easize=$($LCTL get_param -n llite.*.default_easize)
2654
2655         [ $easize -eq $min_easize ] ||
2656                 error "failed to set default_easize"
2657
2658         $LFS setstripe -c $OSTCOUNT $DIR/$tfile ||
2659                 error "setstripe failed"
2660         # In order to ensure stat() call actually talks to MDS we need to
2661         # do something drastic to this file to shake off all lock, e.g.
2662         # rename it (kills lookup lock forcing cache cleaning)
2663         mv $DIR/$tfile $DIR/${tfile}-1
2664         ls -l $DIR/${tfile}-1
2665         rm $DIR/${tfile}-1
2666
2667         easize=$($LCTL get_param -n llite.*.default_easize)
2668
2669         [ $easize -gt $min_easize ] ||
2670                 error "default_easize not updated"
2671 }
2672 run_test 27E "check that default extended attribute size properly increases"
2673
2674 test_27F() { # LU-5346/LU-7975
2675         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2676         [[ $OSTCOUNT -lt 2 ]] && skip "needs >= 2 OSTs"
2677         [[ $MDS1_VERSION -lt $(version_code 2.8.51) ]] &&
2678                 skip "Need MDS version at least 2.8.51"
2679         remote_ost_nodsh && skip "remote OST with nodsh"
2680
2681         test_mkdir $DIR/$tdir
2682         rm -f $DIR/$tdir/f0
2683         $LFS setstripe -c 2 $DIR/$tdir
2684
2685         # stop all OSTs to reproduce situation for LU-7975 ticket
2686         for num in $(seq $OSTCOUNT); do
2687                 stop ost$num
2688         done
2689
2690         # open/create f0 with O_LOV_DELAY_CREATE
2691         # truncate f0 to a non-0 size
2692         # close
2693         multiop $DIR/$tdir/f0 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T1050000c
2694
2695         $CHECKSTAT -s 1050000 $DIR/$tdir/f0 || error "checkstat failed"
2696         # open/write it again to force delayed layout creation
2697         cat /etc/hosts > $DIR/$tdir/f0 &
2698         catpid=$!
2699
2700         # restart OSTs
2701         for num in $(seq $OSTCOUNT); do
2702                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS ||
2703                         error "ost$num failed to start"
2704         done
2705
2706         wait $catpid || error "cat failed"
2707
2708         cmp /etc/hosts $DIR/$tdir/f0 || error "cmp failed"
2709         [[ $($LFS getstripe -c $DIR/$tdir/f0) == 2 ]] ||
2710                 error "wrong stripecount"
2711
2712 }
2713 run_test 27F "Client resend delayed layout creation with non-zero size"
2714
2715 test_27G() { #LU-10629
2716         [ $MDS1_VERSION -lt $(version_code 2.11.51) ] &&
2717                 skip "Need MDS version at least 2.11.51"
2718         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2719         remote_mds_nodsh && skip "remote MDS with nodsh"
2720         local POOL=${POOL:-testpool}
2721         local ostrange="0 0 1"
2722
2723         test_mkdir $DIR/$tdir
2724         touch $DIR/$tdir/$tfile.nopool
2725         pool_add $POOL || error "pool_add failed"
2726         pool_add_targets $POOL $ostrange || error "pool_add_targets failed"
2727         $LFS setstripe -p $POOL $DIR/$tdir
2728
2729         local pool=$($LFS getstripe -p $DIR/$tdir)
2730
2731         [ "$pool" = "$POOL" ] || error "Striping failed got '$pool' not '$POOL'"
2732         touch $DIR/$tdir/$tfile.default
2733         $LFS setstripe -E 1M --pool $POOL -c 1 -E eof -c 1 $DIR/$tdir/$tfile.pfl
2734         $LFS find $DIR/$tdir -type f --pool $POOL
2735         local found=$($LFS find $DIR/$tdir -type f --pool $POOL | wc -l)
2736         [[ "$found" == "2" ]] ||
2737                 error "found $found != 2 files in '$DIR/$tdir' in '$POOL'"
2738
2739         $LFS setstripe -d $DIR/$tdir
2740
2741         pool=$($LFS getstripe -p -d $DIR/$tdir)
2742
2743         [[ "$pool" != "$POOL" ]] || error "$DIR/$tdir is still '$pool'"
2744 }
2745 run_test 27G "Clear OST pool from stripe"
2746
2747 test_27H() {
2748         [[ $MDS1_VERSION -le $(version_code 2.11.54) ]] &&
2749                 skip "Need MDS version newer than 2.11.54"
2750         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
2751         test_mkdir $DIR/$tdir
2752         $LFS setstripe -o 0 -o 2 $DIR/$tdir || error "setstripe failed"
2753         touch $DIR/$tdir/$tfile
2754         $LFS getstripe -c $DIR/$tdir/$tfile
2755         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
2756                 error "two-stripe file doesn't have two stripes"
2757
2758         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
2759         $LFS getstripe -y $DIR/$tdir/$tfile
2760         (( $($LFS getstripe -y $DIR/$tdir/$tfile |
2761              egrep -c "l_ost_idx: [02]$") == "2" )) ||
2762                 error "expected l_ost_idx: [02]$ not matched"
2763
2764         # make sure ost list has been cleared
2765         local stripesize=$($LFS getstripe -S $DIR/$tdir)
2766         $LFS setstripe -S $((stripesize * 4)) -i 1 \
2767                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
2768         touch $DIR/$tdir/f3
2769         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
2770 }
2771 run_test 27H "Set specific OSTs stripe"
2772
2773 test_27I() {
2774         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2775         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2776         [[ $MDS1_VERSION -gt $(version_code 2.12.52) ]] ||
2777                 skip "Need MDS version newer than 2.12.52"
2778         local pool=$TESTNAME
2779         local ostrange="1 1 1"
2780
2781         save_layout_restore_at_exit $MOUNT
2782         $LFS setstripe -c 2 -i 0 $MOUNT
2783         pool_add $pool || error "pool_add failed"
2784         pool_add_targets $pool $ostrange ||
2785                 error "pool_add_targets failed"
2786         test_mkdir $DIR/$tdir
2787         $LFS setstripe -p $pool $DIR/$tdir
2788         $MULTIOP $DIR/$tdir/$tfile Oc || error "multiop failed"
2789         $LFS getstripe $DIR/$tdir/$tfile
2790 }
2791 run_test 27I "check that root dir striping does not break parent dir one"
2792
2793 test_27J() {
2794         [[ $MDS1_VERSION -le $(version_code 2.12.51) ]] &&
2795                 skip "Need MDS version newer than 2.12.51"
2796
2797         test_mkdir $DIR/$tdir
2798         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2799         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2800
2801         # create foreign file (raw way)
2802         ! $LFS setstripe --flags 0xda08 $DIR/$tdir/$tfile ||
2803                 error "creating $tfile w/ hex flags w/o --foreign should fail"
2804
2805         ! $LFS setstripe --foreign --flags foo \
2806                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tfile ||
2807                         error "creating $tfile with '--flags foo' should fail"
2808
2809         ! $LFS setstripe --foreign --flags 0xffffffff \
2810                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tfile ||
2811                         error "creating $tfile w/ 0xffffffff flags should fail"
2812
2813         create_foreign_file -f $DIR/$tdir/$tfile -x "${uuid1}@${uuid2}" \
2814                 -t 1 -F 0xda08 || error "create_foreign_file failed"
2815
2816         # verify foreign file (raw way)
2817         parse_foreign_file -f $DIR/$tdir/$tfile |
2818                 grep "lov_foreign_magic: 0x0BD70BD0" ||
2819                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign magic"
2820         parse_foreign_file -f $DIR/$tdir/$tfile | grep "lov_xattr_size: 89" ||
2821                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2822         parse_foreign_file -f $DIR/$tdir/$tfile |
2823                 grep "lov_foreign_size: 73" ||
2824                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2825         parse_foreign_file -f $DIR/$tdir/$tfile |
2826                 grep "lov_foreign_type: 1" ||
2827                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign type"
2828         parse_foreign_file -f $DIR/$tdir/$tfile |
2829                 grep "lov_foreign_flags: 0x0000DA08" ||
2830                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign flags"
2831         local lov=$(parse_foreign_file -f $DIR/$tdir/$tfile |
2832                 grep "lov_foreign_value: 0x" |
2833                 sed -e 's/lov_foreign_value: 0x//')
2834         local lov2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160)
2835         [[ $lov = ${lov2// /} ]] ||
2836                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign value"
2837
2838         # create foreign file (lfs + API)
2839         $LFS setstripe --foreign=none --flags 0xda08 \
2840                 -x "${uuid1}@${uuid2}" $DIR/$tdir/${tfile}2 ||
2841                 error "$DIR/$tdir/${tfile}2: create failed"
2842
2843         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2844                 grep "lfm_magic:.*0x0BD70BD0" ||
2845                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign magic"
2846         # lfm_length is LOV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2847         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_length:.*73" ||
2848                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign size"
2849         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_type:.*none" ||
2850                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign type"
2851         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2852                 grep "lfm_flags:.*0x0000DA08" ||
2853                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign flags"
2854         $LFS getstripe $DIR/$tdir/${tfile}2 |
2855                 grep "lfm_value:.*${uuid1}@${uuid2}" ||
2856                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign value"
2857
2858         # modify striping should fail
2859         $LFS setstripe -c 2 $DIR/$tdir/$tfile &&
2860                 error "$DIR/$tdir/$tfile: setstripe should fail"
2861         $LFS setstripe -c 2 $DIR/$tdir/${tfile}2 &&
2862                 error "$DIR/$tdir/${tfile}2: setstripe should fail"
2863
2864         # R/W should fail
2865         cat $DIR/$tdir/$tfile && error "$DIR/$tdir/$tfile: read should fail"
2866         cat $DIR/$tdir/${tfile}2 &&
2867                 error "$DIR/$tdir/${tfile}2: read should fail"
2868         cat /etc/passwd > $DIR/$tdir/$tfile &&
2869                 error "$DIR/$tdir/$tfile: write should fail"
2870         cat /etc/passwd > $DIR/$tdir/${tfile}2 &&
2871                 error "$DIR/$tdir/${tfile}2: write should fail"
2872
2873         # chmod should work
2874         chmod 222 $DIR/$tdir/$tfile ||
2875                 error "$DIR/$tdir/$tfile: chmod failed"
2876         chmod 222 $DIR/$tdir/${tfile}2 ||
2877                 error "$DIR/$tdir/${tfile}2: chmod failed"
2878
2879         # chown should work
2880         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tfile ||
2881                 error "$DIR/$tdir/$tfile: chown failed"
2882         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tfile}2 ||
2883                 error "$DIR/$tdir/${tfile}2: chown failed"
2884
2885         # rename should work
2886         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}.new ||
2887                 error "$DIR/$tdir/$tfile: rename of foreign file has failed"
2888         mv $DIR/$tdir/${tfile}2 $DIR/$tdir/${tfile}2.new ||
2889                 error "$DIR/$tdir/${tfile}2: rename of foreign file has failed"
2890
2891         #remove foreign file
2892         rm $DIR/$tdir/${tfile}.new ||
2893                 error "$DIR/$tdir/${tfile}.new: remove of foreign file has failed"
2894         rm $DIR/$tdir/${tfile}2.new ||
2895                 error "$DIR/$tdir/${tfile}2.new: remove of foreign file has failed"
2896 }
2897 run_test 27J "basic ops on file with foreign LOV"
2898
2899 test_27K() {
2900         [[ $MDS1_VERSION -le $(version_code 2.12.49) ]] &&
2901                 skip "Need MDS version newer than 2.12.49"
2902
2903         test_mkdir $DIR/$tdir
2904         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2905         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2906
2907         # create foreign dir (raw way)
2908         ! $LFS setdirstripe --flags 0xda08 $DIR/$tdir/$tdir ||
2909                 error "creating $tdir w/ hex flags w/o --foreign should fail"
2910
2911         ! $LFS setdirstripe --foreign --flags foo \
2912                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tdir ||
2913                         error "creating $tdir with '--flags foo' should fail"
2914
2915         ! $LFS setdirstripe --foreign --flags 0xffffffff \
2916                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tdir ||
2917                         error "creating $tdir w/ 0xffffffff flags should fail"
2918
2919         create_foreign_dir -d $DIR/$tdir/$tdir -x "${uuid1}@${uuid2}" -t 1 ||
2920                 error "create_foreign_dir FAILED"
2921
2922         # verify foreign dir (raw way)
2923         parse_foreign_dir -d $DIR/$tdir/$tdir |
2924                 grep "lmv_foreign_magic:.*0xcd50cd0" ||
2925                 error "$DIR/$tdir/$tfile: invalid LMV EA magic"
2926         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_xattr_size:.*89$" ||
2927                 error "$DIR/$tdir/$tdir: invalid LMV EA size"
2928         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_foreign_type: 1$" ||
2929                 error "$DIR/$tdir/$tdir: invalid LMV EA type"
2930         parse_foreign_dir -d $DIR/$tdir/$tdir |
2931                 grep "lmv_foreign_flags: 55813$" ||
2932                 error "$DIR/$tdir/$tdir: invalid LMV EA flags"
2933         local lmv=$(parse_foreign_dir -d $DIR/$tdir/$tdir |
2934                 grep "lmv_foreign_value: 0x" |
2935                 sed 's/lmv_foreign_value: 0x//')
2936         local lmv2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160 |
2937                 sed 's/ //g')
2938         [[ $lmv == $lmv2 ]] || error "$DIR/$tdir/$tdir: invalid LMV EA value"
2939
2940         # create foreign dir (lfs + API)
2941         $LFS mkdir --foreign=none --xattr="${uuid1}@${uuid2}" --flags=0xda05 \
2942                 $DIR/$tdir/${tdir}2 ||
2943                 error "$DIR/$tdir/${tdir}2: create failed"
2944
2945         $LFS getdirstripe -v $DIR/$tdir/${tdir}2
2946
2947         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2948                 grep "lfm_magic:.*0x0CD50CD0" ||
2949                 error "$DIR/$tdir/${tdir}2: invalid LMV EA magic"
2950         # lfm_length is LMV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2951         # - sizeof(lfm_type) - sizeof(lfm_flags)
2952         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_length:.*73" ||
2953                 error "$DIR/$tdir/${tdir}2: invalid LMV EA size"
2954         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_type:.*none" ||
2955                 error "$DIR/$tdir/${tdir}2: invalid LMV EA type"
2956         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2957                 grep "lfm_flags:.*0x0000DA05" ||
2958                 error "$DIR/$tdir/${tdir}2: invalid LMV EA flags"
2959         $LFS getdirstripe $DIR/$tdir/${tdir}2 |
2960                 grep "lfm_value.*${uuid1}@${uuid2}" ||
2961                 error "$DIR/$tdir/${tdir}2: invalid LMV EA value"
2962
2963         # file create in dir should fail
2964         touch $DIR/$tdir/$tdir/$tfile && error "$DIR/$tdir: file create should fail"
2965         touch $DIR/$tdir/${tdir}2/$tfile &&
2966                 error "$DIR/${tdir}2: file create should fail"
2967
2968         # chmod should work
2969         chmod 777 $DIR/$tdir/$tdir ||
2970                 error "$DIR/$tdir: chmod failed"
2971         chmod 777 $DIR/$tdir/${tdir}2 ||
2972                 error "$DIR/${tdir}2: chmod failed"
2973
2974         # chown should work
2975         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tdir ||
2976                 error "$DIR/$tdir: chown failed"
2977         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tdir}2 ||
2978                 error "$DIR/${tdir}2: chown failed"
2979
2980         # rename should work
2981         mv $DIR/$tdir/$tdir $DIR/$tdir/${tdir}.new ||
2982                 error "$DIR/$tdir/$tdir: rename of foreign dir has failed"
2983         mv $DIR/$tdir/${tdir}2 $DIR/$tdir/${tdir}2.new ||
2984                 error "$DIR/$tdir/${tdir}2: rename of foreign dir has failed"
2985
2986         #remove foreign dir
2987         rmdir $DIR/$tdir/${tdir}.new ||
2988                 error "$DIR/$tdir/${tdir}.new: remove of foreign dir has failed"
2989         rmdir $DIR/$tdir/${tdir}2.new ||
2990                 error "$DIR/$tdir/${tdir}2.new: remove of foreign dir has failed"
2991 }
2992 run_test 27K "basic ops on dir with foreign LMV"
2993
2994 test_27L() {
2995         remote_mds_nodsh && skip "remote MDS with nodsh"
2996
2997         local POOL=${POOL:-$TESTNAME}
2998
2999         pool_add $POOL || error "pool_add failed"
3000
3001         lfs pool_list $MOUNT | grep -Fx "${FSNAME}.${POOL}" ||
3002                  error "pool_list does not contain ${FSNAME}.${POOL}:" \
3003                        "$(lfs pool_list $MOUNT | grep -F "${POOL}")"
3004 }
3005 run_test 27L "lfs pool_list gives correct pool name"
3006
3007 test_27M() {
3008         [[ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.12.57) ]] &&
3009                 skip "Need MDS version >= than 2.12.57"
3010         remote_mds_nodsh && skip "remote MDS with nodsh"
3011         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
3012
3013         # Set default striping on directory
3014         local setcount=4
3015         local stripe_opt
3016         local mdts=$(comma_list $(mdts_nodes))
3017
3018         # if we run against a 2.12 server which lacks overstring support
3019         # then the connect_flag will not report overstriping, even if client
3020         # is 2.14+
3021         if [[ $($LCTL get_param mdc.*.connect_flags) =~ overstriping ]]; then
3022                 stripe_opt="-C $setcount"
3023         elif (( $OSTCOUNT >= $setcount )); then
3024                 stripe_opt="-c $setcount"
3025         else
3026                 skip "server does not support overstriping"
3027         fi
3028
3029         test_mkdir $DIR/$tdir
3030
3031         # Validate existing append_* params and ensure restore
3032         local pool=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_pool)
3033         [[ "$pool" == "" ]] || error "expected append_pool == '', got '$pool'"
3034         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_pool=none"
3035
3036         local orig_count=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_stripe_count)
3037         ((orig_count == 1)) || error "expected append_stripe_count == 1, got $orig_count"
3038         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=1"
3039
3040         $LFS setstripe $stripe_opt $DIR/$tdir
3041
3042         echo 1 > $DIR/$tdir/${tfile}.1
3043         local count=$($LFS getstripe -c $DIR/$tdir/${tfile}.1)
3044         [ $count -eq $setcount ] ||
3045                 error "(1) stripe count $count, should be $setcount"
3046
3047         local appendcount=$orig_count
3048         echo 1 >> $DIR/$tdir/${tfile}.2_append
3049         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.2_append)
3050         [ $count -eq $appendcount ] ||
3051                 error "(2)stripe count $count, should be $appendcount for append"
3052
3053         # Disable O_APPEND striping, verify it works
3054         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
3055
3056         # Should now get the default striping, which is 4
3057         setcount=4
3058         echo 1 >> $DIR/$tdir/${tfile}.3_append
3059         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.3_append)
3060         [ $count -eq $setcount ] ||
3061                 error "(3) stripe count $count, should be $setcount"
3062
3063         # Try changing the stripe count for append files
3064         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=2
3065
3066         # Append striping is now 2 (directory default is still 4)
3067         appendcount=2
3068         echo 1 >> $DIR/$tdir/${tfile}.4_append
3069         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.4_append)
3070         [ $count -eq $appendcount ] ||
3071                 error "(4) stripe count $count, should be $appendcount for append"
3072
3073         # Test append stripe count of -1
3074         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=-1
3075         appendcount=$OSTCOUNT
3076         echo 1 >> $DIR/$tdir/${tfile}.5
3077         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.5)
3078         [ $count -eq $appendcount ] ||
3079                 error "(5) stripe count $count, should be $appendcount for append"
3080
3081         # Set append striping back to default of 1
3082         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=1
3083
3084         # Try a new default striping, PFL + DOM
3085         $LFS setstripe -L mdt -E 1M -E -1 -c 2 $DIR/$tdir
3086
3087         # Create normal DOM file, DOM returns stripe count == 0
3088         setcount=0
3089         touch $DIR/$tdir/${tfile}.6
3090         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.6)
3091         [ $count -eq $setcount ] ||
3092                 error "(6) stripe count $count, should be $setcount"
3093
3094         # Show
3095         appendcount=1
3096         echo 1 >> $DIR/$tdir/${tfile}.7_append
3097         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.7_append)
3098         [ $count -eq $appendcount ] ||
3099                 error "(7) stripe count $count, should be $appendcount for append"
3100
3101         # Clean up DOM layout
3102         $LFS setstripe -d $DIR/$tdir
3103
3104         save_layout_restore_at_exit $MOUNT
3105         # Now test that append striping works when layout is from root
3106         $LFS setstripe -c 2 $MOUNT
3107         # Make a special directory for this
3108         mkdir $DIR/${tdir}/${tdir}.2
3109
3110         # Verify for normal file
3111         setcount=2
3112         echo 1 > $DIR/${tdir}/${tdir}.2/${tfile}.8
3113         count=$($LFS getstripe -c $DIR/$tdir/${tdir}.2/${tfile}.8)
3114         [ $count -eq $setcount ] ||
3115                 error "(8) stripe count $count, should be $setcount"
3116
3117         appendcount=1
3118         echo 1 >> $DIR/${tdir}/${tdir}.2/${tfile}.9_append
3119         count=$($LFS getstripe -c $DIR/${tdir}/${tdir}.2/${tfile}.9_append)
3120         [ $count -eq $appendcount ] ||
3121                 error "(9) stripe count $count, should be $appendcount for append"
3122
3123         # Now test O_APPEND striping with pools
3124         pool_add $TESTNAME || error "pool creation failed"
3125         pool_add_targets $TESTNAME 0 1 || error "Pool add targets failed"
3126         do_nodes $mdts $LCTL set_param mdd.*.append_pool="$TESTNAME"
3127
3128         echo 1 >> $DIR/$tdir/${tfile}.10_append
3129
3130         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.10_append)
3131         [ "$pool" = "$TESTNAME" ] || error "(10) incorrect pool: $pool"
3132
3133         # Check that count is still correct
3134         appendcount=1
3135         echo 1 >> $DIR/$tdir/${tfile}.11_append
3136         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.11_append)
3137         [ $count -eq $appendcount ] ||
3138                 error "(11) stripe count $count, should be $appendcount for append"
3139
3140         # Disable O_APPEND stripe count, verify pool works separately
3141         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
3142
3143         echo 1 >> $DIR/$tdir/${tfile}.12_append
3144
3145         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.12_append)
3146         [ "$pool" = "$TESTNAME" ] || error "(12) incorrect pool: $pool"
3147
3148         # Remove pool setting, verify it's not applied
3149         do_nodes $mdts $LCTL set_param mdd.*.append_pool='none'
3150
3151         echo 1 >> $DIR/$tdir/${tfile}.13_append
3152
3153         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.13_append)
3154         [ "$pool" = "" ] || error "(13) pool found: $pool"
3155 }
3156 run_test 27M "test O_APPEND striping"
3157
3158 test_27N() {
3159         combined_mgs_mds && skip "needs separate MGS/MDT"
3160
3161         pool_add $TESTNAME || error "pool_add failed"
3162         do_facet mgs "$LCTL pool_list $FSNAME" |
3163                 grep -Fx "${FSNAME}.${TESTNAME}" ||
3164                 error "lctl pool_list on MGS failed"
3165 }
3166 run_test 27N "lctl pool_list on separate MGS gives correct pool name"
3167
3168 clean_foreign_symlink() {
3169         trap 0
3170         lctl set_param llite/$FSNAME-*/foreign_symlink_enable=0
3171         for i in $DIR/$tdir/* ; do
3172                 $LFS unlink_foreign $i || true
3173         done
3174 }
3175
3176 test_27O() {
3177         [[ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.12.51) ]] &&
3178                 skip "Need MDS version newer than 2.12.51"
3179
3180         test_mkdir $DIR/$tdir
3181         local uuid1=$(cat /proc/sys/kernel/random/uuid)
3182         local uuid2=$(cat /proc/sys/kernel/random/uuid)
3183
3184         trap clean_foreign_symlink EXIT
3185
3186         # enable foreign_symlink behaviour
3187         $LCTL set_param llite/$FSNAME-*/foreign_symlink_enable=1
3188
3189         # foreign symlink LOV format is a partial path by default
3190
3191         # create foreign file (lfs + API)
3192         $LFS setstripe --foreign=symlink --flags 0xda05 \
3193                 -x "${uuid1}/${uuid2}" --mode 0600 $DIR/$tdir/${tfile} ||
3194                 error "$DIR/$tdir/${tfile}: create failed"
3195
3196         $LFS getstripe -v $DIR/$tdir/${tfile} |
3197                 grep "lfm_magic:.*0x0BD70BD0" ||
3198                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign magic"
3199         $LFS getstripe -v $DIR/$tdir/${tfile} | grep "lfm_type:.*symlink" ||
3200                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign type"
3201         $LFS getstripe -v $DIR/$tdir/${tfile} |
3202                 grep "lfm_flags:.*0x0000DA05" ||
3203                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign flags"
3204         $LFS getstripe $DIR/$tdir/${tfile} |
3205                 grep "lfm_value:.*${uuid1}/${uuid2}" ||
3206                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign value"
3207
3208         # modify striping should fail
3209         $LFS setstripe -c 2 $DIR/$tdir/$tfile &&
3210                 error "$DIR/$tdir/$tfile: setstripe should fail"
3211
3212         # R/W should fail ("/{foreign_symlink_prefix}/${uuid1}/" missing)
3213         cat $DIR/$tdir/$tfile && error "$DIR/$tdir/$tfile: read should fail"
3214         cat /etc/passwd > $DIR/$tdir/$tfile &&
3215                 error "$DIR/$tdir/$tfile: write should fail"
3216
3217         # rename should succeed
3218         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}.new ||
3219                 error "$DIR/$tdir/$tfile: rename has failed"
3220
3221         #remove foreign_symlink file should fail
3222         rm $DIR/$tdir/${tfile}.new &&
3223                 error "$DIR/$tdir/${tfile}.new: remove of foreign_symlink file should fail"
3224
3225         #test fake symlink
3226         mkdir /tmp/${uuid1} ||
3227                 error "/tmp/${uuid1}: mkdir has failed"
3228         echo FOOFOO > /tmp/${uuid1}/${uuid2} ||
3229                 error "/tmp/${uuid1}/${uuid2}: echo has failed"
3230         $LCTL set_param llite/$FSNAME-*/foreign_symlink_prefix=/tmp/
3231         $CHECKSTAT -t link -l /tmp/${uuid1}/${uuid2} $DIR/$tdir/${tfile}.new ||
3232                 error "$DIR/$tdir/${tfile}.new: not seen as a symlink"
3233         #read should succeed now
3234         cat $DIR/$tdir/${tfile}.new | grep FOOFOO ||
3235                 error "$DIR/$tdir/${tfile}.new: symlink resolution has failed"
3236         #write should succeed now
3237         cat /etc/passwd > $DIR/$tdir/${tfile}.new ||
3238                 error "$DIR/$tdir/${tfile}.new: write should succeed"
3239         diff /etc/passwd $DIR/$tdir/${tfile}.new ||
3240                 error "$DIR/$tdir/${tfile}.new: diff has failed"
3241         diff /etc/passwd /tmp/${uuid1}/${uuid2} ||
3242                 error "/tmp/${uuid1}/${uuid2}: diff has failed"
3243
3244         #check that getstripe still works
3245         $LFS getstripe $DIR/$tdir/${tfile}.new ||
3246                 error "$DIR/$tdir/${tfile}.new: getstripe should still work with foreign_symlink enabled"
3247
3248         # chmod should still succeed
3249         chmod 644 $DIR/$tdir/${tfile}.new ||
3250                 error "$DIR/$tdir/${tfile}.new: chmod has failed"
3251
3252         # chown should still succeed
3253         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tfile}.new ||
3254                 error "$DIR/$tdir/${tfile}.new: chown has failed"
3255
3256         # rename should still succeed
3257         mv $DIR/$tdir/${tfile}.new $DIR/$tdir/${tfile} ||
3258                 error "$DIR/$tdir/${tfile}.new: rename has failed"
3259
3260         #remove foreign_symlink file should still fail
3261         rm $DIR/$tdir/${tfile} &&
3262                 error "$DIR/$tdir/${tfile}: remove of foreign_symlink file should fail"
3263
3264         #use special ioctl() to unlink foreign_symlink file
3265         $LFS unlink_foreign $DIR/$tdir/${tfile} ||
3266                 error "$DIR/$tdir/$tfile: unlink/ioctl failed"
3267
3268 }
3269 run_test 27O "basic ops on foreign file of symlink type"
3270
3271 test_27P() {
3272         [[ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.12.49) ]] &&
3273                 skip "Need MDS version newer than 2.12.49"
3274
3275         test_mkdir $DIR/$tdir
3276         local uuid1=$(cat /proc/sys/kernel/random/uuid)
3277         local uuid2=$(cat /proc/sys/kernel/random/uuid)
3278
3279         trap clean_foreign_symlink EXIT
3280
3281         # enable foreign_symlink behaviour
3282         $LCTL set_param llite/$FSNAME-*/foreign_symlink_enable=1
3283
3284         # foreign symlink LMV format is a partial path by default
3285
3286         # create foreign dir (lfs + API)
3287         $LFS mkdir --foreign=symlink --xattr="${uuid1}/${uuid2}" \
3288                 --flags=0xda05 --mode 0750 $DIR/$tdir/${tdir} ||
3289                 error "$DIR/$tdir/${tdir}: create failed"
3290
3291         $LFS getdirstripe -v $DIR/$tdir/${tdir}
3292
3293         $LFS getdirstripe -v $DIR/$tdir/${tdir} |
3294                 grep "lfm_magic:.*0x0CD50CD0" ||
3295                 error "$DIR/$tdir/${tdir}: invalid LMV EA magic"
3296         $LFS getdirstripe -v $DIR/$tdir/${tdir} | grep "lfm_type:.*symlink" ||
3297                 error "$DIR/$tdir/${tdir}: invalid LMV EA type"
3298         $LFS getdirstripe -v $DIR/$tdir/${tdir} |
3299                 grep "lfm_flags:.*0x0000DA05" ||
3300                 error "$DIR/$tdir/${tdir}: invalid LMV EA flags"
3301         $LFS getdirstripe $DIR/$tdir/${tdir} |
3302                 grep "lfm_value.*${uuid1}/${uuid2}" ||
3303                 error "$DIR/$tdir/${tdir}: invalid LMV EA value"
3304
3305         # file create in dir should fail
3306         # ("/{foreign_symlink_prefix}/${uuid1}/${uuid2}/" missing)
3307         touch $DIR/$tdir/$tdir/$tfile && error "$DIR/$tdir: file create should fail"
3308
3309         # rename should succeed
3310         mv $DIR/$tdir/$tdir $DIR/$tdir/${tdir}.new ||
3311                 error "$DIR/$tdir/$tdir: rename of foreign_symlink dir has failed"
3312
3313         #remove foreign_symlink dir should fail
3314         rmdir $DIR/$tdir/${tdir}.new &&
3315                 error "$DIR/$tdir/${tdir}.new: remove of foreign_symlink dir should fail"
3316
3317         #test fake symlink
3318         mkdir -p /tmp/${uuid1}/${uuid2} ||
3319                 error "/tmp/${uuid1}/${uuid2}: mkdir has failed"
3320         echo FOOFOO > /tmp/${uuid1}/${uuid2}/foo ||
3321                 error "/tmp/${uuid1}/${uuid2}/foo: echo has failed"
3322         $LCTL set_param llite/$FSNAME-*/foreign_symlink_prefix=/tmp/
3323         $CHECKSTAT -t link -l /tmp/${uuid1}/${uuid2} $DIR/$tdir/${tdir}.new ||
3324                 error "$DIR/$tdir/${tdir}.new: not seen as a symlink"
3325         cat $DIR/$tdir/${tdir}.new/foo | grep FOOFOO ||
3326                 error "$DIR/$tdir/${tdir}.new: symlink resolution has failed"
3327
3328         #check that getstripe fails now that foreign_symlink enabled
3329         $LFS getdirstripe $DIR/$tdir/${tdir}.new ||
3330                 error "$DIR/$tdir/${tdir}.new: getdirstripe should still work with foreign_symlink enabled"
3331
3332         # file create in dir should work now
3333         cp /etc/passwd $DIR/$tdir/${tdir}.new/$tfile ||
3334                 error "$DIR/$tdir/${tdir}.new/$tfile: file create should fail"
3335         diff /etc/passwd $DIR/$tdir/${tdir}.new/$tfile ||
3336                 error "$DIR/$tdir/${tdir}.new/$tfile: diff has failed"
3337         diff /etc/passwd /tmp/${uuid1}/${uuid2}/$tfile ||
3338                 error "/tmp/${uuid1}/${uuid2}/$tfile: diff has failed"
3339
3340         # chmod should still succeed
3341         chmod 755 $DIR/$tdir/${tdir}.new ||
3342                 error "$DIR/$tdir/${tdir}.new: chmod has failed"
3343
3344         # chown should still succeed
3345         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tdir}.new ||
3346                 error "$DIR/$tdir/${tdir}.new: chown has failed"
3347
3348         # rename should still succeed
3349         mv $DIR/$tdir/${tdir}.new $DIR/$tdir/${tdir} ||
3350                 error "$DIR/$tdir/${tdir}.new: rename of foreign_symlink dir has failed"
3351
3352         #remove foreign_symlink dir should still fail
3353         rmdir $DIR/$tdir/${tdir} &&
3354                 error "$DIR/$tdir/${tdir}: remove of foreign_symlink dir should fail"
3355
3356         #use special ioctl() to unlink foreign_symlink file
3357         $LFS unlink_foreign $DIR/$tdir/${tdir} ||
3358                 error "$DIR/$tdir/$tdir: unlink/ioctl failed"
3359
3360         #created file should still exist
3361         [[ -f /tmp/${uuid1}/${uuid2}/$tfile ]] ||
3362                 error "/tmp/${uuid1}/${uuid2}/$tfile has been removed"
3363         diff /etc/passwd /tmp/${uuid1}/${uuid2}/$tfile ||
3364                 error "/tmp/${uuid1}/${uuid2}/$tfile: diff has failed"
3365 }
3366 run_test 27P "basic ops on foreign dir of foreign_symlink type"
3367
3368 test_27Q() {
3369         rm -f $TMP/$tfile $TMP/$tfile.loop $TMP/$tfile.none $TMP/$tfile.broken
3370         stack_trap "rm -f $TMP/$tfile*"
3371
3372         test_mkdir $DIR/$tdir-1
3373         test_mkdir $DIR/$tdir-2
3374
3375         echo 'It is what it is' > $DIR/$tdir-1/$tfile
3376         lov_getstripe_old $DIR/$tdir-1/$tfile || error "$DIR/$tdir-1/$tfile: rc = $?"
3377
3378         ln -s $DIR/$tdir-1/$tfile $DIR/$tdir-2/$tfile
3379         lov_getstripe_old $DIR/$tdir-2/$tfile || error "$DIR/$tdir-2/$tfile: rc = $?"
3380
3381         ln -s $DIR/$tdir-1/$tfile $TMP/$tfile
3382         lov_getstripe_old $TMP/$tfile || error "$TMP/$tfile: rc = $?"
3383
3384         # Create some bad symlinks and ensure that we don't loop
3385         # forever or something. These should return ELOOP (40) and
3386         # ENOENT (2) but I don't want to test for that because there's
3387         # always some weirdo architecture that needs to ruin
3388         # everything by defining these error numbers differently.
3389
3390         ln -s $TMP/$tfile.loop $TMP/$tfile.loop
3391         lov_getstripe_old $TMP/$tfile.loop && error "$TMP/$tfile.loop: rc = $?"
3392
3393         ln -s $TMP/$tfile.none $TMP/$tfile.broken
3394         lov_getstripe_old $TMP/$tfile.broken && error "$TMP/$tfile.broken: rc = $?"
3395
3396         return 0
3397 }
3398 run_test 27Q "llapi_file_get_stripe() works on symlinks"
3399
3400 test_27R() {
3401         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
3402                 skip "need MDS 2.14.55 or later"
3403         (( $OSTCOUNT >= 2 )) || skip_env "needs at least 2 OSTs"
3404
3405         local testdir="$DIR/$tdir"
3406         test_mkdir -p $testdir
3407         stack_trap "rm -rf $testdir"
3408         $LFS setstripe -c -1 $testdir || error "setstripe failed"
3409
3410         local f1="$testdir/f1"
3411         touch $f1 || error "failed to touch $f1"
3412         local count=$($LFS getstripe -c $f1)
3413         (( $count == $OSTCOUNT )) || error "wrong stripe count"
3414
3415         do_facet $SINGLEMDS $LCTL set_param lod.*.max_stripecount=-1
3416         (( $? == 34 )) || error "setting max_stripecount to -1 should fail and return ERANGE"
3417
3418         local maxcount=$(($OSTCOUNT - 1))
3419         local mdts=$(comma_list $(mdts_nodes))
3420         do_nodes $mdts $LCTL set_param lod.*.max_stripecount=$maxcount
3421         stack_trap "do_nodes $mdts $LCTL set_param lod.*.max_stripecount=0"
3422
3423         local f2="$testdir/f2"
3424         touch $f2 || error "failed to touch $f2"
3425         local count=$($LFS getstripe -c $f2)
3426         (( $count == $maxcount )) || error "wrong stripe count"
3427 }
3428 run_test 27R "test max_stripecount limitation when stripe count is set to -1"
3429
3430 test_27T() {
3431         [ $(facet_host client) == $(facet_host ost1) ] &&
3432                 skip "need ost1 and client on different nodes"
3433
3434 #define OBD_FAIL_OSC_NO_GRANT            0x411
3435         $LCTL set_param fail_loc=0x20000411 fail_val=1
3436 #define OBD_FAIL_OST_ENOSPC              0x215
3437         do_facet ost1 "$LCTL set_param fail_loc=0x80000215"
3438         $LFS setstripe -i 0 -c 1 $DIR/$tfile
3439         $MULTIOP $DIR/$tfile oO_WRONLY:P$((4 * 1024 * 1024 + 10 * 4096))c ||
3440                 error "multiop failed"
3441 }
3442 run_test 27T "no eio on close on partial write due to enosp"
3443
3444 test_27U() {
3445         local dir=$DIR/$tdir
3446         local file=$dir/$tfile
3447         local append_pool=${TESTNAME}-append
3448         local normal_pool=${TESTNAME}-normal
3449         local pool
3450         local stripe_count
3451         local stripe_count2
3452         local mdts=$(comma_list $(mdts_nodes))
3453
3454         (( $MDS1_VERSION >= $(version_code 2.15.51) )) ||
3455                 skip "Need MDS version at least 2.15.51 for append pool feature"
3456
3457         # Validate existing append_* params and ensure restore
3458         pool=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_pool)
3459         [[ "$pool" == "" ]] || error "expected append_pool == '', got '$pool'"
3460         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_pool=none"
3461
3462         stripe_count=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_stripe_count)
3463         ((stripe_count == 1)) || error "expected append_stripe_count != 0, got $stripe_count"
3464         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=$stripe_count"
3465
3466         pool_add $append_pool || error "pool creation failed"
3467         pool_add_targets $append_pool 0 1 || error "Pool add targets failed"
3468
3469         pool_add $normal_pool || error "pool creation failed"
3470         pool_add_targets $normal_pool 0 1 || error "Pool add targets failed"
3471
3472         test_mkdir $dir
3473         $LFS setstripe -E 1M -c 1 -p $normal_pool -E 2M -c 2 -p $normal_pool -E eof -c -1 $dir
3474
3475         echo XXX >> $file.1
3476         $LFS getstripe $file.1
3477
3478         pool=$($LFS getstripe -p $file.1)
3479         [[ "$pool" == "$normal_pool" ]] || error "got pool '$pool', expected '$normal_pool'"
3480
3481         stripe_count2=$($LFS getstripe -c $file.1)
3482         ((stripe_count2 == stripe_count)) ||
3483                 error "got stripe_count '$stripe_count2', expected '$stripe_count'"
3484
3485         do_nodes $mdts $LCTL set_param mdd.*.append_pool=$append_pool
3486
3487         echo XXX >> $file.2
3488         $LFS getstripe $file.2
3489
3490         pool=$($LFS getstripe -p $file.2)
3491         [[ "$pool" == "$append_pool" ]] || error "got pool '$pool', expected '$append_pool'"
3492
3493         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=2
3494
3495         echo XXX >> $file.3
3496         $LFS getstripe $file.3
3497
3498         stripe_count2=$($LFS getstripe -c $file.3)
3499         ((stripe_count2 == 2)) || error "got stripe_count '$stripe_count2', expected 2"
3500 }
3501 run_test 27U "append pool and stripe count work with composite default layout"
3502
3503 # createtest also checks that device nodes are created and
3504 # then visible correctly (#2091)
3505 test_28() { # bug 2091
3506         test_mkdir $DIR/d28
3507         $CREATETEST $DIR/d28/ct || error "createtest failed"
3508 }
3509 run_test 28 "create/mknod/mkdir with bad file types ============"
3510
3511 test_29() {
3512         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3513
3514         [ $MDS1_VERSION -ge $(version_code 2.14.51) ] && {
3515                 disable_opencache
3516                 stack_trap "restore_opencache"
3517         }
3518
3519         sync; sleep 1; sync # flush out any dirty pages from previous tests
3520         cancel_lru_locks
3521         test_mkdir $DIR/d29
3522         touch $DIR/d29/foo
3523         log 'first d29'
3524         ls -l $DIR/d29
3525
3526         declare -i LOCKCOUNTORIG=0
3527         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
3528                 let LOCKCOUNTORIG=$LOCKCOUNTORIG+$lock_count
3529         done
3530         [ $LOCKCOUNTORIG -eq 0 ] && error "No mdc lock count" && return 1
3531
3532         declare -i LOCKUNUSEDCOUNTORIG=0
3533         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3534                 let LOCKUNUSEDCOUNTORIG=$LOCKUNUSEDCOUNTORIG+$unused_count
3535         done
3536
3537         log 'second d29'
3538         ls -l $DIR/d29
3539         log 'done'
3540
3541         declare -i LOCKCOUNTCURRENT=0
3542         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
3543                 let LOCKCOUNTCURRENT=$LOCKCOUNTCURRENT+$lock_count
3544         done
3545
3546         declare -i LOCKUNUSEDCOUNTCURRENT=0
3547         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3548                 let LOCKUNUSEDCOUNTCURRENT=$LOCKUNUSEDCOUNTCURRENT+$unused_count
3549         done
3550
3551         if [[ $LOCKCOUNTCURRENT -gt $LOCKCOUNTORIG ]]; then
3552                 $LCTL set_param -n ldlm.dump_namespaces ""
3553                 error "CURRENT: $LOCKCOUNTCURRENT > $LOCKCOUNTORIG"
3554                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3555                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3556                 return 2
3557         fi
3558         if [[ $LOCKUNUSEDCOUNTCURRENT -gt $LOCKUNUSEDCOUNTORIG ]]; then
3559                 error "UNUSED: $LOCKUNUSEDCOUNTCURRENT > $LOCKUNUSEDCOUNTORIG"
3560                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3561                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3562                 return 3
3563         fi
3564 }
3565 run_test 29 "IT_GETATTR regression  ============================"
3566
3567 test_30a() { # was test_30
3568         cp $(which ls) $DIR || cp /bin/ls $DIR
3569         $DIR/ls / || error "Can't execute binary from lustre"
3570         rm $DIR/ls
3571 }
3572 run_test 30a "execute binary from Lustre (execve) =============="
3573
3574 test_30b() {
3575         cp `which ls` $DIR || cp /bin/ls $DIR
3576         chmod go+rx $DIR/ls
3577         $RUNAS $DIR/ls / || error "Can't execute binary from lustre as non-root"
3578         rm $DIR/ls
3579 }
3580 run_test 30b "execute binary from Lustre as non-root ==========="
3581
3582 test_30c() { # b=22376
3583         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3584
3585         cp $(which ls) $DIR || cp /bin/ls $DIR
3586         chmod a-rw $DIR/ls
3587         cancel_lru_locks mdc
3588         cancel_lru_locks osc
3589         $RUNAS $DIR/ls / || error "Can't execute binary from lustre"
3590         rm -f $DIR/ls
3591 }
3592 run_test 30c "execute binary from Lustre without read perms ===="
3593
3594 test_30d() {
3595         cp $(which dd) $DIR || error "failed to copy dd to $DIR/dd"
3596
3597         for i in {1..10}; do
3598                 $DIR/dd bs=1M count=128 if=/dev/zero of=$DIR/$tfile &
3599                 local PID=$!
3600                 sleep 1
3601                 $LCTL set_param ldlm.namespaces.*MDT*.lru_size=clear
3602                 wait $PID || error "executing dd from Lustre failed"
3603                 rm -f $DIR/$tfile
3604         done
3605
3606         rm -f $DIR/dd
3607 }
3608 run_test 30d "execute binary from Lustre while clear locks"
3609
3610 test_31a() {
3611         $OPENUNLINK $DIR/f31 $DIR/f31 || error "openunlink failed"
3612         $CHECKSTAT -a $DIR/f31 || error "$DIR/f31 exists"
3613 }
3614 run_test 31a "open-unlink file =================================="
3615
3616 test_31b() {
3617         touch $DIR/f31 || error "touch $DIR/f31 failed"
3618         ln $DIR/f31 $DIR/f31b || error "ln failed"
3619         $MULTIOP $DIR/f31b Ouc || error "multiop failed"
3620         $CHECKSTAT -t file $DIR/f31 || error "$DIR/f31 not file type"
3621 }
3622 run_test 31b "unlink file with multiple links while open ======="
3623
3624 test_31c() {
3625         touch $DIR/f31 || error "touch $DIR/f31 failed"
3626         ln $DIR/f31 $DIR/f31c || error "ln failed"
3627         multiop_bg_pause $DIR/f31 O_uc ||
3628                 error "multiop_bg_pause for $DIR/f31 failed"
3629         MULTIPID=$!
3630         $MULTIOP $DIR/f31c Ouc
3631         kill -USR1 $MULTIPID
3632         wait $MULTIPID
3633 }
3634 run_test 31c "open-unlink file with multiple links ============="
3635
3636 test_31d() {
3637         opendirunlink $DIR/d31d $DIR/d31d || error "opendirunlink failed"
3638         $CHECKSTAT -a $DIR/d31d || error "$DIR/d31d exists"
3639 }
3640 run_test 31d "remove of open directory ========================="
3641
3642 test_31e() { # bug 2904
3643         openfilleddirunlink $DIR/d31e || error "openfilleddirunlink failed"
3644 }
3645 run_test 31e "remove of open non-empty directory ==============="
3646
3647 test_31f() { # bug 4554
3648         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3649
3650         set -vx
3651         test_mkdir $DIR/d31f
3652         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3653         cp /etc/hosts $DIR/d31f
3654         ls -l $DIR/d31f
3655         $LFS getstripe $DIR/d31f/hosts
3656         multiop_bg_pause $DIR/d31f D_c || return 1
3657         MULTIPID=$!
3658
3659         rm -rv $DIR/d31f || error "first of $DIR/d31f"
3660         test_mkdir $DIR/d31f
3661         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3662         cp /etc/hosts $DIR/d31f
3663         ls -l $DIR/d31f
3664         $LFS getstripe $DIR/d31f/hosts
3665         multiop_bg_pause $DIR/d31f D_c || return 1
3666         MULTIPID2=$!
3667
3668         kill -USR1 $MULTIPID || error "first opendir $MULTIPID not running"
3669         wait $MULTIPID || error "first opendir $MULTIPID failed"
3670
3671         sleep 6
3672
3673         kill -USR1 $MULTIPID2 || error "second opendir $MULTIPID not running"
3674         wait $MULTIPID2 || error "second opendir $MULTIPID2 failed"
3675         set +vx
3676 }
3677 run_test 31f "remove of open directory with open-unlink file ==="
3678
3679 test_31g() {
3680         echo "-- cross directory link --"
3681         test_mkdir -c1 $DIR/${tdir}ga
3682         test_mkdir -c1 $DIR/${tdir}gb
3683         touch $DIR/${tdir}ga/f
3684         ln $DIR/${tdir}ga/f $DIR/${tdir}gb/g
3685         $CHECKSTAT -t file $DIR/${tdir}ga/f || error "source"
3686         [ `stat -c%h $DIR/${tdir}ga/f` == '2' ] || error "source nlink"
3687         $CHECKSTAT -t file $DIR/${tdir}gb/g || error "target"
3688         [ `stat -c%h $DIR/${tdir}gb/g` == '2' ] || error "target nlink"
3689 }
3690 run_test 31g "cross directory link==============="
3691
3692 test_31h() {
3693         echo "-- cross directory link --"
3694         test_mkdir -c1 $DIR/${tdir}
3695         test_mkdir -c1 $DIR/${tdir}/dir
3696         touch $DIR/${tdir}/f
3697         ln $DIR/${tdir}/f $DIR/${tdir}/dir/g
3698         $CHECKSTAT -t file $DIR/${tdir}/f || error "source"
3699         [ `stat -c%h $DIR/${tdir}/f` == '2' ] || error "source nlink"
3700         $CHECKSTAT -t file $DIR/${tdir}/dir/g || error "target"
3701         [ `stat -c%h $DIR/${tdir}/dir/g` == '2' ] || error "target nlink"
3702 }
3703 run_test 31h "cross directory link under child==============="
3704
3705 test_31i() {
3706         echo "-- cross directory link --"
3707         test_mkdir -c1 $DIR/$tdir
3708         test_mkdir -c1 $DIR/$tdir/dir
3709         touch $DIR/$tdir/dir/f
3710         ln $DIR/$tdir/dir/f $DIR/$tdir/g
3711         $CHECKSTAT -t file $DIR/$tdir/dir/f || error "source"
3712         [ `stat -c%h $DIR/$tdir/dir/f` == '2' ] || error "source nlink"
3713         $CHECKSTAT -t file $DIR/$tdir/g || error "target"
3714         [ `stat -c%h $DIR/$tdir/g` == '2' ] || error "target nlink"
3715 }
3716 run_test 31i "cross directory link under parent==============="
3717
3718 test_31j() {
3719         test_mkdir -c1 -p $DIR/$tdir
3720         test_mkdir -c1 -p $DIR/$tdir/dir1
3721         ln $DIR/$tdir/dir1 $DIR/$tdir/dir2 && error "ln for dir"
3722         link $DIR/$tdir/dir1 $DIR/$tdir/dir3 && error "link for dir"
3723         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir4 && error "mlink for dir"
3724         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir1 && error "mlink to the same dir"
3725         return 0
3726 }
3727 run_test 31j "link for directory==============="
3728
3729 test_31k() {
3730         test_mkdir -c1 -p $DIR/$tdir
3731         touch $DIR/$tdir/s
3732         touch $DIR/$tdir/exist
3733         mlink $DIR/$tdir/s $DIR/$tdir/t || error "mlink"
3734         mlink $DIR/$tdir/s $DIR/$tdir/exist && error "mlink to exist file"
3735         mlink $DIR/$tdir/s $DIR/$tdir/s && error "mlink to the same file"
3736         mlink $DIR/$tdir/s $DIR/$tdir && error "mlink to parent dir"
3737         mlink $DIR/$tdir $DIR/$tdir/s && error "mlink parent dir to target"
3738         mlink $DIR/$tdir/not-exist $DIR/$tdir/foo && error "mlink non-existing to new"
3739         mlink $DIR/$tdir/not-exist $DIR/$tdir/s && error "mlink non-existing to exist"
3740         return 0
3741 }
3742 run_test 31k "link to file: the same, non-existing, dir==============="
3743
3744 test_31l() {
3745         local ln_ver=$(ln --version | awk '/coreutils/ { print $4 }')
3746
3747         (( $(version_code $ln_ver) < $(version_code 8.31) )) ||
3748         (( $(version_code $(uname -r)) >= $(version_code 5.18) )) ||
3749                 skip "need coreutils < 8.31 or kernel >= 5.18 for ln"
3750
3751         touch $DIR/$tfile || error "create failed"
3752         mkdir $DIR/$tdir || error "mkdir failed"
3753         ln $DIR/$tfile $DIR/$tdir/ || error "ln to '$tdir/' failed"
3754 }
3755 run_test 31l "link to file: target dir has trailing slash"
3756
3757 test_31m() {
3758         mkdir $DIR/d31m
3759         touch $DIR/d31m/s
3760         mkdir $DIR/d31m2
3761         touch $DIR/d31m2/exist
3762         mlink $DIR/d31m/s $DIR/d31m2/t || error "mlink"
3763         mlink $DIR/d31m/s $DIR/d31m2/exist && error "mlink to exist file"
3764         mlink $DIR/d31m/s $DIR/d31m2 && error "mlink to parent dir"
3765         mlink $DIR/d31m2 $DIR/d31m/s && error "mlink parent dir to target"
3766         mlink $DIR/d31m/not-exist $DIR/d31m2/foo && error "mlink non-existing to new"
3767         mlink $DIR/d31m/not-exist $DIR/d31m2/s && error "mlink non-existing to exist"
3768         return 0
3769 }
3770 run_test 31m "link to file: the same, non-existing, dir==============="
3771
3772 test_31n() {
3773         touch $DIR/$tfile || error "cannot create '$DIR/$tfile'"
3774         nlink=$(stat --format=%h $DIR/$tfile)
3775         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3776         local fd=$(free_fd)
3777         local cmd="exec $fd<$DIR/$tfile"
3778         eval $cmd
3779         cmd="exec $fd<&-"
3780         trap "eval $cmd" EXIT
3781         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3782         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3783         rm $DIR/$tfile || error "cannot remove '$DIR/$tfile'"
3784         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3785         [ ${nlink:--1} -eq 0 ] || error "nlink is $nlink, expected 0"
3786         eval $cmd
3787 }
3788 run_test 31n "check link count of unlinked file"
3789
3790 link_one() {
3791         local tempfile=$(mktemp $1_XXXXXX)
3792         mlink $tempfile $1 2> /dev/null &&
3793                 echo "$BASHPID: link $tempfile to $1 succeeded"
3794         munlink $tempfile
3795 }
3796
3797 test_31o() { # LU-2901
3798         test_mkdir $DIR/$tdir
3799         for LOOP in $(seq 100); do
3800                 rm -f $DIR/$tdir/$tfile*
3801                 for THREAD in $(seq 8); do
3802                         link_one $DIR/$tdir/$tfile.$LOOP &
3803                 done
3804                 wait
3805                 local LINKS=$(ls -1 $DIR/$tdir | grep -c $tfile.$LOOP)
3806                 [[ $LINKS -gt 1 ]] && ls $DIR/$tdir &&
3807                         error "$LINKS duplicate links to $tfile.$LOOP" &&
3808                         break || true
3809         done
3810 }
3811 run_test 31o "duplicate hard links with same filename"
3812
3813 test_31p() {
3814         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3815
3816         test_mkdir $DIR/$tdir
3817         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3818         $LFS setdirstripe -D -c2 -H all_char $DIR/$tdir/striped_dir
3819
3820         opendirunlink $DIR/$tdir/striped_dir/test1 ||
3821                 error "open unlink test1 failed"
3822         opendirunlink $DIR/$tdir/striped_dir/test2 ||
3823                 error "open unlink test2 failed"
3824
3825         $CHECKSTAT -a $DIR/$tdir/striped_dir/test1 ||
3826                 error "test1 still exists"
3827         $CHECKSTAT -a $DIR/$tdir/striped_dir/test2 ||
3828                 error "test2 still exists"
3829 }
3830 run_test 31p "remove of open striped directory"
3831
3832 test_31q() {
3833         [ $MDSCOUNT -lt 3 ] && skip_env "needs >= 3 MDTs"
3834
3835         $LFS mkdir -i 3,1 $DIR/$tdir || error "mkdir failed"
3836         index=$($LFS getdirstripe -i $DIR/$tdir)
3837         [ $index -eq 3 ] || error "first stripe index $index != 3"
3838         index=$($LFS getdirstripe $DIR/$tdir | tail -1 | awk '{print $1}')
3839         [ $index -eq 1 ] || error "second stripe index $index != 1"
3840
3841         # when "-c <stripe_count>" is set, the number of MDTs specified after
3842         # "-i" should equal to the stripe count
3843         $LFS mkdir -i 3,1 -c 3 $DIR/$tdir.2 && error "mkdir should fail" || true
3844 }
3845 run_test 31q "create striped directory on specific MDTs"
3846
3847 #LU-14949
3848 test_31r() {
3849         touch $DIR/$tfile.target
3850         touch $DIR/$tfile.source
3851
3852         #OBD_FAIL_LLITE_OPEN_DELAY 0x1419
3853         $LCTL set_param fail_loc=0x1419 fail_val=3
3854         cat $DIR/$tfile.target &
3855         CATPID=$!
3856
3857         # Guarantee open is waiting before we get here
3858         sleep 1
3859         mv $DIR/$tfile.source $DIR/$tfile.target
3860
3861         wait $CATPID
3862         RC=$?
3863         if [[ $RC -ne 0 ]]; then
3864                 error "open with cat failed, rc=$RC"
3865         fi
3866 }
3867 run_test 31r "open-rename(replace) race"
3868
3869 cleanup_test32_mount() {
3870         local rc=0
3871         trap 0
3872         local loopdev=$(losetup -a | grep $EXT2_DEV | sed -ne 's/:.*$//p')
3873         $UMOUNT $DIR/$tdir/ext2-mountpoint || rc=$?
3874         losetup -d $loopdev || true
3875         rm -rf $DIR/$tdir
3876         return $rc
3877 }
3878
3879 test_32a() {
3880         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3881
3882         echo "== more mountpoints and symlinks ================="
3883         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3884         trap cleanup_test32_mount EXIT
3885         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3886         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3887                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3888         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/.. ||
3889                 error "$DIR/$tdir/ext2-mountpoint/.. not dir type"
3890         cleanup_test32_mount
3891 }
3892 run_test 32a "stat d32a/ext2-mountpoint/.. ====================="
3893
3894 test_32b() {
3895         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3896
3897         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3898         trap cleanup_test32_mount EXIT
3899         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3900         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3901                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3902         ls -al $DIR/$tdir/ext2-mountpoint/.. ||
3903                 error "Can't list $DIR/$tdir/ext2-mountpoint/.."
3904         cleanup_test32_mount
3905 }
3906 run_test 32b "open d32b/ext2-mountpoint/.. ====================="
3907
3908 test_32c() {
3909         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3910
3911         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3912         trap cleanup_test32_mount EXIT
3913         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3914         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3915                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3916         test_mkdir -p $DIR/$tdir/d2/test_dir
3917         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3918                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_dir not dir type"
3919         cleanup_test32_mount
3920 }
3921 run_test 32c "stat d32c/ext2-mountpoint/../d2/test_dir ========="
3922
3923 test_32d() {
3924         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3925
3926         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3927         trap cleanup_test32_mount EXIT
3928         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3929         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3930                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3931         test_mkdir -p $DIR/$tdir/d2/test_dir
3932         ls -al $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3933                 error "Can't list $DIR/$tdir/ext2-mountpoint/../d2/test_dir"
3934         cleanup_test32_mount
3935 }
3936 run_test 32d "open d32d/ext2-mountpoint/../d2/test_dir"
3937
3938 test_32e() {
3939         rm -fr $DIR/$tdir
3940         test_mkdir -p $DIR/$tdir/tmp
3941         local tmp_dir=$DIR/$tdir/tmp
3942         ln -s $DIR/$tdir $tmp_dir/symlink11
3943         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3944         $CHECKSTAT -t link $DIR/$tdir/tmp/symlink11 || error "symlink11 bad"
3945         $CHECKSTAT -t link $DIR/$tdir/symlink01 || error "symlink01 bad"
3946 }
3947 run_test 32e "stat d32e/symlink->tmp/symlink->lustre-subdir"
3948
3949 test_32f() {
3950         rm -fr $DIR/$tdir
3951         test_mkdir -p $DIR/$tdir/tmp
3952         local tmp_dir=$DIR/$tdir/tmp
3953         ln -s $DIR/$tdir $tmp_dir/symlink11
3954         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3955         ls $DIR/$tdir/tmp/symlink11  || error "symlink11 bad"
3956         ls $DIR/$tdir/symlink01 || error "symlink01 bad"
3957 }
3958 run_test 32f "open d32f/symlink->tmp/symlink->lustre-subdir"
3959
3960 test_32g() {
3961         local tmp_dir=$DIR/$tdir/tmp
3962         test_mkdir -p $tmp_dir
3963         test_mkdir $DIR/${tdir}2
3964         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3965         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3966         $CHECKSTAT -t link $tmp_dir/symlink12 || error "symlink12 not a link"
3967         $CHECKSTAT -t link $DIR/$tdir/symlink02 || error "symlink02 not a link"
3968         $CHECKSTAT -t dir -f $tmp_dir/symlink12 || error "symlink12 not a dir"
3969         $CHECKSTAT -t dir -f $DIR/$tdir/symlink02 || error "symlink12 not a dir"
3970 }
3971 run_test 32g "stat d32g/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3972
3973 test_32h() {
3974         rm -fr $DIR/$tdir $DIR/${tdir}2
3975         tmp_dir=$DIR/$tdir/tmp
3976         test_mkdir -p $tmp_dir
3977         test_mkdir $DIR/${tdir}2
3978         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3979         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3980         ls $tmp_dir/symlink12 || error "listing symlink12"
3981         ls $DIR/$tdir/symlink02  || error "listing symlink02"
3982 }
3983 run_test 32h "open d32h/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3984
3985 test_32i() {
3986         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3987
3988         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3989         trap cleanup_test32_mount EXIT
3990         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3991         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3992                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3993         touch $DIR/$tdir/test_file
3994         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../test_file ||
3995                 error "$DIR/$tdir/ext2-mountpoint/../test_file not file type"
3996         cleanup_test32_mount
3997 }
3998 run_test 32i "stat d32i/ext2-mountpoint/../test_file ==========="
3999
4000 test_32j() {
4001         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4002
4003         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
4004         trap cleanup_test32_mount EXIT
4005         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4006         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4007                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4008         touch $DIR/$tdir/test_file
4009         cat $DIR/$tdir/ext2-mountpoint/../test_file ||
4010                 error "Can't open $DIR/$tdir/ext2-mountpoint/../test_file"
4011         cleanup_test32_mount
4012 }
4013 run_test 32j "open d32j/ext2-mountpoint/../test_file ==========="
4014
4015 test_32k() {
4016         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4017
4018         rm -fr $DIR/$tdir
4019         trap cleanup_test32_mount EXIT
4020         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4021         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4022                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4023         test_mkdir -p $DIR/$tdir/d2
4024         touch $DIR/$tdir/d2/test_file || error "touch failed"
4025         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
4026                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_file not file type"
4027         cleanup_test32_mount
4028 }
4029 run_test 32k "stat d32k/ext2-mountpoint/../d2/test_file ========"
4030
4031 test_32l() {
4032         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4033
4034         rm -fr $DIR/$tdir
4035         trap cleanup_test32_mount EXIT
4036         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4037         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4038                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4039         test_mkdir -p $DIR/$tdir/d2
4040         touch $DIR/$tdir/d2/test_file || error "touch failed"
4041         cat  $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
4042                 error "Can't open $DIR/$tdir/ext2-mountpoint/../d2/test_file"
4043         cleanup_test32_mount
4044 }
4045 run_test 32l "open d32l/ext2-mountpoint/../d2/test_file ========"
4046
4047 test_32m() {
4048         rm -fr $DIR/d32m
4049         test_mkdir -p $DIR/d32m/tmp
4050         TMP_DIR=$DIR/d32m/tmp
4051         ln -s $DIR $TMP_DIR/symlink11
4052         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
4053         $CHECKSTAT -t link $DIR/d32m/tmp/symlink11 ||
4054                 error "symlink11 not a link"
4055         $CHECKSTAT -t link $DIR/d32m/symlink01 ||
4056                 error "symlink01 not a link"
4057 }
4058 run_test 32m "stat d32m/symlink->tmp/symlink->lustre-root ======"
4059
4060 test_32n() {
4061         rm -fr $DIR/d32n
4062         test_mkdir -p $DIR/d32n/tmp
4063         TMP_DIR=$DIR/d32n/tmp
4064         ln -s $DIR $TMP_DIR/symlink11
4065         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
4066         ls -l $DIR/d32n/tmp/symlink11  || error "listing symlink11"
4067         ls -l $DIR/d32n/symlink01 || error "listing symlink01"
4068 }
4069 run_test 32n "open d32n/symlink->tmp/symlink->lustre-root ======"
4070
4071 test_32o() {
4072         touch $DIR/$tfile
4073         test_mkdir -p $DIR/d32o/tmp
4074         TMP_DIR=$DIR/d32o/tmp
4075         ln -s $DIR/$tfile $TMP_DIR/symlink12
4076         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
4077         $CHECKSTAT -t link $DIR/d32o/tmp/symlink12 ||
4078                 error "symlink12 not a link"
4079         $CHECKSTAT -t link $DIR/d32o/symlink02 || error "symlink02 not a link"
4080         $CHECKSTAT -t file -f $DIR/d32o/tmp/symlink12 ||
4081                 error "$DIR/d32o/tmp/symlink12 not file type"
4082         $CHECKSTAT -t file -f $DIR/d32o/symlink02 ||
4083                 error "$DIR/d32o/symlink02 not file type"
4084 }
4085 run_test 32o "stat d32o/symlink->tmp/symlink->lustre-root/$tfile"
4086
4087 test_32p() {
4088         log 32p_1
4089         rm -fr $DIR/d32p
4090         log 32p_2
4091         rm -f $DIR/$tfile
4092         log 32p_3
4093         touch $DIR/$tfile
4094         log 32p_4
4095         test_mkdir -p $DIR/d32p/tmp
4096         log 32p_5
4097         TMP_DIR=$DIR/d32p/tmp
4098         log 32p_6
4099         ln -s $DIR/$tfile $TMP_DIR/symlink12
4100         log 32p_7
4101         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
4102         log 32p_8
4103         cat $DIR/d32p/tmp/symlink12 ||
4104                 error "Can't open $DIR/d32p/tmp/symlink12"
4105         log 32p_9
4106         cat $DIR/d32p/symlink02 || error "Can't open $DIR/d32p/symlink02"
4107         log 32p_10
4108 }
4109 run_test 32p "open d32p/symlink->tmp/symlink->lustre-root/$tfile"
4110
4111 test_32q() {
4112         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4113
4114         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
4115         trap cleanup_test32_mount EXIT
4116         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4117         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
4118         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4119                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4120         ls $DIR/$tdir/ext2-mountpoint | grep "\<under_the_mount\>" && error
4121         cleanup_test32_mount
4122 }
4123 run_test 32q "stat follows mountpoints in Lustre (should return error)"
4124
4125 test_32r() {
4126         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4127
4128         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
4129         trap cleanup_test32_mount EXIT
4130         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4131         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
4132         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4133                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4134         ls $DIR/$tdir/ext2-mountpoint | grep -q under_the_mount && error || true
4135         cleanup_test32_mount
4136 }
4137 run_test 32r "opendir follows mountpoints in Lustre (should return error)"
4138
4139 test_33aa() {
4140         rm -f $DIR/$tfile
4141         touch $DIR/$tfile
4142         chmod 444 $DIR/$tfile
4143         chown $RUNAS_ID $DIR/$tfile
4144         log 33_1
4145         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
4146         log 33_2
4147 }
4148 run_test 33aa "write file with mode 444 (should return error)"
4149
4150 test_33a() {
4151         rm -fr $DIR/$tdir
4152         test_mkdir $DIR/$tdir
4153         chown $RUNAS_ID $DIR/$tdir
4154         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile ||
4155                 error "$RUNAS create $tdir/$tfile failed"
4156         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile &&
4157                 error "open RDWR" || true
4158 }
4159 run_test 33a "test open file(mode=0444) with O_RDWR (should return error)"
4160
4161 test_33b() {
4162         rm -fr $DIR/$tdir
4163         test_mkdir $DIR/$tdir
4164         chown $RUNAS_ID $DIR/$tdir
4165         $RUNAS $OPENFILE -f 1286739555 $DIR/$tdir/$tfile || true
4166 }
4167 run_test 33b "test open file with malformed flags (No panic)"
4168
4169 test_33c() {
4170         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4171         remote_ost_nodsh && skip "remote OST with nodsh"
4172
4173         local ostnum
4174         local ostname
4175         local write_bytes
4176         local all_zeros
4177
4178         all_zeros=true
4179         test_mkdir $DIR/$tdir
4180         # Read: 0, Write: 4, create/destroy: 2/0, stat: 1, punch: 0
4181
4182         sync
4183         for ostnum in $(seq $OSTCOUNT); do
4184                 # test-framework's OST numbering is one-based, while Lustre's
4185                 # is zero-based
4186                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4187                 # check if at least some write_bytes stats are counted
4188                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
4189                               obdfilter.$ostname.stats |
4190                               awk '/^write_bytes/ {print $7}' )
4191                 echo "baseline_write_bytes@ost$ostnum/$ostname=$write_bytes"
4192                 if (( ${write_bytes:-0} > 0 )); then
4193                         all_zeros=false
4194                         break
4195                 fi
4196         done
4197
4198         $all_zeros || return 0
4199
4200         # Write four bytes
4201         echo foo > $DIR/$tdir/bar
4202         # Really write them
4203         sync
4204
4205         # Total up write_bytes after writing.  We'd better find non-zeros.
4206         for ostnum in $(seq $OSTCOUNT); do
4207                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4208                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
4209                               obdfilter/$ostname/stats |
4210                               awk '/^write_bytes/ {print $7}' )
4211                 echo "write_bytes@ost$ostnum/$ostname=$write_bytes"
4212                 if (( ${write_bytes:-0} > 0 )); then
4213                         all_zeros=false
4214                         break
4215                 fi
4216         done
4217
4218         if $all_zeros; then
4219                 for ostnum in $(seq $OSTCOUNT); do
4220                         ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4221                         echo "Check write_bytes is in obdfilter.*.stats:"
4222                         do_facet ost$ostnum lctl get_param -n \
4223                                 obdfilter.$ostname.stats
4224                 done
4225                 error "OST not keeping write_bytes stats (b=22312)"
4226         fi
4227 }
4228 run_test 33c "test write_bytes stats"
4229
4230 test_33d() {
4231         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
4232         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4233
4234         local MDTIDX=1
4235         local remote_dir=$DIR/$tdir/remote_dir
4236
4237         test_mkdir $DIR/$tdir
4238         $LFS mkdir -i $MDTIDX $remote_dir ||
4239                 error "create remote directory failed"
4240
4241         touch $remote_dir/$tfile
4242         chmod 444 $remote_dir/$tfile
4243         chown $RUNAS_ID $remote_dir/$tfile
4244
4245         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
4246
4247         chown $RUNAS_ID $remote_dir
4248         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 ||
4249                                         error "create" || true
4250         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 &&
4251                                     error "open RDWR" || true
4252         $RUNAS $OPENFILE -f 1286739555 $remote_dir/f33 || true
4253 }
4254 run_test 33d "openfile with 444 modes and malformed flags under remote dir"
4255
4256 test_33e() {
4257         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4258
4259         mkdir $DIR/$tdir
4260
4261         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4262         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4263         mkdir $DIR/$tdir/local_dir
4264
4265         local s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4266         local s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4267         local l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4268
4269         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4270                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode"
4271
4272         rmdir $DIR/$tdir/* || error "rmdir failed"
4273
4274         umask 777
4275         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4276         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4277         mkdir $DIR/$tdir/local_dir
4278
4279         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4280         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4281         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4282
4283         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4284                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 777"
4285
4286         rmdir $DIR/$tdir/* || error "rmdir(umask 777) failed"
4287
4288         umask 000
4289         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4290         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4291         mkdir $DIR/$tdir/local_dir
4292
4293         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4294         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4295         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4296
4297         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4298                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 0"
4299 }
4300 run_test 33e "mkdir and striped directory should have same mode"
4301
4302 cleanup_33f() {
4303         trap 0
4304         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=0
4305 }
4306
4307 test_33f() {
4308         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4309         remote_mds_nodsh && skip "remote MDS with nodsh"
4310
4311         mkdir $DIR/$tdir
4312         chmod go+rwx $DIR/$tdir
4313         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=-1
4314         trap cleanup_33f EXIT
4315
4316         $RUNAS lfs mkdir -i 0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
4317                 error "cannot create striped directory"
4318
4319         $RUNAS touch $DIR/$tdir/striped_dir/{0..16} ||
4320                 error "cannot create files in striped directory"
4321
4322         $RUNAS rm $DIR/$tdir/striped_dir/{0..16} ||
4323                 error "cannot remove files in striped directory"
4324
4325         $RUNAS rmdir $DIR/$tdir/striped_dir ||
4326                 error "cannot remove striped directory"
4327
4328         cleanup_33f
4329 }
4330 run_test 33f "nonroot user can create, access, and remove a striped directory"
4331
4332 test_33g() {
4333         mkdir -p $DIR/$tdir/dir2
4334
4335         local err=$($RUNAS mkdir $DIR/$tdir/dir2 2>&1)
4336         echo $err
4337         [[ $err =~ "exists" ]] || error "Not exists error"
4338 }
4339 run_test 33g "nonroot user create already existing root created file"
4340
4341 sub_33h() {
4342         local hash_type=$1
4343         local count=250
4344
4345         test_mkdir -c $MDSCOUNT -H $hash_type $DIR/$tdir ||
4346                 error "lfs mkdir -H $hash_type $tdir failed"
4347         touch $DIR/$tdir/$tfile || error "touch $tfile failed"
4348
4349         local index=$($LFS getstripe -m $DIR/$tdir/$tfile)
4350         local index2
4351         local fname
4352
4353         for fname in $DIR/$tdir/$tfile.bak \
4354                      $DIR/$tdir/$tfile.SAV \
4355                      $DIR/$tdir/$tfile.orig \
4356                      $DIR/$tdir/$tfile~; do
4357                 touch $fname || error "touch $fname failed"
4358                 index2=$($LFS getstripe -m $fname)
4359                 (( $index == $index2 )) ||
4360                         error "$fname MDT index mismatch $index != $index2"
4361         done
4362
4363         local failed=0
4364         local patterns=(".$tfile.XXXXXX" "$tfile.XXXXXXXX")
4365         local pattern
4366
4367         for pattern in ${patterns[*]}; do
4368                 echo "pattern $pattern"
4369                 fname=$DIR/$tdir/$pattern
4370                 for (( i = 0; i < $count; i++ )); do
4371                         fname=$(mktemp $DIR/$tdir/$pattern) ||
4372                                 error "mktemp $DIR/$tdir/$pattern failed"
4373                         index2=$($LFS getstripe -m $fname)
4374                         (( $index == $index2 )) && continue
4375
4376                         failed=$((failed + 1))
4377                         echo "$fname MDT index mismatch $index != $index2"
4378                 done
4379         done
4380
4381         echo "$failed/$count MDT index mismatches, expect ~2-4"
4382         (( failed < 10 )) || error "MDT index mismatch $failed/$count times"
4383
4384         local same=0
4385         local expect
4386
4387         # verify that "crush" is still broken with all files on same MDT,
4388         # crush2 should have about 1/MDSCOUNT files on each MDT, with margin
4389         [[ "$hash_type" == "crush" ]] && expect=$count ||
4390                 expect=$((count / MDSCOUNT))
4391
4392         # crush2 doesn't put all-numeric suffixes on the same MDT,
4393         # filename like $tfile.12345678 should *not* be considered temp
4394         for pattern in ${patterns[*]}; do
4395                 local base=${pattern%%X*}
4396                 local suff=${pattern#$base}
4397
4398                 echo "pattern $pattern"
4399                 for (( i = 0; i < $count; i++ )); do
4400                         fname=$DIR/$tdir/$base$((${suff//X/1} + i))
4401                         touch $fname || error "touch $fname failed"
4402                         index2=$($LFS getstripe -m $fname)
4403                         (( $index != $index2 )) && continue
4404
4405                         same=$((same + 1))
4406                 done
4407         done
4408
4409         # the number of "bad" hashes is random, as it depends on the random
4410         # filenames generated by "mktemp".  Allow some margin in the results.
4411         echo "$((same/${#patterns[*]}))/$count matches, expect ~$expect for $1"
4412         (( same / ${#patterns[*]} <= expect * 9 / 7 &&
4413            same / ${#patterns[*]} > expect * 5 / 7 )) ||
4414                 error "MDT index match $((same / ${#patterns[*]}))/$count times"
4415         same=0
4416
4417         # crush2 doesn't put suffixes with special characters on the same MDT
4418         # filename like $tfile.txt.1234 should *not* be considered temp
4419         for pattern in ${patterns[*]}; do
4420                 local base=${pattern%%X*}
4421                 local suff=${pattern#$base}
4422
4423                 pattern=$base...${suff/XXX}
4424                 echo "pattern=$pattern"
4425                 for (( i = 0; i < $count; i++ )); do
4426                         fname=$(mktemp $DIR/$tdir/$pattern) ||
4427                                 error "touch $fname failed"
4428                         index2=$($LFS getstripe -m $fname)
4429                         (( $index != $index2 )) && continue
4430
4431                         same=$((same + 1))
4432                 done
4433         done
4434
4435         # the number of "bad" hashes is random, as it depends on the random
4436         # filenames generated by "mktemp".  Allow some margin in the results.
4437         echo "$((same/${#patterns[*]}))/$count matches, expect ~$expect for $1"
4438         (( same / ${#patterns[*]} <= expect * 9 / 7 &&
4439            same / ${#patterns[*]} > expect * 5 / 7 )) ||
4440                 error "MDT index match $((same / ${#patterns[*]}))/$count times"
4441 }
4442
4443 test_33h() {
4444         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
4445         (( $MDS1_VERSION >= $(version_code 2.13.50) )) ||
4446                 skip "Need MDS version at least 2.13.50"
4447
4448         sub_33h crush
4449 }
4450 run_test 33h "temp file is located on the same MDT as target (crush)"
4451
4452 test_33hh() {
4453         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
4454         echo "MDS1_VERSION=$MDS1_VERSION version_code=$(version_code 2.15.0)"
4455         (( $MDS1_VERSION > $(version_code 2.15.0) )) ||
4456                 skip "Need MDS version at least 2.15.0 for crush2"
4457
4458         sub_33h crush2
4459 }
4460 run_test 33hh "temp file is located on the same MDT as target (crush2)"
4461
4462 test_33i()
4463 {
4464         (( MDSCOUNT < 2 )) && skip "needs >= 2 MDTs"
4465
4466         local FNAME=$(str_repeat 'f' 250)
4467
4468         test_mkdir -i 0 -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
4469         createmany -o $DIR/$tdir/$FNAME 1000 || error "createmany failed"
4470
4471         local count
4472         local total
4473
4474         count=$($LFS getstripe -m $DIR/$tdir/* | grep -cw 1)
4475
4476         local MDC=$(lctl dl | awk '/MDT0001-mdc-[^M]/ { print $4 }')
4477
4478         lctl --device %$MDC deactivate
4479         stack_trap "lctl --device %$MDC activate"
4480         ls $DIR/$tdir > /dev/null && error "ls should return an error"
4481         total=$(\ls -l $DIR/$tdir | wc -l)
4482         # "ls -l" will list total in the first line
4483         total=$((total - 1))
4484         (( total + count == 1000 )) ||
4485                 error "ls list $total files, $count files on MDT1"
4486 }
4487 run_test 33i "striped directory can be accessed when one MDT is down"
4488
4489 test_33j() {
4490         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
4491
4492         mkdir -p $DIR/$tdir/
4493
4494         $LFS setdirstripe -D -i0,1 $DIR/$tdir/striped_dir_a &&
4495                 error "setdirstripe -D -i0,1 incorrectly succeeded"
4496
4497         $LFS setdirstripe -D -i0,1 -c1 $DIR/$tdir/striped_dir_b &&
4498                 error "setdirstripe -D -i0,1 -c1 incorrectly succeeded"
4499
4500         $LFS setdirstripe -D -i0,1 -c3 $DIR/$tdir/striped_dir_c &&
4501                 error "setdirstripe -D -i0,1 -c3 incorrectly succeeded"
4502
4503         $LFS setdirstripe -i0,1 $DIR/$tdir/striped_dir_e ||
4504                 error "-D was not specified, but still failed"
4505 }
4506 run_test 33j "lfs setdirstripe -D -i x,y,x should fail"
4507
4508 TEST_34_SIZE=${TEST_34_SIZE:-2000000000000}
4509 test_34a() {
4510         rm -f $DIR/f34
4511         $MCREATE $DIR/f34 || error "mcreate failed"
4512         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4513                 error "getstripe failed"
4514         $TRUNCATE $DIR/f34 $TEST_34_SIZE || error "truncate failed"
4515         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4516                 error "getstripe failed"
4517         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4518                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4519 }
4520 run_test 34a "truncate file that has not been opened ==========="
4521
4522 test_34b() {
4523         [ ! -f $DIR/f34 ] && test_34a
4524         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4525                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4526         $OPENFILE -f O_RDONLY $DIR/f34
4527         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4528                 error "getstripe failed"
4529         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4530                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4531 }
4532 run_test 34b "O_RDONLY opening file doesn't create objects ====="
4533
4534 test_34c() {
4535         [ ! -f $DIR/f34 ] && test_34a
4536         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4537                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4538         $OPENFILE -f O_RDWR $DIR/f34
4539         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" &&
4540                 error "$LFS getstripe failed"
4541         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4542                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4543 }
4544 run_test 34c "O_RDWR opening file-with-size works =============="
4545
4546 test_34d() {
4547         [ ! -f $DIR/f34 ] && test_34a
4548         dd if=/dev/zero of=$DIR/f34 conv=notrunc bs=4k count=1 ||
4549                 error "dd failed"
4550         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4551                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4552         rm $DIR/f34
4553 }
4554 run_test 34d "write to sparse file ============================="
4555
4556 test_34e() {
4557         rm -f $DIR/f34e
4558         $MCREATE $DIR/f34e || error "mcreate failed"
4559         $TRUNCATE $DIR/f34e 1000 || error "truncate failed"
4560         $CHECKSTAT -s 1000 $DIR/f34e ||
4561                 error "Size of $DIR/f34e not equal to 1000 bytes"
4562         $OPENFILE -f O_RDWR $DIR/f34e
4563         $CHECKSTAT -s 1000 $DIR/f34e ||
4564                 error "Size of $DIR/f34e not equal to 1000 bytes"
4565 }
4566 run_test 34e "create objects, some with size and some without =="
4567
4568 test_34f() { # bug 6242, 6243
4569         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4570
4571         SIZE34F=48000
4572         rm -f $DIR/f34f
4573         $MCREATE $DIR/f34f || error "mcreate failed"
4574         $TRUNCATE $DIR/f34f $SIZE34F || error "truncating $DIR/f3f to $SIZE34F"
4575         dd if=$DIR/f34f of=$TMP/f34f
4576         $CHECKSTAT -s $SIZE34F $TMP/f34f || error "$TMP/f34f not $SIZE34F bytes"
4577         dd if=/dev/zero of=$TMP/f34fzero bs=$SIZE34F count=1
4578         cmp $DIR/f34f $TMP/f34fzero || error "$DIR/f34f not all zero"
4579         cmp $TMP/f34f $TMP/f34fzero || error "$TMP/f34f not all zero"
4580         rm $TMP/f34f $TMP/f34fzero $DIR/f34f
4581 }
4582 run_test 34f "read from a file with no objects until EOF ======="
4583
4584 test_34g() {
4585         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4586
4587         dd if=/dev/zero of=$DIR/$tfile bs=1 count=100 seek=$TEST_34_SIZE ||
4588                 error "dd failed"
4589         $TRUNCATE $DIR/$tfile $((TEST_34_SIZE / 2))|| error "truncate failed"
4590         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
4591                 error "Size of $DIR/$tfile not equal to $((TEST_34_SIZE / 2))"
4592         cancel_lru_locks osc
4593         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
4594                 error "wrong size after lock cancel"
4595
4596         $TRUNCATE $DIR/$tfile $TEST_34_SIZE || error "truncate failed"
4597         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
4598                 error "expanding truncate failed"
4599         cancel_lru_locks osc
4600         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
4601                 error "wrong expanded size after lock cancel"
4602 }
4603 run_test 34g "truncate long file ==============================="
4604
4605 test_34h() {
4606         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4607
4608         local gid=10
4609         local sz=1000
4610
4611         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 || error "dd failed"
4612         sync # Flush the cache so that multiop below does not block on cache
4613              # flush when getting the group lock
4614         $MULTIOP $DIR/$tfile OG${gid}T${sz}g${gid}c &
4615         MULTIPID=$!
4616
4617         # Since just timed wait is not good enough, let's do a sync write
4618         # that way we are sure enough time for a roundtrip + processing
4619         # passed + 2 seconds of extra margin.
4620         dd if=/dev/zero of=$DIR/${tfile}-1 bs=$PAGE_SIZE oflag=direct count=1
4621         rm $DIR/${tfile}-1
4622         sleep 2
4623
4624         if [[ `ps h -o comm -p $MULTIPID` == "multiop" ]]; then
4625                 error "Multiop blocked on ftruncate, pid=$MULTIPID"
4626                 kill -9 $MULTIPID
4627         fi
4628         wait $MULTIPID
4629         local nsz=`stat -c %s $DIR/$tfile`
4630         [[ $nsz == $sz ]] || error "New size wrong $nsz != $sz"
4631 }
4632 run_test 34h "ftruncate file under grouplock should not block"
4633
4634 test_35a() {
4635         cp /bin/sh $DIR/f35a
4636         chmod 444 $DIR/f35a
4637         chown $RUNAS_ID $DIR/f35a
4638         $RUNAS $DIR/f35a && error || true
4639         rm $DIR/f35a
4640 }
4641 run_test 35a "exec file with mode 444 (should return and not leak)"
4642
4643 test_36a() {
4644         rm -f $DIR/f36
4645         utime $DIR/f36 || error "utime failed for MDS"
4646 }
4647 run_test 36a "MDS utime check (mknod, utime)"
4648
4649 test_36b() {
4650         echo "" > $DIR/f36
4651         utime $DIR/f36 || error "utime failed for OST"
4652 }
4653 run_test 36b "OST utime check (open, utime)"
4654
4655 test_36c() {
4656         rm -f $DIR/d36/f36
4657         test_mkdir $DIR/d36
4658         chown $RUNAS_ID $DIR/d36
4659         $RUNAS utime $DIR/d36/f36 || error "utime failed for MDS as non-root"
4660 }
4661 run_test 36c "non-root MDS utime check (mknod, utime)"
4662
4663 test_36d() {
4664         [ ! -d $DIR/d36 ] && test_36c
4665         echo "" > $DIR/d36/f36
4666         $RUNAS utime $DIR/d36/f36 || error "utime failed for OST as non-root"
4667 }
4668 run_test 36d "non-root OST utime check (open, utime)"
4669
4670 test_36e() {
4671         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID -- skipping"
4672
4673         test_mkdir $DIR/$tdir
4674         touch $DIR/$tdir/$tfile
4675         $RUNAS utime $DIR/$tdir/$tfile &&
4676                 error "utime worked, expected failure" || true
4677 }
4678 run_test 36e "utime on non-owned file (should return error)"
4679
4680 subr_36fh() {
4681         local fl="$1"
4682         local LANG_SAVE=$LANG
4683         local LC_LANG_SAVE=$LC_LANG
4684         export LANG=C LC_LANG=C # for date language
4685
4686         DATESTR="Dec 20  2000"
4687         test_mkdir $DIR/$tdir
4688         lctl set_param fail_loc=$fl
4689         date; date +%s
4690         cp /etc/hosts $DIR/$tdir/$tfile
4691         sync & # write RPC generated with "current" inode timestamp, but delayed
4692         sleep 1
4693         touch --date="$DATESTR" $DIR/$tdir/$tfile # setattr timestamp in past
4694         LS_BEFORE="`ls -l $DIR/$tdir/$tfile`" # old timestamp from client cache
4695         cancel_lru_locks $OSC
4696         LS_AFTER="`ls -l $DIR/$tdir/$tfile`"  # timestamp from OST object
4697         date; date +%s
4698         [ "$LS_BEFORE" != "$LS_AFTER" ] && \
4699                 echo "BEFORE: $LS_BEFORE" && \
4700                 echo "AFTER : $LS_AFTER" && \
4701                 echo "WANT  : $DATESTR" && \
4702                 error "$DIR/$tdir/$tfile timestamps changed" || true
4703
4704         export LANG=$LANG_SAVE LC_LANG=$LC_LANG_SAVE
4705 }
4706
4707 test_36f() {
4708         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4709
4710         #define OBD_FAIL_OST_BRW_PAUSE_BULK 0x214
4711         subr_36fh "0x80000214"
4712 }
4713 run_test 36f "utime on file racing with OST BRW write =========="
4714
4715 test_36g() {
4716         remote_ost_nodsh && skip "remote OST with nodsh"
4717         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4718         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
4719                 skip "Need MDS version at least 2.12.51"
4720
4721         local fmd_max_age
4722         local fmd
4723         local facet="ost1"
4724         local tgt="obdfilter"
4725
4726         [[ $OSC == "mdc" ]] && tgt="mdt" && facet="mds1"
4727
4728         test_mkdir $DIR/$tdir
4729         fmd_max_age=$(do_facet $facet \
4730                 "lctl get_param -n $tgt.*.tgt_fmd_seconds 2> /dev/null | \
4731                 head -n 1")
4732
4733         echo "FMD max age: ${fmd_max_age}s"
4734         touch $DIR/$tdir/$tfile
4735         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4736                 gawk '{cnt=cnt+$1}  END{print cnt}')
4737         echo "FMD before: $fmd"
4738         [[ $fmd == 0 ]] &&
4739                 error "FMD wasn't create by touch"
4740         sleep $((fmd_max_age + 12))
4741         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4742                 gawk '{cnt=cnt+$1}  END{print cnt}')
4743         echo "FMD after: $fmd"
4744         [[ $fmd == 0 ]] ||
4745                 error "FMD wasn't expired by ping"
4746 }
4747 run_test 36g "FMD cache expiry ====================="
4748
4749 test_36h() {
4750         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4751
4752         #define OBD_FAIL_OST_BRW_PAUSE_BULK2 0x227
4753         subr_36fh "0x80000227"
4754 }
4755 run_test 36h "utime on file racing with OST BRW write =========="
4756
4757 test_36i() {
4758         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4759
4760         test_mkdir $DIR/$tdir
4761         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir
4762
4763         local mtime=$(stat -c%Y $DIR/$tdir/striped_dir)
4764         local new_mtime=$((mtime + 200))
4765
4766         #change Modify time of striped dir
4767         touch -m -d @$new_mtime $DIR/$tdir/striped_dir ||
4768                         error "change mtime failed"
4769
4770         local got=$(stat -c%Y $DIR/$tdir/striped_dir)
4771
4772         [ "$new_mtime" = "$got" ] || error "expect $new_mtime got $got"
4773 }
4774 run_test 36i "change mtime on striped directory"
4775
4776 # test_37 - duplicate with tests 32q 32r
4777
4778 test_38() {
4779         local file=$DIR/$tfile
4780         touch $file
4781         openfile -f O_DIRECTORY $file
4782         local RC=$?
4783         local ENOTDIR=20
4784         [ $RC -eq 0 ] && error "opened file $file with O_DIRECTORY" || true
4785         [ $RC -eq $ENOTDIR ] || error "error $RC should be ENOTDIR ($ENOTDIR)"
4786 }
4787 run_test 38 "open a regular file with O_DIRECTORY should return -ENOTDIR ==="
4788
4789 test_39a() { # was test_39
4790         touch $DIR/$tfile
4791         touch $DIR/${tfile}2
4792 #       ls -l  $DIR/$tfile $DIR/${tfile}2
4793 #       ls -lu  $DIR/$tfile $DIR/${tfile}2
4794 #       ls -lc  $DIR/$tfile $DIR/${tfile}2
4795         sleep 2
4796         $OPENFILE -f O_CREAT:O_TRUNC:O_WRONLY $DIR/${tfile}2
4797         if [ ! $DIR/${tfile}2 -nt $DIR/$tfile ]; then
4798                 echo "mtime"
4799                 ls -l --full-time $DIR/$tfile $DIR/${tfile}2
4800                 echo "atime"
4801                 ls -lu --full-time $DIR/$tfile $DIR/${tfile}2
4802                 echo "ctime"
4803                 ls -lc --full-time $DIR/$tfile $DIR/${tfile}2
4804                 error "O_TRUNC didn't change timestamps"
4805         fi
4806 }
4807 run_test 39a "mtime changed on create"
4808
4809 test_39b() {
4810         test_mkdir -c1 $DIR/$tdir
4811         cp -p /etc/passwd $DIR/$tdir/fopen
4812         cp -p /etc/passwd $DIR/$tdir/flink
4813         cp -p /etc/passwd $DIR/$tdir/funlink
4814         cp -p /etc/passwd $DIR/$tdir/frename
4815         ln $DIR/$tdir/funlink $DIR/$tdir/funlink2
4816
4817         sleep 1
4818         echo "aaaaaa" >> $DIR/$tdir/fopen
4819         echo "aaaaaa" >> $DIR/$tdir/flink
4820         echo "aaaaaa" >> $DIR/$tdir/funlink
4821         echo "aaaaaa" >> $DIR/$tdir/frename
4822
4823         local open_new=`stat -c %Y $DIR/$tdir/fopen`
4824         local link_new=`stat -c %Y $DIR/$tdir/flink`
4825         local unlink_new=`stat -c %Y $DIR/$tdir/funlink`
4826         local rename_new=`stat -c %Y $DIR/$tdir/frename`
4827
4828         cat $DIR/$tdir/fopen > /dev/null
4829         ln $DIR/$tdir/flink $DIR/$tdir/flink2
4830         rm -f $DIR/$tdir/funlink2
4831         mv -f $DIR/$tdir/frename $DIR/$tdir/frename2
4832
4833         for (( i=0; i < 2; i++ )) ; do
4834                 local open_new2=`stat -c %Y $DIR/$tdir/fopen`
4835                 local link_new2=`stat -c %Y $DIR/$tdir/flink`
4836                 local unlink_new2=`stat -c %Y $DIR/$tdir/funlink`
4837                 local rename_new2=`stat -c %Y $DIR/$tdir/frename2`
4838
4839                 [ $open_new2 -eq $open_new ] || error "open file reverses mtime"
4840                 [ $link_new2 -eq $link_new ] || error "link file reverses mtime"
4841                 [ $unlink_new2 -eq $unlink_new ] || error "unlink file reverses mtime"
4842                 [ $rename_new2 -eq $rename_new ] || error "rename file reverses mtime"
4843
4844                 cancel_lru_locks $OSC
4845                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4846         done
4847 }
4848 run_test 39b "mtime change on open, link, unlink, rename  ======"
4849
4850 # this should be set to past
4851 TEST_39_MTIME=`date -d "1 year ago" +%s`
4852
4853 # bug 11063
4854 test_39c() {
4855         touch $DIR1/$tfile
4856         sleep 2
4857         local mtime0=`stat -c %Y $DIR1/$tfile`
4858
4859         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4860         local mtime1=`stat -c %Y $DIR1/$tfile`
4861         [ "$mtime1" = $TEST_39_MTIME ] || \
4862                 error "mtime is not set to past: $mtime1, should be $TEST_39_MTIME"
4863
4864         local d1=`date +%s`
4865         echo hello >> $DIR1/$tfile
4866         local d2=`date +%s`
4867         local mtime2=`stat -c %Y $DIR1/$tfile`
4868         [ "$mtime2" -ge "$d1" ] && [ "$mtime2" -le "$d2" ] || \
4869                 error "mtime is not updated on write: $d1 <= $mtime2 <= $d2"
4870
4871         mv $DIR1/$tfile $DIR1/$tfile-1
4872
4873         for (( i=0; i < 2; i++ )) ; do
4874                 local mtime3=`stat -c %Y $DIR1/$tfile-1`
4875                 [ "$mtime2" = "$mtime3" ] || \
4876                         error "mtime ($mtime2) changed (to $mtime3) on rename"
4877
4878                 cancel_lru_locks $OSC
4879                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4880         done
4881 }
4882 run_test 39c "mtime change on rename ==========================="
4883
4884 # bug 21114
4885 test_39d() {
4886         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4887
4888         touch $DIR1/$tfile
4889         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4890
4891         for (( i=0; i < 2; i++ )) ; do
4892                 local mtime=`stat -c %Y $DIR1/$tfile`
4893                 [ $mtime = $TEST_39_MTIME ] || \
4894                         error "mtime($mtime) is not set to $TEST_39_MTIME"
4895
4896                 cancel_lru_locks $OSC
4897                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4898         done
4899 }
4900 run_test 39d "create, utime, stat =============================="
4901
4902 # bug 21114
4903 test_39e() {
4904         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4905
4906         touch $DIR1/$tfile
4907         local mtime1=`stat -c %Y $DIR1/$tfile`
4908
4909         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4910
4911         for (( i=0; i < 2; i++ )) ; do
4912                 local mtime2=`stat -c %Y $DIR1/$tfile`
4913                 [ $mtime2 = $TEST_39_MTIME ] || \
4914                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4915
4916                 cancel_lru_locks $OSC
4917                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4918         done
4919 }
4920 run_test 39e "create, stat, utime, stat ========================"
4921
4922 # bug 21114
4923 test_39f() {
4924         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4925
4926         touch $DIR1/$tfile
4927         mtime1=`stat -c %Y $DIR1/$tfile`
4928
4929         sleep 2
4930         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4931
4932         for (( i=0; i < 2; i++ )) ; do
4933                 local mtime2=`stat -c %Y $DIR1/$tfile`
4934                 [ $mtime2 = $TEST_39_MTIME ] || \
4935                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4936
4937                 cancel_lru_locks $OSC
4938                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4939         done
4940 }
4941 run_test 39f "create, stat, sleep, utime, stat ================="
4942
4943 # bug 11063
4944 test_39g() {
4945         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4946
4947         echo hello >> $DIR1/$tfile
4948         local mtime1=`stat -c %Y $DIR1/$tfile`
4949
4950         sleep 2
4951         chmod o+r $DIR1/$tfile
4952
4953         for (( i=0; i < 2; i++ )) ; do
4954                 local mtime2=`stat -c %Y $DIR1/$tfile`
4955                 [ "$mtime1" = "$mtime2" ] || \
4956                         error "lost mtime: $mtime2, should be $mtime1"
4957
4958                 cancel_lru_locks $OSC
4959                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4960         done
4961 }
4962 run_test 39g "write, chmod, stat ==============================="
4963
4964 # bug 11063
4965 test_39h() {
4966         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4967
4968         touch $DIR1/$tfile
4969         sleep 1
4970
4971         local d1=`date`
4972         echo hello >> $DIR1/$tfile
4973         local mtime1=`stat -c %Y $DIR1/$tfile`
4974
4975         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4976         local d2=`date`
4977         if [ "$d1" != "$d2" ]; then
4978                 echo "write and touch not within one second"
4979         else
4980                 for (( i=0; i < 2; i++ )) ; do
4981                         local mtime2=`stat -c %Y $DIR1/$tfile`
4982                         [ "$mtime2" = $TEST_39_MTIME ] || \
4983                                 error "lost mtime: $mtime2, should be $TEST_39_MTIME"
4984
4985                         cancel_lru_locks $OSC
4986                         if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4987                 done
4988         fi
4989 }
4990 run_test 39h "write, utime within one second, stat ============="
4991
4992 test_39i() {
4993         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4994
4995         touch $DIR1/$tfile
4996         sleep 1
4997
4998         echo hello >> $DIR1/$tfile
4999         local mtime1=`stat -c %Y $DIR1/$tfile`
5000
5001         mv $DIR1/$tfile $DIR1/$tfile-1
5002
5003         for (( i=0; i < 2; i++ )) ; do
5004                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
5005
5006                 [ "$mtime1" = "$mtime2" ] || \
5007                         error "lost mtime: $mtime2, should be $mtime1"
5008
5009                 cancel_lru_locks $OSC
5010                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
5011         done
5012 }
5013 run_test 39i "write, rename, stat =============================="
5014
5015 test_39j() {
5016         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5017
5018         start_full_debug_logging
5019         touch $DIR1/$tfile
5020         sleep 1
5021
5022         #define OBD_FAIL_OSC_DELAY_SETTIME       0x412
5023         lctl set_param fail_loc=0x80000412
5024         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c ||
5025                 error "multiop failed"
5026         local multipid=$!
5027         local mtime1=`stat -c %Y $DIR1/$tfile`
5028
5029         mv $DIR1/$tfile $DIR1/$tfile-1
5030
5031         kill -USR1 $multipid
5032         wait $multipid || error "multiop close failed"
5033
5034         for (( i=0; i < 2; i++ )) ; do
5035                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
5036                 [ "$mtime1" = "$mtime2" ] ||
5037                         error "mtime is lost on close: $mtime2, " \
5038                               "should be $mtime1"
5039
5040                 cancel_lru_locks
5041                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
5042         done
5043         lctl set_param fail_loc=0
5044         stop_full_debug_logging
5045 }
5046 run_test 39j "write, rename, close, stat ======================="
5047
5048 test_39k() {
5049         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5050
5051         touch $DIR1/$tfile
5052         sleep 1
5053
5054         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c || error "multiop failed"
5055         local multipid=$!
5056         local mtime1=`stat -c %Y $DIR1/$tfile`
5057
5058         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
5059
5060         kill -USR1 $multipid
5061         wait $multipid || error "multiop close failed"
5062
5063         for (( i=0; i < 2; i++ )) ; do
5064                 local mtime2=`stat -c %Y $DIR1/$tfile`
5065
5066                 [ "$mtime2" = $TEST_39_MTIME ] || \
5067                         error "mtime is lost on close: $mtime2, should be $TEST_39_MTIME"
5068
5069                 cancel_lru_locks
5070                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
5071         done
5072 }
5073 run_test 39k "write, utime, close, stat ========================"
5074
5075 # this should be set to future
5076 TEST_39_ATIME=`date -d "1 year" +%s`
5077
5078 test_39l() {
5079         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5080         remote_mds_nodsh && skip "remote MDS with nodsh"
5081
5082         local atime_diff=$(do_facet $SINGLEMDS \
5083                                 lctl get_param -n mdd.*MDT0000*.atime_diff)
5084         rm -rf $DIR/$tdir
5085         mkdir_on_mdt0 $DIR/$tdir
5086
5087         # test setting directory atime to future
5088         touch -a -d @$TEST_39_ATIME $DIR/$tdir
5089         local atime=$(stat -c %X $DIR/$tdir)
5090         [ "$atime" = $TEST_39_ATIME ] ||
5091                 error "atime is not set to future: $atime, $TEST_39_ATIME"
5092
5093         # test setting directory atime from future to now
5094         local now=$(date +%s)
5095         touch -a -d @$now $DIR/$tdir
5096
5097         atime=$(stat -c %X $DIR/$tdir)
5098         [ "$atime" -eq "$now"  ] ||
5099                 error "atime is not updated from future: $atime, $now"
5100
5101         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=2
5102         sleep 3
5103
5104         # test setting directory atime when now > dir atime + atime_diff
5105         local d1=$(date +%s)
5106         ls $DIR/$tdir
5107         local d2=$(date +%s)
5108         cancel_lru_locks mdc
5109         atime=$(stat -c %X $DIR/$tdir)
5110         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
5111                 error "atime is not updated  : $atime, should be $d2"
5112
5113         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=60
5114         sleep 3
5115
5116         # test not setting directory atime when now < dir atime + atime_diff
5117         ls $DIR/$tdir
5118         cancel_lru_locks mdc
5119         atime=$(stat -c %X $DIR/$tdir)
5120         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
5121                 error "atime is updated to $atime, should remain $d1<atime<$d2"
5122
5123         do_facet $SINGLEMDS \
5124                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
5125 }
5126 run_test 39l "directory atime update ==========================="
5127
5128 test_39m() {
5129         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5130
5131         touch $DIR1/$tfile
5132         sleep 2
5133         local far_past_mtime=$(date -d "May 29 1953" +%s)
5134         local far_past_atime=$(date -d "Dec 17 1903" +%s)
5135
5136         touch -m -d @$far_past_mtime $DIR1/$tfile
5137         touch -a -d @$far_past_atime $DIR1/$tfile
5138
5139         for (( i=0; i < 2; i++ )) ; do
5140                 local timestamps=$(stat -c "%X %Y" $DIR1/$tfile)
5141                 [ "$timestamps" = "$far_past_atime $far_past_mtime" ] || \
5142                         error "atime or mtime set incorrectly"
5143
5144                 cancel_lru_locks $OSC
5145                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
5146         done
5147 }
5148 run_test 39m "test atime and mtime before 1970"
5149
5150 test_39n() { # LU-3832
5151         remote_mds_nodsh && skip "remote MDS with nodsh"
5152
5153         local atime_diff=$(do_facet $SINGLEMDS \
5154                 lctl get_param -n mdd.*MDT0000*.atime_diff)
5155         local atime0
5156         local atime1
5157         local atime2
5158
5159         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=1
5160
5161         rm -rf $DIR/$tfile
5162         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 status=noxfer
5163         atime0=$(stat -c %X $DIR/$tfile)
5164
5165         sleep 5
5166         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
5167         atime1=$(stat -c %X $DIR/$tfile)
5168
5169         sleep 5
5170         cancel_lru_locks mdc
5171         cancel_lru_locks osc
5172         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
5173         atime2=$(stat -c %X $DIR/$tfile)
5174
5175         do_facet $SINGLEMDS \
5176                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
5177
5178         [ "$atime0" -eq "$atime1" ] || error "atime0 $atime0 != atime1 $atime1"
5179         [ "$atime1" -eq "$atime2" ] || error "atime0 $atime0 != atime1 $atime1"
5180 }
5181 run_test 39n "check that O_NOATIME is honored"
5182
5183 test_39o() {
5184         TESTDIR=$DIR/$tdir/$tfile
5185         [ -e $TESTDIR ] && rm -rf $TESTDIR
5186         mkdir -p $TESTDIR
5187         cd $TESTDIR
5188         links1=2
5189         ls
5190         mkdir a b
5191         ls
5192         links2=$(stat -c %h .)
5193         [ $(($links1 + 2)) != $links2 ] &&
5194                 error "wrong links count $(($links1 + 2)) != $links2"
5195         rmdir b
5196         links3=$(stat -c %h .)
5197         [ $(($links1 + 1)) != $links3 ] &&
5198                 error "wrong links count $links1 != $links3"
5199         return 0
5200 }
5201 run_test 39o "directory cached attributes updated after create"
5202
5203 test_39p() {
5204         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
5205
5206         local MDTIDX=1
5207         TESTDIR=$DIR/$tdir/$tdir
5208         [ -e $TESTDIR ] && rm -rf $TESTDIR
5209         test_mkdir -p $TESTDIR
5210         cd $TESTDIR
5211         links1=2
5212         ls
5213         test_mkdir -i $MDTIDX $TESTDIR/remote_dir1
5214         test_mkdir -i $MDTIDX $TESTDIR/remote_dir2
5215         ls
5216         links2=$(stat -c %h .)
5217         [ $(($links1 + 2)) != $links2 ] &&
5218                 error "wrong links count $(($links1 + 2)) != $links2"
5219         rmdir remote_dir2
5220         links3=$(stat -c %h .)
5221         [ $(($links1 + 1)) != $links3 ] &&
5222                 error "wrong links count $links1 != $links3"
5223         return 0
5224 }
5225 run_test 39p "remote directory cached attributes updated after create ========"
5226
5227 test_39r() {
5228         [ $OST1_VERSION -ge $(version_code 2.13.52) ] ||
5229                 skip "no atime update on old OST"
5230         if [ "$ost1_FSTYPE" != ldiskfs ]; then
5231                 skip_env "ldiskfs only test"
5232         fi
5233
5234         local saved_adiff
5235         saved_adiff=$(do_facet ost1 \
5236                 lctl get_param -n obdfilter.*OST0000.atime_diff)
5237         stack_trap "do_facet ost1 \
5238                 lctl set_param obdfilter.*.atime_diff=$saved_adiff"
5239
5240         do_facet ost1 "lctl set_param obdfilter.*.atime_diff=5"
5241
5242         $LFS setstripe -i 0 $DIR/$tfile
5243         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 ||
5244                 error "can't write initial file"
5245         cancel_lru_locks osc
5246
5247         # exceed atime_diff and access file
5248         sleep 10
5249         dd if=$DIR/$tfile of=/dev/null bs=4k count=1 ||
5250                 error "can't udpate atime"
5251
5252         local atime_cli=$(stat -c %X $DIR/$tfile)
5253         echo "client atime: $atime_cli"
5254         # allow atime update to be written to device
5255         do_facet ost1 "$LCTL set_param -n osd*.*OST*.force_sync 1"
5256         sleep 5
5257
5258         local ostdev=$(ostdevname 1)
5259         local fid=($($LFS getstripe $DIR/$tfile | grep 0x))
5260         local seq=${fid[3]#0x}
5261         local oid=${fid[1]}
5262         local oid_hex
5263
5264         if [ $seq == 0 ]; then
5265                 oid_hex=${fid[1]}
5266         else
5267                 oid_hex=${fid[2]#0x}
5268         fi
5269         local objpath="O/$seq/d$(($oid % 32))/$oid_hex"
5270         local cmd="debugfs -c -R \\\"stat $objpath\\\" $ostdev"
5271
5272         echo "OST atime: $(do_facet ost1 "$cmd" |& grep atime)"
5273         local atime_ost=$(do_facet ost1 "$cmd" |&
5274                           awk -F'[: ]' '/atime:/ { print $4 }')
5275         (( atime_cli == atime_ost )) ||
5276                 error "atime on client $atime_cli != ost $atime_ost"
5277 }
5278 run_test 39r "lazy atime update on OST"
5279
5280 test_39q() { # LU-8041
5281         local testdir=$DIR/$tdir
5282         mkdir -p $testdir
5283         multiop_bg_pause $testdir D_c || error "multiop failed"
5284         local multipid=$!
5285         cancel_lru_locks mdc
5286         kill -USR1 $multipid
5287         local atime=$(stat -c %X $testdir)
5288         [ "$atime" -ne 0 ] || error "atime is zero"
5289 }
5290 run_test 39q "close won't zero out atime"
5291
5292 test_39s() {
5293         local atime0
5294         local atime1
5295         local atime2
5296         local atime3
5297         local atime4
5298
5299         umount_client $MOUNT
5300         mount_client $MOUNT relatime
5301
5302         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 status=noxfer conv=fsync
5303         atime0=$(stat -c %X $DIR/$tfile)
5304
5305         # First read updates atime
5306         sleep 1
5307         cat $DIR/$tfile >/dev/null
5308         atime1=$(stat -c %X $DIR/$tfile) # (atime = atime0 + 1)
5309
5310         # Next reads do not update atime
5311         sleep 1
5312         cat $DIR/$tfile >/dev/null
5313         atime2=$(stat -c %X $DIR/$tfile) # (atime = atime0 + 1)
5314
5315         # If mtime is greater than atime, atime is updated
5316         sleep 1
5317         touch -m $DIR/$tfile # (mtime = now)
5318         sleep 1
5319         cat $DIR/$tfile >/dev/null # (atime is updated because atime < mtime)
5320         atime3=$(stat -c %X $DIR/$tfile) # (atime = mtime = atime0 + 3)
5321
5322         # Next reads do not update atime
5323         sleep 1
5324         cat $DIR/$tfile >/dev/null
5325         atime4=$(stat -c %X $DIR/$tfile)
5326
5327         # Remount the client to clear 'relatime' option
5328         remount_client $MOUNT
5329
5330         (( atime0 < atime1 )) ||
5331                 error "atime $atime0 should be smaller than $atime1"
5332         (( atime1 == atime2 )) ||
5333                 error "atime $atime1 was updated to $atime2"
5334         (( atime1 < atime3 )) || error "atime1 $atime1 != atime3 $atime3"
5335         (( atime3 == atime4 )) || error "atime3 $atime3 != atime4 $atime4"
5336 }
5337 run_test 39s "relatime is supported"
5338
5339 test_40() {
5340         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
5341         $RUNAS $OPENFILE -f O_WRONLY:O_TRUNC $DIR/$tfile &&
5342                 error "openfile O_WRONLY:O_TRUNC $tfile failed"
5343         $CHECKSTAT -t file -s 4096 $DIR/$tfile ||
5344                 error "$tfile is not 4096 bytes in size"
5345 }
5346 run_test 40 "failed open(O_TRUNC) doesn't truncate ============="
5347
5348 test_41() {
5349         # bug 1553
5350         small_write $DIR/f41 18
5351 }
5352 run_test 41 "test small file write + fstat ====================="
5353
5354 count_ost_writes() {
5355         lctl get_param -n ${OSC}.*.stats |
5356                 awk -vwrites=0 '/ost_write/ { writes += $2 } \
5357                         END { printf("%0.0f", writes) }'
5358 }
5359
5360 # decent default
5361 WRITEBACK_SAVE=500
5362 DIRTY_RATIO_SAVE=40
5363 MAX_DIRTY_RATIO=50
5364 BG_DIRTY_RATIO_SAVE=10
5365 MAX_BG_DIRTY_RATIO=25
5366
5367 start_writeback() {
5368         trap 0
5369         # in 2.6, restore /proc/sys/vm/dirty_writeback_centisecs,
5370         # dirty_ratio, dirty_background_ratio
5371         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
5372                 sysctl -w vm.dirty_writeback_centisecs=$WRITEBACK_SAVE
5373                 sysctl -w vm.dirty_background_ratio=$BG_DIRTY_RATIO_SAVE
5374                 sysctl -w vm.dirty_ratio=$DIRTY_RATIO_SAVE
5375         else
5376                 # if file not here, we are a 2.4 kernel
5377                 kill -CONT `pidof kupdated`
5378         fi
5379 }
5380
5381 stop_writeback() {
5382         # setup the trap first, so someone cannot exit the test at the
5383         # exact wrong time and mess up a machine
5384         trap start_writeback EXIT
5385         # in 2.6, save and 0 /proc/sys/vm/dirty_writeback_centisecs
5386         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
5387                 WRITEBACK_SAVE=`sysctl -n vm.dirty_writeback_centisecs`
5388                 sysctl -w vm.dirty_writeback_centisecs=0
5389                 sysctl -w vm.dirty_writeback_centisecs=0
5390                 # save and increase /proc/sys/vm/dirty_ratio
5391                 DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_ratio`
5392                 sysctl -w vm.dirty_ratio=$MAX_DIRTY_RATIO
5393                 # save and increase /proc/sys/vm/dirty_background_ratio
5394                 BG_DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_background_ratio`
5395                 sysctl -w vm.dirty_background_ratio=$MAX_BG_DIRTY_RATIO
5396         else
5397                 # if file not here, we are a 2.4 kernel
5398                 kill -STOP `pidof kupdated`
5399         fi
5400 }
5401
5402 # ensure that all stripes have some grant before we test client-side cache
5403 setup_test42() {
5404         for i in `seq -f $DIR/f42-%g 1 $OSTCOUNT`; do
5405                 dd if=/dev/zero of=$i bs=4k count=1
5406                 rm $i
5407         done
5408 }
5409
5410 # Tests 42* verify that our behaviour is correct WRT caching, file closure,
5411 # file truncation, and file removal.
5412 test_42a() {
5413         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5414
5415         setup_test42
5416         cancel_lru_locks $OSC
5417         stop_writeback
5418         sync; sleep 1; sync # just to be safe
5419         BEFOREWRITES=`count_ost_writes`
5420         lctl get_param -n osc.*[oO][sS][cC][_-]*.cur_grant_bytes | grep "[0-9]"
5421         dd if=/dev/zero of=$DIR/f42a bs=1024 count=100
5422         AFTERWRITES=`count_ost_writes`
5423         [ $BEFOREWRITES -eq $AFTERWRITES ] || \
5424                 error "$BEFOREWRITES < $AFTERWRITES"
5425         start_writeback
5426 }
5427 run_test 42a "ensure that we don't flush on close"
5428
5429 test_42b() {
5430         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5431
5432         setup_test42
5433         cancel_lru_locks $OSC
5434         stop_writeback
5435         sync
5436         dd if=/dev/zero of=$DIR/f42b bs=1024 count=100
5437         BEFOREWRITES=$(count_ost_writes)
5438         $MUNLINK $DIR/f42b || error "$MUNLINK $DIR/f42b: $?"
5439         AFTERWRITES=$(count_ost_writes)
5440         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
5441                 error "$BEFOREWRITES < $AFTERWRITES on unlink"
5442         fi
5443         BEFOREWRITES=$(count_ost_writes)
5444         sync || error "sync: $?"
5445         AFTERWRITES=$(count_ost_writes)
5446         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
5447                 error "$BEFOREWRITES < $AFTERWRITES on sync"
5448         fi
5449         dmesg | grep 'error from obd_brw_async' && error 'error writing back'
5450         start_writeback
5451         return 0
5452 }
5453 run_test 42b "test destroy of file with cached dirty data ======"
5454
5455 # if these tests just want to test the effect of truncation,
5456 # they have to be very careful.  consider:
5457 # - the first open gets a {0,EOF}PR lock
5458 # - the first write conflicts and gets a {0, count-1}PW
5459 # - the rest of the writes are under {count,EOF}PW
5460 # - the open for truncate tries to match a {0,EOF}PR
5461 #   for the filesize and cancels the PWs.
5462 # any number of fixes (don't get {0,EOF} on open, match
5463 # composite locks, do smarter file size management) fix
5464 # this, but for now we want these tests to verify that
5465 # the cancellation with truncate intent works, so we
5466 # start the file with a full-file pw lock to match against
5467 # until the truncate.
5468 trunc_test() {
5469         test=$1
5470         file=$DIR/$test
5471         offset=$2
5472         cancel_lru_locks $OSC
5473         stop_writeback
5474         # prime the file with 0,EOF PW to match
5475         touch $file
5476         $TRUNCATE $file 0
5477         sync; sync
5478         # now the real test..
5479         dd if=/dev/zero of=$file bs=1024 count=100
5480         BEFOREWRITES=`count_ost_writes`
5481         $TRUNCATE $file $offset
5482         cancel_lru_locks $OSC
5483         AFTERWRITES=`count_ost_writes`
5484         start_writeback
5485 }
5486
5487 test_42c() {
5488         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5489
5490         trunc_test 42c 1024
5491         [ $BEFOREWRITES -eq $AFTERWRITES ] &&
5492                 error "beforewrites $BEFOREWRITES == afterwrites $AFTERWRITES on truncate"
5493         rm $file
5494 }
5495 run_test 42c "test partial truncate of file with cached dirty data"
5496
5497 test_42d() {
5498         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5499
5500         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
5501         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
5502         $LCTL set_param debug=+cache
5503
5504         trunc_test 42d 0
5505         [ $BEFOREWRITES -eq $AFTERWRITES ] ||
5506                 error "beforewrites $BEFOREWRITES != afterwrites $AFTERWRITES on truncate"
5507         rm $file
5508 }
5509 run_test 42d "test complete truncate of file with cached dirty data"
5510
5511 test_42e() { # bug22074
5512         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5513
5514         local TDIR=$DIR/${tdir}e
5515         local pages=16 # hardcoded 16 pages, don't change it.
5516         local files=$((OSTCOUNT * 500)) # hopefully 500 files on each OST
5517         local proc_osc0="osc.${FSNAME}-OST0000-osc-[^MDT]*"
5518         local max_dirty_mb
5519         local warmup_files
5520
5521         test_mkdir $DIR/${tdir}e
5522         $LFS setstripe -c 1 $TDIR
5523         createmany -o $TDIR/f $files
5524
5525         max_dirty_mb=$($LCTL get_param -n $proc_osc0/max_dirty_mb)
5526
5527         # we assume that with $OSTCOUNT files, at least one of them will
5528         # be allocated on OST0.
5529         warmup_files=$((OSTCOUNT * max_dirty_mb))
5530         createmany -o $TDIR/w $warmup_files
5531
5532         # write a large amount of data into one file and sync, to get good
5533         # avail_grant number from OST.
5534         for ((i=0; i<$warmup_files; i++)); do
5535                 idx=$($LFS getstripe -i $TDIR/w$i)
5536                 [ $idx -ne 0 ] && continue
5537                 dd if=/dev/zero of=$TDIR/w$i bs="$max_dirty_mb"M count=1
5538                 break
5539         done
5540         [[ $i -gt $warmup_files ]] && error "OST0 is still cold"
5541         sync
5542         $LCTL get_param $proc_osc0/cur_dirty_bytes
5543         $LCTL get_param $proc_osc0/cur_grant_bytes
5544
5545         # create as much dirty pages as we can while not to trigger the actual
5546         # RPCs directly. but depends on the env, VFS may trigger flush during this
5547         # period, hopefully we are good.
5548         for ((i=0; i<$warmup_files; i++)); do
5549                 idx=$($LFS getstripe -i $TDIR/w$i)
5550                 [ $idx -ne 0 ] && continue
5551                 dd if=/dev/zero of=$TDIR/w$i bs=1M count=1 2>/dev/null
5552         done
5553         $LCTL get_param $proc_osc0/cur_dirty_bytes
5554         $LCTL get_param $proc_osc0/cur_grant_bytes
5555
5556         # perform the real test
5557         $LCTL set_param $proc_osc0/rpc_stats 0
5558         for ((;i<$files; i++)); do
5559                 [ $($LFS getstripe -i $TDIR/f$i) -eq 0 ] || continue
5560                 dd if=/dev/zero of=$TDIR/f$i bs=$PAGE_SIZE count=$pages 2>/dev/null
5561         done
5562         sync
5563         $LCTL get_param $proc_osc0/rpc_stats
5564
5565         local percent=0
5566         local have_ppr=false
5567         $LCTL get_param $proc_osc0/rpc_stats |
5568                 while read PPR RRPC RPCT RCUM BAR WRPC WPCT WCUM; do
5569                         # skip lines until we are at the RPC histogram data
5570                         [ "$PPR" == "pages" ] && have_ppr=true && continue
5571                         $have_ppr || continue
5572
5573                         # we only want the percent stat for < 16 pages
5574                         [[ $(echo $PPR | tr -d ':') -ge $pages ]] && break
5575
5576                         percent=$((percent + WPCT))
5577                         if [[ $percent -gt 15 ]]; then
5578                                 error "less than 16-pages write RPCs" \
5579                                       "$percent% > 15%"
5580                                 break
5581                         fi
5582                 done
5583         rm -rf $TDIR
5584 }
5585 run_test 42e "verify sub-RPC writes are not done synchronously"
5586
5587 test_43A() { # was test_43
5588         test_mkdir $DIR/$tdir
5589         cp -p /bin/ls $DIR/$tdir/$tfile
5590         $MULTIOP $DIR/$tdir/$tfile Ow_c &
5591         pid=$!
5592         # give multiop a chance to open
5593         sleep 1
5594
5595         $DIR/$tdir/$tfile && error "execute $DIR/$tdir/$tfile succeeded" || true
5596         kill -USR1 $pid
5597         # Wait for multiop to exit
5598         wait $pid
5599 }
5600 run_test 43A "execution of file opened for write should return -ETXTBSY"
5601
5602 test_43a() {
5603         test_mkdir $DIR/$tdir
5604         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
5605         $DIR/$tdir/sleep 60 &
5606         SLEEP_PID=$!
5607         # Make sure exec of $tdir/sleep wins race with truncate
5608         sleep 1
5609         $MULTIOP $DIR/$tdir/sleep Oc && error "expected error, got success"
5610         kill $SLEEP_PID
5611 }
5612 run_test 43a "open(RDWR) of file being executed should return -ETXTBSY"
5613
5614 test_43b() {
5615         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5616
5617         test_mkdir $DIR/$tdir
5618         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
5619         $DIR/$tdir/sleep 60 &
5620         SLEEP_PID=$!
5621         # Make sure exec of $tdir/sleep wins race with truncate
5622         sleep 1
5623         $TRUNCATE $DIR/$tdir/sleep 0 && error "expected error, got success"
5624         kill $SLEEP_PID
5625 }
5626 run_test 43b "truncate of file being executed should return -ETXTBSY"
5627
5628 test_43c() {
5629         local testdir="$DIR/$tdir"
5630         test_mkdir $testdir
5631         cp $SHELL $testdir/
5632         ( cd $(dirname $SHELL) && md5sum $(basename $SHELL) ) |
5633                 ( cd $testdir && md5sum -c )
5634 }
5635 run_test 43c "md5sum of copy into lustre"
5636
5637 test_44A() { # was test_44
5638         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5639
5640         dd if=/dev/zero of=$DIR/f1 bs=4k count=1 seek=1023
5641         dd if=$DIR/f1 bs=4k count=1 > /dev/null
5642 }
5643 run_test 44A "zero length read from a sparse stripe"
5644
5645 test_44a() {
5646         local nstripe=$($LFS getstripe -c -d $DIR)
5647         [ -z "$nstripe" ] && skip "can't get stripe info"
5648         [[ $nstripe -gt $OSTCOUNT ]] &&
5649                 skip "Wrong default stripe_count: $nstripe OSTCOUNT: $OSTCOUNT"
5650
5651         local stride=$($LFS getstripe -S -d $DIR)
5652         if [[ $nstripe -eq 0 || $nstripe -eq -1 ]]; then
5653                 nstripe=$($LFS df $DIR | grep OST: | wc -l)
5654         fi
5655
5656         OFFSETS="0 $((stride/2)) $((stride-1))"
5657         for offset in $OFFSETS; do
5658                 for i in $(seq 0 $((nstripe-1))); do
5659                         local GLOBALOFFSETS=""
5660                         # size in Bytes
5661                         local size=$((((i + 2 * $nstripe )*$stride + $offset)))
5662                         local myfn=$DIR/d44a-$size
5663                         echo "--------writing $myfn at $size"
5664                         ll_sparseness_write $myfn $size ||
5665                                 error "ll_sparseness_write"
5666                         GLOBALOFFSETS="$GLOBALOFFSETS $size"
5667                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
5668                                 error "ll_sparseness_verify $GLOBALOFFSETS"
5669
5670                         for j in $(seq 0 $((nstripe-1))); do
5671                                 # size in Bytes
5672                                 size=$((((j + $nstripe )*$stride + $offset)))
5673                                 ll_sparseness_write $myfn $size ||
5674                                         error "ll_sparseness_write"
5675                                 GLOBALOFFSETS="$GLOBALOFFSETS $size"
5676                         done
5677                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
5678                                 error "ll_sparseness_verify $GLOBALOFFSETS"
5679                         rm -f $myfn
5680                 done
5681         done
5682 }
5683 run_test 44a "test sparse pwrite ==============================="
5684
5685 dirty_osc_total() {
5686         tot=0
5687         for d in `lctl get_param -n ${OSC}.*.cur_dirty_bytes`; do
5688                 tot=$(($tot + $d))
5689         done
5690         echo $tot
5691 }
5692 do_dirty_record() {
5693         before=`dirty_osc_total`
5694         echo executing "\"$*\""
5695         eval $*
5696         after=`dirty_osc_total`
5697         echo before $before, after $after
5698 }
5699 test_45() {
5700         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5701
5702         f="$DIR/f45"
5703         # Obtain grants from OST if it supports it
5704         echo blah > ${f}_grant
5705         stop_writeback
5706         sync
5707         do_dirty_record "echo blah > $f"
5708         [[ $before -eq $after ]] && error "write wasn't cached"
5709         do_dirty_record "> $f"
5710         [[ $before -gt $after ]] || error "truncate didn't lower dirty count"
5711         do_dirty_record "echo blah > $f"
5712         [[ $before -eq $after ]] && error "write wasn't cached"
5713         do_dirty_record "sync"
5714         [[ $before -gt $after ]] || error "writeback didn't lower dirty count"
5715         do_dirty_record "echo blah > $f"
5716         [[ $before -eq $after ]] && error "write wasn't cached"
5717         do_dirty_record "cancel_lru_locks osc"
5718         [[ $before -gt $after ]] ||
5719                 error "lock cancellation didn't lower dirty count"
5720         start_writeback
5721 }
5722 run_test 45 "osc io page accounting ============================"
5723
5724 # in a 2 stripe file (lov.sh), page 1023 maps to page 511 in its object.  this
5725 # test tickles a bug where re-dirtying a page was failing to be mapped to the
5726 # objects offset and an assert hit when an rpc was built with 1023's mapped
5727 # offset 511 and 511's raw 511 offset. it also found general redirtying bugs.
5728 test_46() {
5729         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5730
5731         f="$DIR/f46"
5732         stop_writeback
5733         sync
5734         dd if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5735         sync
5736         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=1023 count=1
5737         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5738         sync
5739         start_writeback
5740 }
5741 run_test 46 "dirtying a previously written page ================"
5742
5743 # test_47 is removed "Device nodes check" is moved to test_28
5744
5745 test_48a() { # bug 2399
5746         [ "$mds1_FSTYPE" = "zfs" ] &&
5747         [ $MDS1_VERSION -lt $(version_code 2.3.63) ] &&
5748                 skip "MDS prior to 2.3.63 handle ZFS dir .. incorrectly"
5749
5750         test_mkdir $DIR/$tdir
5751         cd $DIR/$tdir
5752         mv $DIR/$tdir $DIR/$tdir.new || error "move directory failed"
5753         test_mkdir $DIR/$tdir
5754         touch foo || error "'touch foo' failed after recreating cwd"
5755         test_mkdir bar
5756         touch .foo || error "'touch .foo' failed after recreating cwd"
5757         test_mkdir .bar
5758         ls . > /dev/null || error "'ls .' failed after recreating cwd"
5759         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5760         cd . || error "'cd .' failed after recreating cwd"
5761         mkdir . && error "'mkdir .' worked after recreating cwd"
5762         rmdir . && error "'rmdir .' worked after recreating cwd"
5763         ln -s . baz || error "'ln -s .' failed after recreating cwd"
5764         cd .. || error "'cd ..' failed after recreating cwd"
5765 }
5766 run_test 48a "Access renamed working dir (should return errors)="
5767
5768 test_48b() { # bug 2399
5769         rm -rf $DIR/$tdir
5770         test_mkdir $DIR/$tdir
5771         cd $DIR/$tdir
5772         rmdir $DIR/$tdir || error "remove cwd $DIR/$tdir failed"
5773         touch foo && error "'touch foo' worked after removing cwd"
5774         mkdir foo && error "'mkdir foo' worked after removing cwd"
5775         touch .foo && error "'touch .foo' worked after removing cwd"
5776         mkdir .foo && error "'mkdir .foo' worked after removing cwd"
5777         ls . > /dev/null && error "'ls .' worked after removing cwd"
5778         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5779         mkdir . && error "'mkdir .' worked after removing cwd"
5780         rmdir . && error "'rmdir .' worked after removing cwd"
5781         ln -s . foo && error "'ln -s .' worked after removing cwd"
5782         cd .. || echo "'cd ..' failed after removing cwd `pwd`"  #bug 3517
5783 }
5784 run_test 48b "Access removed working dir (should return errors)="
5785
5786 test_48c() { # bug 2350
5787         #lctl set_param debug=-1
5788         #set -vx
5789         rm -rf $DIR/$tdir
5790         test_mkdir -p $DIR/$tdir/dir
5791         cd $DIR/$tdir/dir
5792         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5793         $TRACE touch foo && error "touch foo worked after removing cwd"
5794         $TRACE mkdir foo && error "'mkdir foo' worked after removing cwd"
5795         touch .foo && error "touch .foo worked after removing cwd"
5796         mkdir .foo && error "mkdir .foo worked after removing cwd"
5797         $TRACE ls . && error "'ls .' worked after removing cwd"
5798         $TRACE ls .. || error "'ls ..' failed after removing cwd"
5799         $TRACE mkdir . && error "'mkdir .' worked after removing cwd"
5800         $TRACE rmdir . && error "'rmdir .' worked after removing cwd"
5801         $TRACE ln -s . foo && error "'ln -s .' worked after removing cwd"
5802         $TRACE cd .. || echo "'cd ..' failed after removing cwd `pwd`" #bug 3415
5803 }
5804 run_test 48c "Access removed working subdir (should return errors)"
5805
5806 test_48d() { # bug 2350
5807         #lctl set_param debug=-1
5808         #set -vx
5809         rm -rf $DIR/$tdir
5810         test_mkdir -p $DIR/$tdir/dir
5811         cd $DIR/$tdir/dir
5812         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5813         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5814         $TRACE touch foo && error "'touch foo' worked after removing parent"
5815         $TRACE mkdir foo && error "mkdir foo worked after removing parent"
5816         touch .foo && error "'touch .foo' worked after removing parent"
5817         mkdir .foo && error "mkdir .foo worked after removing parent"
5818         $TRACE ls . && error "'ls .' worked after removing parent"
5819         $TRACE ls .. && error "'ls ..' worked after removing parent"
5820         $TRACE mkdir . && error "'mkdir .' worked after removing parent"
5821         $TRACE rmdir . && error "'rmdir .' worked after removing parent"
5822         $TRACE ln -s . foo && error "'ln -s .' worked after removing parent"
5823         true
5824 }
5825 run_test 48d "Access removed parent subdir (should return errors)"
5826
5827 test_48e() { # bug 4134
5828         #lctl set_param debug=-1
5829         #set -vx
5830         rm -rf $DIR/$tdir
5831         test_mkdir -p $DIR/$tdir/dir
5832         cd $DIR/$tdir/dir
5833         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5834         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5835         $TRACE touch $DIR/$tdir || error "'touch $DIR/$tdir' failed"
5836         $TRACE chmod +x $DIR/$tdir || error "'chmod +x $DIR/$tdir' failed"
5837         # On a buggy kernel addition of "touch foo" after cd .. will
5838         # produce kernel oops in lookup_hash_it
5839         touch ../foo && error "'cd ..' worked after recreate parent"
5840         cd $DIR
5841         $TRACE rm $DIR/$tdir || error "rm '$DIR/$tdir' failed"
5842 }
5843 run_test 48e "Access to recreated parent subdir (should return errors)"
5844
5845 test_48f() {
5846         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
5847                 skip "need MDS >= 2.13.55"
5848         [[ $MDSCOUNT -ge 2 ]] || skip "needs >= 2 MDTs"
5849         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] ||
5850                 skip "needs different host for mdt1 mdt2"
5851         [[ $(facet_fstype mds1) == ldiskfs ]] || skip "ldiskfs only"
5852
5853         $LFS mkdir -i0 $DIR/$tdir
5854         $LFS mkdir -i 1 $DIR/$tdir/sub1 $DIR/$tdir/sub2 $DIR/$tdir/sub3
5855
5856         for d in sub1 sub2 sub3; do
5857                 #define OBD_FAIL_OSD_REF_DEL    0x19c
5858                 do_facet mds1 $LCTL set_param fail_loc=0x8000019c
5859                 rm -rf $DIR/$tdir/$d && error "rm $d should fail"
5860         done
5861
5862         rm -d --interactive=never $DIR/$tdir || error "rm $tdir fail"
5863 }
5864 run_test 48f "non-zero nlink dir unlink won't LBUG()"
5865
5866 test_49() { # LU-1030
5867         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5868         remote_ost_nodsh && skip "remote OST with nodsh"
5869
5870         # get ost1 size - $FSNAME-OST0000
5871         ost1_size=$(do_facet ost1 $LFS df | grep ${ost1_svc} |
5872                 awk '{ print $4 }')
5873         # write 800M at maximum
5874         [[ $ost1_size -lt 2 ]] && ost1_size=2
5875         [[ $ost1_size -gt 819200 ]] && ost1_size=819200
5876
5877         $LFS setstripe -c 1 -i 0 $DIR/$tfile
5878         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((ost1_size >> 2)) &
5879         local dd_pid=$!
5880
5881         # change max_pages_per_rpc while writing the file
5882         local osc1_mppc=osc.$(get_osc_import_name client ost1).max_pages_per_rpc
5883         local orig_mppc=$($LCTL get_param -n $osc1_mppc)
5884         # loop until dd process exits
5885         while ps ax -opid | grep -wq $dd_pid; do
5886                 $LCTL set_param $osc1_mppc=$((RANDOM % 256 + 1))
5887                 sleep $((RANDOM % 5 + 1))
5888         done
5889         # restore original max_pages_per_rpc
5890         $LCTL set_param $osc1_mppc=$orig_mppc
5891         rm $DIR/$tfile || error "rm $DIR/$tfile failed"
5892 }
5893 run_test 49 "Change max_pages_per_rpc won't break osc extent"
5894
5895 test_50() {
5896         # bug 1485
5897         test_mkdir $DIR/$tdir
5898         cd $DIR/$tdir
5899         ls /proc/$$/cwd || error "ls /proc/$$/cwd failed"
5900 }
5901 run_test 50 "special situations: /proc symlinks  ==============="
5902
5903 test_51a() {    # was test_51
5904         # bug 1516 - create an empty entry right after ".." then split dir
5905         test_mkdir -c1 $DIR/$tdir
5906         touch $DIR/$tdir/foo
5907         $MCREATE $DIR/$tdir/bar
5908         rm $DIR/$tdir/foo
5909         createmany -m $DIR/$tdir/longfile 201
5910         FNUM=202
5911         while [[ $(ls -sd $DIR/$tdir | awk '{ print $1 }') -eq 4 ]]; do
5912                 $MCREATE $DIR/$tdir/longfile$FNUM
5913                 FNUM=$(($FNUM + 1))
5914                 echo -n "+"
5915         done
5916         echo
5917         ls -l $DIR/$tdir > /dev/null || error "ls -l $DIR/$tdir failed"
5918 }
5919 run_test 51a "special situations: split htree with empty entry =="
5920
5921 cleanup_print_lfs_df () {
5922         trap 0
5923         $LFS df
5924         $LFS df -i
5925 }
5926
5927 test_51b() {
5928         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5929
5930         local dir=$DIR/$tdir
5931         local nrdirs=$((65536 + 100))
5932
5933         # cleanup the directory
5934         rm -fr $dir
5935
5936         mkdir_on_mdt -i $((RANDOM % MDSCOUNT)) $dir
5937
5938         $LFS df
5939         $LFS df -i
5940         local mdtidx=$(printf "%04x" $($LFS getstripe -m $dir))
5941         local numfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.filesfree)
5942         [[ $numfree -lt $nrdirs ]] &&
5943                 skip "not enough free inodes ($numfree) on MDT$mdtidx"
5944
5945         # need to check free space for the directories as well
5946         local blkfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.kbytesavail)
5947         numfree=$(( blkfree / $(fs_inode_ksize) ))
5948         [[ $numfree -lt $nrdirs ]] && skip "not enough blocks ($numfree)"
5949
5950         trap cleanup_print_lfs_df EXIT
5951
5952         # create files
5953         createmany -d $dir/d $nrdirs || {
5954                 unlinkmany $dir/d $nrdirs
5955                 error "failed to create $nrdirs subdirs in MDT$mdtidx:$dir"
5956         }
5957
5958         # really created :
5959         nrdirs=$(ls -U $dir | wc -l)
5960
5961         # unlink all but 100 subdirectories, then check it still works
5962         local left=100
5963         local delete=$((nrdirs - left))
5964
5965         $LFS df
5966         $LFS df -i
5967
5968         # for ldiskfs the nlink count should be 1, but this is OSD specific
5969         # and so this is listed for informational purposes only
5970         echo "nlink before: $(stat -c %h $dir), created before: $nrdirs"
5971         unlinkmany -d $dir/d $delete ||
5972                 error "unlink of first $delete subdirs failed"
5973
5974         echo "nlink between: $(stat -c %h $dir)"
5975         local found=$(ls -U $dir | wc -l)
5976         [ $found -ne $left ] &&
5977                 error "can't find subdirs: found only $found, expected $left"
5978
5979         unlinkmany -d $dir/d $delete $left ||
5980                 error "unlink of second $left subdirs failed"
5981         # regardless of whether the backing filesystem tracks nlink accurately
5982         # or not, the nlink count shouldn't be more than "." and ".." here
5983         local after=$(stat -c %h $dir)
5984         [[ $after -gt 2 ]] && error "nlink after: $after > 2" ||
5985                 echo "nlink after: $after"
5986
5987         cleanup_print_lfs_df
5988 }
5989 run_test 51b "exceed 64k subdirectory nlink limit on create, verify unlink"
5990
5991 test_51d_sub() {
5992         local stripecount=$1
5993         local nfiles=$2
5994
5995         log "create files with stripecount=$stripecount"
5996         $LFS setstripe -C $stripecount $DIR/$tdir
5997         createmany -o $DIR/$tdir/t- $nfiles
5998         $LFS getstripe $DIR/$tdir > $TMP/$tfile
5999         for ((n = 0; n < $OSTCOUNT; n++)); do
6000                 objs[$n]=$(awk -vobjs=0 '($1 == '$n') { objs += 1 } \
6001                            END { printf("%0.0f", objs) }' $TMP/$tfile)
6002                 objs0[$n]=$(grep -A 1 idx $TMP/$tfile | awk -vobjs=0 \
6003                             '($1 == '$n') { objs += 1 } \
6004                             END { printf("%0.0f", objs) }')
6005                 log "OST$n has ${objs[$n]} objects, ${objs0[$n]} are index 0"
6006         done
6007         unlinkmany $DIR/$tdir/t- $nfiles
6008         rm  -f $TMP/$tfile
6009
6010         local nlast
6011         local min=4
6012         local max=6 # allow variance of (1 - $min/$max) = 33% by default
6013
6014         # For some combinations of stripecount and OSTCOUNT current code
6015         # is not ideal, and allocates 50% fewer *first* objects to some OSTs
6016         # than others. Rather than skipping this test entirely, check that
6017         # and keep testing to ensure imbalance does not get worse. LU-15282
6018         (( (OSTCOUNT == 6 && stripecount == 4) ||
6019            (OSTCOUNT == 10 && (stripecount == 4 || stripecount == 8)) ||
6020            (OSTCOUNT == 12 && (stripecount == 8 || stripecount == 9)))) && max=9
6021         for ((nlast=0, n = 1; n < $OSTCOUNT; nlast=n,n++)); do
6022                 (( ${objs[$n]} > ${objs[$nlast]} * 4 / 5 )) ||
6023                         { $LFS df && $LFS df -i &&
6024                         error "stripecount=$stripecount: " \
6025                               "OST $n has fewer objects vs. OST $nlast " \
6026                               "(${objs[$n]} < ${objs[$nlast]} x 4/5)"; }
6027                 (( ${objs[$n]} < ${objs[$nlast]} * 5 / 4 )) ||
6028                         { $LFS df && $LFS df -i &&
6029                         error "stripecount=$stripecount: " \
6030                               "OST $n has more objects vs. OST $nlast " \
6031                               "(${objs[$n]} > ${objs[$nlast]} x 5/4)"; }
6032
6033                 (( ${objs0[$n]} > ${objs0[$nlast]} * $min / $max )) ||
6034                         { $LFS df && $LFS df -i &&
6035                         error "stripecount=$stripecount: " \
6036                               "OST $n has fewer #0 objects vs. OST $nlast " \
6037                               "(${objs0[$n]} < ${objs0[$nlast]} x $min/$max)"; }
6038                 (( ${objs0[$n]} < ${objs0[$nlast]} * $max / $min )) ||
6039                         { $LFS df && $LFS df -i &&
6040                         error "stripecount=$stripecount: " \
6041                               "OST $n has more #0 objects vs. OST $nlast " \
6042                               "(${objs0[$n]} > ${objs0[$nlast]} x $max/$min)"; }
6043         done
6044 }
6045
6046 test_51d() {
6047         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6048         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
6049
6050         local stripecount
6051         local per_ost=100
6052         local nfiles=$((per_ost * OSTCOUNT))
6053         local mdts=$(comma_list $(mdts_nodes))
6054         local param="osp.*.create_count"
6055         local qos_old=$(do_facet mds1 \
6056                 "$LCTL get_param -n lod.$FSNAME-*.qos_threshold_rr" | head -n 1)
6057
6058         do_nodes $mdts \
6059                 "$LCTL set_param lod.$FSNAME-*.qos_threshold_rr=100"
6060         stack_trap "do_nodes $mdts \
6061                 '$LCTL set_param lod.$FSNAME-*.qos_threshold_rr=${qos_old%%%}'"
6062
6063         test_mkdir $DIR/$tdir
6064         local dirstripes=$(lfs getdirstripe -c $DIR/$tdir)
6065         (( dirstripes > 0 )) || dirstripes=1
6066
6067         # Ensure enough OST objects precreated for tests to pass without
6068         # running out of objects.  This is an LOV r-r OST algorithm test,
6069         # not an OST object precreation test.
6070         local old=$(do_facet mds1 "$LCTL get_param -n $param" | head -n 1)
6071         (( old >= nfiles )) ||
6072         {
6073                 local create_count=$((nfiles * OSTCOUNT / dirstripes))
6074
6075                 do_nodes $mdts "$LCTL set_param $param=$create_count"
6076                 stack_trap "do_nodes $mdts $LCTL set_param $param=$old"
6077
6078                 # trigger precreation from all MDTs for all OSTs
6079                 for ((i = 0; i < $MDSCOUNT * 2; i++ )); do
6080                         $LFS setstripe -c -1 $DIR/$tdir/wide.$i
6081                 done
6082         }
6083
6084         for ((stripecount = 3; stripecount <= $OSTCOUNT; stripecount++)); do
6085                 sleep 8  # allow object precreation to catch up
6086                 test_51d_sub $stripecount $nfiles
6087         done
6088 }
6089 run_test 51d "check LOV round-robin OST object distribution"
6090
6091 test_51e() {
6092         if [ "$mds1_FSTYPE" != ldiskfs ]; then
6093                 skip_env "ldiskfs only test"
6094         fi
6095
6096         test_mkdir -c1 $DIR/$tdir
6097         test_mkdir -c1 $DIR/$tdir/d0
6098
6099         touch $DIR/$tdir/d0/foo
6100         createmany -l $DIR/$tdir/d0/foo $DIR/$tdir/d0/f- 65001 &&
6101                 error "file exceed 65000 nlink limit!"
6102         unlinkmany $DIR/$tdir/d0/f- 65001
6103         return 0
6104 }
6105 run_test 51e "check file nlink limit"
6106
6107 test_51f() {
6108         test_mkdir $DIR/$tdir
6109
6110         local max=100000
6111         local ulimit_old=$(ulimit -n)
6112         local spare=20 # number of spare fd's for scripts/libraries, etc.
6113         local mdt=$($LFS getstripe -m $DIR/$tdir)
6114         local numfree=$($LFS df -i $DIR/$tdir | awk '/MDT:'$mdt'/ { print $4 }')
6115
6116         echo "MDT$mdt numfree=$numfree, max=$max"
6117         [[ $numfree -gt $max ]] && numfree=$max || numfree=$((numfree * 7 / 8))
6118         if [ $((numfree + spare)) -gt $ulimit_old ]; then
6119                 while ! ulimit -n $((numfree + spare)); do
6120                         numfree=$((numfree * 3 / 4))
6121                 done
6122                 echo "changed ulimit from $ulimit_old to $((numfree + spare))"
6123         else
6124                 echo "left ulimit at $ulimit_old"
6125         fi
6126
6127         createmany -o -k -t 120 $DIR/$tdir/f $numfree || {
6128                 unlinkmany $DIR/$tdir/f $numfree
6129                 error "create+open $numfree files in $DIR/$tdir failed"
6130         }
6131         ulimit -n $ulimit_old
6132
6133         # if createmany exits at 120s there will be fewer than $numfree files
6134         unlinkmany $DIR/$tdir/f $numfree || true
6135 }
6136 run_test 51f "check many open files limit"
6137
6138 test_52a() {
6139         [ -f $DIR/$tdir/foo ] && chattr -a $DIR/$tdir/foo
6140         test_mkdir $DIR/$tdir
6141         touch $DIR/$tdir/foo
6142         chattr +a $DIR/$tdir/foo || error "chattr +a failed"
6143         echo bar >> $DIR/$tdir/foo || error "append bar failed"
6144         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
6145         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
6146         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
6147                                         error "link worked"
6148         echo foo >> $DIR/$tdir/foo || error "append foo failed"
6149         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
6150         lsattr $DIR/$tdir/foo | egrep -q "^-+a[-e]+ $DIR/$tdir/foo" ||
6151                                                      error "lsattr"
6152         chattr -a $DIR/$tdir/foo || error "chattr -a failed"
6153         cp -r $DIR/$tdir $TMP/
6154         rm -fr $DIR/$tdir $TMP/$tdir || error "cleanup rm failed"
6155 }
6156 run_test 52a "append-only flag test (should return errors)"
6157
6158 test_52b() {
6159         [ -f $DIR/$tdir/foo ] && chattr -i $DIR/$tdir/foo
6160         test_mkdir $DIR/$tdir
6161         touch $DIR/$tdir/foo
6162         chattr +i $DIR/$tdir/foo || error "chattr +i failed"
6163         cat test > $DIR/$tdir/foo && error "cat test worked"
6164         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
6165         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
6166         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
6167                                         error "link worked"
6168         echo foo >> $DIR/$tdir/foo && error "echo worked"
6169         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
6170         [ -f $DIR/$tdir/foo ] || error "$tdir/foo is not a file"
6171         [ -f $DIR/$tdir/foo_ren ] && error "$tdir/foo_ren is not a file"
6172         lsattr $DIR/$tdir/foo | egrep -q "^-+i[-e]+ $DIR/$tdir/foo" ||
6173                                                         error "lsattr"
6174         chattr -i $DIR/$tdir/foo || error "chattr failed"
6175
6176         rm -fr $DIR/$tdir || error "unable to remove $DIR/$tdir"
6177 }
6178 run_test 52b "immutable flag test (should return errors) ======="
6179
6180 test_53() {
6181         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6182         remote_mds_nodsh && skip "remote MDS with nodsh"
6183         remote_ost_nodsh && skip "remote OST with nodsh"
6184
6185         local param
6186         local param_seq
6187         local ostname
6188         local mds_last
6189         local mds_last_seq
6190         local ost_last
6191         local ost_last_seq
6192         local ost_last_id
6193         local ostnum
6194         local node
6195         local found=false
6196         local support_last_seq=true
6197
6198         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
6199                 support_last_seq=false
6200
6201         # only test MDT0000
6202         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS)
6203         local value
6204         for value in $(do_facet $SINGLEMDS \
6205                        $LCTL get_param osp.$mdtosc.prealloc_last_id) ; do
6206                 param=$(echo ${value[0]} | cut -d "=" -f1)
6207                 ostname=$(echo $param | cut -d "." -f2 | cut -d - -f 1-2)
6208
6209                 if $support_last_seq; then
6210                         param_seq=$(echo $param |
6211                                 sed -e s/prealloc_last_id/prealloc_last_seq/g)
6212                         mds_last_seq=$(do_facet $SINGLEMDS \
6213                                        $LCTL get_param -n $param_seq)
6214                 fi
6215                 mds_last=$(do_facet $SINGLEMDS $LCTL get_param -n $param)
6216
6217                 ostnum=$(index_from_ostuuid ${ostname}_UUID)
6218                 node=$(facet_active_host ost$((ostnum+1)))
6219                 param="obdfilter.$ostname.last_id"
6220                 for ost_last in $(do_node $node $LCTL get_param -n $param) ; do
6221                         echo "$ostname.last_id=$ost_last; MDS.last_id=$mds_last"
6222                         ost_last_id=$ost_last
6223
6224                         if $support_last_seq; then
6225                                 ost_last_id=$(echo $ost_last |
6226                                               awk -F':' '{print $2}' |
6227                                               sed -e "s/^0x//g")
6228                                 ost_last_seq=$(echo $ost_last |
6229                                                awk -F':' '{print $1}')
6230                                 [[ $ost_last_seq = $mds_last_seq ]] || continue
6231                         fi
6232
6233                         if [[ $ost_last_id != $mds_last ]]; then
6234                                 error "$ost_last_id != $mds_last"
6235                         else
6236                                 found=true
6237                                 break
6238                         fi
6239                 done
6240         done
6241         $found || error "can not match last_seq/last_id for $mdtosc"
6242         return 0
6243 }
6244 run_test 53 "verify that MDS and OSTs agree on pre-creation ===="
6245
6246 test_54a() {
6247         LANG=C perl -MSocket -e ';' || skip "no Socket perl module installed"
6248
6249         LANG=C $SOCKETSERVER $DIR/socket ||
6250                 error "$SOCKETSERVER $DIR/socket failed: $?"
6251         LANG=C $SOCKETCLIENT $DIR/socket ||
6252                 error "$SOCKETCLIENT $DIR/socket failed: $?"
6253         $MUNLINK $DIR/socket || error "$MUNLINK $DIR/socket failed: $?"
6254 }
6255 run_test 54a "unix domain socket test =========================="
6256
6257 test_54b() {
6258         f="$DIR/f54b"
6259         mknod $f c 1 3
6260         chmod 0666 $f
6261         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1
6262 }
6263 run_test 54b "char device works in lustre ======================"
6264
6265 find_loop_dev() {
6266         [ -b /dev/loop/0 ] && LOOPBASE=/dev/loop/
6267         [ -b /dev/loop0 ] && LOOPBASE=/dev/loop
6268         [ -z "$LOOPBASE" ] && echo "/dev/loop/0 and /dev/loop0 gone?" && return
6269
6270         for i in $(seq 3 7); do
6271                 losetup $LOOPBASE$i > /dev/null 2>&1 && continue
6272                 LOOPDEV=$LOOPBASE$i
6273                 LOOPNUM=$i
6274                 break
6275         done
6276 }
6277
6278 cleanup_54c() {
6279         local rc=0
6280         loopdev="$DIR/loop54c"
6281
6282         trap 0
6283         $UMOUNT $DIR/$tdir || rc=$?
6284         losetup -d $loopdev || true
6285         losetup -d $LOOPDEV || true
6286         rm -rf $loopdev $DIR/$tfile $DIR/$tdir
6287         return $rc
6288 }
6289
6290 test_54c() {
6291         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6292
6293         loopdev="$DIR/loop54c"
6294
6295         find_loop_dev
6296         [ -z "$LOOPNUM" ] && skip_env "couldn't find empty loop device"
6297         trap cleanup_54c EXIT
6298         mknod $loopdev b 7 $LOOPNUM
6299         echo "make a loop file system with $DIR/$tfile on $loopdev ($LOOPNUM)."
6300         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE seek=1024 count=1 > /dev/null
6301         losetup $loopdev $DIR/$tfile ||
6302                 error "can't set up $loopdev for $DIR/$tfile"
6303         mkfs.ext2 $loopdev || error "mke2fs on $loopdev"
6304         test_mkdir $DIR/$tdir
6305         mount -t ext2 $loopdev $DIR/$tdir ||
6306                 error "error mounting $loopdev on $DIR/$tdir"
6307         dd if=/dev/zero of=$DIR/$tdir/tmp bs=$PAGE_SIZE count=30 ||
6308                 error "dd write"
6309         df $DIR/$tdir
6310         dd if=$DIR/$tdir/tmp of=/dev/zero bs=$PAGE_SIZE count=30 ||
6311                 error "dd read"
6312         cleanup_54c
6313 }
6314 run_test 54c "block device works in lustre ====================="
6315
6316 test_54d() {
6317         local pipe="$DIR/$tfile.pipe"
6318         local string="aaaaaa"
6319
6320         mknod $pipe p
6321         echo -n "$string" > $pipe &
6322         local result=$(cat $pipe)
6323         [[ "$result" == "$string" ]] || error "$result != $string"
6324 }
6325 run_test 54d "fifo device works in lustre ======================"
6326
6327 test_54e() {
6328         f="$DIR/f54e"
6329         string="aaaaaa"
6330         cp -aL /dev/console $f
6331         echo $string > $f || error "echo $string to $f failed"
6332 }
6333 run_test 54e "console/tty device works in lustre ======================"
6334
6335 test_56a() {
6336         local numfiles=3
6337         local numdirs=2
6338         local dir=$DIR/$tdir
6339
6340         rm -rf $dir
6341         test_mkdir -p $dir/dir
6342         for i in $(seq $numfiles); do
6343                 touch $dir/file$i
6344                 touch $dir/dir/file$i
6345         done
6346
6347         local numcomp=$($LFS getstripe --component-count $dir)
6348
6349         [[ $numcomp == 0 ]] && numcomp=1
6350
6351         # test lfs getstripe with --recursive
6352         local filenum=$($LFS getstripe -r $dir | egrep -c "obdidx|l_ost_idx")
6353
6354         [[ $filenum -eq $((numfiles * 2)) ]] ||
6355                 error "$LFS getstripe -r: found $filenum != $((numfiles * 2))"
6356         filenum=$($LFS getstripe $dir | egrep -c "obdidx|l_ost_idx")
6357         [[ $filenum -eq $numfiles ]] ||
6358                 error "$LFS getstripe $dir: found $filenum, not $numfiles"
6359         echo "$LFS getstripe showed obdidx or l_ost_idx"
6360
6361         # test lfs getstripe with file instead of dir
6362         filenum=$($LFS getstripe $dir/file1 | egrep -c "obdidx|l_ost_idx")
6363         [[ $filenum -eq 1 ]] ||
6364                 error "$LFS getstripe $dir/file1: found $filenum, not 1"
6365         echo "$LFS getstripe file1 passed"
6366
6367         #test lfs getstripe with --verbose
6368         filenum=$($LFS getstripe --verbose $dir | grep -c lmm_magic)
6369         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
6370                 error "$LFS getstripe --verbose $dir: "\
6371                       "got $filenum want $((numfiles * numcomp)) lmm_magic"
6372         [[ $($LFS getstripe $dir | grep -c lmm_magic) -eq 0 ]] ||
6373                 error "$LFS getstripe $dir: showed lmm_magic"
6374
6375         #test lfs getstripe with -v prints lmm_fid
6376         filenum=$($LFS getstripe -v $dir | grep -c lmm_fid)
6377         local countfids=$((numdirs + numfiles * numcomp))
6378         [[ $filenum -eq $countfids ]] ||
6379                 error "$LFS getstripe -v $dir: "\
6380                       "got $filenum want $countfids lmm_fid"
6381         [[ $($LFS getstripe $dir | grep -c lmm_fid) -eq 0 ]] ||
6382                 error "$LFS getstripe $dir: showed lmm_fid by default"
6383         echo "$LFS getstripe --verbose passed"
6384
6385         #check for FID information
6386         local fid1=$($LFS getstripe --fid $dir/file1)
6387         local fid2=$($LFS getstripe --verbose $dir/file1 |
6388                      awk '/lmm_fid: / { print $2; exit; }')
6389         local fid3=$($LFS path2fid $dir/file1)
6390
6391         [ "$fid1" != "$fid2" ] &&
6392                 error "getstripe --fid '$fid1' != getstripe --verbose '$fid2'"
6393         [ "$fid1" != "$fid3" ] &&
6394                 error "getstripe --fid '$fid1' != lfs path2fid '$fid3'"
6395         echo "$LFS getstripe --fid passed"
6396
6397         #test lfs getstripe with --obd
6398         $LFS getstripe --obd wrong_uuid $dir 2>&1 | grep -q "unknown obduuid" ||
6399                 error "$LFS getstripe --obd wrong_uuid: should return error"
6400
6401         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6402
6403         local ostidx=1
6404         local obduuid=$(ostuuid_from_index $ostidx)
6405         local found=$($LFS getstripe -r --obd $obduuid $dir |
6406                 grep 'lmm_stripe_offset:' | grep -c " $ostidx\$")
6407
6408         filenum=$($LFS getstripe -ir $dir | grep -c "^$ostidx\$")
6409         [[ $($LFS getstripe -id $dir) -ne $ostidx ]] ||
6410                 ((filenum--))
6411         [[ $($LFS getstripe -id $dir/dir) -ne $ostidx ]] ||
6412                 ((filenum--))
6413
6414         [[ $found -eq $filenum ]] ||
6415                 error "$LFS getstripe --obd: found $found expect $filenum"
6416         [[ $($LFS getstripe -r -v --obd $obduuid $dir |
6417                 sed '/^[         ]*'${ostidx}'[  ]/d' |
6418                 sed -n '/^[      ]*[0-9][0-9]*[  ]/p' | wc -l) -eq 0 ]] ||
6419                 error "$LFS getstripe --obd: should not show file on other obd"
6420         echo "$LFS getstripe --obd passed"
6421 }
6422 run_test 56a "check $LFS getstripe"
6423
6424 test_56b() {
6425         local dir=$DIR/$tdir
6426         local numdirs=3
6427
6428         test_mkdir $dir
6429         for i in $(seq $numdirs); do
6430                 test_mkdir $dir/dir$i
6431         done
6432
6433         # test lfs getdirstripe default mode is non-recursion, which is
6434         # different from lfs getstripe
6435         local dircnt=$($LFS getdirstripe $dir | grep -c lmv_stripe_count)
6436
6437         [[ $dircnt -eq 1 ]] ||
6438                 error "$LFS getdirstripe: found $dircnt, not 1"
6439         dircnt=$($LFS getdirstripe --recursive $dir |
6440                 grep -c lmv_stripe_count)
6441         [[ $dircnt -eq $((numdirs + 1)) ]] ||
6442                 error "$LFS getdirstripe -r: $dircnt, != $((numdirs + 1))"
6443 }
6444 run_test 56b "check $LFS getdirstripe"
6445
6446 test_56bb() {
6447         verify_yaml_available || skip_env "YAML verification not installed"
6448         local output_file=$DIR/$tfile.out
6449
6450         $LFS getdirstripe -v -D -y $DIR 1> $output_file
6451
6452         cat $output_file
6453         cat $output_file | verify_yaml || error "layout is not valid YAML"
6454 }
6455 run_test 56bb "check $LFS getdirstripe layout is YAML"
6456
6457 test_56c() {
6458         remote_ost_nodsh && skip "remote OST with nodsh"
6459
6460         local ost_idx=0
6461         local ost_name=$(ostname_from_index $ost_idx)
6462         local old_status=$(ost_dev_status $ost_idx)
6463         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
6464
6465         [[ -z "$old_status" ]] ||
6466                 skip_env "OST $ost_name is in $old_status status"
6467
6468         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=1
6469         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
6470                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=1
6471         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
6472                 save_lustre_params ost1 osd-*.$ost_name.nonrotational > $p
6473                 do_facet ost1 $LCTL set_param -n osd-*.$ost_name.nonrotational=1
6474         fi
6475
6476         [[ $($LFS df -v $MOUNT |& grep -c "inactive device") -eq 0 ]] ||
6477                 error "$LFS df -v showing inactive devices"
6478         sleep_maxage
6479
6480         local new_status=$(ost_dev_status $ost_idx $MOUNT -v)
6481
6482         [[ "$new_status" =~ "D" ]] ||
6483                 error "$ost_name status is '$new_status', missing 'D'"
6484         if [[ $OST1_VERSION -ge $(version_code 2.12.55) ]]; then
6485                 [[ "$new_status" =~ "N" ]] ||
6486                         error "$ost_name status is '$new_status', missing 'N'"
6487         fi
6488         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
6489                 [[ "$new_status" =~ "f" ]] ||
6490                         error "$ost_name status is '$new_status', missing 'f'"
6491         fi
6492
6493         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=0
6494         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
6495                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=0
6496         [[ -z "$p" ]] && restore_lustre_params < $p || true
6497         sleep_maxage
6498
6499         new_status=$(ost_dev_status $ost_idx)
6500         [[ ! "$new_status" =~ "D" && ! "$new_status" =~ "N" ]] ||
6501                 error "$ost_name status is '$new_status', has 'D' and/or 'N'"
6502         # can't check 'f' as devices may actually be on flash
6503 }
6504 run_test 56c "check 'lfs df' showing device status"
6505
6506 test_56d() {
6507         local mdts=$($LFS df -v $MOUNT | grep -c MDT)
6508         local osts=$($LFS df -v $MOUNT | grep -c OST)
6509
6510         $LFS df $MOUNT
6511
6512         (( mdts == MDSCOUNT )) ||
6513                 error "lfs df -v showed $mdts MDTs, not $MDSCOUNT"
6514         (( osts == OSTCOUNT )) ||
6515                 error "lfs df -v showed $osts OSTs, not $OSTCOUNT"
6516 }
6517 run_test 56d "'lfs df -v' prints only configured devices"
6518
6519 test_56e() {
6520         err_enoent=2 # No such file or directory
6521         err_eopnotsupp=95 # Operation not supported
6522
6523         enoent_mnt=/pmt1 # Invalid dentry. Path not present
6524         notsup_mnt=/tmp  # Valid dentry, but Not a lustreFS
6525
6526         # Check for handling of path not exists
6527         output=$($LFS df $enoent_mnt 2>&1)
6528         ret=$?
6529
6530         fs=$(echo $output | awk -F: '{print $2}' | awk '{print $3}' | tr -d \')
6531         [[ $fs = $enoent_mnt && $ret -eq $err_enoent ]] ||
6532                 error "expect failure $err_enoent, not $ret"
6533
6534         # Check for handling of non-Lustre FS
6535         output=$($LFS df $notsup_mnt)
6536         ret=$?
6537
6538         fs=$(echo $output | awk '{print $1}' | awk -F: '{print $2}')
6539         [[ $fs = $notsup_mnt && $ret -eq $err_eopnotsupp ]] ||
6540                 error "expect success $err_eopnotsupp, not $ret"
6541
6542         # Check for multiple LustreFS argument
6543         output=$($LFS df $MOUNT $MOUNT $MOUNT | grep -c "filesystem_summary:")
6544         ret=$?
6545
6546         [[ $output -eq 3 && $ret -eq 0 ]] ||
6547                 error "expect success 3, not $output, rc = $ret"
6548
6549         # Check for correct non-Lustre FS handling among multiple
6550         # LustreFS argument
6551         output=$($LFS df $MOUNT $notsup_mnt $MOUNT |
6552                 grep -c "filesystem_summary:"; exit ${PIPESTATUS[0]})
6553         ret=$?
6554
6555         [[ $output -eq 2 && $ret -eq $err_eopnotsupp ]] ||
6556                 error "expect success 2, not $output, rc = $ret"
6557 }
6558 run_test 56e "'lfs df' Handle non LustreFS & multiple LustreFS"
6559
6560 NUMFILES=3
6561 NUMDIRS=3
6562 setup_56() {
6563         local local_tdir="$1"
6564         local local_numfiles="$2"
6565         local local_numdirs="$3"
6566         local dir_params="$4"
6567         local dir_stripe_params="$5"
6568
6569         if [ ! -d "$local_tdir" ] ; then
6570                 test_mkdir -p $dir_stripe_params $local_tdir
6571                 [ "$dir_params" ] && $LFS setstripe $dir_params $local_tdir
6572                 for i in $(seq $local_numfiles) ; do
6573                         touch $local_tdir/file$i
6574                 done
6575                 for i in $(seq $local_numdirs) ; do
6576                         test_mkdir $dir_stripe_params $local_tdir/dir$i
6577                         for j in $(seq $local_numfiles) ; do
6578                                 touch $local_tdir/dir$i/file$j
6579                         done
6580                 done
6581         fi
6582 }
6583
6584 setup_56_special() {
6585         local local_tdir=$1
6586         local local_numfiles=$2
6587         local local_numdirs=$3
6588
6589         setup_56 $local_tdir $local_numfiles $local_numdirs
6590
6591         if [ ! -e "$local_tdir/loop${local_numfiles}b" ] ; then
6592                 for i in $(seq $local_numfiles) ; do
6593                         mknod $local_tdir/loop${i}b b 7 $i
6594                         mknod $local_tdir/null${i}c c 1 3
6595                         ln -s $local_tdir/file1 $local_tdir/link${i}
6596                 done
6597                 for i in $(seq $local_numdirs) ; do
6598                         mknod $local_tdir/dir$i/loop${i}b b 7 $i
6599                         mknod $local_tdir/dir$i/null${i}c c 1 3
6600                         ln -s $local_tdir/dir$i/file1 $local_tdir/dir$i/link${i}
6601                 done
6602         fi
6603 }
6604
6605 test_56g() {
6606         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6607         local expected=$(($NUMDIRS + 2))
6608
6609         setup_56 $dir $NUMFILES $NUMDIRS
6610
6611         # test lfs find with -name
6612         for i in $(seq $NUMFILES) ; do
6613                 local nums=$($LFS find -name "*$i" $dir | wc -l)
6614
6615                 [ $nums -eq $expected ] ||
6616                         error "lfs find -name '*$i' $dir wrong: "\
6617                               "found $nums, expected $expected"
6618         done
6619 }
6620 run_test 56g "check lfs find -name"
6621
6622 test_56h() {
6623         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6624         local expected=$(((NUMDIRS + 1) * (NUMFILES - 1) + NUMFILES))
6625
6626         setup_56 $dir $NUMFILES $NUMDIRS
6627
6628         # test lfs find with ! -name
6629         for i in $(seq $NUMFILES) ; do
6630                 local nums=$($LFS find ! -name "*$i" $dir | wc -l)
6631
6632                 [ $nums -eq $expected ] ||
6633                         error "lfs find ! -name '*$i' $dir wrong: "\
6634                               "found $nums, expected $expected"
6635         done
6636 }
6637 run_test 56h "check lfs find ! -name"
6638
6639 test_56i() {
6640         local dir=$DIR/$tdir
6641
6642         test_mkdir $dir
6643
6644         local cmd="$LFS find -ost $(ostuuid_from_index 0 $dir) $dir"
6645         local out=$($cmd)
6646
6647         [ -z "$out" ] || error "'$cmd' returned directory '$out'"
6648 }
6649 run_test 56i "check 'lfs find -ost UUID' skips directories"
6650
6651 test_56j() {
6652         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6653
6654         setup_56_special $dir $NUMFILES $NUMDIRS
6655
6656         local expected=$((NUMDIRS + 1))
6657         local cmd="$LFS find -type d $dir"
6658         local nums=$($cmd | wc -l)
6659
6660         [ $nums -eq $expected ] ||
6661                 error "'$cmd' wrong: found $nums, expected $expected"
6662 }
6663 run_test 56j "check lfs find -type d"
6664
6665 test_56k() {
6666         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6667
6668         setup_56_special $dir $NUMFILES $NUMDIRS
6669
6670         local expected=$(((NUMDIRS + 1) * NUMFILES))
6671         local cmd="$LFS find -type f $dir"
6672         local nums=$($cmd | wc -l)
6673
6674         [ $nums -eq $expected ] ||
6675                 error "'$cmd' wrong: found $nums, expected $expected"
6676 }
6677 run_test 56k "check lfs find -type f"
6678
6679 test_56l() {
6680         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6681
6682         setup_56_special $dir $NUMFILES $NUMDIRS
6683
6684         local expected=$((NUMDIRS + NUMFILES))
6685         local cmd="$LFS find -type b $dir"
6686         local nums=$($cmd | wc -l)
6687
6688         [ $nums -eq $expected ] ||
6689                 error "'$cmd' wrong: found $nums, expected $expected"
6690 }
6691 run_test 56l "check lfs find -type b"
6692
6693 test_56m() {
6694         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6695
6696         setup_56_special $dir $NUMFILES $NUMDIRS
6697
6698         local expected=$((NUMDIRS + NUMFILES))
6699         local cmd="$LFS find -type c $dir"
6700         local nums=$($cmd | wc -l)
6701         [ $nums -eq $expected ] ||
6702                 error "'$cmd' wrong: found $nums, expected $expected"
6703 }
6704 run_test 56m "check lfs find -type c"
6705
6706 test_56n() {
6707         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6708         setup_56_special $dir $NUMFILES $NUMDIRS
6709
6710         local expected=$((NUMDIRS + NUMFILES))
6711         local cmd="$LFS find -type l $dir"
6712         local nums=$($cmd | wc -l)
6713
6714         [ $nums -eq $expected ] ||
6715                 error "'$cmd' wrong: found $nums, expected $expected"
6716 }
6717 run_test 56n "check lfs find -type l"
6718
6719 test_56o() {
6720         local dir=$DIR/$tdir
6721
6722         setup_56 $dir $NUMFILES $NUMDIRS
6723         utime $dir/file1 > /dev/null || error "utime (1)"
6724         utime $dir/file2 > /dev/null || error "utime (2)"
6725         utime $dir/dir1 > /dev/null || error "utime (3)"
6726         utime $dir/dir2 > /dev/null || error "utime (4)"
6727         utime $dir/dir1/file1 > /dev/null || error "utime (5)"
6728         dd if=/dev/zero count=1 >> $dir/dir1/file1 && sync
6729
6730         local expected=4
6731         local nums=$($LFS find -mtime +0 $dir | wc -l)
6732
6733         [ $nums -eq $expected ] ||
6734                 error "lfs find -mtime +0 $dir: found $nums expect $expected"
6735
6736         expected=12
6737         cmd="$LFS find -mtime 0 $dir"
6738         nums=$($cmd | wc -l)
6739         [ $nums -eq $expected ] ||
6740                 error "'$cmd' wrong: found $nums, expected $expected"
6741 }
6742 run_test 56o "check lfs find -mtime for old files"
6743
6744 test_56ob() {
6745         local dir=$DIR/$tdir
6746         local expected=1
6747         local count=0
6748
6749         # just to make sure there is something that won't be found
6750         test_mkdir $dir
6751         touch $dir/$tfile.now
6752
6753         for age in year week day hour min; do
6754                 count=$((count + 1))
6755
6756                 touch $dir/$tfile-a.$age $dir/$tfile-m.$age
6757                 touch --date="$count $age ago" -a $dir/$tfile-a.$age
6758                 touch --date="$count $age ago" -m $dir/$tfile-m.$age
6759
6760                 local cmd="$LFS find $dir -mtime $count${age:0:1}"
6761                 local nums=$($cmd | wc -l)
6762                 [ $nums -eq $expected ] ||
6763                         error "'$cmd' wrong: found $nums, expected $expected"
6764
6765                 cmd="$LFS find $dir -atime $count${age:0:1}"
6766                 nums=$($cmd | wc -l)
6767                 [ $nums -eq $expected ] ||
6768                         error "'$cmd' wrong: found $nums, expected $expected"
6769         done
6770
6771         sleep 2
6772         cmd="$LFS find $dir -ctime +1s -type f"
6773         nums=$($cmd | wc -l)
6774         (( $nums == $count * 2 + 1)) ||
6775                 error "'$cmd' wrong: found $nums, expected $((count * 2 + 1))"
6776 }
6777 run_test 56ob "check lfs find -atime -mtime -ctime with units"
6778
6779 test_newerXY_base() {
6780         local x=$1
6781         local y=$2
6782         local dir=$DIR/$tdir
6783         local ref
6784         local negref
6785
6786         if [ $y == "t" ]; then
6787                 if [ $x == "b" ]; then
6788                         ref=\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\"
6789                 else
6790                         ref=\"$(date +"%Y-%m-%d %H:%M:%S")\"
6791                 fi
6792         else
6793                 ref=$DIR/$tfile.newer.$x$y
6794                 touch $ref || error "touch $ref failed"
6795         fi
6796
6797         echo "before = $ref"
6798         sleep 2
6799         setup_56 $dir $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6800         sleep 2
6801         if [ $y == "t" ]; then
6802                 if [ $x == "b" ]; then
6803                         negref=\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\"
6804                 else
6805                         negref=\"$(date +"%Y-%m-%d %H:%M:%S")\"
6806                 fi
6807         else
6808                 negref=$DIR/$tfile.negnewer.$x$y
6809                 touch $negref || error "touch $negref failed"
6810         fi
6811
6812         echo "after = $negref"
6813         local cmd="$LFS find $dir -newer$x$y $ref"
6814         local nums=$(eval $cmd | wc -l)
6815         local expected=$(((NUMFILES + 2) * NUMDIRS + 1))
6816
6817         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6818                 error "'$cmd' wrong: found $nums newer, expected $expected"  ; }
6819
6820         cmd="$LFS find $dir ! -newer$x$y $negref"
6821         nums=$(eval $cmd | wc -l)
6822         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6823                 error "'$cmd' wrong: found $nums older, expected $expected"  ; }
6824
6825         cmd="$LFS find $dir -newer$x$y $ref ! -newer$x$y $negref"
6826         nums=$(eval $cmd | wc -l)
6827         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6828                 error "'$cmd' wrong: found $nums between, expected $expected"; }
6829
6830         rm -rf $DIR/*
6831 }
6832
6833 test_56oc() {
6834         test_newerXY_base "a" "a"
6835         test_newerXY_base "a" "m"
6836         test_newerXY_base "a" "c"
6837         test_newerXY_base "m" "a"
6838         test_newerXY_base "m" "m"
6839         test_newerXY_base "m" "c"
6840         test_newerXY_base "c" "a"
6841         test_newerXY_base "c" "m"
6842         test_newerXY_base "c" "c"
6843
6844         test_newerXY_base "a" "t"
6845         test_newerXY_base "m" "t"
6846         test_newerXY_base "c" "t"
6847
6848         [[ $MDS1_VERSION -lt $(version_code 2.13.54) ||
6849            $CLIENT_VERSION -lt $(version_code 2.13.54) ]] &&
6850                 ! btime_supported && echo "btime unsupported" && return 0
6851
6852         test_newerXY_base "b" "b"
6853         test_newerXY_base "b" "t"
6854 }
6855 run_test 56oc "check lfs find -newerXY work"
6856
6857 btime_supported() {
6858         local dir=$DIR/$tdir
6859         local rc
6860
6861         mkdir -p $dir
6862         touch $dir/$tfile
6863         $LFS find $dir -btime -1d -type f
6864         rc=$?
6865         rm -rf $dir
6866         return $rc
6867 }
6868
6869 test_56od() {
6870         [ $MDS1_VERSION -lt $(version_code 2.13.53) ] &&
6871                 ! btime_supported && skip "btime unsupported on MDS"
6872
6873         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
6874                 ! btime_supported && skip "btime unsupported on clients"
6875
6876         local dir=$DIR/$tdir
6877         local ref=$DIR/$tfile.ref
6878         local negref=$DIR/$tfile.negref
6879
6880         mkdir $dir || error "mkdir $dir failed"
6881         touch $dir/$tfile.n1 || error "touch $dir/$tfile.n1 failed"
6882         touch $dir/$tfile.n2 || error "touch $dir/$tfile.n2 failed"
6883         mkdir $dir/$tdir.n1 || error "mkdir $dir/$tdir.n1 failed"
6884         mkdir $dir/$tdir.n2 || error "mkdir $dir/$tdir.n2 failed"
6885         touch $ref || error "touch $ref failed"
6886         # sleep 3 seconds at least
6887         sleep 3
6888
6889         local before=$(do_facet mds1 date +%s)
6890         local skew=$(($(date +%s) - before + 1))
6891
6892         if (( skew < 0 && skew > -5 )); then
6893                 sleep $((0 - skew + 1))
6894                 skew=0
6895         fi
6896
6897         # Set the dir stripe params to limit files all on MDT0,
6898         # otherwise we need to calc the max clock skew between
6899         # the client and MDTs.
6900         setup_56 $dir/d.btime $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6901         sleep 2
6902         touch $negref || error "touch $negref failed"
6903
6904         local cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type f"
6905         local nums=$($cmd | wc -l)
6906         local expected=$(((NUMFILES + 1) * NUMDIRS))
6907
6908         [ $nums -eq $expected ] ||
6909                 error "'$cmd' wrong: found $nums, expected $expected"
6910
6911         cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type d"
6912         nums=$($cmd | wc -l)
6913         expected=$((NUMFILES + 1))
6914         [ $nums -eq $expected ] ||
6915                 error "'$cmd' wrong: found $nums, expected $expected"
6916
6917         [ $skew -lt 0 ] && return
6918
6919         local after=$(do_facet mds1 date +%s)
6920         local age=$((after - before + 1 + skew))
6921
6922         cmd="$LFS find $dir -btime -${age}s -type f"
6923         nums=$($cmd | wc -l)
6924         expected=$(((NUMFILES + 1) * NUMDIRS))
6925
6926         echo "Clock skew between client and server: $skew, age:$age"
6927         [ $nums -eq $expected ] ||
6928                 error "'$cmd' wrong: found $nums, expected $expected"
6929
6930         expected=$(($NUMDIRS + 1))
6931         cmd="$LFS find $dir -btime -${age}s -type d"
6932         nums=$($cmd | wc -l)
6933         [ $nums -eq $expected ] ||
6934                 error "'$cmd' wrong: found $nums, expected $expected"
6935         rm -f $ref $negref || error "Failed to remove $ref $negref"
6936 }
6937 run_test 56od "check lfs find -btime with units"
6938
6939 test_56p() {
6940         [ $RUNAS_ID -eq $UID ] &&
6941                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6942
6943         local dir=$DIR/$tdir
6944
6945         setup_56 $dir $NUMFILES $NUMDIRS
6946         chown $RUNAS_ID $dir/file* || error "chown $DIR/${tdir}g/file$i failed"
6947
6948         local expected=$NUMFILES
6949         local cmd="$LFS find -uid $RUNAS_ID $dir"
6950         local nums=$($cmd | wc -l)
6951
6952         [ $nums -eq $expected ] ||
6953                 error "'$cmd' wrong: found $nums, expected $expected"
6954
6955         expected=$(((NUMFILES + 1) * NUMDIRS + 1))
6956         cmd="$LFS find ! -uid $RUNAS_ID $dir"
6957         nums=$($cmd | wc -l)
6958         [ $nums -eq $expected ] ||
6959                 error "'$cmd' wrong: found $nums, expected $expected"
6960 }
6961 run_test 56p "check lfs find -uid and ! -uid"
6962
6963 test_56q() {
6964         [ $RUNAS_ID -eq $UID ] &&
6965                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6966
6967         local dir=$DIR/$tdir
6968
6969         setup_56 $dir $NUMFILES $NUMDIRS
6970         chgrp $RUNAS_GID $dir/file* || error "chown $dir/file$i failed"
6971
6972         local expected=$NUMFILES
6973         local cmd="$LFS find -gid $RUNAS_GID $dir"
6974         local nums=$($cmd | wc -l)
6975
6976         [ $nums -eq $expected ] ||
6977                 error "'$cmd' wrong: found $nums, expected $expected"
6978
6979         expected=$(( ($NUMFILES+1) * $NUMDIRS + 1))
6980         cmd="$LFS find ! -gid $RUNAS_GID $dir"
6981         nums=$($cmd | wc -l)
6982         [ $nums -eq $expected ] ||
6983                 error "'$cmd' wrong: found $nums, expected $expected"
6984 }
6985 run_test 56q "check lfs find -gid and ! -gid"
6986
6987 test_56r() {
6988         local dir=$DIR/$tdir
6989
6990         setup_56 $dir $NUMFILES $NUMDIRS
6991
6992         local expected=12
6993         local cmd="$LFS find -size 0 -type f -lazy $dir"
6994         local nums=$($cmd | wc -l)
6995
6996         [ $nums -eq $expected ] ||
6997                 error "'$cmd' wrong: found $nums, expected $expected"
6998         cmd="$LFS find -size 0 -type f $dir"
6999         nums=$($cmd | wc -l)
7000         [ $nums -eq $expected ] ||
7001                 error "'$cmd' wrong: found $nums, expected $expected"
7002
7003         expected=0
7004         cmd="$LFS find ! -size 0 -type f -lazy $dir"
7005         nums=$($cmd | wc -l)
7006         [ $nums -eq $expected ] ||
7007                 error "'$cmd' wrong: found $nums, expected $expected"
7008         cmd="$LFS find ! -size 0 -type f $dir"
7009         nums=$($cmd | wc -l)
7010         [ $nums -eq $expected ] ||
7011                 error "'$cmd' wrong: found $nums, expected $expected"
7012
7013         echo "test" > $dir/$tfile
7014         echo "test2" > $dir/$tfile.2 && sync
7015         expected=1
7016         cmd="$LFS find -size 5 -type f -lazy $dir"
7017         nums=$($cmd | wc -l)
7018         [ $nums -eq $expected ] ||
7019                 error "'$cmd' wrong: found $nums, expected $expected"
7020         cmd="$LFS find -size 5 -type f $dir"
7021         nums=$($cmd | wc -l)
7022         [ $nums -eq $expected ] ||
7023                 error "'$cmd' wrong: found $nums, expected $expected"
7024
7025         expected=1
7026         cmd="$LFS find -size +5 -type f -lazy $dir"
7027         nums=$($cmd | wc -l)
7028         [ $nums -eq $expected ] ||
7029                 error "'$cmd' wrong: found $nums, expected $expected"
7030         cmd="$LFS find -size +5 -type f $dir"
7031         nums=$($cmd | wc -l)
7032         [ $nums -eq $expected ] ||
7033                 error "'$cmd' wrong: found $nums, expected $expected"
7034
7035         expected=2
7036         cmd="$LFS find -size +0 -type f -lazy $dir"
7037         nums=$($cmd | wc -l)
7038         [ $nums -eq $expected ] ||
7039                 error "'$cmd' wrong: found $nums, expected $expected"
7040         cmd="$LFS find -size +0 -type f $dir"
7041         nums=$($cmd | wc -l)
7042         [ $nums -eq $expected ] ||
7043                 error "'$cmd' wrong: found $nums, expected $expected"
7044
7045         expected=2
7046         cmd="$LFS find ! -size -5 -type f -lazy $dir"
7047         nums=$($cmd | wc -l)
7048         [ $nums -eq $expected ] ||
7049                 error "'$cmd' wrong: found $nums, expected $expected"
7050         cmd="$LFS find ! -size -5 -type f $dir"
7051         nums=$($cmd | wc -l)
7052         [ $nums -eq $expected ] ||
7053                 error "'$cmd' wrong: found $nums, expected $expected"
7054
7055         expected=12
7056         cmd="$LFS find -size -5 -type f -lazy $dir"
7057         nums=$($cmd | wc -l)
7058         [ $nums -eq $expected ] ||
7059                 error "'$cmd' wrong: found $nums, expected $expected"
7060         cmd="$LFS find -size -5 -type f $dir"
7061         nums=$($cmd | wc -l)
7062         [ $nums -eq $expected ] ||
7063                 error "'$cmd' wrong: found $nums, expected $expected"
7064 }
7065 run_test 56r "check lfs find -size works"
7066
7067 test_56ra_sub() {
7068         local expected=$1
7069         local glimpses=$2
7070         local cmd="$3"
7071
7072         cancel_lru_locks $OSC
7073
7074         local rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
7075         local nums=$($cmd | wc -l)
7076
7077         [ $nums -eq $expected ] ||
7078                 error "'$cmd' wrong: found $nums, expected $expected"
7079
7080         local rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
7081
7082         if (( rpcs_before + glimpses != rpcs_after )); then
7083                 echo "Before: $rpcs_before After: $rpcs_after $NUMFILES"
7084                 $LCTL get_param osc.*.stats | grep ldlm_glimpse_enqueue
7085
7086                 if [[ $glimpses == 0 ]]; then
7087                         error "'$cmd' should not send glimpse RPCs to OST"
7088                 else
7089                         error "'$cmd' should send $glimpses glimpse RPCs to OST"
7090                 fi
7091         fi
7092 }
7093
7094 test_56ra() {
7095         [[ $MDS1_VERSION -gt $(version_code 2.12.58) ]] ||
7096                 skip "MDS < 2.12.58 doesn't return LSOM data"
7097         local dir=$DIR/$tdir
7098         local old_agl=$($LCTL get_param -n llite.*.statahead_agl)
7099
7100         [[ $OSC == "mdc" ]] && skip "statahead not needed for DoM files"
7101
7102         # statahead_agl may cause extra glimpse which confuses results. LU-13017
7103         $LCTL set_param -n llite.*.statahead_agl=0
7104         stack_trap "$LCTL set_param -n llite.*.statahead_agl=$old_agl"
7105
7106         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
7107         # open and close all files to ensure LSOM is updated
7108         cancel_lru_locks $OSC
7109         find $dir -type f | xargs cat > /dev/null
7110
7111         #   expect_found  glimpse_rpcs  command_to_run
7112         test_56ra_sub 12  0 "$LFS find -size 0 -type f -lazy $dir"
7113         test_56ra_sub 12 12 "$LFS find -size 0 -type f $dir"
7114         test_56ra_sub  0  0 "$LFS find ! -size 0 -type f -lazy $dir"
7115         test_56ra_sub  0 12 "$LFS find ! -size 0 -type f $dir"
7116
7117         echo "test" > $dir/$tfile
7118         echo "test2" > $dir/$tfile.2 && sync
7119         cancel_lru_locks $OSC
7120         cat $dir/$tfile $dir/$tfile.2 > /dev/null
7121
7122         test_56ra_sub  1  0 "$LFS find -size 5 -type f -lazy $dir"
7123         test_56ra_sub  1 14 "$LFS find -size 5 -type f $dir"
7124         test_56ra_sub  1  0 "$LFS find -size +5 -type f -lazy $dir"
7125         test_56ra_sub  1 14 "$LFS find -size +5 -type f $dir"
7126
7127         test_56ra_sub  2  0 "$LFS find -size +0 -type f -lazy $dir"
7128         test_56ra_sub  2 14 "$LFS find -size +0 -type f $dir"
7129         test_56ra_sub  2  0 "$LFS find ! -size -5 -type f -lazy $dir"
7130         test_56ra_sub  2 14 "$LFS find ! -size -5 -type f $dir"
7131         test_56ra_sub 12  0 "$LFS find -size -5 -type f -lazy $dir"
7132         test_56ra_sub 12 14 "$LFS find -size -5 -type f $dir"
7133 }
7134 run_test 56ra "check lfs find -size -lazy works for data on OSTs"
7135
7136 test_56rb() {
7137         local dir=$DIR/$tdir
7138         local tmp=$TMP/$tfile.log
7139         local mdt_idx;
7140
7141         test_mkdir -p $dir || error "failed to mkdir $dir"
7142         $LFS setstripe -c 1 -i 0 $dir/$tfile ||
7143                 error "failed to setstripe $dir/$tfile"
7144         mdt_idx=$($LFS getdirstripe -i $dir)
7145         dd if=/dev/zero of=$dir/$tfile bs=1M count=1
7146
7147         stack_trap "rm -f $tmp" EXIT
7148         $LFS find --size +100K --ost 0 $dir |& tee $tmp
7149         ! grep -q obd_uuid $tmp ||
7150                 error "failed to find --size +100K --ost 0 $dir"
7151         $LFS find --size +100K --mdt $mdt_idx $dir |& tee $tmp
7152         ! grep -q obd_uuid $tmp ||
7153                 error "failed to find --size +100K --mdt $mdt_idx $dir"
7154 }
7155 run_test 56rb "check lfs find --size --ost/--mdt works"
7156
7157 test_56rc() {
7158         (( MDSCOUNT >= 2 )) || skip "needs at least 2 MDTs"
7159         local dir=$DIR/$tdir
7160         local found
7161
7162         test_mkdir -c 2 -H all_char $dir || error "failed to mkdir $dir"
7163         $LFS mkdir -c 2 --mdt-hash all_char $dir/$tdir-all{1..10}
7164         (( $MDSCOUNT > 2 )) &&
7165                 $LFS mkdir -c 3 --mdt-hash fnv_1a_64 $dir/$tdir-fnv{1..10}
7166         mkdir $dir/$tdir-{1..10}
7167         touch $dir/$tfile-{1..10}
7168
7169         found=$($LFS find $dir --mdt-count 2 | wc -l)
7170         expect=11
7171         (( $found == $expect )) || error "found $found 2-stripe, expect $expect"
7172
7173         found=$($LFS find $dir -T +1 | wc -l)
7174         (( $MDSCOUNT > 2 )) && expect=$((expect + 10))
7175         (( $found == $expect )) || error "found $found 2+stripe, expect $expect"
7176
7177         found=$($LFS find $dir --mdt-hash all_char | wc -l)
7178         expect=11
7179         (( $found == $expect )) || error "found $found all_char, expect $expect"
7180
7181         found=$($LFS find $dir --mdt-hash fnv_1a_64 | wc -l)
7182         (( $MDSCOUNT > 2 )) && expect=10 || expect=0
7183         (( $found == $expect )) || error "found $found all_char, expect $expect"
7184 }
7185 run_test 56rc "check lfs find --mdt-count/--mdt-hash works"
7186
7187 test_56rd() {
7188         local dir=$DIR/$tdir
7189
7190         test_mkdir $dir
7191         rm -f $dir/*
7192
7193         mkfifo $dir/fifo || error "failed to create fifo file"
7194         $LFS find $dir -t p --printf "%p %y %LP\n" ||
7195                 error "should not fail even cannot get projid from pipe file"
7196         found=$($LFS find $dir -t p --printf "%y")
7197         [[ "p" == $found ]] || error "found $found, expect p"
7198
7199         mknod $dir/chardev c 1 5 ||
7200                 error "failed to create character device file"
7201         $LFS find $dir -t c --printf "%p %y %LP\n" ||
7202                 error "should not fail even cannot get projid from chardev file"
7203         found=$($LFS find $dir -t c --printf "%y")
7204         [[ "c" == $found ]] || error "found $found, expect c"
7205
7206         found=$($LFS find $dir ! -type d --printf "%p %y %LP\n" | wc -l)
7207         (( found == 2 )) || error "unable to list all files"
7208 }
7209 run_test 56rd "check lfs find --printf special files"
7210
7211 test_56s() { # LU-611 #LU-9369
7212         [[ $OSTCOUNT -lt 2 ]] && skip_env "need at least 2 OSTs"
7213
7214         local dir=$DIR/$tdir
7215         local onestripe=$(((NUMDIRS + 1) * NUMFILES))
7216
7217         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
7218         for i in $(seq $NUMDIRS); do
7219                 $LFS setstripe -c $((OSTCOUNT + 1)) $dir/dir$i/$tfile
7220         done
7221
7222         local expected=$NUMDIRS
7223         local cmd="$LFS find -c $OSTCOUNT $dir"
7224         local nums=$($cmd | wc -l)
7225
7226         [ $nums -eq $expected ] || {
7227                 $LFS getstripe -R $dir
7228                 error "'$cmd' wrong: found $nums, expected $expected"
7229         }
7230
7231         expected=$((NUMDIRS + onestripe))
7232         cmd="$LFS find -stripe-count +0 -type f $dir"
7233         nums=$($cmd | wc -l)
7234         [ $nums -eq $expected ] || {
7235                 $LFS getstripe -R $dir
7236                 error "'$cmd' wrong: found $nums, expected $expected"
7237         }
7238
7239         expected=$onestripe
7240         cmd="$LFS find -stripe-count 1 -type f $dir"
7241         nums=$($cmd | wc -l)
7242         [ $nums -eq $expected ] || {
7243                 $LFS getstripe -R $dir
7244                 error "'$cmd' wrong: found $nums, expected $expected"
7245         }
7246
7247         cmd="$LFS find -stripe-count -2 -type f $dir"
7248         nums=$($cmd | wc -l)
7249         [ $nums -eq $expected ] || {
7250                 $LFS getstripe -R $dir
7251                 error "'$cmd' wrong: found $nums, expected $expected"
7252         }
7253
7254         expected=0
7255         cmd="$LFS find -stripe-count $((OSTCOUNT + 1)) -type f $dir"
7256         nums=$($cmd | wc -l)
7257         [ $nums -eq $expected ] || {
7258                 $LFS getstripe -R $dir
7259                 error "'$cmd' wrong: found $nums, expected $expected"
7260         }
7261 }
7262 run_test 56s "check lfs find -stripe-count works"
7263
7264 test_56t() { # LU-611 #LU-9369
7265         local dir=$DIR/$tdir
7266
7267         setup_56 $dir 0 $NUMDIRS
7268         for i in $(seq $NUMDIRS); do
7269                 $LFS setstripe -S 8M $dir/dir$i/$tfile
7270         done
7271
7272         local expected=$NUMDIRS
7273         local cmd="$LFS find -S 8M $dir"
7274         local nums=$($cmd | wc -l)
7275
7276         [ $nums -eq $expected ] || {
7277                 $LFS getstripe -R $dir
7278                 error "'$cmd' wrong: found $nums, expected $expected"
7279         }
7280         rm -rf $dir
7281
7282         setup_56 $dir $NUMFILES $NUMDIRS "--stripe-size 512k"
7283
7284         $LFS setstripe -S 256k $dir/$tfile.{0,1,2,3}
7285
7286         expected=$(((NUMDIRS + 1) * NUMFILES))
7287         cmd="$LFS find -stripe-size 512k -type f $dir"
7288         nums=$($cmd | wc -l)
7289         [ $nums -eq $expected ] ||
7290                 error "'$cmd' wrong: found $nums, expected $expected"
7291
7292         cmd="$LFS find -stripe-size +320k -type f $dir"
7293         nums=$($cmd | wc -l)
7294         [ $nums -eq $expected ] ||
7295                 error "'$cmd' wrong: found $nums, expected $expected"
7296
7297         expected=$(((NUMDIRS + 1) * NUMFILES + 4))
7298         cmd="$LFS find -stripe-size +200k -type f $dir"
7299         nums=$($cmd | wc -l)
7300         [ $nums -eq $expected ] ||
7301                 error "'$cmd' wrong: found $nums, expected $expected"
7302
7303         cmd="$LFS find -stripe-size -640k -type f $dir"
7304         nums=$($cmd | wc -l)
7305         [ $nums -eq $expected ] ||
7306                 error "'$cmd' wrong: found $nums, expected $expected"
7307
7308         expected=4
7309         cmd="$LFS find -stripe-size 256k -type f $dir"
7310         nums=$($cmd | wc -l)
7311         [ $nums -eq $expected ] ||
7312                 error "'$cmd' wrong: found $nums, expected $expected"
7313
7314         cmd="$LFS find -stripe-size -320k -type f $dir"
7315         nums=$($cmd | wc -l)
7316         [ $nums -eq $expected ] ||
7317                 error "'$cmd' wrong: found $nums, expected $expected"
7318
7319         expected=0
7320         cmd="$LFS find -stripe-size 1024k -type f $dir"
7321         nums=$($cmd | wc -l)
7322         [ $nums -eq $expected ] ||
7323                 error "'$cmd' wrong: found $nums, expected $expected"
7324 }
7325 run_test 56t "check lfs find -stripe-size works"
7326
7327 test_56u() { # LU-611
7328         local dir=$DIR/$tdir
7329
7330         setup_56 $dir $NUMFILES $NUMDIRS "-i 0 -c 1"
7331
7332         if [[ $OSTCOUNT -gt 1 ]]; then
7333                 $LFS setstripe -i 1 -c 1 $dir/$tfile.{0,1,2,3}
7334                 onestripe=4
7335         else
7336                 onestripe=0
7337         fi
7338
7339         local expected=$(((NUMDIRS + 1) * NUMFILES))
7340         local cmd="$LFS find -stripe-index 0 -type f $dir"
7341         local nums=$($cmd | wc -l)
7342
7343         [ $nums -eq $expected ] ||
7344                 error "'$cmd' wrong: found $nums, expected $expected"
7345
7346         expected=$onestripe
7347         cmd="$LFS find -stripe-index 1 -type f $dir"
7348         nums=$($cmd | wc -l)
7349         [ $nums -eq $expected ] ||
7350                 error "'$cmd' wrong: found $nums, expected $expected"
7351
7352         cmd="$LFS find ! -stripe-index 0 -type f $dir"
7353         nums=$($cmd | wc -l)
7354         [ $nums -eq $expected ] ||
7355                 error "'$cmd' wrong: found $nums, expected $expected"
7356
7357         expected=0
7358         # This should produce an error and not return any files
7359         cmd="$LFS find -stripe-index $OSTCOUNT -type f $dir"
7360         nums=$($cmd 2>/dev/null | wc -l)
7361         [ $nums -eq $expected ] ||
7362                 error "'$cmd' wrong: found $nums, expected $expected"
7363
7364         if [[ $OSTCOUNT -gt 1 ]]; then
7365                 expected=$(((NUMDIRS + 1) * NUMFILES + onestripe))
7366                 cmd="$LFS find -stripe-index 0,1 -type f $dir"
7367                 nums=$($cmd | wc -l)
7368                 [ $nums -eq $expected ] ||
7369                         error "'$cmd' wrong: found $nums, expected $expected"
7370         fi
7371 }
7372 run_test 56u "check lfs find -stripe-index works"
7373
7374 test_56v() {
7375         local mdt_idx=0
7376         local dir=$DIR/$tdir
7377
7378         setup_56 $dir $NUMFILES $NUMDIRS
7379
7380         UUID=$(mdtuuid_from_index $mdt_idx $dir)
7381         [ -z "$UUID" ] && error "mdtuuid_from_index cannot find MDT $mdt_idx"
7382
7383         for file in $($LFS find -m $UUID $dir); do
7384                 file_midx=$($LFS getstripe -m $file)
7385                 [ $file_midx -eq $mdt_idx ] ||
7386                         error "lfs find -m $UUID != getstripe -m $file_midx"
7387         done
7388 }
7389 run_test 56v "check 'lfs find -m match with lfs getstripe -m'"
7390
7391 test_56wa() {
7392         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
7393         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7394
7395         local dir=$DIR/$tdir
7396
7397         setup_56 $dir $NUMFILES $NUMDIRS "-c $OSTCOUNT" "-c1"
7398         stack_trap "rm -rf $dir"
7399
7400         local stripe_size=$($LFS getstripe -S -d $dir) ||
7401                 error "$LFS getstripe -S -d $dir failed"
7402         stripe_size=${stripe_size%% *}
7403
7404         local file_size=$((stripe_size * OSTCOUNT))
7405         local file_num=$((NUMDIRS * NUMFILES + NUMFILES))
7406         local required_space=$((file_num * file_size))
7407         local free_space=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
7408                            head -n1)
7409         (( free_space >= required_space / 1024 )) ||
7410                 skip_env "need $required_space, have $free_space kbytes"
7411
7412         local dd_bs=65536
7413         local dd_count=$((file_size / dd_bs))
7414
7415         # write data into the files
7416         local i
7417         local j
7418         local file
7419
7420         for ((i = 1; i <= NUMFILES; i++ )); do
7421                 file=$dir/file$i
7422                 yes | dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
7423                         error "write data into $file failed"
7424         done
7425         for ((i = 1; i <= NUMDIRS; i++ )); do
7426                 for ((j = 1; j <= NUMFILES; j++ )); do
7427                         file=$dir/dir$i/file$j
7428                         yes|dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
7429                                 error "write data into $file failed"
7430                 done
7431         done
7432
7433         # $LFS_MIGRATE will fail if hard link migration is unsupported
7434         if (( MDS1_VERSION > $(version_code 2.5.55) )); then
7435                 createmany -l$dir/dir1/file1 $dir/dir1/link 200 ||
7436                         error "creating links to $dir/dir1/file1 failed"
7437         fi
7438
7439         local expected=-1
7440
7441         (( OSTCOUNT <= 1 )) || expected=$((OSTCOUNT - 1))
7442
7443         # lfs_migrate file
7444         local cmd="$LFS_MIGRATE -y -c $expected $dir/file1"
7445
7446         echo "$cmd"
7447         eval $cmd || error "$cmd failed"
7448
7449         check_stripe_count $dir/file1 $expected
7450
7451         if (( $MDS1_VERSION >= $(version_code 2.6.90) )); then
7452                 # lfs_migrate file onto OST 0 if it is on OST 1, or onto
7453                 # OST 1 if it is on OST 0. This file is small enough to
7454                 # be on only one stripe.
7455                 file=$dir/migr_1_ost
7456                 dd bs=$dd_bs count=1 if=/dev/urandom of=$file >/dev/null 2>&1 ||
7457                         error "write data into $file failed"
7458                 local obdidx=$($LFS getstripe -i $file)
7459                 local oldmd5=$(md5sum $file)
7460                 local newobdidx=0
7461
7462                 (( obdidx != 0 )) || newobdidx=1
7463                 cmd="$LFS migrate -i $newobdidx $file"
7464                 echo $cmd
7465                 eval $cmd || error "$cmd failed"
7466
7467                 local realobdix=$($LFS getstripe -i $file)
7468                 local newmd5=$(md5sum $file)
7469
7470                 (( $newobdidx == $realobdix )) ||
7471                         error "new OST is different (was=$obdidx, wanted=$newobdidx, got=$realobdix)"
7472                 [[ "$oldmd5" == "$newmd5" ]] ||
7473                         error "md5sum differ: $oldmd5, $newmd5"
7474         fi
7475
7476         # lfs_migrate dir
7477         cmd="$LFS_MIGRATE -y -c $expected $dir/dir1"
7478         echo "$cmd"
7479         eval $cmd || error "$cmd failed"
7480
7481         for (( j = 1; j <= NUMFILES; j++ )); do
7482                 check_stripe_count $dir/dir1/file$j $expected
7483         done
7484
7485         # lfs_migrate works with lfs find
7486         cmd="$LFS find -stripe_count $OSTCOUNT -type f $dir |
7487              $LFS_MIGRATE -y -c $expected"
7488         echo "$cmd"
7489         eval $cmd || error "$cmd failed"
7490
7491         for (( i = 2; i <= NUMFILES; i++ )); do
7492                 check_stripe_count $dir/file$i $expected
7493         done
7494         for (( i = 2; i <= NUMDIRS; i++ )); do
7495                 for (( j = 1; j <= NUMFILES; j++ )); do
7496                         check_stripe_count $dir/dir$i/file$j $expected
7497                 done
7498         done
7499 }
7500 run_test 56wa "check lfs_migrate -c stripe_count works"
7501
7502 test_56wb() {
7503         local file1=$DIR/$tdir/file1
7504         local create_pool=false
7505         local initial_pool=$($LFS getstripe -p $DIR)
7506         local pool_list=()
7507         local pool=""
7508
7509         echo -n "Creating test dir..."
7510         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
7511         echo "done."
7512
7513         echo -n "Creating test file..."
7514         touch $file1 || error "cannot create file"
7515         echo "done."
7516
7517         echo -n "Detecting existing pools..."
7518         pool_list=($($LFS pool_list $FSNAME | grep "$FSNAME\." | cut -d. -f2))
7519
7520         if [ ${#pool_list[@]} -gt 0 ]; then
7521                 echo "${pool_list[@]}"
7522                 for thispool in "${pool_list[@]}"; do
7523                         if [[ -z "$initial_pool" ||
7524                               "$initial_pool" != "$thispool" ]]; then
7525                                 pool="$thispool"
7526                                 echo "Using existing pool '$pool'"
7527                                 break
7528                         fi
7529                 done
7530         else
7531                 echo "none detected."
7532         fi
7533         if [ -z "$pool" ]; then
7534                 pool=${POOL:-testpool}
7535                 [ "$initial_pool" = "$pool" ] && pool="testpool2"
7536                 echo -n "Creating pool '$pool'..."
7537                 create_pool=true
7538                 pool_add $pool &> /dev/null ||
7539                         error "pool_add failed"
7540                 echo "done."
7541
7542                 echo -n "Adding target to pool..."
7543                 pool_add_targets $pool 0 0 1 &> /dev/null ||
7544                         error "pool_add_targets failed"
7545                 echo "done."
7546         fi
7547
7548         echo -n "Setting pool using -p option..."
7549         $LFS_MIGRATE -y -q --no-rsync -p $pool $file1 &> /dev/null ||
7550                 error "migrate failed rc = $?"
7551         echo "done."
7552
7553         echo -n "Verifying test file is in pool after migrating..."
7554         [ "$($LFS getstripe -p $file1)" = $pool ] ||
7555                 error "file was not migrated to pool $pool"
7556         echo "done."
7557
7558         echo -n "Removing test file from pool '$pool'..."
7559         # "lfs migrate $file" won't remove the file from the pool
7560         # until some striping information is changed.
7561         $LFS migrate -c 1 $file1 &> /dev/null ||
7562                 error "cannot remove from pool"
7563         [ "$($LFS getstripe -p $file1)" ] &&
7564                 error "pool still set"
7565         echo "done."
7566
7567         echo -n "Setting pool using --pool option..."
7568         $LFS_MIGRATE -y -q --no-rsync --pool $pool $file1 &> /dev/null ||
7569                 error "migrate failed rc = $?"
7570         echo "done."
7571
7572         # Clean up
7573         rm -f $file1
7574         if $create_pool; then
7575                 destroy_test_pools 2> /dev/null ||
7576                         error "destroy test pools failed"
7577         fi
7578 }
7579 run_test 56wb "check lfs_migrate pool support"
7580
7581 test_56wc() {
7582         local file1="$DIR/$tdir/$tfile"
7583         local md5
7584         local parent_ssize
7585         local parent_scount
7586         local cur_ssize
7587         local cur_scount
7588         local orig_ssize
7589         local new_scount
7590         local cur_comp
7591
7592         echo -n "Creating test dir..."
7593         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
7594         $LFS setstripe -S 1M -c 1 "$DIR/$tdir" &> /dev/null ||
7595                 error "cannot set stripe by '-S 1M -c 1'"
7596         echo "done"
7597
7598         echo -n "Setting initial stripe for test file..."
7599         $LFS setstripe -S 512K -c 1 "$file1" &> /dev/null ||
7600                 error "cannot set stripe"
7601         cur_ssize=$($LFS getstripe -S "$file1")
7602         (( cur_ssize == 524288 )) || error "setstripe -S $cur_ssize != 524288"
7603         echo "done."
7604
7605         dd if=/dev/urandom of=$file1 bs=1M count=12 || error "dd $file1 failed"
7606         stack_trap "rm -f $file1"
7607         md5="$(md5sum $file1)"
7608
7609         # File currently set to -S 512K -c 1
7610
7611         # Ensure -c and -S options are rejected when -R is set
7612         echo -n "Verifying incompatible options are detected..."
7613         $LFS_MIGRATE -R -c 1 "$file1" &&
7614                 error "incompatible -R and -c options not detected"
7615         $LFS_MIGRATE -R -S 1M "$file1" &&
7616                 error "incompatible -R and -S options not detected"
7617         $LFS_MIGRATE -R -p pool "$file1" &&
7618                 error "incompatible -R and -p options not detected"
7619         $LFS_MIGRATE -R -E eof -c 1 "$file1" &&
7620                 error "incompatible -R and -E options not detected"
7621         $LFS_MIGRATE -R -A "$file1" &&
7622                 error "incompatible -R and -A options not detected"
7623         $LFS_MIGRATE -A -c 1 "$file1" &&
7624                 error "incompatible -A and -c options not detected"
7625         $LFS_MIGRATE -A -S 1M "$file1" &&
7626                 error "incompatible -A and -S options not detected"
7627         $LFS_MIGRATE -A -p pool "$file1" &&
7628                 error "incompatible -A and -p options not detected"
7629         $LFS_MIGRATE -A -E eof -c 1 "$file1" &&
7630                 error "incompatible -A and -E options not detected"
7631         echo "done."
7632
7633         # Ensure unrecognized options are passed through to 'lfs migrate'
7634         echo -n "Verifying -S option is passed through to lfs migrate..."
7635         $LFS_MIGRATE -y -S 1M "$file1" || error "migration failed"
7636         cur_ssize=$($LFS getstripe -S "$file1")
7637         (( cur_ssize == 1048576 )) || error "migrate -S $cur_ssize != 1048576"
7638         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (1)"
7639         echo "done."
7640
7641         # File currently set to -S 1M -c 1
7642
7643         # Ensure long options are supported
7644         echo -n "Verifying long options supported..."
7645         $LFS_MIGRATE --non-block "$file1" ||
7646                 error "long option without argument not supported"
7647         $LFS_MIGRATE --stripe-size 512K "$file1" ||
7648                 error "long option with argument not supported"
7649         cur_ssize=$($LFS getstripe -S "$file1")
7650         (( cur_ssize == 524288 )) ||
7651                 error "migrate --stripe-size $cur_ssize != 524288"
7652         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (2)"
7653         echo "done."
7654
7655         # File currently set to -S 512K -c 1
7656
7657         if (( OSTCOUNT > 1 )); then
7658                 echo -n "Verifying explicit stripe count can be set..."
7659                 $LFS_MIGRATE -c 2 "$file1" || error "migrate failed"
7660                 cur_scount=$($LFS getstripe -c "$file1")
7661                 (( cur_scount == 2 )) || error "migrate -c $cur_scount != 2"
7662                 [[ "$(md5sum $file1)" == "$md5" ]] ||
7663                         error "file data has changed (3)"
7664                 echo "done."
7665         fi
7666
7667         # File currently set to -S 512K -c 1 or -S 512K -c 2
7668
7669         # Ensure parent striping is used if -R is set, and no stripe
7670         # count or size is specified
7671         echo -n "Setting stripe for parent directory..."
7672         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
7673                 error "cannot set stripe '-S 2M -c 1'"
7674         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (4)"
7675         echo "done."
7676
7677         echo -n "Verifying restripe option uses parent stripe settings..."
7678         parent_ssize=$($LFS getstripe -S $DIR/$tdir 2>/dev/null)
7679         parent_scount=$($LFS getstripe -c $DIR/$tdir 2>/dev/null)
7680         $LFS_MIGRATE -R "$file1" || error "migrate failed"
7681         cur_ssize=$($LFS getstripe -S "$file1")
7682         (( cur_ssize == parent_ssize )) ||
7683                 error "migrate -R stripe_size $cur_ssize != $parent_ssize"
7684         cur_scount=$($LFS getstripe -c "$file1")
7685         (( cur_scount == parent_scount )) ||
7686                 error "migrate -R stripe_count $cur_scount != $parent_scount"
7687         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (5)"
7688         echo "done."
7689
7690         # File currently set to -S 1M -c 1
7691
7692         # Ensure striping is preserved if -R is not set, and no stripe
7693         # count or size is specified
7694         echo -n "Verifying striping size preserved when not specified..."
7695         orig_ssize=$($LFS getstripe -S "$file1" 2>/dev/null)
7696         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
7697                 error "cannot set stripe on parent directory"
7698         $LFS_MIGRATE "$file1" || error "migrate failed"
7699         cur_ssize=$($LFS getstripe -S "$file1")
7700         (( cur_ssize == orig_ssize )) ||
7701                 error "migrate by default $cur_ssize != $orig_ssize"
7702         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (6)"
7703         echo "done."
7704
7705         # Ensure file name properly detected when final option has no argument
7706         echo -n "Verifying file name properly detected..."
7707         $LFS_MIGRATE "$file1" ||
7708                 error "file name interpreted as option argument"
7709         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (7)"
7710         echo "done."
7711
7712         # Ensure PFL arguments are passed through properly
7713         echo -n "Verifying PFL options passed through..."
7714         new_scount=$(((OSTCOUNT + 1) / 2))
7715         $LFS_MIGRATE -E 1M -c 1 -E 16M -c $new_scount -E eof -c -1 "$file1" ||
7716                 error "migrate PFL arguments failed"
7717         cur_comp=$($LFS getstripe --comp-count $file1)
7718         (( cur_comp == 3 )) || error "component count '$cur_comp' != 3"
7719         cur_scount=$($LFS getstripe --stripe-count $file1)
7720         (( cur_scount == new_scount)) ||
7721                 error "PFL stripe count $cur_scount != $new_scount"
7722         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (8)"
7723         echo "done."
7724 }
7725 run_test 56wc "check unrecognized options for lfs_migrate are passed through"
7726
7727 test_56wd() {
7728         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
7729
7730         local file1=$DIR/$tdir/$tfile
7731
7732         echo -n "Creating test dir..."
7733         test_mkdir $DIR/$tdir || error "cannot create dir"
7734         echo "done."
7735
7736         echo -n "Creating test file..."
7737         echo "$tfile" > $file1
7738         echo "done."
7739
7740         # Ensure 'lfs migrate' will fail by using a non-existent option,
7741         # and make sure rsync is not called to recover
7742         echo -n "Make sure --no-rsync option works..."
7743         $LFS_MIGRATE -y --no-rsync --invalid-opt $file1 2>&1 |
7744                 grep -q 'refusing to fall back to rsync' ||
7745                 error "rsync was called with --no-rsync set"
7746         echo "done."
7747
7748         # Ensure rsync is called without trying 'lfs migrate' first
7749         echo -n "Make sure --rsync option works..."
7750         $LFS_MIGRATE -y --rsync --invalid-opt $file1 2>&1 |
7751                 grep -q 'falling back to rsync' &&
7752                 error "lfs migrate was called with --rsync set"
7753         echo "done."
7754 }
7755 run_test 56wd "check lfs_migrate --rsync and --no-rsync work"
7756
7757 test_56we() {
7758         local td=$DIR/$tdir
7759         local tf=$td/$tfile
7760
7761         test_mkdir $td || error "cannot create $td"
7762         touch $tf || error "cannot touch $tf"
7763
7764         echo -n "Make sure --non-direct|-D works..."
7765         $LFS_MIGRATE -y --non-direct -v $tf 2>&1 |
7766                 grep -q "lfs migrate --non-direct" ||
7767                 error "--non-direct option cannot work correctly"
7768         $LFS_MIGRATE -y -D -v $tf 2>&1 |
7769                 grep -q "lfs migrate -D" ||
7770                 error "-D option cannot work correctly"
7771         echo "done."
7772 }
7773 run_test 56we "check lfs_migrate --non-direct|-D support"
7774
7775 test_56x() {
7776         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7777         check_swap_layouts_support
7778
7779         local dir=$DIR/$tdir
7780         local ref1=/etc/passwd
7781         local file1=$dir/file1
7782
7783         test_mkdir $dir || error "creating dir $dir"
7784         $LFS setstripe -c 2 $file1
7785         cp $ref1 $file1
7786         $LFS migrate -c 1 $file1 || error "migrate failed rc = $?"
7787         stripe=$($LFS getstripe -c $file1)
7788         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
7789         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
7790
7791         # clean up
7792         rm -f $file1
7793 }
7794 run_test 56x "lfs migration support"
7795
7796 test_56xa() {
7797         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7798         check_swap_layouts_support
7799
7800         local dir=$DIR/$tdir/$testnum
7801
7802         test_mkdir -p $dir
7803
7804         local ref1=/etc/passwd
7805         local file1=$dir/file1
7806
7807         $LFS setstripe -c 2 $file1
7808         cp $ref1 $file1
7809         $LFS migrate --block -c 1 $file1 || error "migrate failed rc = $?"
7810
7811         local stripe=$($LFS getstripe -c $file1)
7812
7813         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
7814         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
7815
7816         # clean up
7817         rm -f $file1
7818 }
7819 run_test 56xa "lfs migration --block support"
7820
7821 check_migrate_links() {
7822         [[ "$1" == "--rsync" ]] && local opts="--rsync -y" && shift
7823         local dir="$1"
7824         local file1="$dir/file1"
7825         local begin="$2"
7826         local count="$3"
7827         local runas="$4"
7828         local total_count=$(($begin + $count - 1))
7829         local symlink_count=10
7830         local uniq_count=10
7831
7832         if [ ! -f "$file1" ]; then
7833                 echo -n "creating initial file..."
7834                 $LFS setstripe -c 1 -S "512k" "$file1" ||
7835                         error "cannot setstripe initial file"
7836                 echo "done"
7837
7838                 echo -n "creating symlinks..."
7839                 for s in $(seq 1 $symlink_count); do
7840                         ln -s "$file1" "$dir/slink$s" ||
7841                                 error "cannot create symlinks"
7842                 done
7843                 echo "done"
7844
7845                 echo -n "creating nonlinked files..."
7846                 createmany -o "$dir/uniq" 1 10 &> /dev/null ||
7847                         error "cannot create nonlinked files"
7848                 echo "done"
7849         fi
7850
7851         # create hard links
7852         if [ ! -f "$dir/file$total_count" ]; then
7853                 echo -n "creating hard links $begin:$total_count..."
7854                 createmany -l"$file1" "$dir/file" "$begin" "$count" &>  \
7855                         /dev/null || error "cannot create hard links"
7856                 echo "done"
7857         fi
7858
7859         echo -n "checking number of hard links listed in xattrs..."
7860         local fid=$($LFS getstripe -F "$file1")
7861         local paths=($($LFS fid2path "$MOUNT" "$fid" 2> /dev/null))
7862
7863         echo "${#paths[*]}"
7864         if [ ${#paths[*]} -lt $total_count -a "$begin" -eq 2  ]; then
7865                         skip "hard link list has unexpected size, skipping test"
7866         fi
7867         if [ ${#paths[*]} -ge $total_count -a "$begin" -ne 2  ]; then
7868                         error "link names should exceed xattrs size"
7869         fi
7870
7871         echo -n "migrating files..."
7872         local migrate_out=$($runas $LFS_MIGRATE $opts -S '1m' $dir)
7873         local rc=$?
7874         [ $rc -eq 0 ] || error "migrate failed rc = $rc"
7875         echo "done"
7876
7877         # make sure all links have been properly migrated
7878         echo -n "verifying files..."
7879         fid=$($LFS getstripe -F "$file1") ||
7880                 error "cannot get fid for file $file1"
7881         for i in $(seq 2 $total_count); do
7882                 local fid2=$($LFS getstripe -F $dir/file$i)
7883
7884                 [ "$fid2" == "$fid" ] ||
7885                         error "migrated hard link has mismatched FID"
7886         done
7887
7888         # make sure hard links were properly detected, and migration was
7889         # performed only once for the entire link set; nonlinked files should
7890         # also be migrated
7891         local actual=$(grep -c 'done' <<< "$migrate_out")
7892         local expected=$(($uniq_count + 1))
7893
7894         [ "$actual" -eq  "$expected" ] ||
7895                 error "hard links individually migrated ($actual != $expected)"
7896
7897         # make sure the correct number of hard links are present
7898         local hardlinks=$(stat -c '%h' "$file1")
7899
7900         [ $hardlinks -eq $total_count ] ||
7901                 error "num hard links $hardlinks != $total_count"
7902         echo "done"
7903
7904         return 0
7905 }
7906
7907 test_56xb() {
7908         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
7909                 skip "Need MDS version at least 2.10.55"
7910
7911         local dir="$DIR/$tdir"
7912
7913         test_mkdir "$dir" || error "cannot create dir $dir"
7914
7915         echo "testing lfs migrate mode when all links fit within xattrs"
7916         check_migrate_links "$dir" 2 99
7917
7918         echo "testing rsync mode when all links fit within xattrs"
7919         check_migrate_links --rsync "$dir" 2 99
7920
7921         echo "testing lfs migrate mode when all links do not fit within xattrs"
7922         check_migrate_links "$dir" 101 100
7923
7924         echo "testing rsync mode when all links do not fit within xattrs"
7925         check_migrate_links --rsync "$dir" 101 100
7926
7927         chown -R $RUNAS_ID $dir
7928         echo "testing non-root lfs migrate mode when not all links are in xattr"
7929         check_migrate_links "$dir" 101 100 "$RUNAS"
7930
7931         # clean up
7932         rm -rf $dir
7933 }
7934 run_test 56xb "lfs migration hard link support"
7935
7936 test_56xc() {
7937         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7938
7939         local dir="$DIR/$tdir"
7940
7941         test_mkdir "$dir" || error "cannot create dir $dir"
7942
7943         # Test 1: ensure file < 1 GB is always migrated with 1 stripe
7944         echo -n "Setting initial stripe for 20MB test file..."
7945         $LFS setstripe -c 2 -i 0 "$dir/20mb" ||
7946                 error "cannot setstripe 20MB file"
7947         echo "done"
7948         echo -n "Sizing 20MB test file..."
7949         $TRUNCATE "$dir/20mb" 20971520 || error "cannot create 20MB test file"
7950         echo "done"
7951         echo -n "Verifying small file autostripe count is 1..."
7952         $LFS_MIGRATE -y -A -C 1 "$dir/20mb" ||
7953                 error "cannot migrate 20MB file"
7954         local stripe_count=$($LFS getstripe -c "$dir/20mb") ||
7955                 error "cannot get stripe for $dir/20mb"
7956         [ $stripe_count -eq 1 ] ||
7957                 error "unexpected stripe count $stripe_count for 20MB file"
7958         rm -f "$dir/20mb"
7959         echo "done"
7960
7961         # Test 2: File is small enough to fit within the available space on
7962         # sqrt(size_in_gb) + 1 OSTs but is larger than 1GB.  The file must
7963         # have at least an additional 1KB for each desired stripe for test 3
7964         echo -n "Setting stripe for 1GB test file..."
7965         $LFS setstripe -c 1 -i 0 "$dir/1gb" || error "cannot setstripe 1GB file"
7966         echo "done"
7967         echo -n "Sizing 1GB test file..."
7968         # File size is 1GB + 3KB
7969         $TRUNCATE "$dir/1gb" 1073744896 || error "cannot create 1GB test file"
7970         echo "done"
7971
7972         # need at least 512MB per OST for 1GB file to fit in 2 stripes
7973         local avail=$($LCTL get_param -n llite.$FSNAME*.kbytesavail)
7974         if (( avail > 524288 * OSTCOUNT )); then
7975                 echo -n "Migrating 1GB file..."
7976                 $LFS_MIGRATE -y -A -C 1 "$dir/1gb" ||
7977                         error "cannot migrate 1GB file"
7978                 echo "done"
7979                 echo -n "Verifying autostripe count is sqrt(n) + 1..."
7980                 stripe_count=$($LFS getstripe -c "$dir/1gb") ||
7981                         error "cannot getstripe for 1GB file"
7982                 [ $stripe_count -eq 2 ] ||
7983                         error "unexpected stripe count $stripe_count != 2"
7984                 echo "done"
7985         fi
7986
7987         # Test 3: File is too large to fit within the available space on
7988         # sqrt(n) + 1 OSTs.  Simulate limited available space with -X
7989         if [ $OSTCOUNT -ge 3 ]; then
7990                 # The required available space is calculated as
7991                 # file size (1GB + 3KB) / OST count (3).
7992                 local kb_per_ost=349526
7993
7994                 echo -n "Migrating 1GB file with limit..."
7995                 $LFS_MIGRATE -y -A -C 1 -X $kb_per_ost "$dir/1gb" ||
7996                         error "cannot migrate 1GB file with limit"
7997                 echo "done"
7998
7999                 stripe_count=$($LFS getstripe -c "$dir/1gb")
8000                 echo -n "Verifying 1GB autostripe count with limited space..."
8001                 [ "$stripe_count" -a $stripe_count -ge 3 ] ||
8002                         error "unexpected stripe count $stripe_count (min 3)"
8003                 echo "done"
8004         fi
8005
8006         # clean up
8007         rm -rf $dir
8008 }
8009 run_test 56xc "lfs migration autostripe"
8010
8011 test_56xd() {
8012         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8013
8014         local dir=$DIR/$tdir
8015         local f_mgrt=$dir/$tfile.mgrt
8016         local f_yaml=$dir/$tfile.yaml
8017         local f_copy=$dir/$tfile.copy
8018         local layout_yaml="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
8019         local layout_copy="-c 2 -S 2M -i 1"
8020         local yamlfile=$dir/yamlfile
8021         local layout_before;
8022         local layout_after;
8023
8024         test_mkdir "$dir" || error "cannot create dir $dir"
8025         stack_trap "rm -rf $dir"
8026         $LFS setstripe $layout_yaml $f_yaml ||
8027                 error "cannot setstripe $f_yaml with layout $layout_yaml"
8028         $LFS getstripe --yaml $f_yaml > $yamlfile
8029         $LFS setstripe $layout_copy $f_copy ||
8030                 error "cannot setstripe $f_copy with layout $layout_copy"
8031         touch $f_mgrt
8032         dd if=/dev/zero of=$f_mgrt bs=1M count=4
8033
8034         # 1. test option --yaml
8035         $LFS_MIGRATE -y --yaml $yamlfile $f_mgrt ||
8036                 error "cannot migrate $f_mgrt with --yaml $yamlfile"
8037         layout_before=$(get_layout_param $f_yaml)
8038         layout_after=$(get_layout_param $f_mgrt)
8039         [ "$layout_after" == "$layout_before" ] ||
8040                 error "lfs_migrate --yaml: $layout_after != $layout_before"
8041
8042         # 2. test option --copy
8043         $LFS_MIGRATE -y --copy $f_copy $f_mgrt ||
8044                 error "cannot migrate $f_mgrt with --copy $f_copy"
8045         layout_before=$(SKIP_INDEX=yes get_layout_param $f_copy)
8046         layout_after=$(SKIP_INDEX=yes get_layout_param $f_mgrt)
8047         [ "$layout_after" == "$layout_before" ] ||
8048                 error "lfs_migrate --copy: $layout_after != $layout_before"
8049 }
8050 run_test 56xd "check lfs_migrate --yaml and --copy support"
8051
8052 test_56xe() {
8053         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8054
8055         local dir=$DIR/$tdir
8056         local f_comp=$dir/$tfile
8057         local layout="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
8058         local layout_before=""
8059         local layout_after=""
8060
8061         test_mkdir "$dir" || error "cannot create dir $dir"
8062         stack_trap "rm -rf $dir"
8063         $LFS setstripe $layout $f_comp ||
8064                 error "cannot setstripe $f_comp with layout $layout"
8065         layout_before=$(SKIP_INDEX=yes get_layout_param $f_comp)
8066         dd if=/dev/zero of=$f_comp bs=1M count=4
8067
8068         # 1. migrate a comp layout file by lfs_migrate
8069         $LFS_MIGRATE -y $f_comp || error "cannot migrate $f_comp by lfs_migrate"
8070         layout_after=$(SKIP_INDEX=yes get_layout_param $f_comp)
8071         [ "$layout_before" == "$layout_after" ] ||
8072                 error "lfs_migrate: $layout_before != $layout_after"
8073
8074         # 2. migrate a comp layout file by lfs migrate
8075         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
8076         layout_after=$(SKIP_INDEX=yes get_layout_param $f_comp)
8077         [ "$layout_before" == "$layout_after" ] ||
8078                 error "lfs migrate: $layout_before != $layout_after"
8079 }
8080 run_test 56xe "migrate a composite layout file"
8081
8082 test_56xf() {
8083         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
8084
8085         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
8086                 skip "Need server version at least 2.13.53"
8087
8088         local dir=$DIR/$tdir
8089         local f_comp=$dir/$tfile
8090         local layout="-E 1M -c1 -E -1 -c2"
8091         local fid_before=""
8092         local fid_after=""
8093
8094         test_mkdir "$dir" || error "cannot create dir $dir"
8095         stack_trap "rm -rf $dir"
8096         $LFS setstripe $layout $f_comp ||
8097                 error "cannot setstripe $f_comp with layout $layout"
8098         fid_before=$($LFS getstripe --fid $f_comp)
8099         dd if=/dev/zero of=$f_comp bs=1M count=4
8100
8101         # 1. migrate a comp layout file to a comp layout
8102         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
8103         fid_after=$($LFS getstripe --fid $f_comp)
8104         [ "$fid_before" == "$fid_after" ] ||
8105                 error "comp-to-comp migrate: $fid_before != $fid_after"
8106
8107         # 2. migrate a comp layout file to a plain layout
8108         $LFS migrate -c2 $f_comp ||
8109                 error "cannot migrate $f_comp by lfs migrate"
8110         fid_after=$($LFS getstripe --fid $f_comp)
8111         [ "$fid_before" == "$fid_after" ] ||
8112                 error "comp-to-plain migrate: $fid_before != $fid_after"
8113
8114         # 3. migrate a plain layout file to a comp layout
8115         $LFS migrate $layout $f_comp ||
8116                 error "cannot migrate $f_comp by lfs migrate"
8117         fid_after=$($LFS getstripe --fid $f_comp)
8118         [ "$fid_before" == "$fid_after" ] ||
8119                 error "plain-to-comp migrate: $fid_before != $fid_after"
8120 }
8121 run_test 56xf "FID is not lost during migration of a composite layout file"
8122
8123 check_file_ost_range() {
8124         local file="$1"
8125         shift
8126         local range="$*"
8127         local -a file_range
8128         local idx
8129
8130         file_range=($($LFS getstripe -y "$file" |
8131                 awk '/l_ost_idx:/ { print $NF }'))
8132
8133         if [[ "${#file_range[@]}" = 0 ]]; then
8134                 echo "No osts found for $file"
8135                 return 1
8136         fi
8137
8138         for idx in "${file_range[@]}"; do
8139                 [[ " $range " =~ " $idx " ]] ||
8140                         return 1
8141         done
8142
8143         return 0
8144 }
8145
8146 sub_test_56xg() {
8147         local stripe_opt="$1"
8148         local pool="$2"
8149         shift 2
8150         local pool_ostidx="$(seq $* | tr '\n' ' ')"
8151
8152         $LFS migrate $stripe_opt -p $pool $DIR/$tfile ||
8153                 error "Fail to migrate $tfile on $pool"
8154         [[ "$($LFS getstripe -p $DIR/$tfile)" = "$pool" ]] ||
8155                 error "$tfile is not in pool $pool"
8156         check_file_ost_range "$DIR/$tfile" $pool_ostidx ||
8157                 error "$tfile osts mismatch with pool $pool (osts $pool_ostidx)"
8158 }
8159
8160 test_56xg() {
8161         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
8162         [[ $OSTCOUNT -ge 2 ]] || skip "needs >= 2 OSTs"
8163         [[ $MDS1_VERSION -gt $(version_code 2.14.52) ]] ||
8164                 skip "Need MDS version newer than 2.14.52"
8165
8166         local -a pool_names=("${TESTNAME}_0" "${TESTNAME}_1" "${TESTNAME}_2")
8167         local -a pool_ranges=("0 0" "1 1" "0 1")
8168
8169         # init pools
8170         for i in "${!pool_names[@]}"; do
8171                 pool_add ${pool_names[$i]} ||
8172                         error "pool_add failed (pool: ${pool_names[$i]})"
8173                 pool_add_targets ${pool_names[$i]} ${pool_ranges[$i]} ||
8174                         error "pool_add_targets failed (pool: ${pool_names[$i]})"
8175         done
8176
8177         # init the file to migrate
8178         $LFS setstripe -c1 -i1 $DIR/$tfile ||
8179                 error "Unable to create $tfile on OST1"
8180         stack_trap "rm -f $DIR/$tfile"
8181         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=4 status=none ||
8182                 error "Unable to write on $tfile"
8183
8184         echo "1. migrate $tfile on pool ${pool_names[0]}"
8185         sub_test_56xg "-c-1" "${pool_names[0]}" ${pool_ranges[0]}
8186
8187         echo "2. migrate $tfile on pool ${pool_names[2]}"
8188         sub_test_56xg "-c-1 -S2M" "${pool_names[2]}" ${pool_ranges[2]}
8189
8190         echo "3. migrate $tfile on pool ${pool_names[1]}"
8191         sub_test_56xg "-n -c-1" "${pool_names[1]}" ${pool_ranges[1]}
8192
8193         echo "4. migrate $tfile on pool ${pool_names[2]} with default stripe parameters"
8194         sub_test_56xg "" "${pool_names[2]}" ${pool_ranges[2]}
8195         echo
8196
8197         # Clean pools
8198         destroy_test_pools ||
8199                 error "pool_destroy failed"
8200 }
8201 run_test 56xg "lfs migrate pool support"
8202
8203 test_56xh() {
8204         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
8205
8206         local size_mb=25
8207         local file1=$DIR/$tfile
8208         local tmp1=$TMP/$tfile.tmp
8209
8210         $LFS setstripe -c 2 $file1
8211
8212         stack_trap "rm -f $file1 $tmp1"
8213         dd if=/dev/urandom of=$tmp1 bs=1M count=$size_mb ||
8214                         error "error creating $tmp1"
8215         ls -lsh $tmp1
8216         cp $tmp1 $file1
8217
8218         local start=$SECONDS
8219
8220         $LFS migrate --stats --stats-interval=1 -W 1M -c 1 $file1 ||
8221                 error "migrate failed rc = $?"
8222
8223         local elapsed=$((SECONDS - start))
8224
8225         # with 1MB/s, elapsed should equal size_mb
8226         (( elapsed >= size_mb * 95 / 100 )) ||
8227                 error "'lfs migrate -W' too fast ($elapsed < 0.95 * $size_mb)?"
8228
8229         (( elapsed <= size_mb * 120 / 100 )) ||
8230                 error_not_in_vm "'lfs migrate -W' slow ($elapsed > 1.2 * $size_mb)"
8231
8232         (( elapsed <= size_mb * 350 / 100 )) ||
8233                 error "'lfs migrate -W' too slow in VM ($elapsed > 3.5 * $size_mb)"
8234
8235         stripe=$($LFS getstripe -c $file1)
8236         (( $stripe == 1 )) || error "stripe of $file1 is $stripe != 1"
8237         cmp $file1 $tmp1 || error "content mismatch $file1 differs from $tmp1"
8238
8239         # Clean up file (since it is multiple MB)
8240         rm -f $file1 $tmp1
8241 }
8242 run_test 56xh "lfs migrate bandwidth limitation support"
8243
8244 test_56xi() {
8245         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
8246         verify_yaml_available || skip_env "YAML verification not installed"
8247
8248         local size_mb=5
8249         local file1=$DIR/$tfile.1
8250         local file2=$DIR/$tfile.2
8251         local file3=$DIR/$tfile.3
8252         local output_file=$DIR/$tfile.out
8253         local tmp1=$TMP/$tfile.tmp
8254
8255         $LFS setstripe -c 2 $file1
8256         $LFS setstripe -c 2 $file2
8257         $LFS setstripe -c 2 $file3
8258
8259         stack_trap "rm -f $file1 $file2 $file3 $tmp1 $output_file"
8260         dd if=/dev/urandom of=$tmp1 bs=1M count=$size_mb ||
8261                         error "error creating $tmp1"
8262         ls -lsh $tmp1
8263         cp $tmp1 $file1
8264         cp $tmp1 $file2
8265         cp $tmp1 $file3
8266
8267         $LFS migrate --stats --stats-interval=1 \
8268                 -c 1 $file1 $file2 $file3 1> $output_file ||
8269                 error "migrate failed rc = $?"
8270
8271         cat $output_file
8272         cat $output_file | verify_yaml || error "rename_stats is not valid YAML"
8273
8274         # Clean up file (since it is multiple MB)
8275         rm -f $file1 $file2 $file3 $tmp1 $output_file
8276 }
8277 run_test 56xi "lfs migrate stats support"
8278
8279 test_56xj() { # LU-16571 "lfs migrate -b" can cause thread starvation on OSS
8280         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
8281
8282         local file=$DIR/$tfile
8283         local linkdir=$DIR/$tdir
8284
8285         test_mkdir $linkdir || error "fail to create $linkdir"
8286         $LFS setstripe -i 0 -c 1 -S1M $file
8287         stack_trap "rm -rf $file $linkdir"
8288         dd if=/dev/urandom of=$file bs=1M count=10 ||
8289                 error "fail to create $file"
8290
8291         # Create file links
8292         local cpts
8293         local threads_max
8294         local nlinks
8295
8296         thread_max=$(do_facet ost1 "$LCTL get_param -n ost.OSS.ost.threads_max")
8297         cpts=$(do_facet ost1 "$LCTL get_param -n cpu_partition_table | wc -l")
8298         (( nlinks = thread_max * 3 / 2 / cpts))
8299
8300         echo "create $nlinks hard links of $file"
8301         createmany -l $file $linkdir/link $nlinks
8302
8303         # Parallel migrates (should not block)
8304         local i
8305         for ((i = 0; i < nlinks; i++)); do
8306                 echo $linkdir/link$i
8307         done | xargs -n1 -P $nlinks $LFS migrate -c2
8308
8309         local stripe_count
8310         stripe_count=$($LFS getstripe -c $file) ||
8311                 error "fail to get stripe count on $file"
8312
8313         ((stripe_count == 2)) ||
8314                 error "fail to migrate $file (stripe_count = $stripe_count)"
8315 }
8316 run_test 56xj "lfs migrate -b should not cause starvation of threads on OSS"
8317
8318 test_56y() {
8319         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
8320                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
8321
8322         local res=""
8323         local dir=$DIR/$tdir
8324         local f1=$dir/file1
8325         local f2=$dir/file2
8326
8327         test_mkdir -p $dir || error "creating dir $dir"
8328         touch $f1 || error "creating std file $f1"
8329         $MULTIOP $f2 H2c || error "creating released file $f2"
8330
8331         # a directory can be raid0, so ask only for files
8332         res=$($LFS find $dir -L raid0 -type f | wc -l)
8333         [[ $res == 2 ]] || error "search raid0: found $res files != 2"
8334
8335         res=$($LFS find $dir \! -L raid0 -type f | wc -l)
8336         [[ $res == 0 ]] || error "search !raid0: found $res files != 0"
8337
8338         # only files can be released, so no need to force file search
8339         res=$($LFS find $dir -L released)
8340         [[ $res == $f2 ]] || error "search released: found $res != $f2"
8341
8342         res=$($LFS find $dir -type f \! -L released)
8343         [[ $res == $f1 ]] || error "search !released: found $res != $f1"
8344 }
8345 run_test 56y "lfs find -L raid0|released"
8346
8347 test_56z() { # LU-4824
8348         # This checks to make sure 'lfs find' continues after errors
8349         # There are two classes of errors that should be caught:
8350         # - If multiple paths are provided, all should be searched even if one
8351         #   errors out
8352         # - If errors are encountered during the search, it should not terminate
8353         #   early
8354         local dir=$DIR/$tdir
8355         local i
8356
8357         test_mkdir $dir
8358         for i in d{0..9}; do
8359                 test_mkdir $dir/$i
8360                 touch $dir/$i/$tfile
8361         done
8362         $LFS find $DIR/non_existent_dir $dir &&
8363                 error "$LFS find did not return an error"
8364         # Make a directory unsearchable. This should NOT be the last entry in
8365         # directory order.  Arbitrarily pick the 6th entry
8366         chmod 700 $($LFS find $dir -type d | sed '6!d')
8367
8368         $RUNAS $LFS find $DIR/non_existent $dir
8369         local count=$($RUNAS $LFS find $DIR/non_existent $dir | wc -l)
8370
8371         # The user should be able to see 10 directories and 9 files
8372         (( count == 19 )) ||
8373                 error "$LFS find found $count != 19 entries after error"
8374 }
8375 run_test 56z "lfs find should continue after an error"
8376
8377 test_56aa() { # LU-5937
8378         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
8379
8380         local dir=$DIR/$tdir
8381
8382         mkdir $dir
8383         $LFS setdirstripe -c$MDSCOUNT $dir/striped_dir
8384
8385         createmany -o $dir/striped_dir/${tfile}- 1024
8386         local dirs=$($LFS find --size +8k $dir/)
8387
8388         [ -n "$dirs" ] || error "lfs find --size wrong under striped dir"
8389 }
8390 run_test 56aa "lfs find --size under striped dir"
8391
8392 test_56ab() { # LU-10705
8393         test_mkdir $DIR/$tdir
8394         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=8k count=1 seek=2k
8395         dd if=/dev/zero of=$DIR/$tdir/$tfile.2 bs=4k count=1 seek=4k
8396         dd if=/dev/zero of=$DIR/$tdir/$tfile.3 bs=1M count=2 seek=16
8397         # Flush writes to ensure valid blocks.  Need to be more thorough for
8398         # ZFS, since blocks are not allocated/returned to client immediately.
8399         sync_all_data
8400         wait_zfs_commit ost1 2
8401         cancel_lru_locks osc
8402         ls -ls $DIR/$tdir
8403
8404         local files=$($LFS find --size +16M $DIR/$tdir | wc -l)
8405
8406         [[ $files == 3 ]] || error ">16M size files $files isn't 3 as expected"
8407
8408         files=$($LFS find --blocks +1M $DIR/$tdir | wc -l)
8409         [[ $files == 1 ]] || error ">1M blocks files $files isn't 1 as expected"
8410
8411         rm -f $DIR/$tdir/$tfile.[123]
8412 }
8413 run_test 56ab "lfs find --blocks"
8414
8415 # LU-11188
8416 test_56aca() {
8417         local dir="$DIR/$tdir"
8418         local perms=(001 002 003 004 005 006 007
8419                      010 020 030 040 050 060 070
8420                      100 200 300 400 500 600 700
8421                      111 222 333 444 555 666 777)
8422         local perm_minus=(8 8 4 8 4 4 2
8423                           8 8 4 8 4 4 2
8424                           8 8 4 8 4 4 2
8425                           4 4 2 4 2 2 1)
8426         local perm_slash=(8  8 12  8 12 12 14
8427                           8  8 12  8 12 12 14
8428                           8  8 12  8 12 12 14
8429                          16 16 24 16 24 24 28)
8430
8431         test_mkdir "$dir"
8432         for perm in ${perms[*]}; do
8433                 touch "$dir/$tfile.$perm"
8434                 chmod $perm "$dir/$tfile.$perm"
8435         done
8436
8437         for ((i = 0; i < ${#perms[*]}; i++)); do
8438                 local num=$($LFS find $dir -perm ${perms[i]} | wc -l)
8439                 (( $num == 1 )) ||
8440                         error "lfs find -perm ${perms[i]}:"\
8441                               "$num != 1"
8442
8443                 num=$($LFS find $dir -perm -${perms[i]} -type f| wc -l)
8444                 (( $num == ${perm_minus[i]} )) ||
8445                         error "lfs find -perm -${perms[i]}:"\
8446                               "$num != ${perm_minus[i]}"
8447
8448                 num=$($LFS find $dir -perm /${perms[i]} -type f| wc -l)
8449                 (( $num == ${perm_slash[i]} )) ||
8450                         error "lfs find -perm /${perms[i]}:"\
8451                               "$num != ${perm_slash[i]}"
8452         done
8453 }
8454 run_test 56aca "check lfs find -perm with octal representation"
8455
8456 test_56acb() {
8457         local dir=$DIR/$tdir
8458         # p is the permission of write and execute for user, group and other
8459         # without the umask. It is used to test +wx.
8460         local p=$(printf "%o" "$((0333 & ~$(umask)))")
8461         local perms=(1000 000 2000 4000 $p 644 111 110 100 004)
8462         local symbolic=(+t  a+t u+t g+t o+t
8463                         g+s u+s o+s +s o+sr
8464                         o=r,ug+o,u+w
8465                         u+ g+ o+ a+ ugo+
8466                         u- g- o- a- ugo-
8467                         u= g= o= a= ugo=
8468                         o=r,ug+o,u+w u=r,a+u,u+w
8469                         g=r,ugo=g,u+w u+x,+X +X
8470                         u+x,u+X u+X u+x,g+X o+r,+X
8471                         u+x,go+X +wx +rwx)
8472
8473         test_mkdir $dir
8474         for perm in ${perms[*]}; do
8475                 touch "$dir/$tfile.$perm"
8476                 chmod $perm "$dir/$tfile.$perm"
8477         done
8478
8479         for (( i = 0; i < ${#symbolic[*]}; i++ )); do
8480                 local num=$($LFS find $dir -perm ${symbolic[i]} | wc -l)
8481
8482                 (( $num == 1 )) ||
8483                         error "lfs find $dir -perm ${symbolic[i]}: $num != 1"
8484         done
8485 }
8486 run_test 56acb "check lfs find -perm with symbolic representation"
8487
8488 test_56acc() {
8489         local dir=$DIR/$tdir
8490         local tests="17777 787 789 abcd
8491                 ug=uu ug=a ug=gu uo=ou urw
8492                 u+xg+x a=r,u+x,"
8493
8494         test_mkdir $dir
8495         for err in $tests; do
8496                 if $LFS find $dir -perm $err 2>/dev/null; then
8497                         error "lfs find -perm $err: parsing should have failed"
8498                 fi
8499         done
8500 }
8501 run_test 56acc "check parsing error for lfs find -perm"
8502
8503 test_56ba() {
8504         [ $MDS1_VERSION -lt $(version_code 2.10.50) ] &&
8505                 skip "Need MDS version at least 2.10.50"
8506
8507         # Create composite files with one component
8508         local dir=$DIR/$tdir
8509
8510         setup_56 $dir/1Mfiles 5 1 "-S 1M --component-end 1M"
8511         # Create composite files with three components
8512         setup_56 $dir/2Mfiles 5 2 "-E 2M -S 1M -E 4M -E 6M"
8513         # Create non-composite files
8514         createmany -o $dir/${tfile}- 10
8515
8516         local nfiles=$($LFS find --component-end 1M --type f $dir | wc -l)
8517
8518         [[ $nfiles == 10 ]] ||
8519                 error "lfs find -E 1M found $nfiles != 10 files"
8520
8521         nfiles=$($LFS find ! -E 1M --type f $dir | wc -l)
8522         [[ $nfiles == 25 ]] ||
8523                 error "lfs find ! -E 1M found $nfiles != 25 files"
8524
8525         # All files have a component that starts at 0
8526         nfiles=$($LFS find --component-start 0 --type f $dir | wc -l)
8527         [[ $nfiles == 35 ]] ||
8528                 error "lfs find --component-start 0 - $nfiles != 35 files"
8529
8530         nfiles=$($LFS find --component-start 2M --type f $dir | wc -l)
8531         [[ $nfiles == 15 ]] ||
8532                 error "lfs find --component-start 2M - $nfiles != 15 files"
8533
8534         # All files created here have a componenet that does not starts at 2M
8535         nfiles=$($LFS find ! --component-start 2M --type f $dir | wc -l)
8536         [[ $nfiles == 35 ]] ||
8537                 error "lfs find ! --component-start 2M - $nfiles != 35 files"
8538
8539         # Find files with a specified number of components
8540         local nfiles=$($LFS find --component-count 3 --type f $dir | wc -l)
8541         [[ $nfiles == 15 ]] ||
8542                 error "lfs find --component-count 3 - $nfiles != 15 files"
8543
8544         # Remember non-composite files have a component count of zero
8545         local nfiles=$($LFS find --component-count 0 --type f $dir | wc -l)
8546         [[ $nfiles == 10 ]] ||
8547                 error "lfs find --component-count 0 - $nfiles != 10 files"
8548
8549         nfiles=$($LFS find ! --component-count 3 --type f $dir | wc -l)
8550         [[ $nfiles == 20 ]] ||
8551                 error "lfs find ! --component-count 3 - $nfiles != 20 files"
8552
8553         # All files have a flag called "init"
8554         local nfiles=$($LFS find --component-flags init --type f $dir | wc -l)
8555         [[ $nfiles == 35 ]] ||
8556                 error "lfs find --component-flags init - $nfiles != 35 files"
8557
8558         # Multi-component files will have a component not initialized
8559         local nfiles=$($LFS find ! --component-flags init --type f $dir | wc -l)
8560         [[ $nfiles == 15 ]] ||
8561                 error "lfs find !--component-flags init - $nfiles != 15 files"
8562
8563         rm -rf $dir
8564
8565 }
8566 run_test 56ba "test lfs find --component-end, -start, -count, and -flags"
8567
8568 test_56ca() {
8569         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
8570                 skip "Need MDS version at least 2.10.57"
8571
8572         local td=$DIR/$tdir
8573         local tf=$td/$tfile
8574         local dir
8575         local nfiles
8576         local cmd
8577         local i
8578         local j
8579
8580         # create mirrored directories and mirrored files
8581         mkdir $td || error "mkdir $td failed"
8582         $LFS mirror create -N3 $td || error "create mirrored dir $td failed"
8583         createmany -o $tf- 10 || error "create $tf- failed"
8584
8585         for i in $(seq 2); do
8586                 dir=$td/dir$i
8587                 mkdir $dir || error "mkdir $dir failed"
8588                 $LFS mirror create -N$((3 + i)) $dir ||
8589                         error "create mirrored dir $dir failed"
8590                 createmany -o $dir/$tfile- 10 ||
8591                         error "create $dir/$tfile- failed"
8592         done
8593
8594         # change the states of some mirrored files
8595         echo foo > $tf-6
8596         for i in $(seq 2); do
8597                 dir=$td/dir$i
8598                 for j in $(seq 4 9); do
8599                         echo foo > $dir/$tfile-$j
8600                 done
8601         done
8602
8603         # find mirrored files with specific mirror count
8604         cmd="$LFS find --mirror-count 3 --type f $td"
8605         nfiles=$($cmd | wc -l)
8606         [[ $nfiles = 10 ]] || error "$cmd: $nfiles != 10 files"
8607
8608         cmd="$LFS find ! --mirror-count 3 --type f $td"
8609         nfiles=$($cmd | wc -l)
8610         [[ $nfiles = 20 ]] || error "$cmd: $nfiles != 20 files"
8611
8612         cmd="$LFS find --mirror-count +2 --type f $td"
8613         nfiles=$($cmd | wc -l)
8614         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8615
8616         cmd="$LFS find --mirror-count -6 --type f $td"
8617         nfiles=$($cmd | wc -l)
8618         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8619
8620         # find mirrored files with specific file state
8621         cmd="$LFS find --maxdepth 1 --mirror-state=^ro --type f $td"
8622         [[ $($cmd) = $tf-6 ]] || error "$cmd: didn't return $tf-6"
8623
8624         cmd="$LFS find --mirror-state=ro --type f $td"
8625         nfiles=$($cmd | wc -l)
8626         [[ $nfiles = 17 ]] || error "$cmd: $nfiles != 17 files"
8627
8628         cmd="$LFS find ! --mirror-state=ro --type f $td"
8629         nfiles=$($cmd | wc -l)
8630         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
8631
8632         cmd="$LFS find --mirror-state=wp --type f $td"
8633         nfiles=$($cmd | wc -l)
8634         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
8635
8636         cmd="$LFS find ! --mirror-state=sp --type f $td"
8637         nfiles=$($cmd | wc -l)
8638         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8639 }
8640 run_test 56ca "check lfs find --mirror-count|-N and --mirror-state"
8641
8642 test_56da() { # LU-14179
8643         local path=$DIR/$tdir
8644
8645         test_mkdir $path
8646         cd $path
8647
8648         local longdir=$(str_repeat 'a' 255)
8649
8650         for i in {1..15}; do
8651                 path=$path/$longdir
8652                 test_mkdir $longdir
8653                 cd $longdir
8654         done
8655
8656         local len=${#path}
8657         local lastdir=$(str_repeat 'a' $((4096 - 1 - $len - 1)))
8658
8659         test_mkdir $lastdir
8660         cd $lastdir
8661         # PATH_MAX-1
8662         (( ${#PWD} == 4095 )) || error "bad PWD length ${#PWD}, expect 4095"
8663
8664         # NAME_MAX
8665         touch $(str_repeat 'f' 255)
8666
8667         $LFS find $DIR/$tdir --type d |& grep "lfs find: error" &&
8668                 error "lfs find reported an error"
8669
8670         rm -rf $DIR/$tdir
8671 }
8672 run_test 56da "test lfs find with long paths"
8673
8674 test_56ea() { #LU-10378
8675         local path=$DIR/$tdir
8676         local pool=$TESTNAME
8677
8678         # Create ost pool
8679         pool_add $pool || error "pool_add $pool failed"
8680         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
8681                 error "adding targets to $pool failed"
8682
8683         # Set default pool on directory before creating file
8684         mkdir $path || error "mkdir $path failed"
8685         $LFS setstripe -p $pool $path ||
8686                 error "set OST pool on $pool failed"
8687         touch $path/$tfile || error "touch $path/$tfile failed"
8688
8689         # Compare basic file attributes from -printf and stat
8690         local attr_printf=$($LFS find $path/$tfile -printf "%A@ %T@ %C@ %U %G %n")
8691         local attr_stat=$(stat -c "%X %Y %Z %u %g %h" $path/$tfile)
8692
8693         [[ "${attr_printf}" == "${attr_stat}" ]] ||
8694                 error "Attrs from lfs find and stat don't match"
8695
8696         # Compare Lustre attributes from lfs find and lfs getstripe
8697         local lattr_printf=$($LFS find $path/$tfile -printf "%Lc %LS %Li %Lp")
8698         local str_cnt=$($LFS getstripe --stripe-count $path/$tfile)
8699         local str_size=$($LFS getstripe --stripe-size $path/$tfile)
8700         local str_idx=$($LFS getstripe --stripe-index $path/$tfile)
8701         local fpool=$($LFS getstripe --pool $path/$tfile)
8702         local lattr_getstr="${str_cnt} ${str_size} ${str_idx} ${fpool}"
8703
8704         [[ "${lattr_printf}" == "${lattr_getstr}" ]] ||
8705                 error "Attrs from lfs find and lfs getstripe don't match"
8706
8707         # Verify behavior for unknown escape/format sequences
8708         local esc_printf=$($LFS find $path/$tfile -printf '\\ %% \Q %Q')
8709
8710         [[ "${esc_printf}" == '\ % \Q %Q' ]] ||
8711                 error "Escape/format codes don't match"
8712 }
8713 run_test 56ea "test lfs find -printf option"
8714
8715 test_56eb() {
8716         local dir=$DIR/$tdir
8717         local subdir_1=$dir/subdir_1
8718
8719         test_mkdir -p $subdir_1
8720         ln -s subdir_1 $dir/link_1
8721
8722         $LFS getstripe $dir | grep "^$dir/link_1$" -A1 ||
8723                 error "symlink is not followed"
8724
8725         $LFS getstripe --no-follow $dir |
8726                 grep "^$dir/link_1 has no stripe info$" ||
8727                 error "symlink should not have stripe info"
8728
8729         touch $dir/testfile
8730         ln -s testfile $dir/file_link_2
8731
8732         $LFS getstripe $dir | grep "^$dir/file_link_2$" -A1 ||
8733                 error "symlink is not followed"
8734
8735         $LFS getstripe --no-follow $dir |
8736                 grep "^$dir/file_link_2 has no stripe info$" ||
8737                 error "symlink should not have stripe info"
8738 }
8739 run_test 56eb "check lfs getstripe on symlink"
8740
8741 test_56ec() {
8742         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8743         local dir=$DIR/$tdir
8744         local srcfile=$dir/srcfile
8745         local srcyaml=$dir/srcyaml
8746         local destfile=$dir/destfile
8747
8748         test_mkdir -p $dir
8749
8750         $LFS setstripe -i 1 $srcfile
8751         $LFS getstripe --hex-idx --yaml $srcfile > $srcyaml
8752         # if the setstripe yaml parsing fails for any reason, the command can
8753         # randomly assign the correct OST index, leading to an erroneous
8754         # success. but the chance of false success is low enough that a
8755         # regression should still be quickly caught.
8756         $LFS setstripe --yaml=$srcyaml $destfile
8757
8758         local srcindex=$($LFS getstripe -i $srcfile)
8759         local destindex=$($LFS getstripe -i $destfile)
8760
8761         if [[ ! $srcindex -eq $destindex ]]; then
8762                 error "setstripe did not set OST index correctly"
8763         fi
8764 }
8765 run_test 56ec "check lfs getstripe,setstripe --hex --yaml"
8766
8767 test_56eda() {
8768         local dir=$DIR/$tdir
8769         local subdir=$dir/subdir
8770         local file1=$dir/$tfile
8771         local file2=$dir/$tfile\2
8772         local link=$dir/$tfile-link
8773         local nfiles
8774
8775         test_mkdir -p $dir
8776         $LFS setdirstripe -c1 $subdir
8777         touch $file1
8778         touch $file2
8779         ln $file2 $link
8780
8781         nfiles=$($LFS find --links 1 $dir | wc -l)
8782         (( $nfiles == 1 )) ||
8783                 error "lfs find --links expected 1 file, got $nfiles"
8784
8785         nfiles=$($LFS find --type f --links 2 $dir | wc -l)
8786         (( $nfiles == 2 )) ||
8787                 error "lfs find --links expected 2 files, got $nfiles"
8788
8789         nfiles=$($LFS find --type d --links 2 $dir | wc -l)
8790         (( $nfiles == 1 )) ||
8791                 error "lfs find --links expected 1 directory, got $nfiles"
8792 }
8793 run_test 56eda "check lfs find --links"
8794
8795 test_56edb() {
8796         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
8797
8798         local dir=$DIR/$tdir
8799         local stripedir=$dir/stripedir
8800         local nfiles
8801
8802         test_mkdir -p $dir
8803
8804         $LFS setdirstripe -c2 $stripedir
8805
8806         $LFS getdirstripe $stripedir
8807
8808         nfiles=$($LFS find --type d --links 2 $stripedir | wc -l)
8809         (( $nfiles == 1 )) ||
8810                 error "lfs find --links expected 1 directory, got $nfiles"
8811 }
8812 run_test 56edb "check lfs find --links for directory striped on multiple MDTs"
8813
8814 test_57a() {
8815         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8816         # note test will not do anything if MDS is not local
8817         if [ "$mds1_FSTYPE" != ldiskfs ]; then
8818                 skip_env "ldiskfs only test"
8819         fi
8820         remote_mds_nodsh && skip "remote MDS with nodsh"
8821
8822         local MNTDEV="osd*.*MDT*.mntdev"
8823         DEV=$(do_facet $SINGLEMDS lctl get_param -n $MNTDEV)
8824         [ -z "$DEV" ] && error "can't access $MNTDEV"
8825         for DEV in $(do_facet $SINGLEMDS lctl get_param -n $MNTDEV); do
8826                 do_facet $SINGLEMDS $DUMPE2FS -h $DEV > $TMP/t57a.dump ||
8827                         error "can't access $DEV"
8828                 DEVISIZE=$(awk '/Inode size:/ { print $3 }' $TMP/t57a.dump)
8829                 [[ $DEVISIZE -gt 128 ]] || error "inode size $DEVISIZE"
8830                 rm $TMP/t57a.dump
8831         done
8832 }
8833 run_test 57a "verify MDS filesystem created with large inodes =="
8834
8835 test_57b() {
8836         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8837         if [ "$mds1_FSTYPE" != ldiskfs ]; then
8838                 skip_env "ldiskfs only test"
8839         fi
8840         remote_mds_nodsh && skip "remote MDS with nodsh"
8841
8842         local dir=$DIR/$tdir
8843         local filecount=100
8844         local file1=$dir/f1
8845         local fileN=$dir/f$filecount
8846
8847         rm -rf $dir || error "removing $dir"
8848         test_mkdir -c1 $dir
8849         local mdtidx=$($LFS getstripe -m $dir)
8850         local mdtname=MDT$(printf %04x $mdtidx)
8851         local facet=mds$((mdtidx + 1))
8852
8853         echo "mcreating $filecount files"
8854         createmany -m $dir/f 1 $filecount || error "creating files in $dir"
8855
8856         # verify that files do not have EAs yet
8857         $LFS getstripe $file1 2>&1 | grep -q "no stripe" ||
8858                 error "$file1 has an EA"
8859         $LFS getstripe $fileN 2>&1 | grep -q "no stripe" ||
8860                 error "$fileN has an EA"
8861
8862         sync
8863         sleep 1
8864         df $dir  #make sure we get new statfs data
8865         local mdsfree=$(do_facet $facet \
8866                         lctl get_param -n osd*.*$mdtname.kbytesfree)
8867         local mdcfree=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
8868         local file
8869
8870         echo "opening files to create objects/EAs"
8871         for file in $(seq -f $dir/f%g 1 $filecount); do
8872                 $OPENFILE -f O_RDWR $file > /dev/null 2>&1 ||
8873                         error "opening $file"
8874         done
8875
8876         # verify that files have EAs now
8877         $LFS getstripe $file1 | grep -q "obdidx" || error "$file1 missing EA"
8878         $LFS getstripe $fileN | grep -q "obdidx" || error "$fileN missing EA"
8879
8880         sleep 1  #make sure we get new statfs data
8881         df $dir
8882         local mdsfree2=$(do_facet $facet \
8883                          lctl get_param -n osd*.*$mdtname.kbytesfree)
8884         local mdcfree2=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
8885
8886         if [[ $mdcfree2 -lt $((mdcfree - 16)) ]]; then
8887                 if [ "$mdsfree" != "$mdsfree2" ]; then
8888                         error "MDC before $mdcfree != after $mdcfree2"
8889                 else
8890                         echo "MDC before $mdcfree != after $mdcfree2"
8891                         echo "unable to confirm if MDS has large inodes"
8892                 fi
8893         fi
8894         rm -rf $dir
8895 }
8896 run_test 57b "default LOV EAs are stored inside large inodes ==="
8897
8898 test_58() {
8899         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8900         [ -z "$(which wiretest 2>/dev/null)" ] &&
8901                         skip_env "could not find wiretest"
8902
8903         wiretest
8904 }
8905 run_test 58 "verify cross-platform wire constants =============="
8906
8907 test_59() {
8908         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8909
8910         echo "touch 130 files"
8911         createmany -o $DIR/f59- 130
8912         echo "rm 130 files"
8913         unlinkmany $DIR/f59- 130
8914         sync
8915         # wait for commitment of removal
8916         wait_delete_completed
8917 }
8918 run_test 59 "verify cancellation of llog records async ========="
8919
8920 TEST60_HEAD="test_60 run $RANDOM"
8921 test_60a() {
8922         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8923         remote_mgs_nodsh && skip "remote MGS with nodsh"
8924         do_facet mgs "! which run-llog.sh &> /dev/null" &&
8925                 do_facet mgs "! ls run-llog.sh &> /dev/null" &&
8926                         skip_env "missing subtest run-llog.sh"
8927
8928         log "$TEST60_HEAD - from kernel mode"
8929         do_facet mgs "$LCTL dk > /dev/null"
8930         do_facet mgs "bash run-llog.sh" || error "run-llog.sh failed"
8931         do_facet mgs $LCTL dk > $TMP/$tfile
8932
8933         # LU-6388: test llog_reader
8934         local llog_reader=$(do_facet mgs "which llog_reader 2> /dev/null")
8935         llog_reader=${llog_reader:-$LUSTRE/utils/llog_reader}
8936         [ -z $(do_facet mgs ls -d $llog_reader 2> /dev/null) ] &&
8937                         skip_env "missing llog_reader"
8938         local fstype=$(facet_fstype mgs)
8939         [ $fstype != ldiskfs -a $fstype != zfs ] &&
8940                 skip_env "Only for ldiskfs or zfs type mgs"
8941
8942         local mntpt=$(facet_mntpt mgs)
8943         local mgsdev=$(mgsdevname 1)
8944         local fid_list
8945         local fid
8946         local rec_list
8947         local rec
8948         local rec_type
8949         local obj_file
8950         local path
8951         local seq
8952         local oid
8953         local pass=true
8954
8955         #get fid and record list
8956         fid_list=($(awk '/9_sub.*record/ { print $NF }' $TMP/$tfile |
8957                 tail -n 4))
8958         rec_list=($(awk '/9_sub.*record/ { print $((NF-3)) }' $TMP/$tfile |
8959                 tail -n 4))
8960         #remount mgs as ldiskfs or zfs type
8961         stop mgs || error "stop mgs failed"
8962         mount_fstype mgs || error "remount mgs failed"
8963         for ((i = 0; i < ${#fid_list[@]}; i++)); do
8964                 fid=${fid_list[i]}
8965                 rec=${rec_list[i]}
8966                 seq=$(echo $fid | awk -F ':' '{ print $1 }' | sed -e "s/^0x//g")
8967                 oid=$(echo $fid | awk -F ':' '{ print $2 }' | sed -e "s/^0x//g")
8968                 oid=$((16#$oid))
8969
8970                 case $fstype in
8971                         ldiskfs )
8972                                 obj_file=$mntpt/O/$seq/d$((oid%32))/$oid ;;
8973                         zfs )
8974                                 obj_file=$mntpt/oi.$(($((16#$seq))&127))/$fid ;;
8975                 esac
8976                 echo "obj_file is $obj_file"
8977                 do_facet mgs $llog_reader $obj_file
8978
8979                 rec_type=$(do_facet mgs $llog_reader $obj_file | grep "type=" |
8980                         awk '{ print $3 }' | sed -e "s/^type=//g")
8981                 if [ $rec_type != $rec ]; then
8982                         echo "FAILED test_60a wrong record type $rec_type," \
8983                               "should be $rec"
8984                         pass=false
8985                         break
8986                 fi
8987
8988                 #check obj path if record type is LLOG_LOGID_MAGIC
8989                 if [ "$rec" == "1064553b" ]; then
8990                         path=$(do_facet mgs $llog_reader $obj_file |
8991                                 grep "path=" | awk '{ print $NF }' |
8992                                 sed -e "s/^path=//g")
8993                         if [ $obj_file != $mntpt/$path ]; then
8994                                 echo "FAILED test_60a wrong obj path" \
8995                                       "$montpt/$path, should be $obj_file"
8996                                 pass=false
8997                                 break
8998                         fi
8999                 fi
9000         done
9001         rm -f $TMP/$tfile
9002         #restart mgs before "error", otherwise it will block the next test
9003         stop mgs || error "stop mgs failed"
9004         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
9005         $pass || error "test failed, see FAILED test_60a messages for specifics"
9006 }
9007 run_test 60a "llog_test run from kernel module and test llog_reader"
9008
9009 test_60b() { # bug 6411
9010         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9011
9012         dmesg > $DIR/$tfile
9013         LLOG_COUNT=$(do_facet mgs dmesg |
9014                      awk "/$TEST60_HEAD/ { marker = 1; from_marker = 0; }
9015                           /llog_[a-z]*.c:[0-9]/ {
9016                                 if (marker)
9017                                         from_marker++
9018                                 from_begin++
9019                           }
9020                           END {
9021                                 if (marker)
9022                                         print from_marker
9023                                 else
9024                                         print from_begin
9025                           }")
9026
9027         [[ $LLOG_COUNT -gt 120 ]] &&
9028                 error "CDEBUG_LIMIT not limiting messages ($LLOG_COUNT)" || true
9029 }
9030 run_test 60b "limit repeated messages from CERROR/CWARN"
9031
9032 test_60c() {
9033         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9034
9035         echo "create 5000 files"
9036         createmany -o $DIR/f60c- 5000
9037 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED  0x137
9038         lctl set_param fail_loc=0x80000137
9039         unlinkmany $DIR/f60c- 5000
9040         lctl set_param fail_loc=0
9041 }
9042 run_test 60c "unlink file when mds full"
9043
9044 test_60d() {
9045         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9046
9047         SAVEPRINTK=$(lctl get_param -n printk)
9048         # verify "lctl mark" is even working"
9049         MESSAGE="test message ID $RANDOM $$"
9050         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
9051         dmesg | grep -q "$MESSAGE" || error "didn't find debug marker in log"
9052
9053         lctl set_param printk=0 || error "set lnet.printk failed"
9054         lctl get_param -n printk | grep emerg || error "lnet.printk dropped emerg"
9055         MESSAGE="new test message ID $RANDOM $$"
9056         # Assume here that libcfs_debug_mark_buffer() uses D_WARNING
9057         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
9058         dmesg | grep -q "$MESSAGE" && error "D_WARNING wasn't masked" || true
9059
9060         lctl set_param -n printk="$SAVEPRINTK"
9061 }
9062 run_test 60d "test printk console message masking"
9063
9064 test_60e() {
9065         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9066         remote_mds_nodsh && skip "remote MDS with nodsh"
9067
9068         touch $DIR/$tfile
9069 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED2  0x15b
9070         do_facet mds1 lctl set_param fail_loc=0x15b
9071         rm $DIR/$tfile
9072 }
9073 run_test 60e "no space while new llog is being created"
9074
9075 test_60f() {
9076         local old_path=$($LCTL get_param -n debug_path)
9077
9078         stack_trap "$LCTL set_param debug_path=$old_path"
9079         stack_trap "rm -f $TMP/$tfile*"
9080         rm -f $TMP/$tfile* 2> /dev/null
9081         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
9082         $LCTL set_param debug_path=$TMP/$tfile fail_loc=0x8000050e
9083         test_mkdir $DIR/$tdir
9084         # retry in case the open is cached and not released
9085         for (( i = 0; i < 100 && $(ls $TMP/$tfile* | wc -l) == 0; i++ )); do
9086                 echo $i > $DIR/$tdir/$tfile.$i && cat $DIR/$tdir/$tfile.$i
9087                 sleep 0.1
9088         done
9089         ls $TMP/$tfile*
9090         (( $(ls $TMP/$tfile* | wc -l) > 0 )) || error "$TMP/$tfile not dumped"
9091 }
9092 run_test 60f "change debug_path works"
9093
9094 test_60g() {
9095         local pid
9096         local i
9097
9098         test_mkdir -c $MDSCOUNT $DIR/$tdir
9099
9100         (
9101                 local index=0
9102                 while true; do
9103                         $LFS setdirstripe -i $(($index % $MDSCOUNT)) \
9104                                 -c $MDSCOUNT $DIR/$tdir/subdir$index \
9105                                 2>/dev/null
9106                         mkdir $DIR/$tdir/subdir$index 2>/dev/null
9107                         rmdir $DIR/$tdir/subdir$index 2>/dev/null
9108                         index=$((index + 1))
9109                 done
9110         ) &
9111
9112         pid=$!
9113
9114         for i in {0..100}; do
9115                 # define OBD_FAIL_OSD_TXN_START    0x19a
9116                 local index=$((i % MDSCOUNT + 1))
9117
9118                 do_facet mds$index $LCTL set_param fail_loc=0x8000019a \
9119                         > /dev/null
9120                 sleep 0.01
9121         done
9122
9123         kill -9 $pid
9124
9125         for i in $(seq $MDSCOUNT); do
9126                 do_facet mds$i $LCTL set_param fail_loc=0 > /dev/null
9127         done
9128
9129         mkdir $DIR/$tdir/new || error "mkdir failed"
9130         rmdir $DIR/$tdir/new || error "rmdir failed"
9131
9132         do_facet mds1 $LCTL lfsck_start -M $(facet_svc mds1) -A -C \
9133                 -t namespace
9134         for i in $(seq $MDSCOUNT); do
9135                 wait_update_facet mds$i "$LCTL get_param -n \
9136                         mdd.$(facet_svc mds$i).lfsck_namespace |
9137                         awk '/^status/ { print \\\$2 }'" "completed"
9138         done
9139
9140         ls -R $DIR/$tdir
9141         rm -rf $DIR/$tdir || error "rmdir failed"
9142 }
9143 run_test 60g "transaction abort won't cause MDT hung"
9144
9145 test_60h() {
9146         [ $MDS1_VERSION -le $(version_code 2.12.52) ] &&
9147                 skip "Need MDS version at least 2.12.52"
9148         [ $MDSCOUNT -lt 2 ] && skip "Need at least 2 MDTs"
9149
9150         local f
9151
9152         #define OBD_FAIL_MDS_STRIPE_CREATE       0x188
9153         #define OBD_FAIL_MDS_STRIPE_FID          0x189
9154         for fail_loc in 0x80000188 0x80000189; do
9155                 do_facet mds1 "$LCTL set_param fail_loc=$fail_loc"
9156                 $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir-$fail_loc ||
9157                         error "mkdir $dir-$fail_loc failed"
9158                 for i in {0..10}; do
9159                         # create may fail on missing stripe
9160                         echo $i > $DIR/$tdir-$fail_loc/$i
9161                 done
9162                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
9163                         error "getdirstripe $tdir-$fail_loc failed"
9164                 $LFS migrate -m 1 $DIR/$tdir-$fail_loc ||
9165                         error "migrate $tdir-$fail_loc failed"
9166                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
9167                         error "getdirstripe $tdir-$fail_loc failed"
9168                 pushd $DIR/$tdir-$fail_loc
9169                 for f in *; do
9170                         echo $f | cmp $f - || error "$f data mismatch"
9171                 done
9172                 popd
9173                 rm -rf $DIR/$tdir-$fail_loc
9174         done
9175 }
9176 run_test 60h "striped directory with missing stripes can be accessed"
9177
9178 function t60i_load() {
9179         mkdir $DIR/$tdir
9180         #define OBD_FAIL_LLOG_PAUSE_AFTER_PAD               0x131c
9181         $LCTL set_param fail_loc=0x131c fail_val=1
9182         for ((i=0; i<5000; i++)); do
9183                 touch $DIR/$tdir/f$i
9184         done
9185 }
9186
9187 test_60i() {
9188         changelog_register || error "changelog_register failed"
9189         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
9190         changelog_users $SINGLEMDS | grep -q $cl_user ||
9191                 error "User $cl_user not found in changelog_users"
9192         changelog_chmask "ALL"
9193         t60i_load &
9194         local PID=$!
9195         for((i=0; i<100; i++)); do
9196                 changelog_dump >/dev/null ||
9197                         error "can't read changelog"
9198         done
9199         kill $PID
9200         wait $PID
9201         changelog_deregister || error "changelog_deregister failed"
9202         $LCTL set_param fail_loc=0
9203 }
9204 run_test 60i "llog: new record vs reader race"
9205
9206 test_60j() {
9207         (( $MDS1_VERSION >= $(version_code 2.15.50) )) ||
9208                 skip "need MDS version at least 2.15.50"
9209         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
9210         remote_mds_nodsh && skip "remote MDS with nodsh"
9211         [[ "$mds1_FSTYPE" == "ldiskfs" ]] || skip "ldiskfs only test"
9212
9213         changelog_users $SINGLEMDS | grep "^cl" &&
9214                 skip "active changelog user"
9215
9216         local llog_reader=$(do_facet $SINGLEMDS "which llog_reader 2> /dev/null")
9217
9218         [[ -z $(do_facet $SINGLEMDS ls -d $llog_reader 2> /dev/null) ]] &&
9219                 skip_env "missing llog_reader"
9220
9221         mkdir_on_mdt0 $DIR/$tdir
9222
9223         local f=$DIR/$tdir/$tfile
9224         local mdt_dev
9225         local tmpfile
9226         local plain
9227
9228         changelog_register || error "cannot register changelog user"
9229
9230         # set changelog_mask to ALL
9231         changelog_chmask "ALL"
9232         changelog_clear
9233
9234         createmany -o ${f}- 100 || error "createmany failed as $RUNAS_ID"
9235         unlinkmany ${f}- 100 || error "unlinkmany failed"
9236
9237         tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
9238         mdt_dev=$(facet_device $SINGLEMDS)
9239
9240         do_facet $SINGLEMDS sync
9241         plain=$(do_facet $SINGLEMDS "$DEBUGFS -c -R 'dump changelog_catalog \
9242                 $tmpfile' $mdt_dev; $llog_reader $tmpfile" |
9243                 awk '{match($0,"path=([^ ]+)",a)}END{print a[1]}')
9244
9245         stack_trap "do_facet $SINGLEMDS rm -f $tmpfile"
9246
9247         # if $tmpfile is not on EXT3 filesystem for some reason
9248         [[ ${plain:0:1} == 'O' ]] ||
9249                 skip "path $plain is not in 'O/1/d<n>/<n>' format"
9250
9251         size=$(do_facet $SINGLEMDS "$DEBUGFS -c -R 'dump $plain $tmpfile' \
9252                 $mdt_dev; stat -c %s $tmpfile")
9253         echo "Truncate llog from $size to $((size - size % 8192))"
9254         size=$((size - size % 8192))
9255         do_facet $SINGLEMDS $TRUNCATE $tmpfile $size
9256         errs=$(do_facet $SINGLEMDS "$llog_reader $tmpfile" |
9257                 grep -c 'in bitmap only')
9258         (( $errs > 0 )) || error "llog_reader didn't find lost records"
9259
9260         size=$((size - 9000))
9261         echo "Corrupt llog in the middle at $size"
9262         do_facet $SINGLEMDS dd if=/dev/urandom of=$tmpfile bs=1 seek=$size \
9263                 count=333 conv=notrunc
9264         errs=$(do_facet $SINGLEMDS "$llog_reader $tmpfile" |
9265                 grep -c 'next chunk')
9266         (( $errs > 0 )) || error "llog_reader didn't skip bad chunk"
9267 }
9268 run_test 60j "llog_reader reports corruptions"
9269
9270 test_61a() {
9271         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9272
9273         f="$DIR/f61"
9274         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1 || error "dd $f failed"
9275         cancel_lru_locks osc
9276         $MULTIOP $f OSMWUc || error "$MULTIOP $f failed"
9277         sync
9278 }
9279 run_test 61a "mmap() writes don't make sync hang ================"
9280
9281 test_61b() {
9282         mmap_mknod_test $DIR/$tfile || error "mmap_mknod_test failed"
9283 }
9284 run_test 61b "mmap() of unstriped file is successful"
9285
9286 # bug 2319 - oig_wait() interrupted causes crash because of invalid waitq.
9287 # Though this test is irrelevant anymore, it helped to reveal some
9288 # other grant bugs (LU-4482), let's keep it.
9289 test_63a() {   # was test_63
9290         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9291
9292         MAX_DIRTY_MB=$(lctl get_param -n osc.*.max_dirty_mb | head -n 1)
9293
9294         for i in `seq 10` ; do
9295                 dd if=/dev/zero of=$DIR/f63 bs=8k &
9296                 sleep 5
9297                 kill $!
9298                 sleep 1
9299         done
9300
9301         rm -f $DIR/f63 || true
9302 }
9303 run_test 63a "Verify oig_wait interruption does not crash ======="
9304
9305 # bug 2248 - async write errors didn't return to application on sync
9306 # bug 3677 - async write errors left page locked
9307 test_63b() {
9308         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9309
9310         debugsave
9311         lctl set_param debug=-1
9312
9313         # ensure we have a grant to do async writes
9314         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1
9315         rm $DIR/$tfile
9316
9317         sync    # sync lest earlier test intercept the fail_loc
9318
9319         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
9320         lctl set_param fail_loc=0x80000406
9321         $MULTIOP $DIR/$tfile Owy && \
9322                 error "sync didn't return ENOMEM"
9323         sync; sleep 2; sync     # do a real sync this time to flush page
9324         lctl get_param -n llite.*.dump_page_cache | grep locked && \
9325                 error "locked page left in cache after async error" || true
9326         debugrestore
9327 }
9328 run_test 63b "async write errors should be returned to fsync ==="
9329
9330 test_64a () {
9331         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9332
9333         lfs df $DIR
9334         lctl get_param osc.*[oO][sS][cC][_-]*.cur* | grep "=[1-9]"
9335 }
9336 run_test 64a "verify filter grant calculations (in kernel) ====="
9337
9338 test_64b () {
9339         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9340
9341         bash oos.sh $MOUNT || error "oos.sh failed: $?"
9342 }
9343 run_test 64b "check out-of-space detection on client"
9344
9345 test_64c() {
9346         $LCTL set_param osc.*OST0000-osc-[^mM]*.cur_grant_bytes=0
9347 }
9348 run_test 64c "verify grant shrink"
9349
9350 import_param() {
9351         local tgt=$1
9352         local param=$2
9353
9354         $LCTL get_param osc.$tgt.import | awk "/$param/ { print \$2 }"
9355 }
9356
9357 # this does exactly what osc_request.c:osc_announce_cached() does in
9358 # order to calculate max amount of grants to ask from server
9359 want_grant() {
9360         local tgt=$1
9361
9362         local nrpages=$($LCTL get_param -n osc.$tgt.max_pages_per_rpc)
9363         local rpc_in_flight=$($LCTL get_param -n osc.$tgt.max_rpcs_in_flight)
9364
9365         ((rpc_in_flight++));
9366         nrpages=$((nrpages * rpc_in_flight))
9367
9368         local dirty_max_pages=$($LCTL get_param -n osc.$tgt.max_dirty_mb)
9369
9370         dirty_max_pages=$((dirty_max_pages * 1024 * 1024 / PAGE_SIZE))
9371
9372         [[ $dirty_max_pages -gt $nrpages ]] && nrpages=$dirty_max_pages
9373         local undirty=$((nrpages * PAGE_SIZE))
9374
9375         local max_extent_pages
9376         max_extent_pages=$(import_param $tgt grant_max_extent_size)
9377         max_extent_pages=$((max_extent_pages / PAGE_SIZE))
9378         local nrextents=$(((nrpages + max_extent_pages - 1) / max_extent_pages))
9379         local grant_extent_tax
9380         grant_extent_tax=$(import_param $tgt grant_extent_tax)
9381
9382         undirty=$((undirty + nrextents * grant_extent_tax))
9383
9384         echo $undirty
9385 }
9386
9387 # this is size of unit for grant allocation. It should be equal to
9388 # what tgt_grant.c:tgt_grant_chunk() calculates
9389 grant_chunk() {
9390         local tgt=$1
9391         local max_brw_size
9392         local grant_extent_tax
9393
9394         max_brw_size=$(import_param $tgt max_brw_size)
9395
9396         grant_extent_tax=$(import_param $tgt grant_extent_tax)
9397
9398         echo $(((max_brw_size + grant_extent_tax) * 2))
9399 }
9400
9401 test_64d() {
9402         [ $OST1_VERSION -ge $(version_code 2.10.56) ] ||
9403                 skip "OST < 2.10.55 doesn't limit grants enough"
9404
9405         local tgt=$($LCTL dl | awk '/OST0000-osc-[^mM]/ { print $4 }')
9406
9407         [[ "$($LCTL get_param osc.${tgt}.import)" =~ "grant_param" ]] ||
9408                 skip "no grant_param connect flag"
9409
9410         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
9411
9412         $LCTL set_param -n -n debug="$OLDDEBUG" || true
9413         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
9414
9415
9416         local max_cur_granted=$(($(want_grant $tgt) + $(grant_chunk $tgt)))
9417         stack_trap "rm -f $DIR/$tfile && wait_delete_completed" EXIT
9418
9419         $LFS setstripe $DIR/$tfile -i 0 -c 1
9420         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1000 &
9421         ddpid=$!
9422
9423         while kill -0 $ddpid; do
9424                 local cur_grant=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
9425
9426                 if [[ $cur_grant -gt $max_cur_granted ]]; then
9427                         kill $ddpid
9428                         error "cur_grant $cur_grant > $max_cur_granted"
9429                 fi
9430
9431                 sleep 1
9432         done
9433 }
9434 run_test 64d "check grant limit exceed"
9435
9436 check_grants() {
9437         local tgt=$1
9438         local expected=$2
9439         local msg=$3
9440         local cur_grants=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
9441
9442         ((cur_grants == expected)) ||
9443                 error "$msg: grants mismatch: $cur_grants, expected $expected"
9444 }
9445
9446 round_up_p2() {
9447         echo $((($1 + $2 - 1) & ~($2 - 1)))
9448 }
9449
9450 test_64e() {
9451         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9452         [ $OST1_VERSION -ge $(version_code 2.11.56) ] ||
9453                 skip "Need OSS version at least 2.11.56"
9454
9455         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
9456         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
9457         $LCTL set_param debug=+cache
9458
9459         # Remount client to reset grant
9460         remount_client $MOUNT || error "failed to remount client"
9461         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9462
9463         local init_grants=$(import_param $osc_tgt initial_grant)
9464
9465         check_grants $osc_tgt $init_grants "init grants"
9466
9467         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
9468         local max_brw_size=$(import_param $osc_tgt max_brw_size)
9469         local gbs=$(import_param $osc_tgt grant_block_size)
9470
9471         # write random number of bytes from max_brw_size / 4 to max_brw_size
9472         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
9473         # align for direct io
9474         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
9475         # round to grant consumption unit
9476         local wb_round_up=$(round_up_p2 $write_bytes gbs)
9477
9478         local grants=$((wb_round_up + extent_tax))
9479
9480         $LFS setstripe -c 1 -i 0 $DIR/$tfile  || error "lfs setstripe failed"
9481         stack_trap "rm -f $DIR/$tfile"
9482
9483         # define OBD_FAIL_TGT_NO_GRANT 0x725
9484         # make the server not grant more back
9485         do_facet ost1 $LCTL set_param fail_loc=0x725
9486         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct
9487
9488         do_facet ost1 $LCTL set_param fail_loc=0
9489
9490         check_grants $osc_tgt $((init_grants - grants)) "dio w/o grant alloc"
9491
9492         rm -f $DIR/$tfile || error "rm failed"
9493
9494         # Remount client to reset grant
9495         remount_client $MOUNT || error "failed to remount client"
9496         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9497
9498         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
9499
9500         # define OBD_FAIL_TGT_NO_GRANT 0x725
9501         # make the server not grant more back
9502         do_facet ost1 $LCTL set_param fail_loc=0x725
9503         $MULTIOP $DIR/$tfile "oO_WRONLY:w${write_bytes}yc"
9504         do_facet ost1 $LCTL set_param fail_loc=0
9505
9506         check_grants $osc_tgt $((init_grants - grants)) "buf io w/o grant alloc"
9507 }
9508 run_test 64e "check grant consumption (no grant allocation)"
9509
9510 test_64f() {
9511         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9512
9513         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
9514         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
9515         $LCTL set_param debug=+cache
9516
9517         # Remount client to reset grant
9518         remount_client $MOUNT || error "failed to remount client"
9519         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9520
9521         local init_grants=$(import_param $osc_tgt initial_grant)
9522         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
9523         local max_brw_size=$(import_param $osc_tgt max_brw_size)
9524         local gbs=$(import_param $osc_tgt grant_block_size)
9525         local chunk=$(grant_chunk $osc_tgt)
9526
9527         # write random number of bytes from max_brw_size / 4 to max_brw_size
9528         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
9529         # align for direct io
9530         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
9531         # round to grant consumption unit
9532         local wb_round_up=$(round_up_p2 $write_bytes gbs)
9533
9534         local grants=$((wb_round_up + extent_tax))
9535
9536         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
9537         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct ||
9538                 error "error writing to $DIR/$tfile"
9539
9540         check_grants $osc_tgt $((init_grants - grants + chunk)) \
9541                 "direct io with grant allocation"
9542
9543         rm -f $DIR/$tfile || error "rm failed"
9544
9545         # Remount client to reset grant
9546         remount_client $MOUNT || error "failed to remount client"
9547         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9548
9549         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
9550
9551         local cmd="oO_WRONLY:w${write_bytes}_yc"
9552
9553         $MULTIOP $DIR/$tfile $cmd &
9554         MULTIPID=$!
9555         sleep 1
9556
9557         check_grants $osc_tgt $((init_grants - grants)) \
9558                 "buffered io, not write rpc"
9559
9560         kill -USR1 $MULTIPID
9561         wait
9562
9563         check_grants $osc_tgt $((init_grants - grants + chunk)) \
9564                 "buffered io, one RPC"
9565 }
9566 run_test 64f "check grant consumption (with grant allocation)"
9567
9568 test_64g() {
9569         (( $MDS1_VERSION >= $(version_code 2.14.56) )) ||
9570                 skip "Need MDS version at least 2.14.56"
9571
9572         local mdts=$(comma_list $(mdts_nodes))
9573
9574         local old=$($LCTL get_param mdc.$FSNAME-*.grant_shrink_interval |
9575                         tr '\n' ' ')
9576         stack_trap "$LCTL set_param $old"
9577
9578         # generate dirty pages and increase dirty granted on MDT
9579         stack_trap "rm -f $DIR/$tfile-*"
9580         for (( i = 0; i < 10; i++)); do
9581                 $LFS setstripe -E 1M -L mdt $DIR/$tfile-$i ||
9582                         error "can't set stripe"
9583                 dd if=/dev/zero of=$DIR/$tfile-$i bs=128k count=1 ||
9584                         error "can't dd"
9585                 $LFS getstripe $DIR/$tfile-$i | grep -q pattern.*mdt || {
9586                         $LFS getstripe $DIR/$tfile-$i
9587                         error "not DoM file"
9588                 }
9589         done
9590
9591         # flush dirty pages
9592         sync
9593
9594         # wait until grant shrink reset grant dirty on MDTs
9595         for ((i = 0; i < 120; i++)); do
9596                 grant_dirty=$(do_nodes $mdts $LCTL get_param -n  mdt.*.tot_dirty |
9597                         awk '{sum=sum+$1} END {print sum}')
9598                 vm_dirty=$(awk '/Dirty:/{print $2}' /proc/meminfo)
9599                 echo "$grant_dirty grants, $vm_dirty pages"
9600                 (( grant_dirty + vm_dirty == 0 )) && break
9601                 (( i == 3 )) && sync &&
9602                         $LCTL set_param mdc.$FSNAME-*.grant_shrink_interval=5
9603                 sleep 1
9604         done
9605
9606         grant_dirty=$(do_nodes $mdts $LCTL get_param -n  mdt.*.tot_dirty |
9607                 awk '{sum=sum+$1} END {print sum}')
9608         (( grant_dirty == 0 )) || error "$grant_dirty on MDT"
9609 }
9610 run_test 64g "grant shrink on MDT"
9611
9612 test_64h() {
9613         (( $OST1_VERSION >= $(version_code 2.14.56) )) ||
9614                 skip "need OST at least 2.14.56 to avoid grant shrink on read"
9615
9616         local instance=$($LFS getname -i $DIR)
9617         local osc_tgt="$FSNAME-OST0000-osc-$instance"
9618         local num_exps=$(do_facet ost1 \
9619             $LCTL get_param -n obdfilter.*OST0000*.num_exports)
9620         local max_brw_size=$(import_param $osc_tgt max_brw_size)
9621         local avail=$($LCTL get_param -n osc.*OST0000-osc-$instance.kbytesavail)
9622         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
9623
9624         # 10MiB is for file to be written, max_brw_size * 16 *
9625         # num_exps is space reserve so that tgt_grant_shrink() decided
9626         # to not shrink
9627         local expect=$((max_brw_size * 16 * num_exps + 10 * 1048576))
9628         (( avail * 1024 < expect )) &&
9629                 skip "need $expect bytes on ost1, have $(( avail * 1024 )) only"
9630
9631         save_lustre_params client "osc.*OST0000*.grant_shrink" > $p
9632         save_lustre_params client "osc.*OST0000*.grant_shrink_interval" >> $p
9633         stack_trap "restore_lustre_params < $p; rm -f $save" EXIT
9634         $LCTL set_param osc.*OST0000*.grant_shrink=1
9635         $LCTL set_param osc.*OST0000*.grant_shrink_interval=10
9636
9637         $LFS setstripe -c 1 -i 0 $DIR/$tfile
9638         stack_trap "rm -f $DIR/$tfile"
9639         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 oflag=sync
9640
9641         # drop cache so that coming read would do rpc
9642         cancel_lru_locks osc
9643
9644         # shrink interval is set to 10, pause for 7 seconds so that
9645         # grant thread did not wake up yet but coming read entered
9646         # shrink mode for rpc (osc_should_shrink_grant())
9647         sleep 7
9648
9649         declare -a cur_grant_bytes
9650         declare -a tot_granted
9651         cur_grant_bytes[0]=$($LCTL get_param -n osc.*OST0000*.cur_grant_bytes)
9652         tot_granted[0]=$(do_facet ost1 \
9653             $LCTL get_param -n obdfilter.*OST0000*.tot_granted)
9654
9655         dd if=$DIR/$tfile bs=4K count=1 of=/dev/null
9656
9657         cur_grant_bytes[1]=$($LCTL get_param -n osc.*OST0000*.cur_grant_bytes)
9658         tot_granted[1]=$(do_facet ost1 \
9659             $LCTL get_param -n obdfilter.*OST0000*.tot_granted)
9660
9661         # grant change should be equal on both sides
9662         (( cur_grant_bytes[0] - cur_grant_bytes[1] ==
9663                 tot_granted[0] - tot_granted[1])) ||
9664                 error "grant change mismatch, "                                \
9665                         "server: ${tot_granted[0]} to ${tot_granted[1]}, "     \
9666                         "client: ${cur_grant_bytes[0]} to ${cur_grant_bytes[1]}"
9667 }
9668 run_test 64h "grant shrink on read"
9669
9670 test_64i() {
9671         (( $OST1_VERSION >= $(version_code 2.14.56) )) ||
9672                 skip "need OST at least 2.14.56 to avoid grant shrink on replay"
9673
9674         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9675         remote_ost_nodsh && skip "remote OSTs with nodsh"
9676
9677         $LFS setstripe -c 1 -i 0 $DIR/$tfile
9678         stack_trap "rm -f $DIR/$tfile"
9679
9680         dd if=/dev/zero of=$DIR/$tfile bs=1M count=64
9681
9682         # lustre-ffff9fc75e850800 /mnt/lustre -> ffff9fc75e850800
9683         local instance=$($LFS getname -i $DIR)
9684
9685         local osc_tgt="$FSNAME-OST0000-osc-$instance"
9686         local cgb=$($LCTL get_param -n osc.$osc_tgt.cur_grant_bytes)
9687
9688         # shrink grants and simulate rpc loss
9689         #define OBD_FAIL_PTLRPC_DROP_REQ_OPC     0x513
9690         do_facet ost1 "$LCTL set_param fail_loc=0x80000513 fail_val=17"
9691         $LCTL set_param osc.$osc_tgt.cur_grant_bytes=$((cgb/2))B
9692
9693         fail ost1
9694
9695         dd if=/dev/zero of=$DIR/$tfile oflag=append bs=1M count=8 conv=notrunc
9696
9697         local testid=$(echo $TESTNAME | tr '_' ' ')
9698
9699         do_facet ost1 dmesg | tac | sed "/$testid/,$ d" |
9700                 grep "GRANT, real grant" &&
9701                 error "client has more grants then it owns" || true
9702 }
9703 run_test 64i "shrink on reconnect"
9704
9705 # bug 1414 - set/get directories' stripe info
9706 test_65a() {
9707         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9708
9709         test_mkdir $DIR/$tdir
9710         touch $DIR/$tdir/f1
9711         $LVERIFY $DIR/$tdir $DIR/$tdir/f1 || error "lverify failed"
9712 }
9713 run_test 65a "directory with no stripe info"
9714
9715 test_65b() {
9716         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9717
9718         test_mkdir $DIR/$tdir
9719         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9720
9721         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
9722                                                 error "setstripe"
9723         touch $DIR/$tdir/f2
9724         $LVERIFY $DIR/$tdir $DIR/$tdir/f2 || error "lverify failed"
9725 }
9726 run_test 65b "directory setstripe -S stripe_size*2 -i 0 -c 1"
9727
9728 test_65c() {
9729         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9730         [ $OSTCOUNT -lt 2 ] && skip_env "need at least 2 OSTs"
9731
9732         test_mkdir $DIR/$tdir
9733         local stripesize=$($LFS getstripe -S $DIR/$tdir)
9734
9735         $LFS setstripe -S $((stripesize * 4)) -i 1 \
9736                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
9737         touch $DIR/$tdir/f3
9738         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
9739 }
9740 run_test 65c "directory setstripe -S stripe_size*4 -i 1 -c $((OSTCOUNT-1))"
9741
9742 test_65d() {
9743         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9744
9745         test_mkdir $DIR/$tdir
9746         local STRIPECOUNT=$($LFS getstripe -c $DIR/$tdir)
9747         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9748
9749         if [[ $STRIPECOUNT -le 0 ]]; then
9750                 sc=1
9751         elif [[ $STRIPECOUNT -gt $LOV_MAX_STRIPE_COUNT ]]; then
9752                 [[ $OSTCOUNT -gt $LOV_MAX_STRIPE_COUNT ]] &&
9753                         sc=$LOV_MAX_STRIPE_COUNT || sc=$(($OSTCOUNT - 1))
9754         else
9755                 sc=$(($STRIPECOUNT - 1))
9756         fi
9757         $LFS setstripe -S $STRIPESIZE -c $sc $DIR/$tdir || error "setstripe"
9758         touch $DIR/$tdir/f4 $DIR/$tdir/f5
9759         $LVERIFY $DIR/$tdir $DIR/$tdir/f4 $DIR/$tdir/f5 ||
9760                 error "lverify failed"
9761 }
9762 run_test 65d "directory setstripe -S stripe_size -c stripe_count"
9763
9764 test_65e() {
9765         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9766
9767         test_mkdir $DIR/$tdir
9768
9769         $LFS setstripe $DIR/$tdir || error "setstripe"
9770         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
9771                                         error "no stripe info failed"
9772         touch $DIR/$tdir/f6
9773         $LVERIFY $DIR/$tdir $DIR/$tdir/f6 || error "lverify failed"
9774 }
9775 run_test 65e "directory setstripe defaults"
9776
9777 test_65f() {
9778         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9779
9780         test_mkdir $DIR/${tdir}f
9781         $RUNAS $LFS setstripe $DIR/${tdir}f &&
9782                 error "setstripe succeeded" || true
9783 }
9784 run_test 65f "dir setstripe permission (should return error) ==="
9785
9786 test_65g() {
9787         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9788
9789         test_mkdir $DIR/$tdir
9790         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9791
9792         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
9793                 error "setstripe -S failed"
9794         $LFS setstripe -d $DIR/$tdir || error "setstripe -d failed"
9795         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
9796                 error "delete default stripe failed"
9797 }
9798 run_test 65g "directory setstripe -d"
9799
9800 test_65h() {
9801         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9802
9803         test_mkdir $DIR/$tdir
9804         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9805
9806         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
9807                 error "setstripe -S failed"
9808         test_mkdir $DIR/$tdir/dd1
9809         [ $($LFS getstripe -c $DIR/$tdir) = $($LFS getstripe -c $DIR/$tdir/dd1) ] ||
9810                 error "stripe info inherit failed"
9811 }
9812 run_test 65h "directory stripe info inherit ===================="
9813
9814 test_65i() {
9815         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9816
9817         save_layout_restore_at_exit $MOUNT
9818
9819         # bug6367: set non-default striping on root directory
9820         $LFS setstripe -S 65536 -c -1 $MOUNT || error "error setting stripe"
9821
9822         # bug12836: getstripe on -1 default directory striping
9823         $LFS getstripe $MOUNT || error "getstripe $MOUNT failed"
9824
9825         # bug12836: getstripe -v on -1 default directory striping
9826         $LFS getstripe -v $MOUNT || error "getstripe -v $MOUNT failed"
9827
9828         # bug12836: new find on -1 default directory striping
9829         $LFS find -mtime -1 $MOUNT > /dev/null || error "find $MOUNT failed"
9830 }
9831 run_test 65i "various tests to set root directory striping"
9832
9833 test_65j() { # bug6367
9834         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9835
9836         sync; sleep 1
9837
9838         # if we aren't already remounting for each test, do so for this test
9839         if [ "$I_MOUNTED" = "yes" ]; then
9840                 cleanup || error "failed to unmount"
9841                 setup
9842         fi
9843
9844         save_layout_restore_at_exit $MOUNT
9845
9846         $LFS setstripe -d $MOUNT || error "setstripe failed"
9847 }
9848 run_test 65j "set default striping on root directory (bug 6367)="
9849
9850 cleanup_65k() {
9851         rm -rf $DIR/$tdir
9852         wait_delete_completed
9853         do_facet $SINGLEMDS "lctl set_param -n \
9854                 osp.$ost*MDT0000.max_create_count=$max_count"
9855         do_facet $SINGLEMDS "lctl set_param -n \
9856                 osp.$ost*MDT0000.create_count=$count"
9857         do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
9858         echo $INACTIVE_OSC "is Activate"
9859
9860         wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
9861 }
9862
9863 test_65k() { # bug11679
9864         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9865         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9866         remote_mds_nodsh && skip "remote MDS with nodsh"
9867
9868         local disable_precreate=true
9869         [ $MDS1_VERSION -le $(version_code 2.8.54) ] &&
9870                 disable_precreate=false
9871
9872         echo "Check OST status: "
9873         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
9874                 awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
9875
9876         for OSC in $MDS_OSCS; do
9877                 echo $OSC "is active"
9878                 do_facet $SINGLEMDS lctl --device %$OSC activate
9879         done
9880
9881         for INACTIVE_OSC in $MDS_OSCS; do
9882                 local ost=$(osc_to_ost $INACTIVE_OSC)
9883                 local ostnum=$(do_facet $SINGLEMDS lctl get_param -n \
9884                                lov.*md*.target_obd |
9885                                awk -F: /$ost/'{ print $1 }' | head -n 1)
9886
9887                 mkdir -p $DIR/$tdir
9888                 $LFS setstripe -i $ostnum -c 1 $DIR/$tdir
9889                 createmany -o $DIR/$tdir/$tfile.$ostnum. 1000
9890
9891                 echo "Deactivate: " $INACTIVE_OSC
9892                 do_facet $SINGLEMDS lctl --device %$INACTIVE_OSC deactivate
9893
9894                 local count=$(do_facet $SINGLEMDS "lctl get_param -n \
9895                               osp.$ost*MDT0000.create_count")
9896                 local max_count=$(do_facet $SINGLEMDS "lctl get_param -n \
9897                                   osp.$ost*MDT0000.max_create_count")
9898                 $disable_precreate &&
9899                         do_facet $SINGLEMDS "lctl set_param -n \
9900                                 osp.$ost*MDT0000.max_create_count=0"
9901
9902                 for idx in $(seq 0 $((OSTCOUNT - 1))); do
9903                         [ -f $DIR/$tdir/$idx ] && continue
9904                         echo "$LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx"
9905                         $LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx ||
9906                                 { cleanup_65k;
9907                                   error "setstripe $idx should succeed"; }
9908                         rm -f $DIR/$tdir/$idx || error "rm $idx failed"
9909                 done
9910                 unlinkmany $DIR/$tdir/$tfile.$ostnum. 1000
9911                 rmdir $DIR/$tdir
9912
9913                 do_facet $SINGLEMDS "lctl set_param -n \
9914                         osp.$ost*MDT0000.max_create_count=$max_count"
9915                 do_facet $SINGLEMDS "lctl set_param -n \
9916                         osp.$ost*MDT0000.create_count=$count"
9917                 do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
9918                 echo $INACTIVE_OSC "is Activate"
9919
9920                 wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
9921         done
9922 }
9923 run_test 65k "validate manual striping works properly with deactivated OSCs"
9924
9925 test_65l() { # bug 12836
9926         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9927
9928         test_mkdir -p $DIR/$tdir/test_dir
9929         $LFS setstripe -c -1 $DIR/$tdir/test_dir
9930         $LFS find -mtime -1 $DIR/$tdir >/dev/null
9931 }
9932 run_test 65l "lfs find on -1 stripe dir ========================"
9933
9934 test_65m() {
9935         local layout=$(save_layout $MOUNT)
9936         $RUNAS $LFS setstripe -c 2 $MOUNT && {
9937                 restore_layout $MOUNT $layout
9938                 error "setstripe should fail by non-root users"
9939         }
9940         true
9941 }
9942 run_test 65m "normal user can't set filesystem default stripe"
9943
9944 test_65n() {
9945         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
9946         [[ $MDS1_VERSION -ge $(version_code 2.12.50) ]] ||
9947                 skip "Need MDS version at least 2.12.50"
9948         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
9949
9950         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
9951         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
9952         which setfattr > /dev/null 2>&1 || skip_env "no setfattr command"
9953
9954         save_layout_restore_at_exit $MOUNT
9955
9956         # new subdirectory under root directory should not inherit
9957         # the default layout from root
9958         local dir1=$MOUNT/$tdir-1
9959         mkdir $dir1 || error "mkdir $dir1 failed"
9960         ! getfattr -n trusted.lov $dir1 &> /dev/null ||
9961                 error "$dir1 shouldn't have LOV EA"
9962
9963         # delete the default layout on root directory
9964         $LFS setstripe -d $MOUNT || error "delete root default layout failed"
9965
9966         local dir2=$MOUNT/$tdir-2
9967         mkdir $dir2 || error "mkdir $dir2 failed"
9968         ! getfattr -n trusted.lov $dir2 &> /dev/null ||
9969                 error "$dir2 shouldn't have LOV EA"
9970
9971         # set a new striping pattern on root directory
9972         local def_stripe_size=$($LFS getstripe -S $MOUNT)
9973         local new_def_stripe_size=$((def_stripe_size * 2))
9974         $LFS setstripe -S $new_def_stripe_size $MOUNT ||
9975                 error "set stripe size on $MOUNT failed"
9976
9977         # new file created in $dir2 should inherit the new stripe size from
9978         # the filesystem default
9979         local file2=$dir2/$tfile-2
9980         touch $file2 || error "touch $file2 failed"
9981
9982         local file2_stripe_size=$($LFS getstripe -S $file2)
9983         [[ $file2_stripe_size -eq $new_def_stripe_size ]] ||
9984         {
9985                 echo "file2_stripe_size: '$file2_stripe_size'"
9986                 echo "new_def_stripe_size: '$new_def_stripe_size'"
9987                 error "$file2 didn't inherit stripe size $new_def_stripe_size"
9988         }
9989
9990         local dir3=$MOUNT/$tdir-3
9991         mkdir $dir3 || error "mkdir $dir3 failed"
9992         # $dir3 shouldn't have LOV EA, but "lfs getstripe -d $dir3" should show
9993         # the root layout, which is the actual default layout that will be used
9994         # when new files are created in $dir3.
9995         local dir3_layout=$(get_layout_param $dir3)
9996         local root_dir_layout=$(get_layout_param $MOUNT)
9997         [[ "$dir3_layout" = "$root_dir_layout" ]] ||
9998         {
9999                 echo "dir3_layout: '$dir3_layout'"
10000                 echo "root_dir_layout: '$root_dir_layout'"
10001                 error "$dir3 should show the default layout from $MOUNT"
10002         }
10003
10004         # set OST pool on root directory
10005         local pool=$TESTNAME
10006         pool_add $pool || error "add $pool failed"
10007         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
10008                 error "add targets to $pool failed"
10009
10010         $LFS setstripe -p $pool $MOUNT ||
10011                 error "set OST pool on $MOUNT failed"
10012
10013         # new file created in $dir3 should inherit the pool from
10014         # the filesystem default
10015         local file3=$dir3/$tfile-3
10016         touch $file3 || error "touch $file3 failed"
10017
10018         local file3_pool=$($LFS getstripe -p $file3)
10019         [[ "$file3_pool" = "$pool" ]] ||
10020                 error "$file3 ('$file3_pool') didn't inherit OST pool '$pool'"
10021
10022         local dir4=$MOUNT/$tdir-4
10023         mkdir $dir4 || error "mkdir $dir4 failed"
10024         local dir4_layout=$(get_layout_param $dir4)
10025         root_dir_layout=$(get_layout_param $MOUNT)
10026         echo "$LFS getstripe -d $dir4"
10027         $LFS getstripe -d $dir4
10028         echo "$LFS getstripe -d $MOUNT"
10029         $LFS getstripe -d $MOUNT
10030         [[ "$dir4_layout" = "$root_dir_layout" ]] ||
10031         {
10032                 echo "dir4_layout: '$dir4_layout'"
10033                 echo "root_dir_layout: '$root_dir_layout'"
10034                 error "$dir4 should show the default layout from $MOUNT"
10035         }
10036
10037         # new file created in $dir4 should inherit the pool from
10038         # the filesystem default
10039         local file4=$dir4/$tfile-4
10040         touch $file4 || error "touch $file4 failed"
10041
10042         local file4_pool=$($LFS getstripe -p $file4)
10043         [[ "$file4_pool" = "$pool" ]] ||
10044                 error "$file4 ('$file4_pool') didn't inherit OST pool $pool"
10045
10046         # new subdirectory under non-root directory should inherit
10047         # the default layout from its parent directory
10048         $LFS setstripe -S $new_def_stripe_size -p $pool $dir4 ||
10049                 error "set directory layout on $dir4 failed"
10050
10051         local dir5=$dir4/$tdir-5
10052         mkdir $dir5 || error "mkdir $dir5 failed"
10053
10054         dir4_layout=$(get_layout_param $dir4)
10055         local dir5_layout=$(get_layout_param $dir5)
10056         [[ "$dir4_layout" = "$dir5_layout" ]] ||
10057         {
10058                 echo "dir4_layout: '$dir4_layout'"
10059                 echo "dir5_layout: '$dir5_layout'"
10060                 error "$dir5 should inherit the default layout from $dir4"
10061         }
10062
10063         # though subdir under ROOT doesn't inherit default layout, but
10064         # its sub dir/file should be created with default layout.
10065         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
10066         [[ $MDS1_VERSION -ge $(version_code 2.12.59) ]] ||
10067                 skip "Need MDS version at least 2.12.59"
10068
10069         local default_lmv_count=$($LFS getdirstripe -D -c $MOUNT)
10070         local default_lmv_index=$($LFS getdirstripe -D -i $MOUNT)
10071         local default_lmv_hash=$($LFS getdirstripe -D -H $MOUNT)
10072
10073         if [ $default_lmv_hash == "none" ]; then
10074                 stack_trap "$LFS setdirstripe -D -d $MOUNT" EXIT
10075         else
10076                 stack_trap "$LFS setdirstripe -D -i $default_lmv_index \
10077                         -c $default_lmv_count -H $default_lmv_hash $MOUNT" EXIT
10078         fi
10079
10080         $LFS setdirstripe -D -c 2 $MOUNT ||
10081                 error "setdirstripe -D -c 2 failed"
10082         mkdir $MOUNT/$tdir-6 || error "mkdir $tdir-6 failed"
10083         local lmv_count=$($LFS getdirstripe -c $MOUNT/$tdir-6)
10084         [ $lmv_count -eq 2 ] || error "$tdir-6 stripe count $lmv_count"
10085
10086         # $dir4 layout includes pool
10087         $LFS setstripe -S $((new_def_stripe_size * 2)) $dir4
10088         [[ "$pool" = $($LFS getstripe -p -d $dir4) ]] ||
10089                 error "pool lost on setstripe"
10090         $LFS setstripe -E -1 -S $new_def_stripe_size $dir4
10091         [[ "$pool" = $($LFS getstripe -p -d $dir4) ]] ||
10092                 error "pool lost on compound layout setstripe"
10093 }
10094 run_test 65n "don't inherit default layout from root for new subdirectories"
10095
10096 test_65o() {
10097         (( $MDS1_VERSION >= $(version_code 2.14.57) )) ||
10098                 skip "need MDS version at least 2.14.57"
10099
10100         # set OST pool on root directory
10101         local pool=$TESTNAME
10102
10103         pool_add $pool || error "add $pool failed"
10104         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
10105                 error "add targets to $pool failed"
10106
10107         local dir1=$MOUNT/$tdir
10108
10109         mkdir $dir1 || error "mkdir $dir1 failed"
10110
10111         # set a new striping pattern on root directory
10112         local def_stripe_size=$($LFS getstripe -S $MOUNT)
10113
10114         $LFS setstripe -p $pool $dir1 ||
10115                 error "set directory layout on $dir1 failed"
10116
10117         # $dir1 layout includes pool
10118         $LFS setstripe -S $((def_stripe_size * 2)) $dir1
10119         [[ "$pool" = $($LFS getstripe -p -d $dir1) ]] ||
10120                 error "pool lost on setstripe"
10121         $LFS setstripe -E 1M -L mdt -E -1 -c 1 $dir1
10122         $LFS getstripe $dir1
10123         [[ "$pool" = $($LFS getstripe -p -d $dir1) ]] ||
10124                 error "pool lost on compound layout setstripe"
10125
10126         $LFS setdirstripe -i 0 -c 2 $dir1/dir2 ||
10127                 error "setdirstripe failed on sub-dir with inherited pool"
10128         $LFS getstripe $dir1/dir2
10129         [[ "$pool" = $($LFS getstripe -p -d $dir1/dir2) ]] ||
10130                 error "pool lost on compound layout setdirstripe"
10131
10132         $LFS setstripe -E -1 -c 1 $dir1
10133         $LFS getstripe -d $dir1
10134         [[ "$pool" = $($LFS getstripe -p -d $dir1) ]] ||
10135                 error "pool lost on setstripe"
10136 }
10137 run_test 65o "pool inheritance for mdt component"
10138
10139 test_65p () { # LU-16152
10140         local src_dir=$DIR/$tdir/src_dir
10141         local dst_dir=$DIR/$tdir/dst_dir
10142         local yaml_file=$DIR/$tdir/layout.yaml
10143         local border
10144
10145         (( $CLIENT_VERSION >= $(version_code 2.15.51) )) ||
10146                 skip "Need at least version 2.15.51"
10147
10148         test_mkdir -p $src_dir
10149         $LFS setstripe -E 2048M -c 4 -E EOF -c 8 $src_dir ||
10150                 error "failed to setstripe"
10151         $LFS getstripe --yaml -d $src_dir > $yaml_file ||
10152                 error "failed to getstripe"
10153
10154         test_mkdir -p $dst_dir
10155         $LFS setstripe --yaml $yaml_file $dst_dir ||
10156                 error "failed to setstripe with yaml file"
10157         border=$($LFS getstripe -d $dst_dir |
10158                 awk '/lcme_extent.e_end:/ { print $2; exit; }') ||
10159                 error "failed to getstripe"
10160
10161         # 2048M is 0x80000000, or 2147483648
10162         (( $border == 2147483648 )) ||
10163                 error "failed to handle huge number in yaml layout"
10164 }
10165 run_test 65p "setstripe with yaml file and huge number"
10166
10167 # bug 2543 - update blocks count on client
10168 test_66() {
10169         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10170
10171         local COUNT=${COUNT:-8}
10172         dd if=/dev/zero of=$DIR/f66 bs=1k count=$COUNT
10173         sync; sync_all_data; sync; sync_all_data
10174         cancel_lru_locks osc
10175         local BLOCKS=$(ls -s --block-size=1k $DIR/f66 | awk '{ print $1 }')
10176         (( BLOCKS >= COUNT )) || error "$DIR/f66 blocks $BLOCKS < $COUNT"
10177 }
10178 run_test 66 "update inode blocks count on client ==============="
10179
10180 meminfo() {
10181         awk '($1 == "'$1':") { print $2 }' /proc/meminfo
10182 }
10183
10184 swap_used() {
10185         swapon -s | awk '($1 == "'$1'") { print $4 }'
10186 }
10187
10188 # bug5265, obdfilter oa2dentry return -ENOENT
10189 # #define OBD_FAIL_SRV_ENOENT 0x217
10190 test_69() {
10191         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10192         remote_ost_nodsh && skip "remote OST with nodsh"
10193
10194         f="$DIR/$tfile"
10195         $LFS setstripe -c 1 -i 0 $f
10196         stack_trap "rm -f $f ${f}.2"
10197
10198         $DIRECTIO write ${f}.2 0 1 || error "directio write error"
10199
10200         do_facet ost1 lctl set_param fail_loc=0x217
10201         $TRUNCATE $f 1 # vmtruncate() will ignore truncate() error.
10202         $DIRECTIO write $f 0 2 && error "write succeeded, expect -ENOENT"
10203
10204         do_facet ost1 lctl set_param fail_loc=0
10205         $DIRECTIO write $f 0 2 || error "write error"
10206
10207         cancel_lru_locks osc
10208         $DIRECTIO read $f 0 1 || error "read error"
10209
10210         do_facet ost1 lctl set_param fail_loc=0x217
10211         $DIRECTIO read $f 1 1 && error "read succeeded, expect -ENOENT"
10212
10213         do_facet ost1 lctl set_param fail_loc=0
10214 }
10215 run_test 69 "verify oa2dentry return -ENOENT doesn't LBUG ======"
10216
10217 test_71() {
10218         test_mkdir $DIR/$tdir
10219         $LFS setdirstripe -D -c$MDSCOUNT $DIR/$tdir
10220         bash rundbench -C -D $DIR/$tdir 2 || error "dbench failed!"
10221 }
10222 run_test 71 "Running dbench on lustre (don't segment fault) ===="
10223
10224 test_72a() { # bug 5695 - Test that on 2.6 remove_suid works properly
10225         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10226         [ "$RUNAS_ID" = "$UID" ] &&
10227                 skip_env "RUNAS_ID = UID = $UID -- skipping"
10228         # Check that testing environment is properly set up. Skip if not
10229         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_GID $RUNAS ||
10230                 skip_env "User $RUNAS_ID does not exist - skipping"
10231
10232         touch $DIR/$tfile
10233         chmod 777 $DIR/$tfile
10234         chmod ug+s $DIR/$tfile
10235         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=512 count=1 ||
10236                 error "$RUNAS dd $DIR/$tfile failed"
10237         # See if we are still setuid/sgid
10238         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
10239                 error "S/gid is not dropped on write"
10240         # Now test that MDS is updated too
10241         cancel_lru_locks mdc
10242         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
10243                 error "S/gid is not dropped on MDS"
10244         rm -f $DIR/$tfile
10245 }
10246 run_test 72a "Test that remove suid works properly (bug5695) ===="
10247
10248 test_72b() { # bug 24226 -- keep mode setting when size is not changing
10249         local perm
10250
10251         [ "$RUNAS_ID" = "$UID" ] &&
10252                 skip_env "RUNAS_ID = UID = $UID -- skipping"
10253         [ "$RUNAS_ID" -eq 0 ] &&
10254                 skip_env "RUNAS_ID = 0 -- skipping"
10255         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10256         # Check that testing environment is properly set up. Skip if not
10257         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_ID $RUNAS ||
10258                 skip_env "User $RUNAS_ID does not exist - skipping"
10259
10260         touch $DIR/${tfile}-f{g,u}
10261         test_mkdir $DIR/${tfile}-dg
10262         test_mkdir $DIR/${tfile}-du
10263         chmod 770 $DIR/${tfile}-{f,d}{g,u}
10264         chmod g+s $DIR/${tfile}-{f,d}g
10265         chmod u+s $DIR/${tfile}-{f,d}u
10266         for perm in 777 2777 4777; do
10267                 $RUNAS chmod $perm $DIR/${tfile}-fg && error "S/gid file allowed improper chmod to $perm"
10268                 $RUNAS chmod $perm $DIR/${tfile}-fu && error "S/uid file allowed improper chmod to $perm"
10269                 $RUNAS chmod $perm $DIR/${tfile}-dg && error "S/gid dir allowed improper chmod to $perm"
10270                 $RUNAS chmod $perm $DIR/${tfile}-du && error "S/uid dir allowed improper chmod to $perm"
10271         done
10272         true
10273 }
10274 run_test 72b "Test that we keep mode setting if without file data changed (bug 24226)"
10275
10276 # bug 3462 - multiple simultaneous MDC requests
10277 test_73() {
10278         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10279
10280         test_mkdir $DIR/d73-1
10281         test_mkdir $DIR/d73-2
10282         multiop_bg_pause $DIR/d73-1/f73-1 O_c || return 1
10283         pid1=$!
10284
10285         lctl set_param fail_loc=0x80000129
10286         $MULTIOP $DIR/d73-1/f73-2 Oc &
10287         sleep 1
10288         lctl set_param fail_loc=0
10289
10290         $MULTIOP $DIR/d73-2/f73-3 Oc &
10291         pid3=$!
10292
10293         kill -USR1 $pid1
10294         wait $pid1 || return 1
10295
10296         sleep 25
10297
10298         $CHECKSTAT -t file $DIR/d73-1/f73-1 || return 4
10299         $CHECKSTAT -t file $DIR/d73-1/f73-2 || return 5
10300         $CHECKSTAT -t file $DIR/d73-2/f73-3 || return 6
10301
10302         rm -rf $DIR/d73-*
10303 }
10304 run_test 73 "multiple MDC requests (should not deadlock)"
10305
10306 test_74a() { # bug 6149, 6184
10307         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10308
10309         touch $DIR/f74a
10310         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
10311         #
10312         # very important to OR with CFS_FAIL_ONCE (0x80000000) -- otherwise it
10313         # will spin in a tight reconnection loop
10314         $LCTL set_param fail_loc=0x8000030e
10315         # get any lock that won't be difficult - lookup works.
10316         ls $DIR/f74a
10317         $LCTL set_param fail_loc=0
10318         rm -f $DIR/f74a
10319         true
10320 }
10321 run_test 74a "ldlm_enqueue freed-export error path, ls (shouldn't LBUG)"
10322
10323 test_74b() { # bug 13310
10324         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10325
10326         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
10327         #
10328         # very important to OR with CFS_FAIL_ONCE (0x80000000) -- otherwise it
10329         # will spin in a tight reconnection loop
10330         $LCTL set_param fail_loc=0x8000030e
10331         # get a "difficult" lock
10332         touch $DIR/f74b
10333         $LCTL set_param fail_loc=0
10334         rm -f $DIR/f74b
10335         true
10336 }
10337 run_test 74b "ldlm_enqueue freed-export error path, touch (shouldn't LBUG)"
10338
10339 test_74c() {
10340         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10341
10342         #define OBD_FAIL_LDLM_NEW_LOCK
10343         $LCTL set_param fail_loc=0x319
10344         touch $DIR/$tfile && error "touch successful"
10345         $LCTL set_param fail_loc=0
10346         true
10347 }
10348 run_test 74c "ldlm_lock_create error path, (shouldn't LBUG)"
10349
10350 slab_lic=/sys/kernel/slab/lustre_inode_cache
10351 num_objects() {
10352         [ -f $slab_lic/shrink ] && echo 1 > $slab_lic/shrink
10353         [ -f $slab_lic/objects ] && awk '{ print $1 }' $slab_lic/objects ||
10354                 awk '/lustre_inode_cache/ { print $2; exit }' /proc/slabinfo
10355 }
10356
10357 test_76a() { # Now for b=20433, added originally in b=1443
10358         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10359
10360         cancel_lru_locks osc
10361         # there may be some slab objects cached per core
10362         local cpus=$(getconf _NPROCESSORS_ONLN 2>/dev/null)
10363         local before=$(num_objects)
10364         local count=$((512 * cpus))
10365         [ "$SLOW" = "no" ] && count=$((128 * cpus))
10366         local margin=$((count / 10))
10367         if [[ -f $slab_lic/aliases ]]; then
10368                 local aliases=$(cat $slab_lic/aliases)
10369                 (( aliases > 0 )) && margin=$((margin * aliases))
10370         fi
10371
10372         echo "before slab objects: $before"
10373         for i in $(seq $count); do
10374                 touch $DIR/$tfile
10375                 rm -f $DIR/$tfile
10376         done
10377         cancel_lru_locks osc
10378         local after=$(num_objects)
10379         echo "created: $count, after slab objects: $after"
10380         # shared slab counts are not very accurate, allow significant margin
10381         # the main goal is that the cache growth is not permanently > $count
10382         while (( after > before + margin )); do
10383                 sleep 1
10384                 after=$(num_objects)
10385                 wait=$((wait + 1))
10386                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
10387                 if (( wait > 60 )); then
10388                         error "inode slab grew from $before+$margin to $after"
10389                 fi
10390         done
10391 }
10392 run_test 76a "confirm clients recycle inodes properly ===="
10393
10394 test_76b() {
10395         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10396         [ $CLIENT_VERSION -ge $(version_code 2.13.55) ] || skip "not supported"
10397
10398         local count=512
10399         local before=$(num_objects)
10400
10401         for i in $(seq $count); do
10402                 mkdir $DIR/$tdir
10403                 rmdir $DIR/$tdir
10404         done
10405
10406         local after=$(num_objects)
10407         local wait=0
10408
10409         while (( after > before )); do
10410                 sleep 1
10411                 after=$(num_objects)
10412                 wait=$((wait + 1))
10413                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
10414                 if (( wait > 60 )); then
10415                         error "inode slab grew from $before to $after"
10416                 fi
10417         done
10418
10419         echo "slab objects before: $before, after: $after"
10420 }
10421 run_test 76b "confirm clients recycle directory inodes properly ===="
10422
10423 export ORIG_CSUM=""
10424 set_checksums()
10425 {
10426         # Note: in sptlrpc modes which enable its own bulk checksum, the
10427         # original crc32_le bulk checksum will be automatically disabled,
10428         # and the OBD_FAIL_OSC_CHECKSUM_SEND/OBD_FAIL_OSC_CHECKSUM_RECEIVE
10429         # will be checked by sptlrpc code against sptlrpc bulk checksum.
10430         # In this case set_checksums() will not be no-op, because sptlrpc
10431         # bulk checksum will be enabled all through the test.
10432
10433         [ "$ORIG_CSUM" ] || ORIG_CSUM=`lctl get_param -n osc.*.checksums | head -n1`
10434         lctl set_param -n osc.*.checksums $1
10435         return 0
10436 }
10437
10438 export ORIG_CSUM_TYPE="`lctl get_param -n osc.*osc-[^mM]*.checksum_type |
10439                         sed 's/.*\[\(.*\)\].*/\1/g' | head -n1`"
10440 CKSUM_TYPES=${CKSUM_TYPES:-$(lctl get_param -n osc.*osc-[^mM]*.checksum_type |
10441                              tr -d [] | head -n1)}
10442 set_checksum_type()
10443 {
10444         lctl set_param -n osc.*osc-[^mM]*.checksum_type $1
10445         rc=$?
10446         log "set checksum type to $1, rc = $rc"
10447         return $rc
10448 }
10449
10450 get_osc_checksum_type()
10451 {
10452         # arugment 1: OST name, like OST0000
10453         ost=$1
10454         checksum_type=$(lctl get_param -n osc.*${ost}-osc-[^mM]*.checksum_type |
10455                         sed 's/.*\[\(.*\)\].*/\1/g')
10456         rc=$?
10457         [ $rc -ne 0 ] && error "failed to get checksum type of $ost, rc = $rc, output = $checksum_type"
10458         echo $checksum_type
10459 }
10460
10461 F77_TMP=$TMP/f77-temp
10462 F77SZ=8
10463 setup_f77() {
10464         dd if=/dev/urandom of=$F77_TMP bs=1M count=$F77SZ || \
10465                 error "error writing to $F77_TMP"
10466 }
10467
10468 test_77a() { # bug 10889
10469         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10470         $GSS && skip_env "could not run with gss"
10471
10472         [ ! -f $F77_TMP ] && setup_f77
10473         set_checksums 1
10474         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ || error "dd error"
10475         set_checksums 0
10476         rm -f $DIR/$tfile
10477 }
10478 run_test 77a "normal checksum read/write operation"
10479
10480 test_77b() { # bug 10889
10481         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10482         $GSS && skip_env "could not run with gss"
10483
10484         [ ! -f $F77_TMP ] && setup_f77
10485         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
10486         $LCTL set_param fail_loc=0x80000409
10487         set_checksums 1
10488
10489         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
10490                 error "dd error: $?"
10491         $LCTL set_param fail_loc=0
10492
10493         for algo in $CKSUM_TYPES; do
10494                 cancel_lru_locks osc
10495                 set_checksum_type $algo
10496                 #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
10497                 $LCTL set_param fail_loc=0x80000408
10498                 cmp $F77_TMP $DIR/$tfile || error "file compare failed"
10499                 $LCTL set_param fail_loc=0
10500         done
10501         set_checksums 0
10502         set_checksum_type $ORIG_CSUM_TYPE
10503         rm -f $DIR/$tfile
10504 }
10505 run_test 77b "checksum error on client write, read"
10506
10507 cleanup_77c() {
10508         trap 0
10509         set_checksums 0
10510         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=0
10511         $check_ost &&
10512                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=0
10513         [ -n "$osc_file_prefix" ] && rm -f ${osc_file_prefix}*
10514         $check_ost && [ -n "$ost_file_prefix" ] &&
10515                 do_facet ost1 rm -f ${ost_file_prefix}\*
10516 }
10517
10518 test_77c() {
10519         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10520         $GSS && skip_env "could not run with gss"
10521         remote_ost_nodsh && skip "remote OST with nodsh"
10522
10523         local bad1
10524         local osc_file_prefix
10525         local osc_file
10526         local check_ost=false
10527         local ost_file_prefix
10528         local ost_file
10529         local orig_cksum
10530         local dump_cksum
10531         local fid
10532
10533         # ensure corruption will occur on first OSS/OST
10534         $LFS setstripe -i 0 $DIR/$tfile
10535
10536         [ ! -f $F77_TMP ] && setup_f77
10537         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
10538                 error "dd write error: $?"
10539         fid=$($LFS path2fid $DIR/$tfile)
10540
10541         if [ $OST1_VERSION -ge $(version_code 2.9.57) ]
10542         then
10543                 check_ost=true
10544                 ost_file_prefix=$(do_facet ost1 $LCTL get_param -n debug_path)
10545                 ost_file_prefix=${ost_file_prefix}-checksum_dump-ost-\\${fid}
10546         else
10547                 echo "OSS do not support bulk pages dump upon error"
10548         fi
10549
10550         osc_file_prefix=$($LCTL get_param -n debug_path)
10551         osc_file_prefix=${osc_file_prefix}-checksum_dump-osc-\\${fid}
10552
10553         trap cleanup_77c EXIT
10554
10555         set_checksums 1
10556         # enable bulk pages dump upon error on Client
10557         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=1
10558         # enable bulk pages dump upon error on OSS
10559         $check_ost &&
10560                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=1
10561
10562         # flush Client cache to allow next read to reach OSS
10563         cancel_lru_locks osc
10564
10565         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE       0x408
10566         $LCTL set_param fail_loc=0x80000408
10567         dd if=$DIR/$tfile of=/dev/null bs=1M || error "dd read error: $?"
10568         $LCTL set_param fail_loc=0
10569
10570         rm -f $DIR/$tfile
10571
10572         # check cksum dump on Client
10573         osc_file=$(ls ${osc_file_prefix}*)
10574         [ -n "$osc_file" ] || error "no checksum dump file on Client"
10575         # OBD_FAIL_OSC_CHECKSUM_RECEIVE corrupts with "bad1" at start of file
10576         bad1=$(dd if=$osc_file bs=1 count=4 2>/dev/null) || error "dd error: $?"
10577         [ $bad1 == "bad1" ] || error "unexpected corrupt pattern"
10578         orig_cksum=$(dd if=$F77_TMP bs=1 skip=4 count=1048572 2>/dev/null |
10579                      cksum)
10580         dump_cksum=$(dd if=$osc_file bs=1 skip=4 2>/dev/null | cksum)
10581         [[ "$orig_cksum" == "$dump_cksum" ]] ||
10582                 error "dump content does not match on Client"
10583
10584         $check_ost || skip "No need to check cksum dump on OSS"
10585
10586         # check cksum dump on OSS
10587         ost_file=$(do_facet ost1 ls ${ost_file_prefix}\*)
10588         [ -n "$ost_file" ] || error "no checksum dump file on OSS"
10589         orig_cksum=$(dd if=$F77_TMP bs=1048576 count=1 2>/dev/null | cksum)
10590         dump_cksum=$(do_facet ost1 dd if=$ost_file 2>/dev/null \| cksum)
10591         [[ "$orig_cksum" == "$dump_cksum" ]] ||
10592                 error "dump content does not match on OSS"
10593
10594         cleanup_77c
10595 }
10596 run_test 77c "checksum error on client read with debug"
10597
10598 test_77d() { # bug 10889
10599         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10600         $GSS && skip_env "could not run with gss"
10601
10602         stack_trap "rm -f $DIR/$tfile"
10603         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
10604         $LCTL set_param fail_loc=0x80000409
10605         set_checksums 1
10606         $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
10607                 error "direct write: rc=$?"
10608         $LCTL set_param fail_loc=0
10609         set_checksums 0
10610
10611         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
10612         $LCTL set_param fail_loc=0x80000408
10613         set_checksums 1
10614         cancel_lru_locks osc
10615         $DIRECTIO read $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
10616                 error "direct read: rc=$?"
10617         $LCTL set_param fail_loc=0
10618         set_checksums 0
10619 }
10620 run_test 77d "checksum error on OST direct write, read"
10621
10622 test_77f() { # bug 10889
10623         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10624         $GSS && skip_env "could not run with gss"
10625
10626         set_checksums 1
10627         stack_trap "rm -f $DIR/$tfile"
10628         for algo in $CKSUM_TYPES; do
10629                 cancel_lru_locks osc
10630                 set_checksum_type $algo
10631                 #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
10632                 $LCTL set_param fail_loc=0x409
10633                 $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) &&
10634                         error "direct write succeeded"
10635                 $LCTL set_param fail_loc=0
10636         done
10637         set_checksum_type $ORIG_CSUM_TYPE
10638         set_checksums 0
10639 }
10640 run_test 77f "repeat checksum error on write (expect error)"
10641
10642 test_77g() { # bug 10889
10643         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10644         $GSS && skip_env "could not run with gss"
10645         remote_ost_nodsh && skip "remote OST with nodsh"
10646
10647         [ ! -f $F77_TMP ] && setup_f77
10648
10649         local file=$DIR/$tfile
10650         stack_trap "rm -f $file" EXIT
10651
10652         $LFS setstripe -c 1 -i 0 $file
10653         #define OBD_FAIL_OST_CHECKSUM_RECEIVE       0x21a
10654         do_facet ost1 lctl set_param fail_loc=0x8000021a
10655         set_checksums 1
10656         dd if=$F77_TMP of=$file bs=1M count=$F77SZ ||
10657                 error "write error: rc=$?"
10658         do_facet ost1 lctl set_param fail_loc=0
10659         set_checksums 0
10660
10661         cancel_lru_locks osc
10662         #define OBD_FAIL_OST_CHECKSUM_SEND          0x21b
10663         do_facet ost1 lctl set_param fail_loc=0x8000021b
10664         set_checksums 1
10665         cmp $F77_TMP $file || error "file compare failed"
10666         do_facet ost1 lctl set_param fail_loc=0
10667         set_checksums 0
10668 }
10669 run_test 77g "checksum error on OST write, read"
10670
10671 test_77k() { # LU-10906
10672         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10673         $GSS && skip_env "could not run with gss"
10674
10675         local cksum_param="osc.$FSNAME*.checksums"
10676         local get_checksum="$LCTL get_param -n $cksum_param | head -n1"
10677         local checksum
10678         local i
10679
10680         [ "$ORIG_CSUM" ] || ORIG_CSUM=$(eval $get_checksum)
10681         stack_trap "wait_update $HOSTNAME '$get_checksum' $ORIG_CSUM || true"
10682         stack_trap "do_facet mgs $LCTL set_param -P $cksum_param=$ORIG_CSUM"
10683
10684         for i in 0 1; do
10685                 do_facet mgs $LCTL set_param -P $cksum_param=$i ||
10686                         error "failed to set checksum=$i on MGS"
10687                 wait_update $HOSTNAME "$get_checksum" $i
10688                 #remount
10689                 echo "remount client, checksum should be $i"
10690                 remount_client $MOUNT || error "failed to remount client"
10691                 checksum=$(eval $get_checksum)
10692                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
10693         done
10694         # remove persistent param to avoid races with checksum mountopt below
10695         do_facet mgs $LCTL set_param -P -d $cksum_param ||
10696                 error "failed to delete checksum on MGS"
10697
10698         for opt in "checksum" "nochecksum"; do
10699                 #remount with mount option
10700                 echo "remount client with option $opt, checksum should be $i"
10701                 umount_client $MOUNT || error "failed to umount client"
10702                 mount_client $MOUNT "$MOUNT_OPTS,$opt" ||
10703                         error "failed to mount client with option '$opt'"
10704                 checksum=$(eval $get_checksum)
10705                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
10706                 i=$((i - 1))
10707         done
10708
10709         remount_client $MOUNT || error "failed to remount client"
10710 }
10711 run_test 77k "enable/disable checksum correctly"
10712
10713 test_77l() {
10714         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10715         $GSS && skip_env "could not run with gss"
10716
10717         set_checksums 1
10718         stack_trap "set_checksums $ORIG_CSUM" EXIT
10719         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
10720
10721         set_checksum_type invalid && error "unexpected success of invalid checksum type"
10722
10723         $LFS setstripe -c 1 -i 0 $DIR/$tfile
10724         for algo in $CKSUM_TYPES; do
10725                 set_checksum_type $algo || error "fail to set checksum type $algo"
10726                 osc_algo=$(get_osc_checksum_type OST0000)
10727                 [ "$osc_algo" != "$algo" ] && error "checksum type is $osc_algo after setting it to $algo"
10728
10729                 # no locks, no reqs to let the connection idle
10730                 cancel_lru_locks osc
10731                 lru_resize_disable osc
10732                 wait_osc_import_state client ost1 IDLE
10733
10734                 # ensure ost1 is connected
10735                 stat $DIR/$tfile >/dev/null || error "can't stat"
10736                 wait_osc_import_state client ost1 FULL
10737
10738                 osc_algo=$(get_osc_checksum_type OST0000)
10739                 [ "$osc_algo" != "$algo" ] && error "checksum type changed from $algo to $osc_algo after reconnection"
10740         done
10741         return 0
10742 }
10743 run_test 77l "preferred checksum type is remembered after reconnected"
10744
10745 [ "$ORIG_CSUM" ] && set_checksums $ORIG_CSUM || true
10746 rm -f $F77_TMP
10747 unset F77_TMP
10748
10749 test_77m() {
10750         (( $CLIENT_VERSION >= $(version_code 2.14.52) )) ||
10751                 skip "Need at least version 2.14.52"
10752         local param=checksum_speed
10753
10754         $LCTL get_param $param || error "reading $param failed"
10755
10756         csum_speeds=$($LCTL get_param -n $param)
10757
10758         [[ "$csum_speeds" =~ "adler32" && "$csum_speeds" =~ "crc32" ]] ||
10759                 error "known checksum types are missing"
10760 }
10761 run_test 77m "Verify checksum_speed is correctly read"
10762
10763 check_filefrag_77n() {
10764         local nr_ext=0
10765         local starts=()
10766         local ends=()
10767
10768         while read extidx a b start end rest; do
10769                 if [[ "${extidx}" =~ ^[0-9]+: ]]; then
10770                         nr_ext=$(( $nr_ext + 1 ))
10771                         starts+=( ${start%..} )
10772                         ends+=( ${end%:} )
10773                 fi
10774         done < <( filefrag -sv $1 )
10775
10776         [[ $nr_ext -eq 2 ]] && [[ "${starts[-1]}" == $(( ${ends[0]} + 1 )) ]] && return 0
10777         return 1
10778 }
10779
10780 test_77n() {
10781         [[ "$CKSUM_TYPES" =~ t10 ]] || skip "no T10 checksum support on osc"
10782
10783         touch $DIR/$tfile
10784         $TRUNCATE $DIR/$tfile 0
10785         dd if=/dev/urandom of=$DIR/$tfile bs=4k conv=notrunc count=1 seek=0
10786         dd if=/dev/urandom of=$DIR/$tfile bs=4k conv=notrunc count=1 seek=2
10787         check_filefrag_77n $DIR/$tfile ||
10788                 skip "$tfile blocks not contiguous around hole"
10789
10790         set_checksums 1
10791         stack_trap "set_checksums $ORIG_CSUM" EXIT
10792         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
10793         stack_trap "rm -f $DIR/$tfile"
10794
10795         for algo in $CKSUM_TYPES; do
10796                 if [[ "$algo" =~ ^t10 ]]; then
10797                         set_checksum_type $algo ||
10798                                 error "fail to set checksum type $algo"
10799                         dd if=$DIR/$tfile of=/dev/null bs=12k count=1 iflag=direct ||
10800                                 error "fail to read $tfile with $algo"
10801                 fi
10802         done
10803         rm -f $DIR/$tfile
10804         return 0
10805 }
10806 run_test 77n "Verify read from a hole inside contiguous blocks with T10PI"
10807
10808 test_77o() {
10809         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
10810                 skip "Need MDS version at least 2.14.55"
10811         (( $OST1_VERSION >= $(version_code 2.14.55) )) ||
10812                 skip "Need OST version at least 2.14.55"
10813         local ofd=obdfilter
10814         local mdt=mdt
10815
10816         # print OST checksum_type
10817         echo "$ofd.$FSNAME-*.checksum_type:"
10818         do_nodes $(comma_list $(osts_nodes)) \
10819                 $LCTL get_param -n $ofd.$FSNAME-*.checksum_type
10820
10821         # print MDT checksum_type
10822         echo "$mdt.$FSNAME-*.checksum_type:"
10823         do_nodes $(comma_list $(mdts_nodes)) \
10824                 $LCTL get_param -n $mdt.$FSNAME-*.checksum_type
10825
10826         local o_count=$(do_nodes $(comma_list $(osts_nodes)) \
10827                    $LCTL get_param -n $ofd.$FSNAME-*.checksum_type | wc -l)
10828
10829         (( $o_count == $OSTCOUNT )) ||
10830                 error "found $o_count checksums, not \$MDSCOUNT=$OSTCOUNT"
10831
10832         local m_count=$(do_nodes $(comma_list $(mdts_nodes)) \
10833                    $LCTL get_param -n $mdt.$FSNAME-*.checksum_type | wc -l)
10834
10835         (( $m_count == $MDSCOUNT )) ||
10836                 error "found $m_count checksums, not \$MDSCOUNT=$MDSCOUNT"
10837 }
10838 run_test 77o "Verify checksum_type for server (mdt and ofd(obdfilter))"
10839
10840 cleanup_test_78() {
10841         trap 0
10842         rm -f $DIR/$tfile
10843 }
10844
10845 test_78() { # bug 10901
10846         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10847         remote_ost || skip_env "local OST"
10848
10849         NSEQ=5
10850         F78SIZE=$(($(awk '/MemFree:/ { print $2 }' /proc/meminfo) / 1024))
10851         echo "MemFree: $F78SIZE, Max file size: $MAXFREE"
10852         MEMTOTAL=$(($(awk '/MemTotal:/ { print $2 }' /proc/meminfo) / 1024))
10853         echo "MemTotal: $MEMTOTAL"
10854
10855         # reserve 256MB of memory for the kernel and other running processes,
10856         # and then take 1/2 of the remaining memory for the read/write buffers.
10857         if [ $MEMTOTAL -gt 512 ] ;then
10858                 MEMTOTAL=$(((MEMTOTAL - 256 ) / 2))
10859         else
10860                 # for those poor memory-starved high-end clusters...
10861                 MEMTOTAL=$((MEMTOTAL / 2))
10862         fi
10863         echo "Mem to use for directio: $MEMTOTAL"
10864
10865         [[ $F78SIZE -gt $MEMTOTAL ]] && F78SIZE=$MEMTOTAL
10866         [[ $F78SIZE -gt 512 ]] && F78SIZE=512
10867         [[ $F78SIZE -gt $((MAXFREE / 1024)) ]] && F78SIZE=$((MAXFREE / 1024))
10868         SMALLESTOST=$($LFS df $DIR | grep OST | awk '{ print $4 }' | sort -n |
10869                 head -n1)
10870         echo "Smallest OST: $SMALLESTOST"
10871         [[ $SMALLESTOST -lt 10240 ]] &&
10872                 skip "too small OSTSIZE, useless to run large O_DIRECT test"
10873
10874         trap cleanup_test_78 EXIT
10875
10876         [[ $F78SIZE -gt $((SMALLESTOST * $OSTCOUNT / 1024 - 80)) ]] &&
10877                 F78SIZE=$((SMALLESTOST * $OSTCOUNT / 1024 - 80))
10878
10879         [ "$SLOW" = "no" ] && NSEQ=1 && [ $F78SIZE -gt 32 ] && F78SIZE=32
10880         echo "File size: $F78SIZE"
10881         $LFS setstripe -c $OSTCOUNT $DIR/$tfile || error "setstripe failed"
10882         for i in $(seq 1 $NSEQ); do
10883                 FSIZE=$(($F78SIZE / ($NSEQ - $i + 1)))
10884                 echo directIO rdwr round $i of $NSEQ
10885                 $DIRECTIO rdwr $DIR/$tfile 0 $FSIZE 1048576||error "rdwr failed"
10886         done
10887
10888         cleanup_test_78
10889 }
10890 run_test 78 "handle large O_DIRECT writes correctly ============"
10891
10892 test_79() { # bug 12743
10893         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10894
10895         wait_delete_completed
10896
10897         BKTOTAL=$(calc_osc_kbytes kbytestotal)
10898         BKFREE=$(calc_osc_kbytes kbytesfree)
10899         BKAVAIL=$(calc_osc_kbytes kbytesavail)
10900
10901         STRING=`df -P $MOUNT | tail -n 1 | awk '{print $2","$3","$4}'`
10902         DFTOTAL=`echo $STRING | cut -d, -f1`
10903         DFUSED=`echo $STRING  | cut -d, -f2`
10904         DFAVAIL=`echo $STRING | cut -d, -f3`
10905         DFFREE=$(($DFTOTAL - $DFUSED))
10906
10907         ALLOWANCE=$((64 * $OSTCOUNT))
10908
10909         if [ $DFTOTAL -lt $(($BKTOTAL - $ALLOWANCE)) ] ||
10910            [ $DFTOTAL -gt $(($BKTOTAL + $ALLOWANCE)) ] ; then
10911                 error "df total($DFTOTAL) mismatch OST total($BKTOTAL)"
10912         fi
10913         if [ $DFFREE -lt $(($BKFREE - $ALLOWANCE)) ] ||
10914            [ $DFFREE -gt $(($BKFREE + $ALLOWANCE)) ] ; then
10915                 error "df free($DFFREE) mismatch OST free($BKFREE)"
10916         fi
10917         if [ $DFAVAIL -lt $(($BKAVAIL - $ALLOWANCE)) ] ||
10918            [ $DFAVAIL -gt $(($BKAVAIL + $ALLOWANCE)) ] ; then
10919                 error "df avail($DFAVAIL) mismatch OST avail($BKAVAIL)"
10920         fi
10921 }
10922 run_test 79 "df report consistency check ======================="
10923
10924 test_80() { # bug 10718
10925         remote_ost_nodsh && skip "remote OST with nodsh"
10926         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10927
10928         # relax strong synchronous semantics for slow backends like ZFS
10929         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
10930                 local soc="obdfilter.*.sync_lock_cancel"
10931                 local save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
10932
10933                 # "sync_on_lock_cancel" was broken by v2_11_55_0-26-g7059644e9a
10934                 if [ -z "$save" ]; then
10935                         soc="obdfilter.*.sync_on_lock_cancel"
10936                         save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
10937                 fi
10938
10939                 if [ "$save" != "never" ]; then
10940                         local hosts=$(comma_list $(osts_nodes))
10941
10942                         do_nodes $hosts $LCTL set_param $soc=never
10943                         stack_trap "do_nodes $hosts $LCTL set_param $soc=$save"
10944                 fi
10945         fi
10946
10947         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1M
10948         sync; sleep 1; sync
10949         local before=$(date +%s)
10950         cancel_lru_locks osc
10951         local after=$(date +%s)
10952         local diff=$((after - before))
10953         [ $diff -le 1 ] || error "elapsed for 1M@1T = $diff"
10954
10955         rm -f $DIR/$tfile
10956 }
10957 run_test 80 "Page eviction is equally fast at high offsets too"
10958
10959 test_81a() { # LU-456
10960         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10961         remote_ost_nodsh && skip "remote OST with nodsh"
10962
10963         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
10964         # MUST OR with the CFS_FAIL_ONCE (0x80000000)
10965         do_facet ost1 lctl set_param fail_loc=0x80000228
10966
10967         # write should trigger a retry and success
10968         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10969         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10970         RC=$?
10971         if [ $RC -ne 0 ] ; then
10972                 error "write should success, but failed for $RC"
10973         fi
10974 }
10975 run_test 81a "OST should retry write when get -ENOSPC ==============="
10976
10977 test_81b() { # LU-456
10978         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10979         remote_ost_nodsh && skip "remote OST with nodsh"
10980
10981         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
10982         # Don't OR with the CFS_FAIL_ONCE (0x80000000)
10983         do_facet ost1 lctl set_param fail_loc=0x228
10984
10985         # write should retry several times and return -ENOSPC finally
10986         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10987         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10988         RC=$?
10989         ENOSPC=28
10990         if [ $RC -ne $ENOSPC ] ; then
10991                 error "dd should fail for -ENOSPC, but succeed."
10992         fi
10993 }
10994 run_test 81b "OST should return -ENOSPC when retry still fails ======="
10995
10996 test_99() {
10997         [ -z "$(which cvs 2>/dev/null)" ] && skip_env "could not find cvs"
10998
10999         test_mkdir $DIR/$tdir.cvsroot
11000         chown $RUNAS_ID $DIR/$tdir.cvsroot
11001
11002         cd $TMP
11003         $RUNAS cvs -d $DIR/$tdir.cvsroot init || error "cvs init failed"
11004
11005         cd /etc/init.d
11006         # some versions of cvs import exit(1) when asked to import links or
11007         # files they can't read.  ignore those files.
11008         local toignore=$(find . -type l -printf '-I %f\n' -o \
11009                          ! -perm /4 -printf '-I %f\n')
11010         $RUNAS cvs -d $DIR/$tdir.cvsroot import -m "nomesg" $toignore \
11011                 $tdir.reposname vtag rtag
11012
11013         cd $DIR
11014         test_mkdir $DIR/$tdir.reposname
11015         chown $RUNAS_ID $DIR/$tdir.reposname
11016         $RUNAS cvs -d $DIR/$tdir.cvsroot co $tdir.reposname
11017
11018         cd $DIR/$tdir.reposname
11019         $RUNAS touch foo99
11020         $RUNAS cvs add -m 'addmsg' foo99
11021         $RUNAS cvs update
11022         $RUNAS cvs commit -m 'nomsg' foo99
11023         rm -fr $DIR/$tdir.cvsroot
11024 }
11025 run_test 99 "cvs strange file/directory operations"
11026
11027 test_100() {
11028         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11029         [[ "$NETTYPE" =~ tcp ]] ||
11030                 skip_env "TCP secure port test, not useful for NETTYPE=$NETTYPE"
11031         [[ -n "$(type -p ss)" ]] || skip_env "ss not available"
11032         remote_ost_nodsh && skip "remote OST with nodsh"
11033         remote_mds_nodsh && skip "remote MDS with nodsh"
11034         remote_servers || skip "useless for local single node setup"
11035
11036         ss -tna | ( rc=1; while read STATE SND RCV LOCAL REMOTE STAT; do
11037                 [[ "${REMOTE/*:/}" == "$ACCEPTOR_PORT" ]] || continue
11038
11039                 rc=0
11040                 if (( ${LOCAL/*:/} >= 1024 )); then
11041                         echo "bad: $PROT $SND $RCV $LOCAL $REMOTE $STAT"
11042                         ss -tna
11043                         error "local: ${LOCAL/*:/} > 1024 remote: ${REMOTE/*:/}"
11044                 fi
11045         done
11046         (( $rc == 0 )) || error "privileged port not found" )
11047 }
11048 run_test 100 "check local port using privileged port"
11049
11050 function get_named_value()
11051 {
11052     local tag=$1
11053
11054     grep -w "$tag" | sed "s/^$tag  *\([0-9]*\)  *.*/\1/"
11055 }
11056
11057 export CACHE_MAX=$($LCTL get_param -n llite.*.max_cached_mb |
11058                    awk '/^max_cached_mb/ { print $2 }')
11059
11060 cleanup_101a() {
11061         $LCTL set_param -n llite.*.max_cached_mb $CACHE_MAX
11062         trap 0
11063 }
11064
11065 test_101a() {
11066         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11067
11068         local s
11069         local discard
11070         local nreads=10000
11071         local cache_limit=32
11072
11073         $LCTL set_param -n osc.*-osc*.rpc_stats=0
11074         trap cleanup_101a EXIT
11075         $LCTL set_param -n llite.*.read_ahead_stats=0
11076         $LCTL set_param -n llite.*.max_cached_mb=$cache_limit
11077
11078         #
11079         # randomly read 10000 of 64K chunks from file 3x 32MB in size
11080         #
11081         echo "nreads: $nreads file size: $((cache_limit * 3))MB"
11082         $READS -f $DIR/$tfile -s$((cache_limit * 3192 * 1024)) -b65536 -C -n$nreads -t 180
11083
11084         discard=0
11085         for s in $($LCTL get_param -n llite.*.read_ahead_stats |
11086                    get_named_value 'read.but.discarded'); do
11087                         discard=$(($discard + $s))
11088         done
11089         cleanup_101a
11090
11091         $LCTL get_param osc.*-osc*.rpc_stats
11092         $LCTL get_param llite.*.read_ahead_stats
11093
11094         # Discard is generally zero, but sometimes a few random reads line up
11095         # and trigger larger readahead, which is wasted & leads to discards.
11096         if [[ $(($discard)) -gt $nreads ]]; then
11097                 error "too many ($discard) discarded pages"
11098         fi
11099         rm -f $DIR/$tfile || true
11100 }
11101 run_test 101a "check read-ahead for random reads"
11102
11103 setup_test101bc() {
11104         test_mkdir $DIR/$tdir
11105         local ssize=$1
11106         local FILE_LENGTH=$2
11107         STRIPE_OFFSET=0
11108
11109         local FILE_SIZE_MB=$((FILE_LENGTH / ssize))
11110
11111         local list=$(comma_list $(osts_nodes))
11112         set_osd_param $list '' read_cache_enable 0
11113         set_osd_param $list '' writethrough_cache_enable 0
11114
11115         trap cleanup_test101bc EXIT
11116         # prepare the read-ahead file
11117         $LFS setstripe -S $ssize -i $STRIPE_OFFSET -c $OSTCOUNT $DIR/$tfile
11118
11119         dd if=/dev/zero of=$DIR/$tfile bs=$ssize \
11120                                 count=$FILE_SIZE_MB 2> /dev/null
11121
11122 }
11123
11124 cleanup_test101bc() {
11125         trap 0
11126         rm -rf $DIR/$tdir
11127         rm -f $DIR/$tfile
11128
11129         local list=$(comma_list $(osts_nodes))
11130         set_osd_param $list '' read_cache_enable 1
11131         set_osd_param $list '' writethrough_cache_enable 1
11132 }
11133
11134 calc_total() {
11135         awk 'BEGIN{total=0}; {total+=$1}; END{print total}'
11136 }
11137
11138 ra_check_101() {
11139         local read_size=$1
11140         local stripe_size=$2
11141         local stride_length=$((stripe_size / read_size))
11142         local stride_width=$((stride_length * OSTCOUNT))
11143         local discard_limit=$(( ((stride_length - 1) * 3 / stride_width) *
11144                                 (stride_width - stride_length) ))
11145         local discard=$($LCTL get_param -n llite.*.read_ahead_stats |
11146                   get_named_value 'read.but.discarded' | calc_total)
11147
11148         if [[ $discard -gt $discard_limit ]]; then
11149                 $LCTL get_param llite.*.read_ahead_stats
11150                 error "($discard limit ${discard_limit}) discarded pages with size (${read_size})"
11151         else
11152                 echo "Read-ahead success for size ${read_size}"
11153         fi
11154 }
11155
11156 test_101b() {
11157         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11158         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11159
11160         local STRIPE_SIZE=1048576
11161         local STRIDE_SIZE=$((STRIPE_SIZE*OSTCOUNT))
11162
11163         if [ $SLOW == "yes" ]; then
11164                 local FILE_LENGTH=$((STRIDE_SIZE * 64))
11165         else
11166                 local FILE_LENGTH=$((STRIDE_SIZE * 8))
11167         fi
11168
11169         local ITERATION=$((FILE_LENGTH / STRIDE_SIZE))
11170
11171         # prepare the read-ahead file
11172         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
11173         cancel_lru_locks osc
11174         for BIDX in 2 4 8 16 32 64 128 256
11175         do
11176                 local BSIZE=$((BIDX*4096))
11177                 local READ_COUNT=$((STRIPE_SIZE/BSIZE))
11178                 local STRIDE_LENGTH=$((STRIDE_SIZE/BSIZE))
11179                 local OFFSET=$((STRIPE_SIZE/BSIZE*(OSTCOUNT - 1)))
11180                 $LCTL set_param -n llite.*.read_ahead_stats=0
11181                 $READS -f $DIR/$tfile  -l $STRIDE_LENGTH -o $OFFSET \
11182                               -s $FILE_LENGTH -b $STRIPE_SIZE -a $READ_COUNT -n $ITERATION
11183                 cancel_lru_locks osc
11184                 ra_check_101 $BSIZE $STRIPE_SIZE $FILE_LENGTH
11185         done
11186         cleanup_test101bc
11187         true
11188 }
11189 run_test 101b "check stride-io mode read-ahead ================="
11190
11191 test_101c() {
11192         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11193
11194         local STRIPE_SIZE=1048576
11195         local FILE_LENGTH=$((STRIPE_SIZE*100))
11196         local nreads=10000
11197         local rsize=65536
11198         local osc_rpc_stats
11199
11200         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
11201
11202         cancel_lru_locks osc
11203         $LCTL set_param osc.*.rpc_stats=0
11204         $READS -f $DIR/$tfile -s$FILE_LENGTH -b$rsize -n$nreads -t 180
11205         $LCTL get_param osc.*.rpc_stats
11206         for osc_rpc_stats in $($LCTL get_param -N osc.*.rpc_stats); do
11207                 local stats=$($LCTL get_param -n $osc_rpc_stats)
11208                 local lines=$(echo "$stats" | awk 'END {print NR;}')
11209                 local size
11210
11211                 if [ $lines -le 20 ]; then
11212                         echo "continue debug"
11213                         continue
11214                 fi
11215                 for size in 1 2 4 8; do
11216                         local rpc=$(echo "$stats" |
11217                                     awk '($1 == "'$size':") {print $2; exit; }')
11218                         [ $rpc != 0 ] && ((size * PAGE_SIZE < rsize)) &&
11219                                 error "Small $((size*PAGE_SIZE)) read IO $rpc!"
11220                 done
11221                 echo "$osc_rpc_stats check passed!"
11222         done
11223         cleanup_test101bc
11224         true
11225 }
11226 run_test 101c "check stripe_size aligned read-ahead"
11227
11228 test_101d() {
11229         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11230
11231         local file=$DIR/$tfile
11232         local sz_MB=${FILESIZE_101d:-80}
11233         local ra_MB=${READAHEAD_MB:-40}
11234
11235         local free_MB=$(($(df -P $DIR | tail -n 1 | awk '{ print $4 }') / 1024))
11236         [ $free_MB -lt $sz_MB ] &&
11237                 skip "Need free space ${sz_MB}M, have ${free_MB}M"
11238
11239         echo "Create test file $file size ${sz_MB}M, ${free_MB}M free"
11240         $LFS setstripe -c -1 $file || error "setstripe failed"
11241
11242         dd if=/dev/zero of=$file bs=1M count=$sz_MB || error "dd failed"
11243         echo Cancel LRU locks on lustre client to flush the client cache
11244         cancel_lru_locks osc
11245
11246         echo Disable read-ahead
11247         local old_RA=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
11248         $LCTL set_param -n llite.*.max_read_ahead_mb=0
11249         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb=$old_RA" EXIT
11250         $LCTL get_param -n llite.*.max_read_ahead_mb
11251
11252         echo "Reading the test file $file with read-ahead disabled"
11253         local sz_KB=$((sz_MB * 1024 / 4))
11254         # 10485760 bytes transferred in 0.000938 secs (11179579337 bytes/sec)
11255         # 104857600 bytes (105 MB) copied, 0.00876352 s, 12.0 GB/s
11256         local raOFF=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
11257                       sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
11258
11259         echo "Cancel LRU locks on lustre client to flush the client cache"
11260         cancel_lru_locks osc
11261         echo Enable read-ahead with ${ra_MB}MB
11262         $LCTL set_param -n llite.*.max_read_ahead_mb=$ra_MB
11263
11264         echo "Reading the test file $file with read-ahead enabled"
11265         local raON=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
11266                      sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
11267
11268         echo "read-ahead disabled time read $raOFF"
11269         echo "read-ahead enabled time read $raON"
11270
11271         rm -f $file
11272         wait_delete_completed
11273
11274         # use awk for this check instead of bash because it handles decimals
11275         awk "{ exit !($raOFF < 1.0 || $raOFF > $raON) }" <<<"ignore_me" ||
11276                 error "readahead ${raON}s > no-readahead ${raOFF}s ${sz_MB}M"
11277 }
11278 run_test 101d "file read with and without read-ahead enabled"
11279
11280 test_101e() {
11281         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11282
11283         local file=$DIR/$tfile
11284         local size_KB=500  #KB
11285         local count=100
11286         local bsize=1024
11287
11288         local free_KB=$(df -P $DIR | tail -n 1 | awk '{ print $4 }')
11289         local need_KB=$((count * size_KB))
11290         [[ $free_KB -le $need_KB ]] &&
11291                 skip_env "Need free space $need_KB, have $free_KB"
11292
11293         echo "Creating $count ${size_KB}K test files"
11294         for ((i = 0; i < $count; i++)); do
11295                 dd if=/dev/zero of=$file.$i bs=$bsize count=$size_KB 2>/dev/null
11296         done
11297
11298         echo "Cancel LRU locks on lustre client to flush the client cache"
11299         cancel_lru_locks $OSC
11300
11301         echo "Reset readahead stats"
11302         $LCTL set_param -n llite.*.read_ahead_stats=0
11303
11304         for ((i = 0; i < $count; i++)); do
11305                 dd if=$file.$i of=/dev/null bs=$bsize count=$size_KB 2>/dev/null
11306         done
11307
11308         $LCTL get_param llite.*.max_cached_mb
11309         $LCTL get_param llite.*.read_ahead_stats
11310         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11311                      get_named_value 'misses' | calc_total)
11312
11313         for ((i = 0; i < $count; i++)); do
11314                 rm -rf $file.$i 2>/dev/null
11315         done
11316
11317         #10000 means 20% reads are missing in readahead
11318         [[ $miss -lt 10000 ]] ||  error "misses too much for small reads"
11319 }
11320 run_test 101e "check read-ahead for small read(1k) for small files(500k)"
11321
11322 test_101f() {
11323         which iozone || skip_env "no iozone installed"
11324
11325         local old_debug=$($LCTL get_param debug)
11326         old_debug=${old_debug#*=}
11327         $LCTL set_param debug="reada mmap"
11328
11329         # create a test file
11330         iozone -i 0 -+n -r 1m -s 128m -w -f $DIR/$tfile > /dev/null 2>&1
11331
11332         echo Cancel LRU locks on lustre client to flush the client cache
11333         cancel_lru_locks osc
11334
11335         echo Reset readahead stats
11336         $LCTL set_param -n llite.*.read_ahead_stats=0
11337
11338         echo mmap read the file with small block size
11339         iozone -i 1 -u 1 -l 1 -+n -r 32k -s 128m -B -f $DIR/$tfile \
11340                 > /dev/null 2>&1
11341
11342         echo checking missing pages
11343         $LCTL get_param llite.*.read_ahead_stats
11344         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11345                         get_named_value 'misses' | calc_total)
11346
11347         $LCTL set_param debug="$old_debug"
11348         [ $miss -lt 3 ] || error "misses too much pages ('$miss')!"
11349         rm -f $DIR/$tfile
11350 }
11351 run_test 101f "check mmap read performance"
11352
11353 test_101g_brw_size_test() {
11354         local mb=$1
11355         local pages=$((mb * 1048576 / PAGE_SIZE))
11356         local file=$DIR/$tfile
11357
11358         $LCTL set_param osc.*.max_pages_per_rpc=${mb}M ||
11359                 { error "unable to set max_pages_per_rpc=${mb}M"; return 1; }
11360         for mp in $($LCTL get_param -n osc.*.max_pages_per_rpc); do
11361                 [ $mp -ne $pages ] && error "max_pages_per_rpc $mp != $pages" &&
11362                         return 2
11363         done
11364
11365         stack_trap "rm -f $file" EXIT
11366         $LCTL set_param -n osc.*.rpc_stats=0
11367
11368         # 10 RPCs should be enough for the test
11369         local count=10
11370         dd if=/dev/zero of=$file bs=${mb}M count=$count ||
11371                 { error "dd write ${mb} MB blocks failed"; return 3; }
11372         cancel_lru_locks osc
11373         dd of=/dev/null if=$file bs=${mb}M count=$count ||
11374                 { error "dd write ${mb} MB blocks failed"; return 4; }
11375
11376         # calculate number of full-sized read and write RPCs
11377         rpcs=($($LCTL get_param -n 'osc.*.rpc_stats' |
11378                 sed -n '/pages per rpc/,/^$/p' |
11379                 awk '/'$pages':/ { reads += $2; writes += $6 }; \
11380                 END { print reads,writes }'))
11381         # allow one extra full-sized read RPC for async readahead
11382         [[ ${rpcs[0]} == $count || ${rpcs[0]} == $((count + 1)) ]] ||
11383                 { error "${rpcs[0]} != $count read RPCs"; return 5; }
11384         [[ ${rpcs[1]} == $count ]] ||
11385                 { error "${rpcs[1]} != $count write RPCs"; return 6; }
11386 }
11387
11388 test_101g() {
11389         remote_ost_nodsh && skip "remote OST with nodsh"
11390
11391         local rpcs
11392         local osts=$(get_facets OST)
11393         local list=$(comma_list $(osts_nodes))
11394         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
11395         local brw_size="obdfilter.*.brw_size"
11396
11397         $LFS setstripe -i 0 -c 1 $DIR/$tfile
11398
11399         local orig_mb=$(do_facet ost1 $LCTL get_param -n $brw_size | head -n 1)
11400
11401         if { [ $OST1_VERSION -ge $(version_code 2.8.52) ] ||
11402                 { [ $OST1_VERSION -ge $(version_code 2.7.17) ] &&
11403                   [ $OST1_VERSION -lt $(version_code 2.7.50) ]; }; } &&
11404            { [ $CLIENT_VERSION -ge $(version_code 2.8.52) ] ||
11405                 { [ $CLIENT_VERSION -ge $(version_code 2.7.17) ] &&
11406                   [ $CLIENT_VERSION -lt $(version_code 2.7.50) ]; }; }; then
11407
11408                 [ $OST1_VERSION -ge $(version_code 2.9.52) ] &&
11409                         suffix="M"
11410
11411                 if [[ $orig_mb -lt 16 ]]; then
11412                         save_lustre_params $osts "$brw_size" > $p
11413                         do_nodes $list $LCTL set_param -n $brw_size=16$suffix ||
11414                                 error "set 16MB RPC size failed"
11415
11416                         echo "remount client to enable new RPC size"
11417                         remount_client $MOUNT || error "remount_client failed"
11418                 fi
11419
11420                 test_101g_brw_size_test 16 || error "16MB RPC test failed"
11421                 # should be able to set brw_size=12, but no rpc_stats for that
11422                 test_101g_brw_size_test 8 || error "8MB RPC test failed"
11423         fi
11424
11425         test_101g_brw_size_test 4 || error "4MB RPC test failed"
11426
11427         if [[ $orig_mb -lt 16 ]]; then
11428                 restore_lustre_params < $p
11429                 remount_client $MOUNT || error "remount_client restore failed"
11430         fi
11431
11432         rm -f $p $DIR/$tfile
11433 }
11434 run_test 101g "Big bulk(4/16 MiB) readahead"
11435
11436 test_101h() {
11437         $LFS setstripe -i 0 -c 1 $DIR/$tfile
11438
11439         dd if=/dev/zero of=$DIR/$tfile bs=1M count=70 ||
11440                 error "dd 70M file failed"
11441         echo Cancel LRU locks on lustre client to flush the client cache
11442         cancel_lru_locks osc
11443
11444         echo "Reset readahead stats"
11445         $LCTL set_param -n llite.*.read_ahead_stats 0
11446
11447         echo "Read 10M of data but cross 64M bundary"
11448         dd if=$DIR/$tfile of=/dev/null bs=10M skip=6 count=1
11449         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11450                      get_named_value 'misses' | calc_total)
11451         [ $miss -eq 1 ] || error "expected miss 1 but got $miss"
11452         rm -f $p $DIR/$tfile
11453 }
11454 run_test 101h "Readahead should cover current read window"
11455
11456 test_101i() {
11457         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 ||
11458                 error "dd 10M file failed"
11459
11460         local max_per_file_mb=$($LCTL get_param -n \
11461                 llite.*.max_read_ahead_per_file_mb 2>/dev/null)
11462         cancel_lru_locks osc
11463         stack_trap "$LCTL set_param llite.*.max_read_ahead_per_file_mb=$max_per_file_mb"
11464         $LCTL set_param llite.*.max_read_ahead_per_file_mb=1 ||
11465                 error "set max_read_ahead_per_file_mb to 1 failed"
11466
11467         echo "Reset readahead stats"
11468         $LCTL set_param llite.*.read_ahead_stats=0
11469
11470         dd if=$DIR/$tfile of=/dev/null bs=2M
11471
11472         $LCTL get_param llite.*.read_ahead_stats
11473         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11474                      awk '/misses/ { print $2 }')
11475         [ $miss -eq 5 ] || error "expected misses 5 but got $miss"
11476         rm -f $DIR/$tfile
11477 }
11478 run_test 101i "allow current readahead to exceed reservation"
11479
11480 test_101j() {
11481         $LFS setstripe -i 0 -c 1 $DIR/$tfile ||
11482                 error "setstripe $DIR/$tfile failed"
11483         local file_size=$((1048576 * 16))
11484         local old_ra=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
11485         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb $old_ra" EXIT
11486
11487         echo Disable read-ahead
11488         $LCTL set_param -n llite.*.max_read_ahead_mb=0
11489
11490         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$(($file_size / 1048576))
11491         for blk in $PAGE_SIZE 1048576 $file_size; do
11492                 cancel_lru_locks osc
11493                 echo "Reset readahead stats"
11494                 $LCTL set_param -n llite.*.read_ahead_stats=0
11495                 local count=$(($file_size / $blk))
11496                 dd if=$DIR/$tfile bs=$blk count=$count of=/dev/null
11497                 local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11498                              get_named_value 'failed.to.fast.read' | calc_total)
11499                 $LCTL get_param -n llite.*.read_ahead_stats
11500                 [ $miss -eq $count ] || error "expected $count got $miss"
11501         done
11502
11503         rm -f $p $DIR/$tfile
11504 }
11505 run_test 101j "A complete read block should be submitted when no RA"
11506
11507 test_readahead_base() {
11508         local file=$DIR/$tfile
11509         local size=$1
11510         local iosz
11511         local ramax
11512         local ranum
11513
11514         $LCTL set_param -n llite.*.read_ahead_stats=0
11515         # The first page is not accounted into readahead
11516         ramax=$(((size + PAGE_SIZE - 1) / PAGE_SIZE - 1))
11517         iosz=$(((size + 1048575) / 1048576 * 1048576))
11518         echo "Test readahead: size=$size ramax=$ramx iosz=$iosz"
11519
11520         $LCTL mark  "Test readahead: size=$size ramax=$ramx iosz=$iosz"
11521         fallocate -l $size $file || error "failed to fallocate $file"
11522         cancel_lru_locks osc
11523         $MULTIOP $file or${iosz}c || error "failed to read $file"
11524         $LCTL get_param -n llite.*.read_ahead_stats
11525         ranum=$($LCTL get_param -n llite.*.read_ahead_stats |
11526                 awk '/readahead.pages/ { print $7 }' | calc_total)
11527         (( $ranum <= $ramax )) ||
11528                 error "read-ahead pages is $ranum more than $ramax"
11529         rm -rf $file || error "failed to remove $file"
11530 }
11531
11532 test_101m()
11533 {
11534         local file=$DIR/$tfile
11535         local ramax
11536         local ranum
11537         local size
11538         local iosz
11539
11540         check_set_fallocate_or_skip
11541         stack_trap "rm -f $file" EXIT
11542
11543         test_readahead_base 4096
11544
11545         # file size: 16K = 16384
11546         test_readahead_base 16384
11547         test_readahead_base 16385
11548         test_readahead_base 16383
11549
11550         # file size: 1M + 1 = 1048576 + 1
11551         test_readahead_base 1048577
11552         # file size: 1M + 16K
11553         test_readahead_base $((1048576 + 16384))
11554
11555         # file size: stripe_size * (stripe_count - 1) + 16K
11556         $LFS setstripe -c -1 $file || error "failed to setstripe $file"
11557         test_readahead_base $((1048576 * (OSTCOUNT - 1) + 16384))
11558         # file size: stripe_size * stripe_count + 16K
11559         $LFS setstripe -c -1 $file || error "failed to setstripe $file"
11560         test_readahead_base $((1048576 * OSTCOUNT + 16384))
11561         # file size: 2 * stripe_size * stripe_count + 16K
11562         $LFS setstripe -c -1 $file || error "failed to setstripe $file"
11563         test_readahead_base $((2 * 1048576 * OSTCOUNT + 16384))
11564 }
11565 run_test 101m "read ahead for small file and last stripe of the file"
11566
11567 setup_test102() {
11568         test_mkdir $DIR/$tdir
11569         chown $RUNAS_ID $DIR/$tdir
11570         STRIPE_SIZE=65536
11571         STRIPE_OFFSET=1
11572         STRIPE_COUNT=$OSTCOUNT
11573         [[ $OSTCOUNT -gt 4 ]] && STRIPE_COUNT=4
11574
11575         trap cleanup_test102 EXIT
11576         cd $DIR
11577         $1 $LFS setstripe -S $STRIPE_SIZE -i $STRIPE_OFFSET -c $STRIPE_COUNT $tdir
11578         cd $DIR/$tdir
11579         for num in 1 2 3 4; do
11580                 for count in $(seq 1 $STRIPE_COUNT); do
11581                         for idx in $(seq 0 $[$STRIPE_COUNT - 1]); do
11582                                 local size=`expr $STRIPE_SIZE \* $num`
11583                                 local file=file"$num-$idx-$count"
11584                                 $1 $LFS setstripe -S $size -i $idx -c $count $file
11585                         done
11586                 done
11587         done
11588
11589         cd $DIR
11590         $1 tar cf $TMP/f102.tar $tdir --xattrs
11591 }
11592
11593 cleanup_test102() {
11594         trap 0
11595         rm -f $TMP/f102.tar
11596         rm -rf $DIR/d0.sanity/d102
11597 }
11598
11599 test_102a() {
11600         [ "$UID" != 0 ] && skip "must run as root"
11601         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep xattr)" ] &&
11602                 skip_env "must have user_xattr"
11603
11604         [ -z "$(which setfattr 2>/dev/null)" ] &&
11605                 skip_env "could not find setfattr"
11606
11607         local testfile=$DIR/$tfile
11608
11609         touch $testfile
11610         echo "set/get xattr..."
11611         setfattr -n trusted.name1 -v value1 $testfile ||
11612                 error "setfattr -n trusted.name1=value1 $testfile failed"
11613         getfattr -n trusted.name1 $testfile 2> /dev/null |
11614           grep "trusted.name1=.value1" ||
11615                 error "$testfile missing trusted.name1=value1"
11616
11617         setfattr -n user.author1 -v author1 $testfile ||
11618                 error "setfattr -n user.author1=author1 $testfile failed"
11619         getfattr -n user.author1 $testfile 2> /dev/null |
11620           grep "user.author1=.author1" ||
11621                 error "$testfile missing trusted.author1=author1"
11622
11623         echo "listxattr..."
11624         setfattr -n trusted.name2 -v value2 $testfile ||
11625                 error "$testfile unable to set trusted.name2"
11626         setfattr -n trusted.name3 -v value3 $testfile ||
11627                 error "$testfile unable to set trusted.name3"
11628         [ $(getfattr -d -m "^trusted" $testfile 2> /dev/null |
11629             grep "trusted.name" | wc -l) -eq 3 ] ||
11630                 error "$testfile missing 3 trusted.name xattrs"
11631
11632         setfattr -n user.author2 -v author2 $testfile ||
11633                 error "$testfile unable to set user.author2"
11634         setfattr -n user.author3 -v author3 $testfile ||
11635                 error "$testfile unable to set user.author3"
11636         [ $(getfattr -d -m "^user" $testfile 2> /dev/null |
11637             grep "user.author" | wc -l) -eq 3 ] ||
11638                 error "$testfile missing 3 user.author xattrs"
11639
11640         echo "remove xattr..."
11641         setfattr -x trusted.name1 $testfile ||
11642                 error "$testfile error deleting trusted.name1"
11643         getfattr -d -m trusted $testfile 2> /dev/null | grep "trusted.name1" &&
11644                 error "$testfile did not delete trusted.name1 xattr"
11645
11646         setfattr -x user.author1 $testfile ||
11647                 error "$testfile error deleting user.author1"
11648         echo "set lustre special xattr ..."
11649         $LFS setstripe -c1 $testfile
11650         local lovea=$(getfattr -n "trusted.lov" -e hex $testfile |
11651                 awk -F "=" '/trusted.lov/ { print $2 }' )
11652         setfattr -n "trusted.lov" -v $lovea $testfile ||
11653                 error "$testfile doesn't ignore setting trusted.lov again"
11654         setfattr -n "trusted.lov" -v "invalid_value" $testfile &&
11655                 error "$testfile allow setting invalid trusted.lov"
11656         rm -f $testfile
11657 }
11658 run_test 102a "user xattr test =================================="
11659
11660 check_102b_layout() {
11661         local layout="$*"
11662         local testfile=$DIR/$tfile
11663
11664         echo "test layout '$layout'"
11665         $LFS setstripe $layout $testfile || error "setstripe failed"
11666         $LFS getstripe -y $testfile
11667
11668         echo "get/set/list trusted.lov xattr ..." # b=10930
11669         local value=$(getfattr -n trusted.lov -e hex $testfile | grep trusted)
11670         [[ "$value" =~ "trusted.lov" ]] ||
11671                 error "can't get trusted.lov from $testfile"
11672         local stripe_count_orig=$($LFS getstripe -c $testfile) ||
11673                 error "getstripe failed"
11674
11675         $MCREATE $testfile.2 || error "mcreate $testfile.2 failed"
11676
11677         value=$(cut -d= -f2 <<<$value)
11678         # LU-13168: truncated xattr should fail if short lov_user_md header
11679         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
11680                 lens="${#value}" || lens="$(seq 4 2 ${#value})"
11681         for len in $lens; do
11682                 echo "setfattr $len $testfile.2"
11683                 setfattr -n trusted.lov -v ${value:0:$len} $testfile.2 &&
11684                         [ $len -lt 66 ] && error "short xattr len=$len worked"
11685         done
11686         local stripe_size=$($LFS getstripe -S $testfile.2)
11687         local stripe_count=$($LFS getstripe -c $testfile.2)
11688         [[ $stripe_size -eq 65536 ]] ||
11689                 error "stripe size $stripe_size != 65536"
11690         [[ $stripe_count -eq $stripe_count_orig ]] ||
11691                 error "stripe count $stripe_count != $stripe_count_orig"
11692         rm $testfile $testfile.2
11693 }
11694
11695 test_102b() {
11696         [ -z "$(which setfattr 2>/dev/null)" ] &&
11697                 skip_env "could not find setfattr"
11698         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11699
11700         # check plain layout
11701         check_102b_layout -S 65536 -i 1 -c $OSTCOUNT
11702
11703         # and also check composite layout
11704         check_102b_layout -E 1M -S 65536 -i 1 -c $OSTCOUNT -Eeof -S4M
11705
11706 }
11707 run_test 102b "getfattr/setfattr for trusted.lov EAs"
11708
11709 test_102c() {
11710         [ -z "$(which setfattr 2>/dev/null)" ] &&
11711                 skip_env "could not find setfattr"
11712         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11713
11714         # b10930: get/set/list lustre.lov xattr
11715         echo "get/set/list lustre.lov xattr ..."
11716         test_mkdir $DIR/$tdir
11717         chown $RUNAS_ID $DIR/$tdir
11718         local testfile=$DIR/$tdir/$tfile
11719         $RUNAS $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
11720                 error "setstripe failed"
11721         local STRIPECOUNT=$($RUNAS $LFS getstripe -c $testfile) ||
11722                 error "getstripe failed"
11723         $RUNAS getfattr -d -m "^lustre" $testfile 2> /dev/null | \
11724         grep "lustre.lov" || error "can't get lustre.lov from $testfile"
11725
11726         local testfile2=${testfile}2
11727         local value=`getfattr -n lustre.lov $testfile 2> /dev/null | \
11728                      grep "lustre.lov" |sed -e 's/[^=]\+=//'  `
11729
11730         $RUNAS $MCREATE $testfile2
11731         $RUNAS setfattr -n lustre.lov -v $value $testfile2
11732         local stripe_size=$($RUNAS $LFS getstripe -S $testfile2)
11733         local stripe_count=$($RUNAS $LFS getstripe -c $testfile2)
11734         [ $stripe_size -eq 65536 ] || error "stripe size $stripe_size != 65536"
11735         [ $stripe_count -eq $STRIPECOUNT ] ||
11736                 error "stripe count $stripe_count != $STRIPECOUNT"
11737 }
11738 run_test 102c "non-root getfattr/setfattr for lustre.lov EAs ==========="
11739
11740 compare_stripe_info1() {
11741         local stripe_index_all_zero=true
11742
11743         for num in 1 2 3 4; do
11744                 for count in $(seq 1 $STRIPE_COUNT); do
11745                         for offset in $(seq 0 $[$STRIPE_COUNT - 1]); do
11746                                 local size=$((STRIPE_SIZE * num))
11747                                 local file=file"$num-$offset-$count"
11748                                 stripe_size=$($LFS getstripe -S $PWD/$file)
11749                                 [[ $stripe_size -ne $size ]] &&
11750                                     error "$file: size $stripe_size != $size"
11751                                 stripe_count=$($LFS getstripe -c $PWD/$file)
11752                                 # allow fewer stripes to be created, ORI-601
11753                                 [[ $stripe_count -lt $(((3 * count + 3) / 4)) ]] &&
11754                                     error "$file: count $stripe_count != $count"
11755                                 stripe_index=$($LFS getstripe -i $PWD/$file)
11756                                 [[ $stripe_index -ne 0 ]] &&
11757                                         stripe_index_all_zero=false
11758                         done
11759                 done
11760         done
11761         $stripe_index_all_zero &&
11762                 error "all files are being extracted starting from OST index 0"
11763         return 0
11764 }
11765
11766 have_xattrs_include() {
11767         tar --help | grep -q xattrs-include &&
11768                 echo --xattrs-include="lustre.*"
11769 }
11770
11771 test_102d() {
11772         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11773         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11774
11775         XINC=$(have_xattrs_include)
11776         setup_test102
11777         tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
11778         cd $DIR/$tdir/$tdir
11779         compare_stripe_info1
11780 }
11781 run_test 102d "tar restore stripe info from tarfile,not keep osts"
11782
11783 test_102f() {
11784         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11785         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11786
11787         XINC=$(have_xattrs_include)
11788         setup_test102
11789         test_mkdir $DIR/$tdir.restore
11790         cd $DIR
11791         tar cf - --xattrs $tdir | tar xf - \
11792                 -C $DIR/$tdir.restore --xattrs $XINC
11793         cd $DIR/$tdir.restore/$tdir
11794         compare_stripe_info1
11795 }
11796 run_test 102f "tar copy files, not keep osts"
11797
11798 grow_xattr() {
11799         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep xattr)" ] &&
11800                 skip "must have user_xattr"
11801         [ -z "$(which setfattr 2>/dev/null)" ] &&
11802                 skip_env "could not find setfattr"
11803         [ -z "$(which getfattr 2>/dev/null)" ] &&
11804                 skip_env "could not find getfattr"
11805
11806         local xsize=${1:-1024}  # in bytes
11807         local file=$DIR/$tfile
11808         local value="$(generate_string $xsize)"
11809         local xbig=trusted.big
11810         local toobig=$2
11811
11812         touch $file
11813         log "save $xbig on $file"
11814         if [ -z "$toobig" ]
11815         then
11816                 setfattr -n $xbig -v $value $file ||
11817                         error "saving $xbig on $file failed"
11818         else
11819                 setfattr -n $xbig -v $value $file &&
11820                         error "saving $xbig on $file succeeded"
11821                 return 0
11822         fi
11823
11824         local orig=$(get_xattr_value $xbig $file)
11825         [[ "$orig" != "$value" ]] && error "$xbig different after saving $xbig"
11826
11827         local xsml=trusted.sml
11828         log "save $xsml on $file"
11829         setfattr -n $xsml -v val $file || error "saving $xsml on $file failed"
11830
11831         local new=$(get_xattr_value $xbig $file)
11832         [[ "$new" != "$orig" ]] && error "$xbig different after saving $xsml"
11833
11834         log "grow $xsml on $file"
11835         setfattr -n $xsml -v "$value" $file ||
11836                 error "growing $xsml on $file failed"
11837
11838         new=$(get_xattr_value $xbig $file)
11839         [[ "$new" != "$orig" ]] && error "$xbig different after growing $xsml"
11840         log "$xbig still valid after growing $xsml"
11841
11842         rm -f $file
11843 }
11844
11845 test_102h() { # bug 15777
11846         grow_xattr 1024
11847 }
11848 run_test 102h "grow xattr from inside inode to external block"
11849
11850 test_102ha() {
11851         large_xattr_enabled || skip_env "ea_inode feature disabled"
11852
11853         echo "setting xattr of max xattr size: $(max_xattr_size)"
11854         grow_xattr $(max_xattr_size)
11855
11856         echo "setting xattr of > max xattr size: $(max_xattr_size) + 10"
11857         echo "This should fail:"
11858         grow_xattr $(($(max_xattr_size) + 10)) 1
11859 }
11860 run_test 102ha "grow xattr from inside inode to external inode"
11861
11862 test_102i() { # bug 17038
11863         [ -z "$(which getfattr 2>/dev/null)" ] &&
11864                 skip "could not find getfattr"
11865
11866         touch $DIR/$tfile
11867         ln -s $DIR/$tfile $DIR/${tfile}link
11868         getfattr -n trusted.lov $DIR/$tfile ||
11869                 error "lgetxattr on $DIR/$tfile failed"
11870         getfattr -h -n trusted.lov $DIR/${tfile}link 2>&1 |
11871                 grep -i "no such attr" ||
11872                 error "error for lgetxattr on $DIR/${tfile}link is not ENODATA"
11873         rm -f $DIR/$tfile $DIR/${tfile}link
11874 }
11875 run_test 102i "lgetxattr test on symbolic link ============"
11876
11877 test_102j() {
11878         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11879         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11880
11881         XINC=$(have_xattrs_include)
11882         setup_test102 "$RUNAS"
11883         chown $RUNAS_ID $DIR/$tdir
11884         $RUNAS tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
11885         cd $DIR/$tdir/$tdir
11886         compare_stripe_info1 "$RUNAS"
11887 }
11888 run_test 102j "non-root tar restore stripe info from tarfile, not keep osts ==="
11889
11890 test_102k() {
11891         [ -z "$(which setfattr 2>/dev/null)" ] &&
11892                 skip "could not find setfattr"
11893
11894         touch $DIR/$tfile
11895         # b22187 just check that does not crash for regular file.
11896         setfattr -n trusted.lov $DIR/$tfile
11897         # b22187 'setfattr -n trusted.lov' should remove LOV EA for directories
11898         local test_kdir=$DIR/$tdir
11899         test_mkdir $test_kdir
11900         local default_size=$($LFS getstripe -S $test_kdir)
11901         local default_count=$($LFS getstripe -c $test_kdir)
11902         local default_offset=$($LFS getstripe -i $test_kdir)
11903         $LFS setstripe -S 65536 -i 0 -c $OSTCOUNT $test_kdir ||
11904                 error 'dir setstripe failed'
11905         setfattr -n trusted.lov $test_kdir
11906         local stripe_size=$($LFS getstripe -S $test_kdir)
11907         local stripe_count=$($LFS getstripe -c $test_kdir)
11908         local stripe_offset=$($LFS getstripe -i $test_kdir)
11909         [ $stripe_size -eq $default_size ] ||
11910                 error "stripe size $stripe_size != $default_size"
11911         [ $stripe_count -eq $default_count ] ||
11912                 error "stripe count $stripe_count != $default_count"
11913         [ $stripe_offset -eq $default_offset ] ||
11914                 error "stripe offset $stripe_offset != $default_offset"
11915         rm -rf $DIR/$tfile $test_kdir
11916 }
11917 run_test 102k "setfattr without parameter of value shouldn't cause a crash"
11918
11919 test_102l() {
11920         [ -z "$(which getfattr 2>/dev/null)" ] &&
11921                 skip "could not find getfattr"
11922
11923         # LU-532 trusted. xattr is invisible to non-root
11924         local testfile=$DIR/$tfile
11925
11926         touch $testfile
11927
11928         echo "listxattr as user..."
11929         chown $RUNAS_ID $testfile
11930         $RUNAS getfattr -d -m '.*' $testfile 2>&1 |
11931             grep -q "trusted" &&
11932                 error "$testfile trusted xattrs are user visible"
11933
11934         return 0;
11935 }
11936 run_test 102l "listxattr size test =================================="
11937
11938 test_102m() { # LU-3403 llite: error of listxattr when buffer is small
11939         local path=$DIR/$tfile
11940         touch $path
11941
11942         listxattr_size_check $path || error "listattr_size_check $path failed"
11943 }
11944 run_test 102m "Ensure listxattr fails on small bufffer ========"
11945
11946 cleanup_test102
11947
11948 getxattr() { # getxattr path name
11949         # Return the base64 encoding of the value of xattr name on path.
11950         local path=$1
11951         local name=$2
11952
11953         # # getfattr --absolute-names --encoding=base64 --name=trusted.lov $path
11954         # file: $path
11955         # trusted.lov=0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
11956         #
11957         # We print just 0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
11958
11959         getfattr --absolute-names --encoding=base64 --name=$name $path |
11960                 awk -F= -v name=$name '$1 == name {
11961                         print substr($0, index($0, "=") + 1);
11962         }'
11963 }
11964
11965 test_102n() { # LU-4101 mdt: protect internal xattrs
11966         [ -z "$(which setfattr 2>/dev/null)" ] &&
11967                 skip "could not find setfattr"
11968         if [ $MDS1_VERSION -lt $(version_code 2.5.50) ]
11969         then
11970                 skip "MDT < 2.5.50 allows setxattr on internal trusted xattrs"
11971         fi
11972
11973         local file0=$DIR/$tfile.0
11974         local file1=$DIR/$tfile.1
11975         local xattr0=$TMP/$tfile.0
11976         local xattr1=$TMP/$tfile.1
11977         local namelist="lov lma lmv link fid version som hsm"
11978         local name
11979         local value
11980
11981         rm -rf $file0 $file1 $xattr0 $xattr1
11982         touch $file0 $file1
11983
11984         # Get 'before' xattrs of $file1.
11985         getfattr --absolute-names --dump --match=- $file1 > $xattr0
11986
11987         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
11988                 namelist+=" lfsck_namespace"
11989         for name in $namelist; do
11990                 # Try to copy xattr from $file0 to $file1.
11991                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
11992
11993                 setfattr --name=trusted.$name --value="$value" $file1 ||
11994                         error "setxattr 'trusted.$name' failed"
11995
11996                 # Try to set a garbage xattr.
11997                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
11998
11999                 if [[ x$name == "xlov" ]]; then
12000                         setfattr --name=trusted.lov --value="$value" $file1 &&
12001                         error "setxattr invalid 'trusted.lov' success"
12002                 else
12003                         setfattr --name=trusted.$name --value="$value" $file1 ||
12004                                 error "setxattr invalid 'trusted.$name' failed"
12005                 fi
12006
12007                 # Try to remove the xattr from $file1. We don't care if this
12008                 # appears to succeed or fail, we just don't want there to be
12009                 # any changes or crashes.
12010                 setfattr --remove=$trusted.$name $file1 2> /dev/null
12011         done
12012
12013         if [ $MDS1_VERSION -gt $(version_code 2.6.50) ]
12014         then
12015                 name="lfsck_ns"
12016                 # Try to copy xattr from $file0 to $file1.
12017                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
12018
12019                 setfattr --name=trusted.$name --value="$value" $file1 ||
12020                         error "setxattr 'trusted.$name' failed"
12021
12022                 # Try to set a garbage xattr.
12023                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
12024
12025                 setfattr --name=trusted.$name --value="$value" $file1 ||
12026                         error "setxattr 'trusted.$name' failed"
12027
12028                 # Try to remove the xattr from $file1. We don't care if this
12029                 # appears to succeed or fail, we just don't want there to be
12030                 # any changes or crashes.
12031                 setfattr --remove=$trusted.$name $file1 2> /dev/null
12032         fi
12033
12034         # Get 'after' xattrs of file1.
12035         getfattr --absolute-names --dump --match=- $file1 > $xattr1
12036
12037         if ! diff $xattr0 $xattr1; then
12038                 error "before and after xattrs of '$file1' differ"
12039         fi
12040
12041         rm -rf $file0 $file1 $xattr0 $xattr1
12042
12043         return 0
12044 }
12045 run_test 102n "silently ignore setxattr on internal trusted xattrs"
12046
12047 test_102p() { # LU-4703 setxattr did not check ownership
12048         [ $MDS1_VERSION -lt $(version_code 2.5.56) ] &&
12049                 skip "MDS needs to be at least 2.5.56"
12050
12051         local testfile=$DIR/$tfile
12052
12053         touch $testfile
12054
12055         echo "setfacl as user..."
12056         $RUNAS setfacl -m "u:$RUNAS_ID:rwx" $testfile
12057         [ $? -ne 0 ] || error "setfacl by $RUNAS_ID was allowed on $testfile"
12058
12059         echo "setfattr as user..."
12060         setfacl -m "u:$RUNAS_ID:---" $testfile
12061         $RUNAS setfattr -x system.posix_acl_access $testfile
12062         [ $? -ne 0 ] || error "setfattr by $RUNAS_ID was allowed on $testfile"
12063 }
12064 run_test 102p "check setxattr(2) correctly fails without permission"
12065
12066 test_102q() {
12067         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] &&
12068                 skip "MDS needs to be at least 2.6.92"
12069
12070         orphan_linkea_check $DIR/$tfile || error "orphan_linkea_check"
12071 }
12072 run_test 102q "flistxattr should not return trusted.link EAs for orphans"
12073
12074 test_102r() {
12075         [ $MDS1_VERSION -lt $(version_code 2.6.93) ] &&
12076                 skip "MDS needs to be at least 2.6.93"
12077
12078         touch $DIR/$tfile || error "touch"
12079         setfattr -n user.$(basename $tfile) $DIR/$tfile || error "setfattr"
12080         getfattr -n user.$(basename $tfile) $DIR/$tfile || error "getfattr"
12081         rm $DIR/$tfile || error "rm"
12082
12083         #normal directory
12084         mkdir -p $DIR/$tdir || error "mkdir"
12085         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
12086         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
12087         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
12088                 error "$testfile error deleting user.author1"
12089         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
12090                 grep "user.$(basename $tdir)" &&
12091                 error "$tdir did not delete user.$(basename $tdir)"
12092         rmdir $DIR/$tdir || error "rmdir"
12093
12094         #striped directory
12095         test_mkdir $DIR/$tdir
12096         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
12097         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
12098         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
12099                 error "$testfile error deleting user.author1"
12100         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
12101                 grep "user.$(basename $tdir)" &&
12102                 error "$tdir did not delete user.$(basename $tdir)"
12103         rmdir $DIR/$tdir || error "rm striped dir"
12104 }
12105 run_test 102r "set EAs with empty values"
12106
12107 test_102s() {
12108         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
12109                 skip "MDS needs to be at least 2.11.52"
12110
12111         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
12112
12113         save_lustre_params client "llite.*.xattr_cache" > $save
12114
12115         for cache in 0 1; do
12116                 lctl set_param llite.*.xattr_cache=$cache
12117
12118                 rm -f $DIR/$tfile
12119                 touch $DIR/$tfile || error "touch"
12120                 for prefix in lustre security system trusted user; do
12121                         # Note getxattr() may fail with 'Operation not
12122                         # supported' or 'No such attribute' depending
12123                         # on prefix and cache.
12124                         getfattr -n $prefix.n102s $DIR/$tfile &&
12125                                 error "getxattr '$prefix.n102s' should fail (cache = $cache)"
12126                 done
12127         done
12128
12129         restore_lustre_params < $save
12130 }
12131 run_test 102s "getting nonexistent xattrs should fail"
12132
12133 test_102t() {
12134         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
12135                 skip "MDS needs to be at least 2.11.52"
12136
12137         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
12138
12139         save_lustre_params client "llite.*.xattr_cache" > $save
12140
12141         for cache in 0 1; do
12142                 lctl set_param llite.*.xattr_cache=$cache
12143
12144                 for buf_size in 0 256; do
12145                         rm -f $DIR/$tfile
12146                         touch $DIR/$tfile || error "touch"
12147                         setfattr -n user.multiop $DIR/$tfile
12148                         $MULTIOP $DIR/$tfile oa$buf_size ||
12149                                 error "cannot get zero length xattr value (buf_size = $buf_size)"
12150                 done
12151         done
12152
12153         restore_lustre_params < $save
12154 }
12155 run_test 102t "zero length xattr values handled correctly"
12156
12157 run_acl_subtest()
12158 {
12159         local test=$LUSTRE/tests/acl/$1.test
12160         local tmp=$(mktemp -t $1-XXXXXX).test
12161         local bin=$2
12162         local dmn=$3
12163         local grp=$4
12164         local nbd=$5
12165         export LANG=C
12166
12167
12168         local sedusers="-e s/bin/$bin/g -e s/daemon/$dmn/g"
12169         local sedgroups="-e s/:users/:$grp/g"
12170         [[ -z "$nbd" ]] || sedusers+=" -e s/nobody/$nbd/g"
12171
12172         sed $sedusers $sedgroups < $test > $tmp
12173         stack_trap "rm -f $tmp"
12174         [[ -s $tmp ]] || error "sed failed to create test script"
12175
12176         echo "performing $1 with bin='$bin' daemon='$dmn' users='$grp'..."
12177         $LUSTRE/tests/acl/run $tmp || error "run_acl_subtest '$1' failed"
12178 }
12179
12180 test_103a() {
12181         [ "$UID" != 0 ] && skip "must run as root"
12182         $GSS && skip_env "could not run under gss"
12183         [[ "$(lctl get_param -n mdc.*-mdc-*.connect_flags)" =~ "acl" ]] ||
12184                 skip_env "must have acl enabled"
12185         which setfacl || skip_env "could not find setfacl"
12186         remote_mds_nodsh && skip "remote MDS with nodsh"
12187
12188         ACLBIN=${ACLBIN:-"bin"}
12189         ACLDMN=${ACLDMN:-"daemon"}
12190         ACLGRP=${ACLGRP:-"users"}
12191         ACLNBD=${ACLNBD:-"nobody"}
12192
12193         if ! id $ACLBIN ||
12194            [[ "$(id -u $ACLBIN)" != "$(do_facet mds1 id -u $ACLBIN)" ]]; then
12195                 echo "bad 'bin' user '$ACLBIN', using '$USER0'"
12196                 ACLBIN=$USER0
12197                 if ! id $ACLBIN ; then
12198                         cat /etc/passwd
12199                         skip_env "can't find suitable ACL 'bin' $ACLBIN"
12200                 fi
12201         fi
12202         if ! id $ACLDMN || (( $(id -u $ACLDMN) < $(id -u $ACLBIN) )) ||
12203            [[ "$(id -u $ACLDMN)" != "$(do_facet mds1 id -u $ACLDMN)" ]]; then
12204                 echo "bad 'daemon' user '$ACLDMN', using '$USER1'"
12205                 ACLDMN=$USER1
12206                 if ! id $ACLDMN ; then
12207                         cat /etc/passwd
12208                         skip_env "can't find suitable ACL 'daemon' $ACLDMN"
12209                 fi
12210         fi
12211         if ! getent group $ACLGRP; then
12212                 echo "missing 'users' group '$ACLGRP', using '$TSTUSR'"
12213                 ACLGRP="$TSTUSR"
12214                 if ! getent group $ACLGRP; then
12215                         echo "cannot find group '$ACLGRP', adding it"
12216                         cat /etc/group
12217                         add_group 60000 $ACLGRP
12218                 fi
12219         fi
12220
12221         local bingid=$(getent group $ACLBIN | cut -d: -f 3)
12222         local dmngid=$(getent group $ACLDMN | cut -d: -f 3)
12223         local grpgid=$(getent group $ACLGRP | cut -d: -f 3)
12224
12225         if (( $bingid > $grpgid || $dmngid > $grpgid )); then
12226                 echo "group '$ACLGRP' has low gid=$grpgid, use '$TSTUSR'"
12227                 ACLGRP="$TSTUSR"
12228                 if ! getent group $ACLGRP; then
12229                         echo "cannot find group '$ACLGRP', adding it"
12230                         cat /etc/group
12231                         add_group 60000 $ACLGRP
12232                 fi
12233                 grpgid=$(getent group $ACLGRP | cut -d: -f 3)
12234                 if (( $bingid > $grpgid || $dmngid > $grpgid )); then
12235                         cat /etc/group
12236                         skip_env "$ACLGRP gid=$grpgid less than $bingid|$dmngid"
12237                 fi
12238         fi
12239
12240         gpasswd -a $ACLDMN $ACLBIN ||
12241                 error "setting client group failed"             # LU-5641
12242         do_facet mds1 gpasswd -a $ACLDMN $ACLBIN ||
12243                 error "setting MDS group failed"                # LU-5641
12244
12245         declare -a identity_old
12246
12247         for num in $(seq $MDSCOUNT); do
12248                 switch_identity $num true || identity_old[$num]=$?
12249         done
12250
12251         SAVE_UMASK=$(umask)
12252         umask 0022
12253         mkdir -p $DIR/$tdir
12254         cd $DIR/$tdir
12255
12256         run_acl_subtest cp $ACLBIN $ACLDMN $ACLGRP
12257         run_acl_subtest getfacl-noacl $ACLBIN $ACLDMN $ACLGRP
12258         run_acl_subtest misc $ACLBIN $ACLDMN $ACLGRP
12259         run_acl_subtest permissions $ACLBIN $ACLDMN $ACLGRP
12260         # LU-1482 mdd: Setting xattr are properly checked with and without ACLs
12261         # CentOS7- uses nobody=99, while newer distros use nobody=65534
12262         if ! id -u $ACLNBD ||
12263            (( $(id -u nobody) != $(do_facet mds1 id -u nobody) )); then
12264                 ACLNBD="nfsnobody"
12265                 if ! id -u $ACLNBD; then
12266                         ACLNBD=""
12267                 fi
12268         fi
12269         if [[ -n "$ACLNBD" ]] && ! getent group $ACLNBD; then
12270                 add_group $(id -u $ACLNBD) $ACLNBD
12271                 if ! getent group $ACLNBD; then
12272                         ACLNBD=""
12273                 fi
12274         fi
12275         if (( $MDS1_VERSION > $(version_code 2.8.55) )) &&
12276            [[ -n "$ACLNBD" ]] && which setfattr; then
12277                 run_acl_subtest permissions_xattr \
12278                         $ACLBIN $ACLDMN $ACLGRP $ACLNBD
12279         elif [[ -z "$ACLNBD" ]]; then
12280                 echo "skip 'permission_xattr' test - missing 'nobody' user/grp"
12281         else
12282                 echo "skip 'permission_xattr' test - missing setfattr command"
12283         fi
12284         run_acl_subtest setfacl $ACLBIN $ACLDMN $ACLGRP
12285
12286         # inheritance test got from HP
12287         cp $LUSTRE/tests/acl/make-tree . || error "cannot copy make-tree"
12288         chmod +x make-tree || error "chmod +x failed"
12289         run_acl_subtest inheritance $ACLBIN $ACLDMN $ACLGRP
12290         rm -f make-tree
12291
12292         echo "LU-974 ignore umask when acl is enabled..."
12293         run_acl_subtest 974 $ACLBIN $ACLDMN $ACLGRP
12294         if [ $MDSCOUNT -ge 2 ]; then
12295                 run_acl_subtest 974_remote $ACLBIN $ACLDMN $ACLGRP
12296         fi
12297
12298         echo "LU-2561 newly created file is same size as directory..."
12299         if [ "$mds1_FSTYPE" != "zfs" ]; then
12300                 run_acl_subtest 2561 $ACLBIN $ACLDMN $ACLGRP
12301         else
12302                 run_acl_subtest 2561_zfs $ACLBIN $ACLDMN $ACLGRP
12303         fi
12304
12305         run_acl_subtest 4924 $ACLBIN $ACLDMN $ACLGRP
12306
12307         cd $SAVE_PWD
12308         umask $SAVE_UMASK
12309
12310         for num in $(seq $MDSCOUNT); do
12311                 if [ "${identity_old[$num]}" = 1 ]; then
12312                         switch_identity $num false || identity_old[$num]=$?
12313                 fi
12314         done
12315 }
12316 run_test 103a "acl test"
12317
12318 test_103b() {
12319         declare -a pids
12320         local U
12321
12322         stack_trap "rm -f $DIR/$tfile.*"
12323         for U in {0..511}; do
12324                 {
12325                 local O=$(printf "%04o" $U)
12326
12327                 umask $(printf "%04o" $((511 ^ $O)))
12328                 $LFS setstripe -c 1 $DIR/$tfile.s$O
12329                 local S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.s$O))
12330
12331                 (( $S == ($O & 0666) )) ||
12332                         error "lfs setstripe $DIR/$tfile.s$O '$S' != '$O'"
12333
12334                 $LFS setstripe -E16M -c 1 -E1G -S4M $DIR/$tfile.p$O
12335                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.p$O))
12336                 (( $S == ($O & 0666) )) ||
12337                         error "lfs setstripe -E $DIR/$tfile.p$O '$S' != '$O'"
12338
12339                 $LFS setstripe -N2 -c 1 $DIR/$tfile.m$O
12340                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.m$O))
12341                 (( $S == ($O & 0666) )) ||
12342                         error "lfs setstripe -N2 $DIR/$tfile.m$O '$S' != '$O'"
12343                 rm -f $DIR/$tfile.[smp]$0
12344                 } &
12345                 local pid=$!
12346
12347                 # limit the concurrently running threads to 64. LU-11878
12348                 local idx=$((U % 64))
12349                 [ -z "${pids[idx]}" ] || wait ${pids[idx]}
12350                 pids[idx]=$pid
12351         done
12352         wait
12353 }
12354 run_test 103b "umask lfs setstripe"
12355
12356 test_103c() {
12357         mkdir -p $DIR/$tdir
12358         cp -rp $DIR/$tdir $DIR/$tdir.bak
12359
12360         [ -n "$(getfattr -d -m. $DIR/$tdir | grep posix_acl_default)" ] &&
12361                 error "$DIR/$tdir shouldn't contain default ACL"
12362         [ -n "$(getfattr -d -m. $DIR/$tdir.bak | grep posix_acl_default)" ] &&
12363                 error "$DIR/$tdir.bak shouldn't contain default ACL"
12364         true
12365 }
12366 run_test 103c "'cp -rp' won't set empty acl"
12367
12368 test_103e() {
12369         local numacl
12370         local fileacl
12371         local saved_debug=$($LCTL get_param -n debug)
12372
12373         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
12374                 skip "MDS needs to be at least 2.14.52"
12375
12376         large_xattr_enabled || skip_env "ea_inode feature disabled"
12377
12378         mkdir -p $DIR/$tdir
12379         # add big LOV EA to cause reply buffer overflow earlier
12380         $LFS setstripe -C 1000 $DIR/$tdir
12381         lctl set_param mdc.*-mdc*.stats=clear
12382
12383         $LCTL set_param debug=0
12384         stack_trap "$LCTL set_param debug=\"$saved_debug\"" EXIT
12385         stack_trap "$LCTL get_param mdc.*-mdc*.stats" EXIT
12386
12387         # add a large number of default ACLs (expect 8000+ for 2.13+)
12388         for U in {2..7000}; do
12389                 setfacl -d -m user:$U:rwx $DIR/$tdir ||
12390                         error "Able to add just $U default ACLs"
12391         done
12392         numacl=$(getfacl $DIR/$tdir |& grep -c "default:user")
12393         echo "$numacl default ACLs created"
12394
12395         stat $DIR/$tdir || error "Cannot stat directory"
12396         # check file creation
12397         touch $DIR/$tdir/$tfile ||
12398                 error "failed to create $tfile with $numacl default ACLs"
12399         stat $DIR/$tdir/$tfile  || error "Cannot stat file"
12400         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
12401         echo "$fileacl ACLs were inherited"
12402         (( $fileacl == $numacl )) ||
12403                 error "Not all default ACLs were inherited: $numacl != $fileacl"
12404         # check that new ACLs creation adds new ACLs to inherited ACLs
12405         setfacl -m user:19000:rwx $DIR/$tdir/$tfile ||
12406                 error "Cannot set new ACL"
12407         numacl=$((numacl + 1))
12408         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
12409         (( $fileacl == $numacl )) ||
12410                 error "failed to add new ACL: $fileacl != $numacl as expected"
12411         # adds more ACLs to a file to reach their maximum at 8000+
12412         numacl=0
12413         for U in {20000..25000}; do
12414                 setfacl -m user:$U:rwx $DIR/$tdir/$tfile || break
12415                 numacl=$((numacl + 1))
12416         done
12417         echo "Added $numacl more ACLs to the file"
12418         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
12419         echo "Total $fileacl ACLs in file"
12420         stat $DIR/$tdir/$tfile > /dev/null || error "Cannot stat file"
12421         rm -f $DIR/$tdir/$tfile || error "Cannot remove file"
12422         rmdir $DIR/$tdir || error "Cannot remove directory"
12423 }
12424 run_test 103e "inheritance of big amount of default ACLs"
12425
12426 test_103f() {
12427         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
12428                 skip "MDS needs to be at least 2.14.51"
12429
12430         large_xattr_enabled || skip_env "ea_inode feature disabled"
12431
12432         # enable changelog to consume more internal MDD buffers
12433         changelog_register
12434
12435         mkdir -p $DIR/$tdir
12436         # add big LOV EA
12437         $LFS setstripe -C 1000 $DIR/$tdir
12438         setfacl -d -m user:$U:rwx $DIR/$tdir || error "Cannot add default ACLs"
12439         mkdir $DIR/$tdir/inherited || error "failed to create subdirectory"
12440         rmdir $DIR/$tdir/inherited || error "Cannot remove subdirectory"
12441         rmdir $DIR/$tdir || error "Cannot remove directory"
12442 }
12443 run_test 103f "changelog doesn't interfere with default ACLs buffers"
12444
12445 test_104a() {
12446         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12447
12448         touch $DIR/$tfile
12449         lfs df || error "lfs df failed"
12450         lfs df -ih || error "lfs df -ih failed"
12451         lfs df -h $DIR || error "lfs df -h $DIR failed"
12452         lfs df -i $DIR || error "lfs df -i $DIR failed"
12453         lfs df $DIR/$tfile || error "lfs df $DIR/$tfile failed"
12454         lfs df -ih $DIR/$tfile || error "lfs df -ih $DIR/$tfile failed"
12455
12456         local OSC=$(lctl dl | grep OST0000-osc-[^M] | awk '{ print $4 }')
12457         lctl --device %$OSC deactivate
12458         lfs df || error "lfs df with deactivated OSC failed"
12459         lctl --device %$OSC activate
12460         # wait the osc back to normal
12461         wait_osc_import_ready client ost
12462
12463         lfs df || error "lfs df with reactivated OSC failed"
12464         rm -f $DIR/$tfile
12465 }
12466 run_test 104a "lfs df [-ih] [path] test ========================="
12467
12468 test_104b() {
12469         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12470         [ $RUNAS_ID -eq $UID ] &&
12471                 skip_env "RUNAS_ID = UID = $UID -- skipping"
12472
12473         denied_cnt=$(($($RUNAS $LFS check servers 2>&1 |
12474                         grep "Permission denied" | wc -l)))
12475         if [ $denied_cnt -ne 0 ]; then
12476                 error "lfs check servers test failed"
12477         fi
12478 }
12479 run_test 104b "$RUNAS lfs check servers test ===================="
12480
12481 #
12482 # Verify $1 is within range of $2.
12483 # Success when $1 is within range. That is, when $1 is >= 2% of $2 and
12484 # $1 is <= 2% of $2. Else Fail.
12485 #
12486 value_in_range() {
12487         # Strip all units (M, G, T)
12488         actual=$(echo $1 | tr -d A-Z)
12489         expect=$(echo $2 | tr -d A-Z)
12490
12491         expect_lo=$(($expect * 98 / 100)) # 2% below
12492         expect_hi=$(($expect * 102 / 100)) # 2% above
12493
12494         # permit 2% drift above and below
12495         (( $actual >= $expect_lo && $actual <= $expect_hi ))
12496 }
12497
12498 test_104c() {
12499         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12500         [ "$ost1_FSTYPE" == "zfs" ] || skip "zfs only test"
12501
12502         local ost_param="osd-zfs.$FSNAME-OST0000."
12503         local mdt_param="osd-zfs.$FSNAME-MDT0000."
12504         local ofacets=$(get_facets OST)
12505         local mfacets=$(get_facets MDS)
12506         local saved_ost_blocks=
12507         local saved_mdt_blocks=
12508
12509         echo "Before recordsize change"
12510         lfs_df=($($LFS df -h | grep "filesystem_summary:"))
12511         df=($(df -h | grep "$MOUNT"$))
12512
12513         # For checking.
12514         echo "lfs output : ${lfs_df[*]}"
12515         echo "df  output : ${df[*]}"
12516
12517         for facet in ${ofacets//,/ }; do
12518                 if [ -z $saved_ost_blocks ]; then
12519                         saved_ost_blocks=$(do_facet $facet \
12520                                 lctl get_param -n $ost_param.blocksize)
12521                         echo "OST Blocksize: $saved_ost_blocks"
12522                 fi
12523                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
12524                 do_facet $facet zfs set recordsize=32768 $ost
12525         done
12526
12527         # BS too small. Sufficient for functional testing.
12528         for facet in ${mfacets//,/ }; do
12529                 if [ -z $saved_mdt_blocks ]; then
12530                         saved_mdt_blocks=$(do_facet $facet \
12531                                 lctl get_param -n $mdt_param.blocksize)
12532                         echo "MDT Blocksize: $saved_mdt_blocks"
12533                 fi
12534                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
12535                 do_facet $facet zfs set recordsize=32768 $mdt
12536         done
12537
12538         # Give new values chance to reflect change
12539         sleep 2
12540
12541         echo "After recordsize change"
12542         lfs_df_after=($($LFS df -h | grep "filesystem_summary:"))
12543         df_after=($(df -h | grep "$MOUNT"$))
12544
12545         # For checking.
12546         echo "lfs output : ${lfs_df_after[*]}"
12547         echo "df  output : ${df_after[*]}"
12548
12549         # Verify lfs df
12550         value_in_range ${lfs_df_after[1]%.*} ${lfs_df[1]%.*} ||
12551                 error "lfs_df bytes: ${lfs_df_after[1]%.*} != ${lfs_df[1]%.*}"
12552         value_in_range ${lfs_df_after[2]%.*} ${lfs_df[2]%.*} ||
12553                 error "lfs_df used: ${lfs_df_after[2]%.*} != ${lfs_df[2]%.*}"
12554         value_in_range ${lfs_df_after[3]%.*} ${lfs_df[3]%.*} ||
12555                 error "lfs_df avail: ${lfs_df_after[3]%.*} != ${lfs_df[3]%.*}"
12556
12557         # Verify df
12558         value_in_range ${df_after[1]%.*} ${df[1]%.*} ||
12559                 error "df bytes: ${df_after[1]%.*} != ${df[1]%.*}"
12560         value_in_range ${df_after[2]%.*} ${df[2]%.*} ||
12561                 error "df used: ${df_after[2]%.*} != ${df[2]%.*}"
12562         value_in_range ${df_after[3]%.*} ${df[3]%.*} ||
12563                 error "df avail: ${df_after[3]%.*} != ${df[3]%.*}"
12564
12565         # Restore MDT recordize back to original
12566         for facet in ${mfacets//,/ }; do
12567                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
12568                 do_facet $facet zfs set recordsize=$saved_mdt_blocks $mdt
12569         done
12570
12571         # Restore OST recordize back to original
12572         for facet in ${ofacets//,/ }; do
12573                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
12574                 do_facet $facet zfs set recordsize=$saved_ost_blocks $ost
12575         done
12576
12577         return 0
12578 }
12579 run_test 104c "Verify df vs lfs_df stays same after recordsize change"
12580
12581 test_104d() {
12582         (( $RUNAS_ID != $UID )) ||
12583                 skip_env "RUNAS_ID = UID = $UID -- skipping"
12584
12585         (( $CLIENT_VERSION >= $(version_code 2.15.51) )) ||
12586                 skip "lustre version doesn't support lctl dl with non-root"
12587
12588         # debugfs only allows root users to access files, so the
12589         # previous move of the "devices" file to debugfs broke
12590         # "lctl dl" for non-root users. The LU-9680 Netlink
12591         # interface again allows non-root users to list devices.
12592         [ "$($RUNAS $LCTL dl | wc -l)" -ge 3 ] ||
12593                 error "lctl dl doesn't work for non root"
12594
12595         ost_count="$($RUNAS $LCTL dl | grep $FSNAME-OST* | wc -l)"
12596         [ "$ost_count" -eq $OSTCOUNT ]  ||
12597                 error "lctl dl reports wrong number of OST devices"
12598
12599         mdt_count="$($RUNAS $LCTL dl | grep $FSNAME-MDT* | wc -l)"
12600         [ "$mdt_count" -eq $MDSCOUNT ]  ||
12601                 error "lctl dl reports wrong number of MDT devices"
12602 }
12603 run_test 104d "$RUNAS lctl dl test"
12604
12605 test_105a() {
12606         # doesn't work on 2.4 kernels
12607         touch $DIR/$tfile
12608         if $(flock_is_enabled); then
12609                 flocks_test 1 on -f $DIR/$tfile || error "fail flock on"
12610         else
12611                 flocks_test 1 off -f $DIR/$tfile || error "fail flock off"
12612         fi
12613         rm -f $DIR/$tfile
12614 }
12615 run_test 105a "flock when mounted without -o flock test ========"
12616
12617 test_105b() {
12618         touch $DIR/$tfile
12619         if $(flock_is_enabled); then
12620                 flocks_test 1 on -c $DIR/$tfile || error "fail flock on"
12621         else
12622                 flocks_test 1 off -c $DIR/$tfile || error "fail flock off"
12623         fi
12624         rm -f $DIR/$tfile
12625 }
12626 run_test 105b "fcntl when mounted without -o flock test ========"
12627
12628 test_105c() {
12629         touch $DIR/$tfile
12630         if $(flock_is_enabled); then
12631                 flocks_test 1 on -l $DIR/$tfile || error "fail flock on"
12632         else
12633                 flocks_test 1 off -l $DIR/$tfile || error "fail flock off"
12634         fi
12635         rm -f $DIR/$tfile
12636 }
12637 run_test 105c "lockf when mounted without -o flock test"
12638
12639 test_105d() { # bug 15924
12640         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12641
12642         test_mkdir $DIR/$tdir
12643         flock_is_enabled || skip_env "mount w/o flock enabled"
12644         #define OBD_FAIL_LDLM_CP_CB_WAIT  0x315
12645         $LCTL set_param fail_loc=0x80000315
12646         flocks_test 2 $DIR/$tdir
12647 }
12648 run_test 105d "flock race (should not freeze) ========"
12649
12650 test_105e() { # bug 22660 && 22040
12651         flock_is_enabled || skip_env "mount w/o flock enabled"
12652
12653         touch $DIR/$tfile
12654         flocks_test 3 $DIR/$tfile
12655 }
12656 run_test 105e "Two conflicting flocks from same process"
12657
12658 test_106() { #bug 10921
12659         test_mkdir $DIR/$tdir
12660         $DIR/$tdir && error "exec $DIR/$tdir succeeded"
12661         chmod 777 $DIR/$tdir || error "chmod $DIR/$tdir failed"
12662 }
12663 run_test 106 "attempt exec of dir followed by chown of that dir"
12664
12665 test_107() {
12666         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12667
12668         CDIR=`pwd`
12669         local file=core
12670
12671         cd $DIR
12672         rm -f $file
12673
12674         local save_pattern=$(sysctl -n kernel.core_pattern)
12675         local save_uses_pid=$(sysctl -n kernel.core_uses_pid)
12676         sysctl -w kernel.core_pattern=$file
12677         sysctl -w kernel.core_uses_pid=0
12678
12679         ulimit -c unlimited
12680         sleep 60 &
12681         SLEEPPID=$!
12682
12683         sleep 1
12684
12685         kill -s 11 $SLEEPPID
12686         wait $SLEEPPID
12687         if [ -e $file ]; then
12688                 size=`stat -c%s $file`
12689                 [ $size -eq 0 ] && error "Fail to create core file $file"
12690         else
12691                 error "Fail to create core file $file"
12692         fi
12693         rm -f $file
12694         sysctl -w kernel.core_pattern=$save_pattern
12695         sysctl -w kernel.core_uses_pid=$save_uses_pid
12696         cd $CDIR
12697 }
12698 run_test 107 "Coredump on SIG"
12699
12700 test_110() {
12701         test_mkdir $DIR/$tdir
12702         test_mkdir $DIR/$tdir/$(str_repeat 'a' 255)
12703         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/$(str_repeat 'b' 256) &&
12704                 error "mkdir with 256 char should fail, but did not"
12705         touch $DIR/$tdir/$(str_repeat 'x' 255) ||
12706                 error "create with 255 char failed"
12707         touch $DIR/$tdir/$(str_repeat 'y' 256) &&
12708                 error "create with 256 char should fail, but did not"
12709
12710         ls -l $DIR/$tdir
12711         rm -rf $DIR/$tdir
12712 }
12713 run_test 110 "filename length checking"
12714
12715 test_116a() { # was previously test_116()
12716         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12717         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12718         remote_mds_nodsh && skip "remote MDS with nodsh"
12719
12720         echo -n "Free space priority "
12721         do_facet $SINGLEMDS lctl get_param -n lo[vd].*-mdtlov.qos_prio_free |
12722                 head -n1
12723         declare -a AVAIL
12724         free_min_max
12725
12726         [ $MINV -eq 0 ] && skip "no free space in OST$MINI, skip"
12727         [ $MINV -gt 10000000 ] && skip "too much free space in OST$MINI, skip"
12728         stack_trap simple_cleanup_common
12729
12730         # Check if we need to generate uneven OSTs
12731         test_mkdir -p $DIR/$tdir/OST${MINI}
12732         local FILL=$((MINV / 4))
12733         local DIFF=$((MAXV - MINV))
12734         local DIFF2=$((DIFF * 100 / MINV))
12735
12736         local threshold=$(do_facet $SINGLEMDS \
12737                 lctl get_param -n *.*MDT0000-mdtlov.qos_threshold_rr | head -n1)
12738         threshold=${threshold%%%}
12739         echo -n "Check for uneven OSTs: "
12740         echo -n "diff=${DIFF}KB (${DIFF2}%) must be > ${threshold}% ..."
12741
12742         if [[ $DIFF2 -gt $threshold ]]; then
12743                 echo "ok"
12744                 echo "Don't need to fill OST$MINI"
12745         else
12746                 # generate uneven OSTs. Write 2% over the QOS threshold value
12747                 echo "no"
12748                 DIFF=$((threshold - DIFF2 + 2))
12749                 DIFF2=$((MINV * DIFF / 100))
12750                 echo "Fill $DIFF% remaining space in OST$MINI with ${DIFF2}KB"
12751                 $LFS setstripe -i $MINI -c 1 $DIR/$tdir/OST${MINI} ||
12752                         error "setstripe failed"
12753                 DIFF=$((DIFF2 / 2048))
12754                 i=0
12755                 while [ $i -lt $DIFF ]; do
12756                         i=$((i + 1))
12757                         dd if=/dev/zero of=$DIR/$tdir/OST${MINI}/$tfile-$i \
12758                                 bs=2M count=1 2>/dev/null
12759                         echo -n .
12760                 done
12761                 echo .
12762                 sync
12763                 sleep_maxage
12764                 free_min_max
12765         fi
12766
12767         DIFF=$((MAXV - MINV))
12768         DIFF2=$((DIFF * 100 / MINV))
12769         echo -n "diff=$DIFF=$DIFF2% must be > $threshold% for QOS mode..."
12770         if [ $DIFF2 -gt $threshold ]; then
12771                 echo "ok"
12772         else
12773                 skip "QOS imbalance criteria not met"
12774         fi
12775
12776         MINI1=$MINI
12777         MINV1=$MINV
12778         MAXI1=$MAXI
12779         MAXV1=$MAXV
12780
12781         # now fill using QOS
12782         $LFS setstripe -c 1 $DIR/$tdir
12783         FILL=$((FILL / 200))
12784         if [ $FILL -gt 600 ]; then
12785                 FILL=600
12786         fi
12787         echo "writing $FILL files to QOS-assigned OSTs"
12788         i=0
12789         while [ $i -lt $FILL ]; do
12790                 i=$((i + 1))
12791                 dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=200k \
12792                         count=1 2>/dev/null
12793                 echo -n .
12794         done
12795         echo "wrote $i 200k files"
12796         sync
12797         sleep_maxage
12798
12799         echo "Note: free space may not be updated, so measurements might be off"
12800         free_min_max
12801         DIFF2=$((MAXV - MINV))
12802         echo "free space delta: orig $DIFF final $DIFF2"
12803         [ $DIFF2 -gt $DIFF ] && echo "delta got worse!"
12804         DIFF=$((MINV1 - ${AVAIL[$MINI1]}))
12805         echo "Wrote ${DIFF}KB to smaller OST $MINI1"
12806         DIFF2=$((MAXV1 - ${AVAIL[$MAXI1]}))
12807         echo "Wrote ${DIFF2}KB to larger OST $MAXI1"
12808         if [[ $DIFF -gt 0 ]]; then
12809                 FILL=$((DIFF2 * 100 / DIFF - 100))
12810                 echo "Wrote ${FILL}% more data to larger OST $MAXI1"
12811         fi
12812
12813         # Figure out which files were written where
12814         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
12815                awk '/'$MINI1': / {print $2; exit}')
12816         echo $UUID
12817         MINC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
12818         echo "$MINC files created on smaller OST $MINI1"
12819         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
12820                awk '/'$MAXI1': / {print $2; exit}')
12821         echo $UUID
12822         MAXC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
12823         echo "$MAXC files created on larger OST $MAXI1"
12824         if [[ $MINC -gt 0 ]]; then
12825                 FILL=$((MAXC * 100 / MINC - 100))
12826                 echo "Wrote ${FILL}% more files to larger OST $MAXI1"
12827         fi
12828         [[ $MAXC -gt $MINC ]] ||
12829                 error_ignore LU-9 "stripe QOS didn't balance free space"
12830 }
12831 run_test 116a "stripe QOS: free space balance ==================="
12832
12833 test_116b() { # LU-2093
12834         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12835         remote_mds_nodsh && skip "remote MDS with nodsh"
12836
12837 #define OBD_FAIL_MDS_OSC_CREATE_FAIL     0x147
12838         local old_rr=$(do_facet $SINGLEMDS lctl get_param -n \
12839                        lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr | head -1)
12840         [ -z "$old_rr" ] && skip "no QOS"
12841         do_facet $SINGLEMDS lctl set_param \
12842                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=0
12843         mkdir -p $DIR/$tdir
12844         do_facet $SINGLEMDS lctl set_param fail_loc=0x147
12845         createmany -o $DIR/$tdir/f- 20 || error "can't create"
12846         do_facet $SINGLEMDS lctl set_param fail_loc=0
12847         rm -rf $DIR/$tdir
12848         do_facet $SINGLEMDS lctl set_param \
12849                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=$old_rr
12850 }
12851 run_test 116b "QoS shouldn't LBUG if not enough OSTs found on the 2nd pass"
12852
12853 test_117() # bug 10891
12854 {
12855         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12856
12857         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
12858         #define OBD_FAIL_OST_SETATTR_CREDITS 0x21e
12859         lctl set_param fail_loc=0x21e
12860         > $DIR/$tfile || error "truncate failed"
12861         lctl set_param fail_loc=0
12862         echo "Truncate succeeded."
12863         rm -f $DIR/$tfile
12864 }
12865 run_test 117 "verify osd extend =========="
12866
12867 NO_SLOW_RESENDCOUNT=4
12868 export OLD_RESENDCOUNT=""
12869 set_resend_count () {
12870         local PROC_RESENDCOUNT="osc.${FSNAME}-OST*-osc-*.resend_count"
12871         OLD_RESENDCOUNT=$(lctl get_param -n $PROC_RESENDCOUNT | head -n1)
12872         lctl set_param -n $PROC_RESENDCOUNT $1
12873         echo resend_count is set to $(lctl get_param -n $PROC_RESENDCOUNT)
12874 }
12875
12876 # for reduce test_118* time (b=14842)
12877 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
12878
12879 # Reset async IO behavior after error case
12880 reset_async() {
12881         FILE=$DIR/reset_async
12882
12883         # Ensure all OSCs are cleared
12884         $LFS setstripe -c -1 $FILE
12885         dd if=/dev/zero of=$FILE bs=64k count=$OSTCOUNT
12886         sync
12887         rm $FILE
12888 }
12889
12890 test_118a() #bug 11710
12891 {
12892         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12893
12894         reset_async
12895
12896         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12897         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12898         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
12899
12900         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12901                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12902                 return 1;
12903         fi
12904         rm -f $DIR/$tfile
12905 }
12906 run_test 118a "verify O_SYNC works =========="
12907
12908 test_118b()
12909 {
12910         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12911         remote_ost_nodsh && skip "remote OST with nodsh"
12912
12913         reset_async
12914
12915         #define OBD_FAIL_SRV_ENOENT 0x217
12916         set_nodes_failloc "$(osts_nodes)" 0x217
12917         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12918         RC=$?
12919         set_nodes_failloc "$(osts_nodes)" 0
12920         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12921         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12922                     grep -c writeback)
12923
12924         if [[ $RC -eq 0 ]]; then
12925                 error "Must return error due to dropped pages, rc=$RC"
12926                 return 1;
12927         fi
12928
12929         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12930                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12931                 return 1;
12932         fi
12933
12934         echo "Dirty pages not leaked on ENOENT"
12935
12936         # Due to the above error the OSC will issue all RPCs syncronously
12937         # until a subsequent RPC completes successfully without error.
12938         $MULTIOP $DIR/$tfile Ow4096yc
12939         rm -f $DIR/$tfile
12940
12941         return 0
12942 }
12943 run_test 118b "Reclaim dirty pages on fatal error =========="
12944
12945 test_118c()
12946 {
12947         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12948
12949         # for 118c, restore the original resend count, LU-1940
12950         [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] &&
12951                                 set_resend_count $OLD_RESENDCOUNT
12952         remote_ost_nodsh && skip "remote OST with nodsh"
12953
12954         reset_async
12955
12956         #define OBD_FAIL_OST_EROFS               0x216
12957         set_nodes_failloc "$(osts_nodes)" 0x216
12958
12959         # multiop should block due to fsync until pages are written
12960         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
12961         MULTIPID=$!
12962         sleep 1
12963
12964         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
12965                 error "Multiop failed to block on fsync, pid=$MULTIPID"
12966         fi
12967
12968         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12969                     grep -c writeback)
12970         if [[ $WRITEBACK -eq 0 ]]; then
12971                 error "No page in writeback, writeback=$WRITEBACK"
12972         fi
12973
12974         set_nodes_failloc "$(osts_nodes)" 0
12975         wait $MULTIPID
12976         RC=$?
12977         if [[ $RC -ne 0 ]]; then
12978                 error "Multiop fsync failed, rc=$RC"
12979         fi
12980
12981         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12982         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12983                     grep -c writeback)
12984         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12985                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12986         fi
12987
12988         rm -f $DIR/$tfile
12989         echo "Dirty pages flushed via fsync on EROFS"
12990         return 0
12991 }
12992 run_test 118c "Fsync blocks on EROFS until dirty pages are flushed =========="
12993
12994 # continue to use small resend count to reduce test_118* time (b=14842)
12995 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
12996
12997 test_118d()
12998 {
12999         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13000         remote_ost_nodsh && skip "remote OST with nodsh"
13001
13002         reset_async
13003
13004         #define OBD_FAIL_OST_BRW_PAUSE_BULK
13005         set_nodes_failloc "$(osts_nodes)" 0x214
13006         # multiop should block due to fsync until pages are written
13007         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
13008         MULTIPID=$!
13009         sleep 1
13010
13011         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
13012                 error "Multiop failed to block on fsync, pid=$MULTIPID"
13013         fi
13014
13015         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13016                     grep -c writeback)
13017         if [[ $WRITEBACK -eq 0 ]]; then
13018                 error "No page in writeback, writeback=$WRITEBACK"
13019         fi
13020
13021         wait $MULTIPID || error "Multiop fsync failed, rc=$?"
13022         set_nodes_failloc "$(osts_nodes)" 0
13023
13024         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13025         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13026                     grep -c writeback)
13027         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13028                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13029         fi
13030
13031         rm -f $DIR/$tfile
13032         echo "Dirty pages gaurenteed flushed via fsync"
13033         return 0
13034 }
13035 run_test 118d "Fsync validation inject a delay of the bulk =========="
13036
13037 test_118f() {
13038         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13039
13040         reset_async
13041
13042         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
13043         lctl set_param fail_loc=0x8000040a
13044
13045         # Should simulate EINVAL error which is fatal
13046         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13047         RC=$?
13048         if [[ $RC -eq 0 ]]; then
13049                 error "Must return error due to dropped pages, rc=$RC"
13050         fi
13051
13052         lctl set_param fail_loc=0x0
13053
13054         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
13055         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13056         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13057                     grep -c writeback)
13058         if [[ $LOCKED -ne 0 ]]; then
13059                 error "Locked pages remain in cache, locked=$LOCKED"
13060         fi
13061
13062         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13063                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13064         fi
13065
13066         rm -f $DIR/$tfile
13067         echo "No pages locked after fsync"
13068
13069         reset_async
13070         return 0
13071 }
13072 run_test 118f "Simulate unrecoverable OSC side error =========="
13073
13074 test_118g() {
13075         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13076
13077         reset_async
13078
13079         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
13080         lctl set_param fail_loc=0x406
13081
13082         # simulate local -ENOMEM
13083         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13084         RC=$?
13085
13086         lctl set_param fail_loc=0
13087         if [[ $RC -eq 0 ]]; then
13088                 error "Must return error due to dropped pages, rc=$RC"
13089         fi
13090
13091         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
13092         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13093         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13094                         grep -c writeback)
13095         if [[ $LOCKED -ne 0 ]]; then
13096                 error "Locked pages remain in cache, locked=$LOCKED"
13097         fi
13098
13099         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13100                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13101         fi
13102
13103         rm -f $DIR/$tfile
13104         echo "No pages locked after fsync"
13105
13106         reset_async
13107         return 0
13108 }
13109 run_test 118g "Don't stay in wait if we got local -ENOMEM  =========="
13110
13111 test_118h() {
13112         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13113         remote_ost_nodsh && skip "remote OST with nodsh"
13114
13115         reset_async
13116
13117         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
13118         set_nodes_failloc "$(osts_nodes)" 0x20e
13119         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
13120         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13121         RC=$?
13122
13123         set_nodes_failloc "$(osts_nodes)" 0
13124         if [[ $RC -eq 0 ]]; then
13125                 error "Must return error due to dropped pages, rc=$RC"
13126         fi
13127
13128         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
13129         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13130         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13131                     grep -c writeback)
13132         if [[ $LOCKED -ne 0 ]]; then
13133                 error "Locked pages remain in cache, locked=$LOCKED"
13134         fi
13135
13136         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13137                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13138         fi
13139
13140         rm -f $DIR/$tfile
13141         echo "No pages locked after fsync"
13142
13143         return 0
13144 }
13145 run_test 118h "Verify timeout in handling recoverables errors  =========="
13146
13147 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
13148
13149 test_118i() {
13150         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13151         remote_ost_nodsh && skip "remote OST with nodsh"
13152
13153         reset_async
13154
13155         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
13156         set_nodes_failloc "$(osts_nodes)" 0x20e
13157
13158         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
13159         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
13160         PID=$!
13161         sleep 5
13162         set_nodes_failloc "$(osts_nodes)" 0
13163
13164         wait $PID
13165         RC=$?
13166         if [[ $RC -ne 0 ]]; then
13167                 error "got error, but should be not, rc=$RC"
13168         fi
13169
13170         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
13171         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13172         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
13173         if [[ $LOCKED -ne 0 ]]; then
13174                 error "Locked pages remain in cache, locked=$LOCKED"
13175         fi
13176
13177         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13178                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13179         fi
13180
13181         rm -f $DIR/$tfile
13182         echo "No pages locked after fsync"
13183
13184         return 0
13185 }
13186 run_test 118i "Fix error before timeout in recoverable error  =========="
13187
13188 [ "$SLOW" = "no" ] && set_resend_count 4
13189
13190 test_118j() {
13191         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13192         remote_ost_nodsh && skip "remote OST with nodsh"
13193
13194         reset_async
13195
13196         #define OBD_FAIL_OST_BRW_WRITE_BULK2     0x220
13197         set_nodes_failloc "$(osts_nodes)" 0x220
13198
13199         # return -EIO from OST
13200         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13201         RC=$?
13202         set_nodes_failloc "$(osts_nodes)" 0x0
13203         if [[ $RC -eq 0 ]]; then
13204                 error "Must return error due to dropped pages, rc=$RC"
13205         fi
13206
13207         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
13208         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13209         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
13210         if [[ $LOCKED -ne 0 ]]; then
13211                 error "Locked pages remain in cache, locked=$LOCKED"
13212         fi
13213
13214         # in recoverable error on OST we want resend and stay until it finished
13215         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13216                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13217         fi
13218
13219         rm -f $DIR/$tfile
13220         echo "No pages locked after fsync"
13221
13222         return 0
13223 }
13224 run_test 118j "Simulate unrecoverable OST side error =========="
13225
13226 test_118k()
13227 {
13228         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13229         remote_ost_nodsh && skip "remote OSTs with nodsh"
13230
13231         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
13232         set_nodes_failloc "$(osts_nodes)" 0x20e
13233         test_mkdir $DIR/$tdir
13234
13235         for ((i=0;i<10;i++)); do
13236                 (dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=1M count=10 || \
13237                         error "dd to $DIR/$tdir/$tfile-$i failed" )&
13238                 SLEEPPID=$!
13239                 sleep 0.500s
13240                 kill $SLEEPPID
13241                 wait $SLEEPPID
13242         done
13243
13244         set_nodes_failloc "$(osts_nodes)" 0
13245         rm -rf $DIR/$tdir
13246 }
13247 run_test 118k "bio alloc -ENOMEM and IO TERM handling ========="
13248
13249 test_118l() # LU-646
13250 {
13251         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13252
13253         test_mkdir $DIR/$tdir
13254         $MULTIOP $DIR/$tdir Dy || error "fsync dir failed"
13255         rm -rf $DIR/$tdir
13256 }
13257 run_test 118l "fsync dir"
13258
13259 test_118m() # LU-3066
13260 {
13261         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13262
13263         test_mkdir $DIR/$tdir
13264         $MULTIOP $DIR/$tdir DY || error "fdatasync dir failed"
13265         rm -rf $DIR/$tdir
13266 }
13267 run_test 118m "fdatasync dir ========="
13268
13269 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
13270
13271 test_118n()
13272 {
13273         local begin
13274         local end
13275
13276         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13277         remote_ost_nodsh && skip "remote OSTs with nodsh"
13278
13279         # Sleep to avoid a cached response.
13280         #define OBD_STATFS_CACHE_SECONDS 1
13281         sleep 2
13282
13283         # Inject a 10 second delay in the OST_STATFS handler.
13284         #define OBD_FAIL_OST_STATFS_DELAY 0x242
13285         set_nodes_failloc "$(osts_nodes)" 0x242
13286
13287         begin=$SECONDS
13288         stat --file-system $MOUNT > /dev/null
13289         end=$SECONDS
13290
13291         set_nodes_failloc "$(osts_nodes)" 0
13292
13293         if ((end - begin > 20)); then
13294             error "statfs took $((end - begin)) seconds, expected 10"
13295         fi
13296 }
13297 run_test 118n "statfs() sends OST_STATFS requests in parallel"
13298
13299 test_119a() # bug 11737
13300 {
13301         BSIZE=$((512 * 1024))
13302         directio write $DIR/$tfile 0 1 $BSIZE
13303         # We ask to read two blocks, which is more than a file size.
13304         # directio will indicate an error when requested and actual
13305         # sizes aren't equeal (a normal situation in this case) and
13306         # print actual read amount.
13307         NOB=`directio read $DIR/$tfile 0 2 $BSIZE | awk '/error/ {print $6}'`
13308         if [ "$NOB" != "$BSIZE" ]; then
13309                 error "read $NOB bytes instead of $BSIZE"
13310         fi
13311         rm -f $DIR/$tfile
13312 }
13313 run_test 119a "Short directIO read must return actual read amount"
13314
13315 test_119b() # bug 11737
13316 {
13317         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
13318
13319         $LFS setstripe -c 2 $DIR/$tfile || error "setstripe failed"
13320         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1 || error "dd failed"
13321         sync
13322         $MULTIOP $DIR/$tfile oO_RDONLY:O_DIRECT:r$((2048 * 1024)) ||
13323                 error "direct read failed"
13324         rm -f $DIR/$tfile
13325 }
13326 run_test 119b "Sparse directIO read must return actual read amount"
13327
13328 test_119c() # bug 13099
13329 {
13330         BSIZE=1048576
13331         directio write $DIR/$tfile 3 1 $BSIZE || error "direct write failed"
13332         directio readhole $DIR/$tfile 0 2 $BSIZE || error "reading hole failed"
13333         rm -f $DIR/$tfile
13334 }
13335 run_test 119c "Testing for direct read hitting hole"
13336
13337 test_120a() {
13338         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13339         remote_mds_nodsh && skip "remote MDS with nodsh"
13340         test_mkdir -i0 -c1 $DIR/$tdir
13341         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13342                 skip_env "no early lock cancel on server"
13343
13344         lru_resize_disable mdc
13345         lru_resize_disable osc
13346         cancel_lru_locks mdc
13347         # asynchronous object destroy at MDT could cause bl ast to client
13348         cancel_lru_locks osc
13349
13350         stat $DIR/$tdir > /dev/null
13351         can1=$(do_facet mds1 \
13352                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13353                awk '/ldlm_cancel/ {print $2}')
13354         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13355                awk '/ldlm_bl_callback/ {print $2}')
13356         test_mkdir -i0 -c1 $DIR/$tdir/d1
13357         can2=$(do_facet mds1 \
13358                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13359                awk '/ldlm_cancel/ {print $2}')
13360         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13361                awk '/ldlm_bl_callback/ {print $2}')
13362         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
13363         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
13364         lru_resize_enable mdc
13365         lru_resize_enable osc
13366 }
13367 run_test 120a "Early Lock Cancel: mkdir test"
13368
13369 test_120b() {
13370         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13371         remote_mds_nodsh && skip "remote MDS with nodsh"
13372         test_mkdir $DIR/$tdir
13373         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13374                 skip_env "no early lock cancel on server"
13375
13376         lru_resize_disable mdc
13377         lru_resize_disable osc
13378         cancel_lru_locks mdc
13379         stat $DIR/$tdir > /dev/null
13380         can1=$(do_facet $SINGLEMDS \
13381                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13382                awk '/ldlm_cancel/ {print $2}')
13383         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13384                awk '/ldlm_bl_callback/ {print $2}')
13385         touch $DIR/$tdir/f1
13386         can2=$(do_facet $SINGLEMDS \
13387                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13388                awk '/ldlm_cancel/ {print $2}')
13389         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13390                awk '/ldlm_bl_callback/ {print $2}')
13391         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
13392         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
13393         lru_resize_enable mdc
13394         lru_resize_enable osc
13395 }
13396 run_test 120b "Early Lock Cancel: create test"
13397
13398 test_120c() {
13399         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13400         remote_mds_nodsh && skip "remote MDS with nodsh"
13401         test_mkdir -i0 -c1 $DIR/$tdir
13402         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13403                 skip "no early lock cancel on server"
13404
13405         lru_resize_disable mdc
13406         lru_resize_disable osc
13407         test_mkdir -i0 -c1 $DIR/$tdir/d1
13408         test_mkdir -i0 -c1 $DIR/$tdir/d2
13409         touch $DIR/$tdir/d1/f1
13410         cancel_lru_locks mdc
13411         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 > /dev/null
13412         can1=$(do_facet mds1 \
13413                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13414                awk '/ldlm_cancel/ {print $2}')
13415         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13416                awk '/ldlm_bl_callback/ {print $2}')
13417         ln $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
13418         can2=$(do_facet mds1 \
13419                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13420                awk '/ldlm_cancel/ {print $2}')
13421         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13422                awk '/ldlm_bl_callback/ {print $2}')
13423         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
13424         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
13425         lru_resize_enable mdc
13426         lru_resize_enable osc
13427 }
13428 run_test 120c "Early Lock Cancel: link test"
13429
13430 test_120d() {
13431         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13432         remote_mds_nodsh && skip "remote MDS with nodsh"
13433         test_mkdir -i0 -c1 $DIR/$tdir
13434         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13435                 skip_env "no early lock cancel on server"
13436
13437         lru_resize_disable mdc
13438         lru_resize_disable osc
13439         touch $DIR/$tdir
13440         cancel_lru_locks mdc
13441         stat $DIR/$tdir > /dev/null
13442         can1=$(do_facet mds1 \
13443                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13444                awk '/ldlm_cancel/ {print $2}')
13445         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13446                awk '/ldlm_bl_callback/ {print $2}')
13447         chmod a+x $DIR/$tdir
13448         can2=$(do_facet mds1 \
13449                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13450                awk '/ldlm_cancel/ {print $2}')
13451         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13452                awk '/ldlm_bl_callback/ {print $2}')
13453         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
13454         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
13455         lru_resize_enable mdc
13456         lru_resize_enable osc
13457 }
13458 run_test 120d "Early Lock Cancel: setattr test"
13459
13460 test_120e() {
13461         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13462         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13463                 skip_env "no early lock cancel on server"
13464         remote_mds_nodsh && skip "remote MDS with nodsh"
13465
13466         local dlmtrace_set=false
13467
13468         test_mkdir -i0 -c1 $DIR/$tdir
13469         lru_resize_disable mdc
13470         lru_resize_disable osc
13471         ! $LCTL get_param debug | grep -q dlmtrace &&
13472                 $LCTL set_param debug=+dlmtrace && dlmtrace_set=true
13473         dd if=/dev/zero of=$DIR/$tdir/f1 count=1
13474         cancel_lru_locks mdc
13475         cancel_lru_locks osc
13476         dd if=$DIR/$tdir/f1 of=/dev/null
13477         stat $DIR/$tdir $DIR/$tdir/f1 > /dev/null
13478         # XXX client can not do early lock cancel of OST lock
13479         # during unlink (LU-4206), so cancel osc lock now.
13480         sleep 2
13481         cancel_lru_locks osc
13482         can1=$(do_facet mds1 \
13483                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13484                awk '/ldlm_cancel/ {print $2}')
13485         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13486                awk '/ldlm_bl_callback/ {print $2}')
13487         unlink $DIR/$tdir/f1
13488         sleep 5
13489         can2=$(do_facet mds1 \
13490                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13491                awk '/ldlm_cancel/ {print $2}')
13492         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13493                awk '/ldlm_bl_callback/ {print $2}')
13494         [ $can1 -ne $can2 ] && error "$((can2 - can1)) cancel RPC occured" &&
13495                 $LCTL dk $TMP/cancel.debug.txt
13496         [ $blk1 -ne $blk2 ] && error "$((blk2 - blk1)) blocking RPC occured" &&
13497                 $LCTL dk $TMP/blocking.debug.txt
13498         $dlmtrace_set && $LCTL set_param debug=-dlmtrace
13499         lru_resize_enable mdc
13500         lru_resize_enable osc
13501 }
13502 run_test 120e "Early Lock Cancel: unlink test"
13503
13504 test_120f() {
13505         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13506         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13507                 skip_env "no early lock cancel on server"
13508         remote_mds_nodsh && skip "remote MDS with nodsh"
13509
13510         test_mkdir -i0 -c1 $DIR/$tdir
13511         lru_resize_disable mdc
13512         lru_resize_disable osc
13513         test_mkdir -i0 -c1 $DIR/$tdir/d1
13514         test_mkdir -i0 -c1 $DIR/$tdir/d2
13515         dd if=/dev/zero of=$DIR/$tdir/d1/f1 count=1
13516         dd if=/dev/zero of=$DIR/$tdir/d2/f2 count=1
13517         cancel_lru_locks mdc
13518         cancel_lru_locks osc
13519         dd if=$DIR/$tdir/d1/f1 of=/dev/null
13520         dd if=$DIR/$tdir/d2/f2 of=/dev/null
13521         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2 > /dev/null
13522         # XXX client can not do early lock cancel of OST lock
13523         # during rename (LU-4206), so cancel osc lock now.
13524         sleep 2
13525         cancel_lru_locks osc
13526         can1=$(do_facet mds1 \
13527                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13528                awk '/ldlm_cancel/ {print $2}')
13529         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13530                awk '/ldlm_bl_callback/ {print $2}')
13531         mrename $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
13532         sleep 5
13533         can2=$(do_facet mds1 \
13534                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13535                awk '/ldlm_cancel/ {print $2}')
13536         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13537                awk '/ldlm_bl_callback/ {print $2}')
13538         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
13539         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
13540         lru_resize_enable mdc
13541         lru_resize_enable osc
13542 }
13543 run_test 120f "Early Lock Cancel: rename test"
13544
13545 test_120g() {
13546         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13547         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13548                 skip_env "no early lock cancel on server"
13549         remote_mds_nodsh && skip "remote MDS with nodsh"
13550
13551         lru_resize_disable mdc
13552         lru_resize_disable osc
13553         count=10000
13554         echo create $count files
13555         test_mkdir $DIR/$tdir
13556         cancel_lru_locks mdc
13557         cancel_lru_locks osc
13558         t0=$(date +%s)
13559
13560         can0=$(do_facet $SINGLEMDS \
13561                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13562                awk '/ldlm_cancel/ {print $2}')
13563         blk0=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13564                awk '/ldlm_bl_callback/ {print $2}')
13565         createmany -o $DIR/$tdir/f $count
13566         sync
13567         can1=$(do_facet $SINGLEMDS \
13568                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13569                awk '/ldlm_cancel/ {print $2}')
13570         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13571                awk '/ldlm_bl_callback/ {print $2}')
13572         t1=$(date +%s)
13573         echo total: $((can1-can0)) cancels, $((blk1-blk0)) blockings
13574         echo rm $count files
13575         rm -r $DIR/$tdir
13576         sync
13577         can2=$(do_facet $SINGLEMDS \
13578                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13579                awk '/ldlm_cancel/ {print $2}')
13580         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13581                awk '/ldlm_bl_callback/ {print $2}')
13582         t2=$(date +%s)
13583         echo total: $count removes in $((t2-t1))
13584         echo total: $((can2-can1)) cancels, $((blk2-blk1)) blockings
13585         sleep 2
13586         # wait for commitment of removal
13587         lru_resize_enable mdc
13588         lru_resize_enable osc
13589 }
13590 run_test 120g "Early Lock Cancel: performance test"
13591
13592 test_121() { #bug #10589
13593         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13594
13595         rm -rf $DIR/$tfile
13596         writes=$(LANG=C dd if=/dev/zero of=$DIR/$tfile count=1 2>&1 | awk -F '+' '/out$/ {print $1}')
13597 #define OBD_FAIL_LDLM_CANCEL_RACE        0x310
13598         lctl set_param fail_loc=0x310
13599         cancel_lru_locks osc > /dev/null
13600         reads=$(LANG=C dd if=$DIR/$tfile of=/dev/null 2>&1 | awk -F '+' '/in$/ {print $1}')
13601         lctl set_param fail_loc=0
13602         [[ $reads -eq $writes ]] ||
13603                 error "read $reads blocks, must be $writes blocks"
13604 }
13605 run_test 121 "read cancel race ========="
13606
13607 test_123a_base() { # was test 123, statahead(bug 11401)
13608         local lsx="$1"
13609
13610         ost_set_temp_seq_width_all $DATA_SEQ_MAX_WIDTH
13611
13612         SLOWOK=0
13613         if ! grep -q "processor.*: 1" /proc/cpuinfo; then
13614                 log "testing UP system. Performance may be lower than expected."
13615                 SLOWOK=1
13616         fi
13617         running_in_vm && SLOWOK=1
13618
13619         $LCTL set_param mdc.*.batch_stats=0
13620
13621         rm -rf $DIR/$tdir
13622         test_mkdir $DIR/$tdir
13623         NUMFREE=$(df -i -P $DIR | tail -n 1 | awk '{ print $4 }')
13624         [[ $NUMFREE -gt 100000 ]] && NUMFREE=100000 || NUMFREE=$((NUMFREE-1000))
13625         MULT=10
13626         for ((i=100, j=0; i<=$NUMFREE; j=$i, i=$((i * MULT)) )); do
13627                 createmany -o $DIR/$tdir/$tfile $j $((i - j))
13628
13629                 max=$(lctl get_param -n llite.*.statahead_max | head -n 1)
13630                 lctl set_param -n llite.*.statahead_max 0
13631                 lctl get_param llite.*.statahead_max
13632                 cancel_lru_locks mdc
13633                 cancel_lru_locks osc
13634                 stime=$(date +%s)
13635                 time $lsx $DIR/$tdir | wc -l
13636                 etime=$(date +%s)
13637                 delta=$((etime - stime))
13638                 log "$lsx $i files without statahead: $delta sec"
13639                 lctl set_param llite.*.statahead_max=$max
13640
13641                 swrong=$(lctl get_param -n llite.*.statahead_stats |
13642                          awk '/statahead.wrong:/ { print $NF }')
13643                 lctl get_param -n llite.*.statahead_max | grep '[0-9]'
13644                 cancel_lru_locks mdc
13645                 cancel_lru_locks osc
13646                 stime=$(date +%s)
13647                 time $lsx $DIR/$tdir | wc -l
13648                 etime=$(date +%s)
13649                 delta_sa=$((etime - stime))
13650                 log "$lsx $i files with statahead: $delta_sa sec"
13651                 lctl get_param -n llite.*.statahead_stats
13652                 ewrong=$(lctl get_param -n llite.*.statahead_stats |
13653                          awk '/statahead.wrong:/ { print $NF }')
13654
13655                 [[ $swrong -lt $ewrong ]] &&
13656                         log "statahead was stopped, maybe too many locks held!"
13657                 [[ $delta -eq 0 || $delta_sa -eq 0 ]] && continue
13658
13659                 if (( $delta_sa*100 > $delta*105 && $delta_sa > $delta+2)); then
13660                         max=$(lctl get_param -n llite.*.statahead_max |
13661                                 head -n 1)
13662                         lctl set_param -n llite.*.statahead_max 0
13663                         lctl get_param llite.*.statahead_max
13664                         cancel_lru_locks mdc
13665                         cancel_lru_locks osc
13666                         stime=$(date +%s)
13667                         time $lsx $DIR/$tdir | wc -l
13668                         etime=$(date +%s)
13669                         delta=$((etime - stime))
13670                         log "$lsx $i files again without statahead: $delta sec"
13671                         lctl set_param llite.*.statahead_max=$max
13672                         if (( $delta_sa*100 > delta*105 && delta_sa > delta+2 )); then
13673                                 if [ $SLOWOK -eq 0 ]; then
13674                                         error "$lsx $i files is slower with statahead!"
13675                                 else
13676                                         log "$lsx $i files is slower with statahead!"
13677                                 fi
13678                                 break
13679                         fi
13680                 fi
13681
13682                 [ $delta -gt 20 ] && break
13683                 [ $delta -gt 8 ] && MULT=$((50 / delta))
13684                 [ "$SLOW" = "no" -a $delta -gt 5 ] && break
13685         done
13686         log "$lsx done"
13687
13688         stime=$(date +%s)
13689         rm -r $DIR/$tdir
13690         sync
13691         etime=$(date +%s)
13692         delta=$((etime - stime))
13693         log "rm -r $DIR/$tdir/: $delta seconds"
13694         log "rm done"
13695         lctl get_param -n llite.*.statahead_stats
13696         $LCTL get_param mdc.*.batch_stats
13697 }
13698
13699 test_123aa() {
13700         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13701
13702         test_123a_base "ls -l"
13703 }
13704 run_test 123aa "verify statahead work"
13705
13706 test_123ab() {
13707         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13708
13709         statx_supported || skip_env "Test must be statx() syscall supported"
13710
13711         test_123a_base "$STATX -l"
13712 }
13713 run_test 123ab "verify statahead work by using statx"
13714
13715 test_123ac() {
13716         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13717
13718         statx_supported || skip_env "Test must be statx() syscall supported"
13719
13720         local rpcs_before
13721         local rpcs_after
13722         local agl_before
13723         local agl_after
13724
13725         cancel_lru_locks $OSC
13726         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
13727         agl_before=$($LCTL get_param -n llite.*.statahead_stats |
13728                      awk '/agl.total:/ { print $NF }')
13729         test_123a_base "$STATX -c \"%n %i %A %h %u %g %W %X %Z\" -D"
13730         test_123a_base "$STATX --cached=always -D"
13731         agl_after=$($LCTL get_param -n llite.*.statahead_stats |
13732                     awk '/agl.total:/ { print $NF }')
13733         [ $agl_before -eq $agl_after ] ||
13734                 error "Should not trigger AGL thread - $agl_before:$agl_after"
13735         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
13736         [ $rpcs_after -eq $rpcs_before ] ||
13737                 error "$STATX should not send glimpse RPCs to $OSC"
13738 }
13739 run_test 123ac "verify statahead work by using statx without glimpse RPCs"
13740
13741 test_batch_statahead() {
13742         local max=$1
13743         local batch_max=$2
13744         local num=10000
13745         local batch_rpcs
13746         local unbatch_rpcs
13747         local hit_total
13748
13749         echo -e "\nbatching: statahead_max=$max statahead_batch_max=$batch_max"
13750         $LCTL set_param mdc.*.batch_stats=0
13751         $LCTL set_param llite.*.statahead_max=$max
13752         $LCTL set_param llite.*.statahead_batch_max=$batch_max
13753         # Verify that batched statahead is faster than one without statahead
13754         test_123a_base "ls -l"
13755
13756         stack_trap "rm -rf $DIR/$tdir" EXIT
13757         mkdir $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
13758         createmany -o $DIR/$tdir/$tfile $num || error "failed to create files"
13759
13760         # unbatched statahead
13761         $LCTL set_param llite.*.statahead_batch_max=0
13762         $LCTL set_param llite.*.statahead_stats=clear
13763         $LCTL set_param mdc.*.stats=clear
13764         cancel_lru_locks mdc
13765         cancel_lru_locks osc
13766         time ls -l $DIR/$tdir | wc -l
13767         unbatch_rpcs=$(calc_stats mdc.*.stats ldlm_ibits_enqueue)
13768         sleep 2
13769         hit_total=$($LCTL get_param -n llite.*.statahead_stats |
13770                     awk '/hit.total:/ { print $NF }')
13771         # hit ratio should be larger than 75% (7500).
13772         (( $hit_total > 7500 )) ||
13773                 error "unbatched statahead hit count ($hit_total) is too low"
13774
13775         # batched statahead
13776         $LCTL set_param llite.*.statahead_batch_max=$batch_max
13777         $LCTL set_param llite.*.statahead_stats=clear
13778         $LCTL set_param mdc.*.batch_stats=clear
13779         $LCTL set_param mdc.*.stats=clear
13780         cancel_lru_locks mdc
13781         cancel_lru_locks osc
13782         time ls -l $DIR/$tdir | wc -l
13783         batch_rpcs=$(calc_stats mdc.*.stats mds_batch)
13784         # wait for statahead thread to quit and update statahead stats
13785         sleep 2
13786         hit_total=$($LCTL get_param -n llite.*.statahead_stats |
13787                     awk '/hit.total:/ { print $NF }')
13788         # hit ratio should be larger than 75% (7500).
13789         (( $hit_total > 7500 )) ||
13790                 error "batched statahead hit count ($hit_total) is too low"
13791
13792         echo "unbatched RPCs: $unbatch_rpcs, batched RPCs: $batch_rpcs"
13793         (( $unbatch_rpcs > $batch_rpcs )) ||
13794                 error "batched statahead does not reduce RPC count"
13795         $LCTL get_param mdc.*.batch_stats
13796 }
13797
13798 test_123ad() {
13799         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13800
13801         (( $MDS1_VERSION >= $(version_code 2.15.53) )) ||
13802                 skip "Need server version at least 2.15.53"
13803
13804         local max
13805         local batch_max
13806
13807         max=$($LCTL get_param -n llite.*.statahead_max | head -n 1)
13808         batch_max=$($LCTL get_param -n llite.*.statahead_batch_max | head -n 1)
13809
13810         stack_trap "$LCTL set_param llite.*.statahead_max=$max" EXIT
13811         stack_trap "$LCTL set_param llite.*.statahead_batch_max=$batch_max" EXIT
13812
13813         test_batch_statahead 32 32
13814         test_batch_statahead 2048 256
13815 }
13816 run_test 123ad "Verify batching statahead works correctly"
13817
13818 test_123b () { # statahead(bug 15027)
13819         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13820
13821         test_mkdir $DIR/$tdir
13822         createmany -o $DIR/$tdir/$tfile-%d 1000
13823
13824         cancel_lru_locks mdc
13825         cancel_lru_locks osc
13826
13827 #define OBD_FAIL_MDC_GETATTR_ENQUEUE     0x803
13828         lctl set_param fail_loc=0x80000803
13829         ls -lR $DIR/$tdir > /dev/null
13830         log "ls done"
13831         lctl set_param fail_loc=0x0
13832         lctl get_param -n llite.*.statahead_stats
13833         rm -r $DIR/$tdir
13834         sync
13835
13836 }
13837 run_test 123b "not panic with network error in statahead enqueue (bug 15027)"
13838
13839 test_123c() {
13840         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
13841
13842         test_mkdir -i 0 -c 1 $DIR/$tdir.0
13843         test_mkdir -i 1 -c 1 $DIR/$tdir.1
13844         touch $DIR/$tdir.1/{1..3}
13845         mv $DIR/$tdir.1/{1..3} $DIR/$tdir.0
13846
13847         remount_client $MOUNT
13848
13849         $MULTIOP $DIR/$tdir.0 Q
13850
13851         # let statahead to complete
13852         ls -l $DIR/$tdir.0 > /dev/null
13853
13854         testid=$(echo $TESTNAME | tr '_' ' ')
13855         dmesg | tac | sed "/$testid/,$ d" | grep "Can not initialize inode" &&
13856                 error "statahead warning" || true
13857 }
13858 run_test 123c "Can not initialize inode warning on DNE statahead"
13859
13860 test_123d() {
13861         local num=100
13862         local swrong
13863         local ewrong
13864
13865         test_mkdir -c -1 $DIR/$tdir || error "test_mkdir $DIR/$tdir failed"
13866         $LFS setdirstripe -D -c $MDSCOUNT $DIR/$tdir ||
13867                 error "setdirstripe $DIR/$tdir failed"
13868         createmany -d $DIR/$tdir/$tfile $num || error "createmany $num failed"
13869         remount_client $MOUNT
13870         $LCTL get_param llite.*.statahead_max
13871         $LCTL set_param llite.*.statahead_stats=0 ||
13872                 error "clear statahead_stats failed"
13873         swrong=$(lctl get_param -n llite.*.statahead_stats |
13874                  awk '/statahead.wrong:/ { print $NF }')
13875         ls -l $DIR/$tdir || error "ls -l $DIR/$tdir failed"
13876         # wait for statahead thread finished to update hit/miss stats.
13877         sleep 1
13878         $LCTL get_param -n llite.*.statahead_stats
13879         ewrong=$(lctl get_param -n llite.*.statahead_stats |
13880                  awk '/statahead.wrong:/ { print $NF }')
13881         (( $swrong == $ewrong )) ||
13882                 log "statahead was stopped, maybe too many locks held!"
13883 }
13884 run_test 123d "Statahead on striped directories works correctly"
13885
13886 test_123e() {
13887         local max
13888         local batch_max
13889         local dir=$DIR/$tdir
13890
13891         mkdir $dir || error "mkdir $dir failed"
13892         $LFS setstripe -C 32 $dir || error "setstripe $dir failed"
13893         stack_trap "rm -rf $dir"
13894
13895         touch $dir/$tfile.{0..1000} || error "touch 1000 files failed"
13896
13897         max=$($LCTL get_param -n llite.*.statahead_max | head -n 1)
13898         batch_max=$($LCTL get_param -n llite.*.statahead_batch_max | head -n 1)
13899         stack_trap "$LCTL set_param llite.*.statahead_max=$max" EXIT
13900         stack_trap "$LCTL set_param llite.*.statahead_batch_max=$batch_max" EXIT
13901
13902         $LCTL set_param llite.*.statahead_max=2048
13903         $LCTL set_param llite.*.statahead_batch_max=1024
13904
13905         ls -l $dir
13906         $LCTL get_param mdc.*.batch_stats
13907         $LCTL get_param llite.*.statahead_*
13908 }
13909 run_test 123e "statahead with large wide striping"
13910
13911 test_123f() {
13912         local max
13913         local batch_max
13914         local dir=$DIR/$tdir
13915
13916         mkdir $dir || error "mkdir $dir failed"
13917         $LFS setstripe -C 1000 $dir || error "setstripe $dir failed"
13918         stack_trap "rm -rf $dir"
13919
13920         touch $dir/$tfile.{0..200} || error "touch 200 files failed"
13921
13922         max=$($LCTL get_param -n llite.*.statahead_max | head -n 1)
13923         batch_max=$($LCTL get_param -n llite.*.statahead_batch_max | head -n 1)
13924
13925         $LCTL set_param llite.*.statahead_max=64
13926         $LCTL set_param llite.*.statahead_batch_max=64
13927
13928         ls -l $dir
13929         lctl get_param mdc.*.batch_stats
13930         lctl get_param llite.*.statahead_*
13931
13932         $LCTL set_param llite.*.statahead_max=$max
13933         $LCTL set_param llite.*.statahead_batch_max=$batch_max
13934 }
13935 run_test 123f "Retry mechanism with large wide striping files"
13936
13937 test_124a() {
13938         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13939         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13940                 skip_env "no lru resize on server"
13941
13942         local NR=2000
13943
13944         test_mkdir $DIR/$tdir
13945
13946         log "create $NR files at $DIR/$tdir"
13947         createmany -o $DIR/$tdir/f $NR ||
13948                 error "failed to create $NR files in $DIR/$tdir"
13949
13950         cancel_lru_locks mdc
13951         ls -l $DIR/$tdir > /dev/null
13952
13953         local NSDIR=""
13954         local LRU_SIZE=0
13955         for VALUE in $($LCTL get_param ldlm.namespaces.*mdc-*.lru_size); do
13956                 local PARAM=$(echo ${VALUE[0]} | cut -d "=" -f1)
13957                 LRU_SIZE=$($LCTL get_param -n $PARAM)
13958                 if [[ $LRU_SIZE -gt $(default_lru_size) ]]; then
13959                         NSDIR=$(echo $PARAM | cut -d "." -f1-3)
13960                         log "NSDIR=$NSDIR"
13961                         log "NS=$(basename $NSDIR)"
13962                         break
13963                 fi
13964         done
13965
13966         if [[ -z "$NSDIR" || $LRU_SIZE -lt $(default_lru_size) ]]; then
13967                 skip "Not enough cached locks created!"
13968         fi
13969         log "LRU=$LRU_SIZE"
13970
13971         local SLEEP=30
13972
13973         # We know that lru resize allows one client to hold $LIMIT locks
13974         # for 10h. After that locks begin to be killed by client.
13975         local MAX_HRS=10
13976         local LIMIT=$($LCTL get_param -n $NSDIR.pool.limit)
13977         log "LIMIT=$LIMIT"
13978         if [ $LIMIT -lt $LRU_SIZE ]; then
13979                 skip "Limit is too small $LIMIT"
13980         fi
13981
13982         # Make LVF so higher that sleeping for $SLEEP is enough to _start_
13983         # killing locks. Some time was spent for creating locks. This means
13984         # that up to the moment of sleep finish we must have killed some of
13985         # them (10-100 locks). This depends on how fast ther were created.
13986         # Many of them were touched in almost the same moment and thus will
13987         # be killed in groups.
13988         local LVF=$(($MAX_HRS * 60 * 60 / $SLEEP * $LIMIT / $LRU_SIZE * 100))
13989
13990         # Use $LRU_SIZE_B here to take into account real number of locks
13991         # created in the case of CMD, LRU_SIZE_B != $NR in most of cases
13992         local LRU_SIZE_B=$LRU_SIZE
13993         log "LVF=$LVF"
13994         local OLD_LVF=$($LCTL get_param -n $NSDIR.pool.lock_volume_factor)
13995         log "OLD_LVF=$OLD_LVF"
13996         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $LVF
13997
13998         # Let's make sure that we really have some margin. Client checks
13999         # cached locks every 10 sec.
14000         SLEEP=$((SLEEP+20))
14001         log "Sleep ${SLEEP} sec"
14002         local SEC=0
14003         while ((SEC<$SLEEP)); do
14004                 echo -n "..."
14005                 sleep 5
14006                 SEC=$((SEC+5))
14007                 LRU_SIZE=$($LCTL get_param -n $NSDIR/lru_size)
14008                 echo -n "$LRU_SIZE"
14009         done
14010         echo ""
14011         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $OLD_LVF
14012         local LRU_SIZE_A=$($LCTL get_param -n $NSDIR.lru_size)
14013
14014         [[ $LRU_SIZE_B -gt $LRU_SIZE_A ]] || {
14015                 error "No locks dropped in ${SLEEP}s. LRU size: $LRU_SIZE_A"
14016                 unlinkmany $DIR/$tdir/f $NR
14017                 return
14018         }
14019
14020         log "Dropped "$((LRU_SIZE_B-LRU_SIZE_A))" locks in ${SLEEP}s"
14021         log "unlink $NR files at $DIR/$tdir"
14022         unlinkmany $DIR/$tdir/f $NR
14023 }
14024 run_test 124a "lru resize ======================================="
14025
14026 get_max_pool_limit()
14027 {
14028         local limit=$($LCTL get_param \
14029                       -n ldlm.namespaces.*-MDT0000-mdc-*.pool.limit)
14030         local max=0
14031         for l in $limit; do
14032                 if [[ $l -gt $max ]]; then
14033                         max=$l
14034                 fi
14035         done
14036         echo $max
14037 }
14038
14039 test_124b() {
14040         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14041         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
14042                 skip_env "no lru resize on server"
14043
14044         LIMIT=$(get_max_pool_limit)
14045
14046         NR=$(($(default_lru_size)*20))
14047         if [[ $NR -gt $LIMIT ]]; then
14048                 log "Limit lock number by $LIMIT locks"
14049                 NR=$LIMIT
14050         fi
14051
14052         IFree=$(mdsrate_inodes_available)
14053         if [ $IFree -lt $NR ]; then
14054                 log "Limit lock number by $IFree inodes"
14055                 NR=$IFree
14056         fi
14057
14058         lru_resize_disable mdc
14059         test_mkdir -p $DIR/$tdir/disable_lru_resize
14060
14061         createmany -o $DIR/$tdir/disable_lru_resize/f $NR
14062         log "doing ls -la $DIR/$tdir/disable_lru_resize 3 times"
14063         cancel_lru_locks mdc
14064         stime=`date +%s`
14065         PID=""
14066         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
14067         PID="$PID $!"
14068         sleep 2
14069         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
14070         PID="$PID $!"
14071         sleep 2
14072         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
14073         PID="$PID $!"
14074         wait $PID
14075         etime=`date +%s`
14076         nolruresize_delta=$((etime-stime))
14077         log "ls -la time: $nolruresize_delta seconds"
14078         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
14079         unlinkmany $DIR/$tdir/disable_lru_resize/f $NR
14080
14081         lru_resize_enable mdc
14082         test_mkdir -p $DIR/$tdir/enable_lru_resize
14083
14084         createmany -o $DIR/$tdir/enable_lru_resize/f $NR
14085         log "doing ls -la $DIR/$tdir/enable_lru_resize 3 times"
14086         cancel_lru_locks mdc
14087         stime=`date +%s`
14088         PID=""
14089         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
14090         PID="$PID $!"
14091         sleep 2
14092         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
14093         PID="$PID $!"
14094         sleep 2
14095         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
14096         PID="$PID $!"
14097         wait $PID
14098         etime=`date +%s`
14099         lruresize_delta=$((etime-stime))
14100         log "ls -la time: $lruresize_delta seconds"
14101         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
14102
14103         if [ $lruresize_delta -gt $nolruresize_delta ]; then
14104                 log "ls -la is $(((lruresize_delta - $nolruresize_delta) * 100 / $nolruresize_delta))% slower with lru resize enabled"
14105         elif [ $nolruresize_delta -gt $lruresize_delta ]; then
14106                 log "ls -la is $(((nolruresize_delta - $lruresize_delta) * 100 / $nolruresize_delta))% faster with lru resize enabled"
14107         else
14108                 log "lru resize performs the same with no lru resize"
14109         fi
14110         unlinkmany $DIR/$tdir/enable_lru_resize/f $NR
14111 }
14112 run_test 124b "lru resize (performance test) ======================="
14113
14114 test_124c() {
14115         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14116         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
14117                 skip_env "no lru resize on server"
14118
14119         # cache ununsed locks on client
14120         local nr=100
14121         cancel_lru_locks mdc
14122         test_mkdir $DIR/$tdir
14123         createmany -o $DIR/$tdir/f $nr ||
14124                 error "failed to create $nr files in $DIR/$tdir"
14125         ls -l $DIR/$tdir > /dev/null
14126
14127         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
14128         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
14129         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
14130         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
14131         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
14132
14133         # set lru_max_age to 1 sec
14134         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
14135         echo "sleep $((recalc_p * 2)) seconds..."
14136         sleep $((recalc_p * 2))
14137
14138         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
14139         # restore lru_max_age
14140         $LCTL set_param -n $nsdir.lru_max_age $max_age
14141         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
14142         unlinkmany $DIR/$tdir/f $nr
14143 }
14144 run_test 124c "LRUR cancel very aged locks"
14145
14146 test_124d() {
14147         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14148         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
14149                 skip_env "no lru resize on server"
14150
14151         # cache ununsed locks on client
14152         local nr=100
14153
14154         lru_resize_disable mdc
14155         stack_trap "lru_resize_enable mdc" EXIT
14156
14157         cancel_lru_locks mdc
14158
14159         # asynchronous object destroy at MDT could cause bl ast to client
14160         test_mkdir $DIR/$tdir
14161         createmany -o $DIR/$tdir/f $nr ||
14162                 error "failed to create $nr files in $DIR/$tdir"
14163         stack_trap "unlinkmany $DIR/$tdir/f $nr" EXIT
14164
14165         ls -l $DIR/$tdir > /dev/null
14166
14167         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
14168         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
14169         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
14170         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
14171
14172         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
14173
14174         # set lru_max_age to 1 sec
14175         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
14176         stack_trap "$LCTL set_param -n $nsdir.lru_max_age $max_age" EXIT
14177
14178         echo "sleep $((recalc_p * 2)) seconds..."
14179         sleep $((recalc_p * 2))
14180
14181         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
14182
14183         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
14184 }
14185 run_test 124d "cancel very aged locks if lru-resize diasbaled"
14186
14187 test_125() { # 13358
14188         $LCTL get_param -n llite.*.client_type | grep -q local ||
14189                 skip "must run as local client"
14190         $LCTL get_param -n mdc.*-mdc-*.connect_flags | grep -q acl ||
14191                 skip_env "must have acl enabled"
14192         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
14193
14194         test_mkdir $DIR/$tdir
14195         $LFS setstripe -S 65536 -c -1 $DIR/$tdir || error "setstripe failed"
14196         setfacl -R -m u:$USER0:rwx $DIR/$tdir ||
14197                 error "setfacl $DIR/$tdir failed"
14198         ls -ld $DIR/$tdir || error "cannot access $DIR/$tdir"
14199 }
14200 run_test 125 "don't return EPROTO when a dir has a non-default striping and ACLs"
14201
14202 test_126() { # bug 12829/13455
14203         $GSS && skip_env "must run as gss disabled"
14204         $LCTL get_param -n llite.*.client_type | grep -q local ||
14205                 skip "must run as local client"
14206         [ "$UID" != 0 ] && skip "must run as root, not UID $UID"
14207
14208         $RUNAS -u 0 -g 1 touch $DIR/$tfile || error "touch failed"
14209         gid=`ls -n $DIR/$tfile | awk '{print $4}'`
14210         rm -f $DIR/$tfile
14211         [ $gid -eq "1" ] || error "gid is set to" $gid "instead of 1"
14212 }
14213 run_test 126 "check that the fsgid provided by the client is taken into account"
14214
14215 test_127a() { # bug 15521
14216         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14217         local name count samp unit min max sum sumsq
14218         local tmpfile=$TMP/$tfile.tmp
14219
14220         $LFS setstripe -i 0 -c 1 $DIR/$tfile || error "setstripe failed"
14221         echo "stats before reset"
14222         stack_trap "rm -f $tmpfile"
14223         local now=$(date +%s)
14224
14225         $LCTL get_param osc.*.stats | tee $tmpfile
14226
14227         local snapshot_time=$(awk '/snapshot_time/ { print $2; exit }' $tmpfile)
14228         local start_time=$(awk '/start_time/ { print $2; exit }' $tmpfile)
14229         local elapsed=$(awk '/elapsed_time/ { print $2; exit }' $tmpfile)
14230         local uptime=$(awk '{ print $1 }' /proc/uptime)
14231
14232         # snapshot_time should match POSIX epoch time, allow some delta for VMs
14233         (( ${snapshot_time%\.*} >= $now - 5 &&
14234            ${snapshot_time%\.*} <= $now + 5 )) ||
14235                 error "snapshot_time=$snapshot_time != now=$now"
14236         # elapsed _should_ be from mount, but at least less than uptime
14237         (( ${elapsed%\.*} < ${uptime%\.*} )) ||
14238                 error "elapsed=$elapsed > uptime=$uptime"
14239         (( ${snapshot_time%\.*} - ${start_time%\.*} >= ${elapsed%\.*} - 2 &&
14240            ${snapshot_time%\.*} - ${start_time%\.*} <= ${elapsed%\.*} + 2 )) ||
14241                 error "elapsed=$elapsed != $snapshot_time - $start_time"
14242
14243         $LCTL set_param osc.*.stats=0
14244         local reset=$(date +%s)
14245         local fsize=$((2048 * 1024))
14246
14247         dd if=/dev/zero of=$DIR/$tfile bs=$fsize count=1
14248         cancel_lru_locks osc
14249         dd if=$DIR/$tfile of=/dev/null bs=$fsize
14250
14251         now=$(date +%s)
14252         $LCTL get_param osc.*0000-osc-*.stats > $tmpfile
14253         while read name count samp unit min max sum sumsq; do
14254                 [[ "$samp" == "samples" ]] || continue
14255
14256                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
14257                 [ ! $min ] && error "Missing min value for $name proc entry"
14258                 eval $name=$count || error "Wrong proc format"
14259
14260                 case $name in
14261                 read_bytes|write_bytes)
14262                         [[ "$unit" =~ "bytes" ]] ||
14263                                 error "unit is not 'bytes': $unit"
14264                         (( $min >= 4096 )) || error "min is too small: $min"
14265                         (( $min <= $fsize )) || error "min is too big: $min"
14266                         (( $max >= 4096 )) || error "max is too small: $max"
14267                         (( $max <= $fsize )) || error "max is too big: $max"
14268                         (( $sum == $fsize )) || error "sum is wrong: $sum"
14269                         (( $sumsq >= ($fsize / 4096) * (4096 * 4096) )) ||
14270                                 error "sumsquare is too small: $sumsq"
14271                         (( $sumsq <= $fsize * $fsize )) ||
14272                                 error "sumsquare is too big: $sumsq"
14273                         ;;
14274                 ost_read|ost_write)
14275                         [[ "$unit" =~ "usec" ]] ||
14276                                 error "unit is not 'usec': $unit"
14277                         ;;
14278                 *)      ;;
14279                 esac
14280         done < $tmpfile
14281
14282         #check that we actually got some stats
14283         [ "$read_bytes" ] || error "Missing read_bytes stats"
14284         [ "$write_bytes" ] || error "Missing write_bytes stats"
14285         [ "$read_bytes" != 0 ] || error "no read done"
14286         [ "$write_bytes" != 0 ] || error "no write done"
14287
14288         snapshot_time=$(awk '/snapshot_time/ { print $2; exit }' $tmpfile)
14289         start_time=$(awk '/start_time/ { print $2; exit }' $tmpfile)
14290         elapsed=$(awk '/elapsed_time/ { print $2; exit }' $tmpfile)
14291
14292         # snapshot_time should match POSIX epoch time, allow some delta for VMs
14293         (( ${snapshot_time%\.*} >= $now - 5 &&
14294            ${snapshot_time%\.*} <= $now + 5 )) ||
14295                 error "reset snapshot_time=$snapshot_time != now=$now"
14296         # elapsed should be from time of stats reset
14297         (( ${elapsed%\.*} >= $now - $reset - 2 &&
14298            ${elapsed%\.*} <= $now - $reset + 2 )) ||
14299                 error "reset elapsed=$elapsed > $now - $reset"
14300         (( ${snapshot_time%\.*} - ${start_time%\.*} >= ${elapsed%\.*} - 2 &&
14301            ${snapshot_time%\.*} - ${start_time%\.*} <= ${elapsed%\.*} + 2 )) ||
14302                 error "reset elapsed=$elapsed != $snapshot_time - $start_time"
14303 }
14304 run_test 127a "verify the client stats are sane"
14305
14306 test_127b() { # bug LU-333
14307         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14308         local name count samp unit min max sum sumsq
14309
14310         echo "stats before reset"
14311         $LCTL get_param llite.*.stats
14312         $LCTL set_param llite.*.stats=0
14313
14314         # perform 2 reads and writes so MAX is different from SUM.
14315         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
14316         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
14317         cancel_lru_locks osc
14318         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
14319         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
14320
14321         $LCTL get_param llite.*.stats | grep samples > $TMP/$tfile.tmp
14322         stack_trap "rm -f $TMP/$tfile.tmp"
14323         while read name count samp unit min max sum sumsq; do
14324                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
14325                 eval $name=$count || error "Wrong proc format"
14326
14327                 case $name in
14328                 read_bytes|write_bytes)
14329                         [[ "$unit" =~ "bytes" ]] ||
14330                                 error "unit is not 'bytes': $unit"
14331                         (( $count == 2 )) || error "count is not 2: $count"
14332                         (( $min == $PAGE_SIZE )) ||
14333                                 error "min is not $PAGE_SIZE: $min"
14334                         (( $max == $PAGE_SIZE )) ||
14335                                 error "max is not $PAGE_SIZE: $max"
14336                         (( $sum == $PAGE_SIZE * 2 )) ||
14337                                 error "sum is not $((PAGE_SIZE * 2)): $sum"
14338                         ;;
14339                 read|write)
14340                         [[ "$unit" =~ "usec" ]] ||
14341                                 error "unit is not 'usec': $unit"
14342                         ;;
14343                 *)      ;;
14344                 esac
14345         done < $TMP/$tfile.tmp
14346
14347         #check that we actually got some stats
14348         [ "$read_bytes" ] || error "Missing read_bytes stats"
14349         [ "$write_bytes" ] || error "Missing write_bytes stats"
14350         [ "$read_bytes" != 0 ] || error "no read done"
14351         [ "$write_bytes" != 0 ] || error "no write done"
14352 }
14353 run_test 127b "verify the llite client stats are sane"
14354
14355 test_127c() { # LU-12394
14356         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
14357         local size
14358         local bsize
14359         local reads
14360         local writes
14361         local count
14362
14363         $LCTL set_param llite.*.extents_stats=1
14364         stack_trap "$LCTL set_param llite.*.extents_stats=0" EXIT
14365
14366         # Use two stripes so there is enough space in default config
14367         $LFS setstripe -c 2 $DIR/$tfile
14368
14369         # Extent stats start at 0-4K and go in power of two buckets
14370         # LL_HIST_START = 12 --> 2^12 = 4K
14371         # We do 3K*2^i, so 3K, 6K, 12K, 24K... hitting each bucket.
14372         # We do not do buckets larger than 64 MiB to avoid ENOSPC issues on
14373         # small configs
14374         for size in 3K 6K 12K 24K 48K 96K 192K 384K 768K 1536K 3M 6M 12M 24M 48M;
14375                 do
14376                 # Write and read, 2x each, second time at a non-zero offset
14377                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1
14378                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1 seek=10
14379                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1
14380                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1 seek=10
14381                 rm -f $DIR/$tfile
14382         done
14383
14384         $LCTL get_param llite.*.extents_stats
14385
14386         count=2
14387         for bsize in 4K 8K 16K 32K 64K 128K 256K 512K 1M 2M 4M 8M 16M 32M 64M;
14388                 do
14389                 local bucket=$($LCTL get_param -n llite.*.extents_stats |
14390                                 grep -m 1 $bsize)
14391                 reads=$(echo $bucket | awk '{print $5}')
14392                 writes=$(echo $bucket | awk '{print $9}')
14393                 [ "$reads" -eq $count ] ||
14394                         error "$reads reads in < $bsize bucket, expect $count"
14395                 [ "$writes" -eq $count ] ||
14396                         error "$writes writes in < $bsize bucket, expect $count"
14397         done
14398
14399         # Test mmap write and read
14400         $LCTL set_param llite.*.extents_stats=c
14401         size=512
14402         dd if=/dev/zero of=$DIR/$tfile bs=${size}K count=1
14403         $MULTIOP $DIR/$tfile OSMRUc || error "$MULTIOP $DIR/$tfile failed"
14404         $MULTIOP $DIR/$tfile OSMWUc || error "$MULTIOP $DIR/$tfile failed"
14405
14406         $LCTL get_param llite.*.extents_stats
14407
14408         count=$(((size*1024) / PAGE_SIZE))
14409
14410         bsize=$((2 * PAGE_SIZE / 1024))K
14411
14412         bucket=$($LCTL get_param -n llite.*.extents_stats |
14413                         grep -m 1 $bsize)
14414         reads=$(echo $bucket | awk '{print $5}')
14415         writes=$(echo $bucket | awk '{print $9}')
14416         # mmap writes fault in the page first, creating an additonal read
14417         [ "$reads" -eq $((2 * count)) ] ||
14418                 error "$reads reads in < $bsize bucket, expect $count"
14419         [ "$writes" -eq $count ] ||
14420                 error "$writes writes in < $bsize bucket, expect $count"
14421 }
14422 run_test 127c "test llite extent stats with regular & mmap i/o"
14423
14424 test_128() { # bug 15212
14425         touch $DIR/$tfile
14426         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
14427                 find $DIR/$tfile
14428                 find $DIR/$tfile
14429         EOF
14430
14431         result=$(grep error $TMP/$tfile.log)
14432         rm -f $DIR/$tfile $TMP/$tfile.log
14433         [ -z "$result" ] ||
14434                 error "consecutive find's under interactive lfs failed"
14435 }
14436 run_test 128 "interactive lfs for 2 consecutive find's"
14437
14438 set_dir_limits () {
14439         local mntdev
14440         local canondev
14441         local node
14442
14443         local ldproc=/proc/fs/ldiskfs
14444         local facets=$(get_facets MDS)
14445
14446         for facet in ${facets//,/ }; do
14447                 canondev=$(ldiskfs_canon \
14448                            *.$(convert_facet2label $facet).mntdev $facet)
14449                 do_facet $facet "test -e $ldproc/$canondev/max_dir_size" ||
14450                         ldproc=/sys/fs/ldiskfs
14451                 do_facet $facet "echo $1 >$ldproc/$canondev/max_dir_size"
14452                 do_facet $facet "echo $2 >$ldproc/$canondev/warning_dir_size"
14453         done
14454 }
14455
14456 check_mds_dmesg() {
14457         local facets=$(get_facets MDS)
14458         for facet in ${facets//,/ }; do
14459                 do_facet $facet "dmesg | tail -3 | grep $1" && return 0
14460         done
14461         return 1
14462 }
14463
14464 test_129() {
14465         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14466         [[ $MDS1_VERSION -ge $(version_code 2.5.56) ]] ||
14467                 skip "Need MDS version with at least 2.5.56"
14468         if [ "$mds1_FSTYPE" != ldiskfs ]; then
14469                 skip_env "ldiskfs only test"
14470         fi
14471         remote_mds_nodsh && skip "remote MDS with nodsh"
14472
14473         local ENOSPC=28
14474         local has_warning=false
14475
14476         rm -rf $DIR/$tdir
14477         mkdir -p $DIR/$tdir
14478
14479         # block size of mds1
14480         local maxsize=$(($($LCTL get_param -n mdc.*MDT0000*.blocksize) * 8))
14481         set_dir_limits $maxsize $((maxsize * 6 / 8))
14482         stack_trap "set_dir_limits 0 0"
14483         stack_trap "unlinkmany $DIR/$tdir/file_base_ 2000 || true"
14484         local dirsize=$(stat -c%s "$DIR/$tdir")
14485         local nfiles=0
14486         while (( $dirsize <= $maxsize )); do
14487                 $MCREATE $DIR/$tdir/file_base_$nfiles
14488                 rc=$?
14489                 # check two errors:
14490                 # ENOSPC for ext4 max_dir_size, which has been used since
14491                 # kernel v3.6-rc1-8-gdf981d03ee, lustre v2_4_50_0-79-gaed82035c0
14492                 if (( rc == ENOSPC )); then
14493                         set_dir_limits 0 0
14494                         echo "rc=$rc returned as expected after $nfiles files"
14495
14496                         createmany -o $DIR/$tdir/file_extra_$nfiles. 5 ||
14497                                 error "create failed w/o dir size limit"
14498
14499                         # messages may be rate limited if test is run repeatedly
14500                         check_mds_dmesg '"is approaching max"' ||
14501                                 echo "warning message should be output"
14502                         check_mds_dmesg '"has reached max"' ||
14503                                 echo "reached message should be output"
14504
14505                         dirsize=$(stat -c%s "$DIR/$tdir")
14506
14507                         [[ $dirsize -ge $maxsize ]] && return 0
14508                         error "dirsize $dirsize < $maxsize after $nfiles files"
14509                 elif (( rc != 0 )); then
14510                         break
14511                 fi
14512                 nfiles=$((nfiles + 1))
14513                 dirsize=$(stat -c%s "$DIR/$tdir")
14514         done
14515
14516         error "rc=$rc, size=$dirsize/$maxsize, mdt=$MDSCOUNT, nfiles=$nfiles"
14517 }
14518 run_test 129 "test directory size limit ========================"
14519
14520 OLDIFS="$IFS"
14521 cleanup_130() {
14522         trap 0
14523         IFS="$OLDIFS"
14524         rm -f $DIR/$tfile
14525 }
14526
14527 test_130a() {
14528         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
14529         [[ -z "$filefrag_op" ]] || skip_env "filefrag does not support FIEMAP"
14530
14531         trap cleanup_130 EXIT RETURN
14532
14533         local fm_file=$DIR/$tfile
14534         $LFS setstripe -S 65536 -c 1 $fm_file || error "setstripe on $fm_file"
14535         dd if=/dev/zero of=$fm_file bs=65536 count=1 ||
14536                 error "dd failed for $fm_file"
14537
14538         # LU-1795: test filefrag/FIEMAP once, even if unsupported on ZFS
14539         filefrag -ves $fm_file
14540         local rc=$?
14541         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14542                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14543         (( $rc == 0 )) || error "filefrag $fm_file failed"
14544
14545         filefrag_op=$(filefrag -ve -k $fm_file |
14546                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
14547         local lun=$($LFS getstripe -i $fm_file)
14548
14549         local start_blk=$(echo $filefrag_op | cut -d: -f2 | cut -d. -f1)
14550         IFS=$'\n'
14551         local tot_len=0
14552         for line in $filefrag_op; do
14553                 local frag_lun=$(echo $line | cut -d: -f5)
14554                 local ext_len=$(echo $line | cut -d: -f4)
14555
14556                 if (( $frag_lun != $lun )); then
14557                         error "FIEMAP on 1-stripe file($fm_file) failed"
14558                         return
14559                 fi
14560                 (( tot_len += ext_len ))
14561         done
14562
14563         if (( lun != frag_lun || start_blk != 0 || tot_len != 64 )); then
14564                 error "FIEMAP on 1-stripe file($fm_file) failed"
14565                 return
14566         fi
14567
14568         echo "FIEMAP on single striped file succeeded"
14569 }
14570 run_test 130a "FIEMAP (1-stripe file)"
14571
14572 test_130b() {
14573         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
14574
14575         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
14576         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
14577         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14578                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14579
14580         trap cleanup_130 EXIT RETURN
14581
14582         local fm_file=$DIR/$tfile
14583         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
14584                 error "setstripe on $fm_file"
14585
14586         dd if=/dev/zero of=$fm_file bs=1M count=$OSTCOUNT ||
14587                 error "dd failed on $fm_file"
14588
14589         filefrag -ves $fm_file || error "filefrag $fm_file failed"
14590         filefrag_op=$(filefrag -ve -k $fm_file |
14591                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
14592
14593         local last_lun=$(echo $filefrag_op | cut -d: -f5 |
14594                          sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14595
14596         IFS=$'\n'
14597         local tot_len=0
14598         local num_luns=1
14599
14600         for line in $filefrag_op; do
14601                 local frag_lun=$(echo $line | cut -d: -f5 |
14602                                  sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14603                 local ext_len=$(echo $line | cut -d: -f4)
14604                 if (( $frag_lun != $last_lun )); then
14605                         if (( tot_len != 1024 )); then
14606                                 error "FIEMAP on $fm_file failed; returned len $tot_len for OST $last_lun instead of 1024"
14607                                 return
14608                         else
14609                                 (( num_luns += 1 ))
14610                                 tot_len=0
14611                         fi
14612                 fi
14613                 (( tot_len += ext_len ))
14614                 last_lun=$frag_lun
14615         done
14616         if (( num_luns != $OSTCOUNT || tot_len != 1024 )); then
14617                 error "FIEMAP on $fm_file failed; returned wrong number of luns or wrong len for OST $last_lun"
14618                 return
14619         fi
14620
14621         echo "FIEMAP on $OSTCOUNT-stripe file succeeded"
14622 }
14623 run_test 130b "FIEMAP ($OSTCOUNT-stripe file)"
14624
14625 test_130c() {
14626         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
14627
14628         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
14629         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
14630         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14631                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14632
14633         trap cleanup_130 EXIT RETURN
14634
14635         local fm_file=$DIR/$tfile
14636         $LFS setstripe -S 65536 -c 2 $fm_file || error "setstripe on $fm_file"
14637
14638         dd if=/dev/zero of=$fm_file seek=1 bs=1M count=1 ||
14639                 error "dd failed on $fm_file"
14640
14641         filefrag -ves $fm_file || error "filefrag $fm_file failed"
14642         filefrag_op=$(filefrag -ve -k $fm_file |
14643                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
14644
14645         local last_lun=$(echo $filefrag_op | cut -d: -f5 |
14646                          sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14647
14648         IFS=$'\n'
14649         local tot_len=0
14650         local num_luns=1
14651         for line in $filefrag_op; do
14652                 local frag_lun=$(echo $line | cut -d: -f5 |
14653                                  sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14654                 local ext_len=$(echo $line | cut -d: -f4)
14655                 if (( $frag_lun != $last_lun )); then
14656                         local logical=$(echo $line | cut -d: -f2 | cut -d. -f1)
14657                         if (( logical != 512 )); then
14658                                 error "FIEMAP on $fm_file failed; returned logical start for lun $logical instead of 512"
14659                                 return
14660                         fi
14661                         if (( tot_len != 512 )); then
14662                                 error "FIEMAP on $fm_file failed; returned len $tot_len for OST $last_lun instead of 1024"
14663                                 return
14664                         else
14665                                 (( num_luns += 1 ))
14666                                 tot_len=0
14667                         fi
14668                 fi
14669                 (( tot_len += ext_len ))
14670                 last_lun=$frag_lun
14671         done
14672         if (( num_luns != 2 || tot_len != 512 )); then
14673                 error "FIEMAP on $fm_file failed; returned wrong number of luns or wrong len for OST $last_lun"
14674                 return
14675         fi
14676
14677         echo "FIEMAP on 2-stripe file with hole succeeded"
14678 }
14679 run_test 130c "FIEMAP (2-stripe file with hole)"
14680
14681 test_130d() {
14682         (( $OSTCOUNT >= 3 )) || skip "needs >= 3 OSTs"
14683
14684         filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
14685         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
14686         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14687                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14688
14689         trap cleanup_130 EXIT RETURN
14690
14691         local fm_file=$DIR/$tfile
14692         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
14693                         error "setstripe on $fm_file"
14694
14695         local actual_stripe_count=$($LFS getstripe -c $fm_file)
14696         dd if=/dev/zero of=$fm_file bs=1M count=$actual_stripe_count ||
14697                 error "dd failed on $fm_file"
14698
14699         filefrag -ves $fm_file || error "filefrag $fm_file failed"
14700         filefrag_op=$(filefrag -ve -k $fm_file |
14701                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
14702
14703         local last_lun=$(echo $filefrag_op | cut -d: -f5 |
14704                          sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14705
14706         IFS=$'\n'
14707         local tot_len=0
14708         local num_luns=1
14709         for line in $filefrag_op; do
14710                 local frag_lun=$(echo $line | cut -d: -f5 |
14711                                  sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14712                 local ext_len=$(echo $line | cut -d: -f4)
14713                 if (( $frag_lun != $last_lun )); then
14714                         if (( tot_len != 1024 )); then
14715                                 error "FIEMAP on $fm_file failed; returned len $tot_len for OST $last_lun instead of 1024"
14716                                 return
14717                         else
14718                                 (( num_luns += 1 ))
14719                                 local tot_len=0
14720                         fi
14721                 fi
14722                 (( tot_len += ext_len ))
14723                 last_lun=$frag_lun
14724         done
14725         if (( num_luns != actual_stripe_count || tot_len != 1024 )); then
14726                 error "FIEMAP on $fm_file failed; returned wrong number of luns or wrong len for OST $last_lun"
14727                 return
14728         fi
14729
14730         echo "FIEMAP on N-stripe file succeeded"
14731 }
14732 run_test 130d "FIEMAP (N-stripe file)"
14733
14734 test_130e() {
14735         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
14736
14737         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
14738         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
14739         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14740                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14741
14742         trap cleanup_130 EXIT RETURN
14743
14744         local fm_file=$DIR/$tfile
14745         $LFS setstripe -S 131072 -c 2 $fm_file || error "setstripe on $fm_file"
14746         stack_trap "rm -f $fm_file"
14747
14748         local num_blks=512
14749         local expected_len=$(( (num_blks / 2) * 64 ))
14750         for ((i = 0; i < $num_blks; i++)); do
14751                 dd if=/dev/zero of=$fm_file count=1 bs=64k seek=$((2*$i)) \
14752                         conv=notrunc > /dev/null 2>&1
14753         done
14754
14755         filefrag -ves $fm_file || error "filefrag $fm_file failed"
14756         filefrag_op=$(filefrag -ve -k $fm_file |
14757                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
14758
14759         local last_lun=$(echo $filefrag_op | cut -d: -f5)
14760
14761         IFS=$'\n'
14762         local tot_len=0
14763         local num_luns=1
14764         for line in $filefrag_op; do
14765                 local frag_lun=$(echo $line | cut -d: -f5)
14766                 local ext_len=$(echo $line | cut -d: -f4)
14767                 if (( $frag_lun != $last_lun )); then
14768                         if (( tot_len != $expected_len )); then
14769                                 error "OST$last_lun $tot_len != $expected_len"
14770                         else
14771                                 (( num_luns += 1 ))
14772                                 tot_len=0
14773                         fi
14774                 fi
14775                 (( tot_len += ext_len ))
14776                 last_lun=$frag_lun
14777         done
14778         if (( num_luns != 2 || tot_len != $expected_len )); then
14779                 error "OST$last_lun $num_luns != 2, $tot_len != $expected_len"
14780         fi
14781
14782         echo "FIEMAP with continuation calls succeeded"
14783 }
14784 run_test 130e "FIEMAP (test continuation FIEMAP calls)"
14785
14786 test_130f() {
14787         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
14788         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
14789         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14790                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14791
14792         local fm_file=$DIR/$tfile
14793         $MULTIOP $fm_file oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T33554432c ||
14794                 error "multiop create with lov_delay_create on $fm_file"
14795
14796         filefrag -ves $fm_file || error "filefrag $fm_file failed"
14797         filefrag_extents=$(filefrag -vek $fm_file |
14798                            awk '/extents? found/ { print $2 }')
14799         if (( $filefrag_extents != 0 )); then
14800                 error "$fm_file: filefrag_extents=$filefrag_extents != 0"
14801         fi
14802
14803         rm -f $fm_file
14804 }
14805 run_test 130f "FIEMAP (unstriped file)"
14806
14807 test_130g() {
14808         (( $MDS1_VERSION >= $(version_code 2.12.53) )) ||
14809                 skip "Need MDS version with at least 2.12.53 for overstriping"
14810         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
14811         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
14812         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14813                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14814
14815         local file=$DIR/$tfile
14816         local nr=$((OSTCOUNT * 100))
14817
14818         $LFS setstripe -C $nr $file || error "failed to setstripe -C $nr $file"
14819
14820         stack_trap "rm -f $file"
14821         dd if=/dev/zero of=$file count=$nr bs=1M
14822         sync
14823         nr=$($LFS getstripe -c $file)
14824
14825         local extents=$(filefrag -v $file |
14826                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}' | wc -l)
14827
14828         echo "filefrag list $extents extents in file with stripecount $nr"
14829         if (( extents < nr )); then
14830                 $LFS getstripe $file
14831                 filefrag -v $file
14832                 error "filefrag printed $extents < $nr extents"
14833         fi
14834 }
14835 run_test 130g "FIEMAP (overstripe file)"
14836
14837 # Test for writev/readv
14838 test_131a() {
14839         rwv -f $DIR/$tfile -w -n 3 524288 1048576 1572864 ||
14840                 error "writev test failed"
14841         rwv -f $DIR/$tfile -r -v -n 2 1572864 1048576 ||
14842                 error "readv failed"
14843         rm -f $DIR/$tfile
14844 }
14845 run_test 131a "test iov's crossing stripe boundary for writev/readv"
14846
14847 test_131b() {
14848         local fsize=$((524288 + 1048576 + 1572864))
14849         rwv -f $DIR/$tfile -w -a -n 3 524288 1048576 1572864 &&
14850                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
14851                         error "append writev test failed"
14852
14853         ((fsize += 1572864 + 1048576))
14854         rwv -f $DIR/$tfile -w -a -n 2 1572864 1048576 &&
14855                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
14856                         error "append writev test failed"
14857         rm -f $DIR/$tfile
14858 }
14859 run_test 131b "test append writev"
14860
14861 test_131c() {
14862         rwv -f $DIR/$tfile -w -d -n 1 1048576 || return 0
14863         error "NOT PASS"
14864 }
14865 run_test 131c "test read/write on file w/o objects"
14866
14867 test_131d() {
14868         rwv -f $DIR/$tfile -w -n 1 1572864
14869         NOB=`rwv -f $DIR/$tfile -r -n 3 524288 524288 1048576 | awk '/error/ {print $6}'`
14870         if [ "$NOB" != 1572864 ]; then
14871                 error "Short read filed: read $NOB bytes instead of 1572864"
14872         fi
14873         rm -f $DIR/$tfile
14874 }
14875 run_test 131d "test short read"
14876
14877 test_131e() {
14878         rwv -f $DIR/$tfile -w -s 1048576 -n 1 1048576
14879         rwv -f $DIR/$tfile -r -z -s 0 -n 1 524288 || \
14880         error "read hitting hole failed"
14881         rm -f $DIR/$tfile
14882 }
14883 run_test 131e "test read hitting hole"
14884
14885 check_stats() {
14886         local facet=$1
14887         local op=$2
14888         local want=${3:-0}
14889         local res
14890
14891         # open             11 samples [usecs] 468 4793 13658 35791898
14892         case $facet in
14893         mds*) res=($(do_facet $facet \
14894                    $LCTL get_param mdt.$FSNAME-MDT0000.md_stats | grep "$op"))
14895                  ;;
14896         ost*) res=($(do_facet $facet \
14897                   $LCTL get_param obdfilter.$FSNAME-OST0000.stats | grep "$op"))
14898                  ;;
14899         *) error "Wrong facet '$facet'" ;;
14900         esac
14901         [[ -n "$res" ]] || error "counter for $op on $facet not incremented"
14902         # if $want is zero, it means any stat increment is ok.
14903         if (( $want > 0 )); then
14904                 local count=${res[1]}
14905
14906                 if (( $count != $want )); then
14907                         if [[ $facet =~ "mds" ]]; then
14908                                 do_nodes $(comma_list $(mdts_nodes)) \
14909                                         $LCTL get_param mdt.*.md_stats
14910                         else
14911                                 do_nodes $(comma_list $(osts-nodes)) \
14912                                         $LCTL get_param obdfilter.*.stats
14913                         fi
14914                         error "The $op counter on $facet is $count, not $want"
14915                 fi
14916         fi
14917 }
14918
14919 test_133a() {
14920         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14921         remote_ost_nodsh && skip "remote OST with nodsh"
14922         remote_mds_nodsh && skip "remote MDS with nodsh"
14923         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
14924                 skip_env "MDS doesn't support rename stats"
14925
14926         local testdir=$DIR/${tdir}/stats_testdir
14927
14928         mkdir -p $DIR/${tdir}
14929
14930         # clear stats.
14931         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14932         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
14933
14934         # verify mdt stats first.
14935         mkdir_on_mdt0 ${testdir} || error "mkdir_on_mdt0 failed"
14936         check_stats $SINGLEMDS "mkdir" 1
14937
14938         # clear "open" from "lfs mkdir" above
14939         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14940         touch ${testdir}/${tfile} || error "touch failed"
14941         check_stats $SINGLEMDS "open" 1
14942         check_stats $SINGLEMDS "close" 1
14943         [ $MDS1_VERSION -ge $(version_code 2.8.54) ] && {
14944                 mknod ${testdir}/${tfile}-pipe p || error "mknod failed"
14945                 check_stats $SINGLEMDS "mknod" 2
14946         }
14947         rm -f ${testdir}/${tfile}-pipe || error "pipe remove failed"
14948         check_stats $SINGLEMDS "unlink" 1
14949         rm -f ${testdir}/${tfile} || error "file remove failed"
14950         check_stats $SINGLEMDS "unlink" 2
14951
14952         # remove working dir and check mdt stats again.
14953         rmdir ${testdir} || error "rmdir failed"
14954         check_stats $SINGLEMDS "rmdir" 1
14955
14956         local testdir1=$DIR/${tdir}/stats_testdir1
14957         mkdir_on_mdt0 -p ${testdir}
14958         mkdir_on_mdt0 -p ${testdir1}
14959         touch ${testdir1}/test1
14960         mv ${testdir1}/test1 ${testdir} || error "file crossdir rename"
14961         check_stats $SINGLEMDS "crossdir_rename" 1
14962
14963         mv ${testdir}/test1 ${testdir}/test0 || error "file samedir rename"
14964         check_stats $SINGLEMDS "samedir_rename" 1
14965
14966         rm -rf $DIR/${tdir}
14967 }
14968 run_test 133a "Verifying MDT stats ========================================"
14969
14970 test_133b() {
14971         local res
14972
14973         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14974         remote_ost_nodsh && skip "remote OST with nodsh"
14975         remote_mds_nodsh && skip "remote MDS with nodsh"
14976
14977         local testdir=$DIR/${tdir}/stats_testdir
14978
14979         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
14980         mkdir_on_mdt0 ${testdir} || error "mkdir_on_mdt0 failed"
14981         touch ${testdir}/${tfile} || error "touch failed"
14982         cancel_lru_locks mdc
14983
14984         # clear stats.
14985         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14986         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
14987
14988         # extra mdt stats verification.
14989         chmod 444 ${testdir}/${tfile} || error "chmod failed"
14990         check_stats $SINGLEMDS "setattr" 1
14991         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14992         if [ $MDS1_VERSION -ne $(version_code 2.2.0) ]
14993         then            # LU-1740
14994                 ls -l ${testdir}/${tfile} > /dev/null|| error "ls failed"
14995                 check_stats $SINGLEMDS "getattr" 1
14996         fi
14997         rm -rf $DIR/${tdir}
14998
14999         # when DNE is enabled, MDT uses STATFS RPC to ping other targets
15000         # so the check below is not reliable
15001         [ $MDSCOUNT -eq 1 ] || return 0
15002
15003         # Sleep to avoid a cached response.
15004         #define OBD_STATFS_CACHE_SECONDS 1
15005         sleep 2
15006         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15007         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
15008         $LFS df || error "lfs failed"
15009         check_stats $SINGLEMDS "statfs" 1
15010
15011         # check aggregated statfs (LU-10018)
15012         [ $MDS1_VERSION -lt $(version_code 2.11.54) ] &&
15013                 return 0
15014         [ $CLIENT_VERSION -lt $(version_code 2.11.54) ] &&
15015                 return 0
15016         sleep 2
15017         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15018         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
15019         df $DIR
15020         check_stats $SINGLEMDS "statfs" 1
15021
15022         # We want to check that the client didn't send OST_STATFS to
15023         # ost1 but the MDT also uses OST_STATFS for precreate. So some
15024         # extra care is needed here.
15025         if remote_mds; then
15026                 local nid=$($LCTL list_nids | head -1 | sed  "s/\./\\\./g")
15027                 local param="obdfilter.$FSNAME-OST0000.exports.'$nid'.stats"
15028
15029                 res=$(do_facet ost1 $LCTL get_param $param | grep statfs)
15030                 [ "$res" ] && error "OST got STATFS"
15031         fi
15032
15033         return 0
15034 }
15035 run_test 133b "Verifying extra MDT stats =================================="
15036
15037 test_133c() {
15038         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15039         remote_ost_nodsh && skip "remote OST with nodsh"
15040         remote_mds_nodsh && skip "remote MDS with nodsh"
15041
15042         local testdir=$DIR/$tdir/stats_testdir
15043
15044         test_mkdir -p $testdir
15045
15046         # verify obdfilter stats.
15047         $LFS setstripe -c 1 -i 0 $testdir/$tfile
15048         sync
15049         cancel_lru_locks osc
15050         wait_delete_completed
15051
15052         # clear stats.
15053         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15054         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
15055
15056         dd if=/dev/zero of=$testdir/$tfile conv=notrunc bs=512k count=1 ||
15057                 error "dd failed"
15058         sync
15059         cancel_lru_locks osc
15060         check_stats ost1 "write" 1
15061
15062         dd if=$testdir/$tfile of=/dev/null bs=1k count=1 || error "dd failed"
15063         check_stats ost1 "read" 1
15064
15065         > $testdir/$tfile || error "truncate failed"
15066         check_stats ost1 "punch" 1
15067
15068         rm -f $testdir/$tfile || error "file remove failed"
15069         wait_delete_completed
15070         check_stats ost1 "destroy" 1
15071
15072         rm -rf $DIR/$tdir
15073 }
15074 run_test 133c "Verifying OST stats ========================================"
15075
15076 order_2() {
15077         local value=$1
15078         local orig=$value
15079         local order=1
15080
15081         while [ $value -ge 2 ]; do
15082                 order=$((order*2))
15083                 value=$((value/2))
15084         done
15085
15086         if [ $orig -gt $order ]; then
15087                 order=$((order*2))
15088         fi
15089         echo $order
15090 }
15091
15092 size_in_KMGT() {
15093     local value=$1
15094     local size=('K' 'M' 'G' 'T');
15095     local i=0
15096     local size_string=$value
15097
15098     while [ $value -ge 1024 ]; do
15099         if [ $i -gt 3 ]; then
15100             #T is the biggest unit we get here, if that is bigger,
15101             #just return XXXT
15102             size_string=${value}T
15103             break
15104         fi
15105         value=$((value >> 10))
15106         if [ $value -lt 1024 ]; then
15107             size_string=${value}${size[$i]}
15108             break
15109         fi
15110         i=$((i + 1))
15111     done
15112
15113     echo $size_string
15114 }
15115
15116 get_rename_size() {
15117         local size=$1
15118         local context=${2:-.}
15119         local sample=$(do_facet $SINGLEMDS $LCTL \
15120                 get_param mdt.$FSNAME-MDT0000.rename_stats |
15121                 grep -A1 $context |
15122                 awk '/ '${size}'/ {print $4}' | sed -e "s/,//g")
15123         echo $sample
15124 }
15125
15126 test_133d() {
15127         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15128         remote_ost_nodsh && skip "remote OST with nodsh"
15129         remote_mds_nodsh && skip "remote MDS with nodsh"
15130         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
15131                 skip_env "MDS doesn't support rename stats"
15132
15133         local testdir1=$DIR/${tdir}/stats_testdir1
15134         local testdir2=$DIR/${tdir}/stats_testdir2
15135         mkdir -p $DIR/${tdir} || error "mkdir $tdir failed"
15136
15137         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
15138
15139         mkdir_on_mdt0 ${testdir1} || error "mkdir $testdir1 failed"
15140         mkdir_on_mdt0 ${testdir2} || error "mkdir $testdir2 failed"
15141
15142         createmany -o $testdir1/test 512 || error "createmany failed"
15143
15144         # check samedir rename size
15145         mv ${testdir1}/test0 ${testdir1}/test_0
15146
15147         local testdir1_size=$(ls -l $DIR/${tdir} |
15148                 awk '/stats_testdir1/ {print $5}')
15149         local testdir2_size=$(ls -l $DIR/${tdir} |
15150                 awk '/stats_testdir2/ {print $5}')
15151
15152         testdir1_size=$(order_2 $testdir1_size)
15153         testdir2_size=$(order_2 $testdir2_size)
15154
15155         testdir1_size=$(size_in_KMGT $testdir1_size)
15156         testdir2_size=$(size_in_KMGT $testdir2_size)
15157
15158         echo "source rename dir size: ${testdir1_size}"
15159         echo "target rename dir size: ${testdir2_size}"
15160
15161         local cmd="do_facet $SINGLEMDS $LCTL "
15162         cmd+="get_param mdt.$FSNAME-MDT0000.rename_stats"
15163
15164         eval $cmd || error "$cmd failed"
15165         local samedir=$($cmd | grep 'same_dir')
15166         local same_sample=$(get_rename_size $testdir1_size)
15167         [ -z "$samedir" ] && error "samedir_rename_size count error"
15168         [[ $same_sample -eq 1 ]] ||
15169                 error "samedir_rename_size error $same_sample"
15170         echo "Check same dir rename stats success"
15171
15172         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
15173
15174         # check crossdir rename size
15175         mv ${testdir1}/test_0 ${testdir2}/test_0
15176
15177         testdir1_size=$(ls -l $DIR/${tdir} |
15178                 awk '/stats_testdir1/ {print $5}')
15179         testdir2_size=$(ls -l $DIR/${tdir} |
15180                 awk '/stats_testdir2/ {print $5}')
15181
15182         testdir1_size=$(order_2 $testdir1_size)
15183         testdir2_size=$(order_2 $testdir2_size)
15184
15185         testdir1_size=$(size_in_KMGT $testdir1_size)
15186         testdir2_size=$(size_in_KMGT $testdir2_size)
15187
15188         echo "source rename dir size: ${testdir1_size}"
15189         echo "target rename dir size: ${testdir2_size}"
15190
15191         eval $cmd || error "$cmd failed"
15192         local crossdir=$($cmd | grep 'crossdir')
15193         local src_sample=$(get_rename_size $testdir1_size crossdir_src)
15194         local tgt_sample=$(get_rename_size $testdir2_size crossdir_tgt)
15195         [ -z "$crossdir" ] && error "crossdir_rename_size count error"
15196         [[ $src_sample -eq 1 ]] ||
15197                 error "crossdir_rename_size error $src_sample"
15198         [[ $tgt_sample -eq 1 ]] ||
15199                 error "crossdir_rename_size error $tgt_sample"
15200         echo "Check cross dir rename stats success"
15201         rm -rf $DIR/${tdir}
15202 }
15203 run_test 133d "Verifying rename_stats ========================================"
15204
15205 test_133e() {
15206         remote_mds_nodsh && skip "remote MDS with nodsh"
15207         remote_ost_nodsh && skip "remote OST with nodsh"
15208         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15209
15210         local testdir=$DIR/${tdir}/stats_testdir
15211         local ctr f0 f1 bs=32768 count=42 sum
15212
15213         mkdir -p ${testdir} || error "mkdir failed"
15214
15215         $LFS setstripe -c 1 -i 0 ${testdir}/${tfile}
15216
15217         for ctr in {write,read}_bytes; do
15218                 sync
15219                 cancel_lru_locks osc
15220
15221                 do_facet ost1 $LCTL set_param -n \
15222                         "obdfilter.*.exports.clear=clear"
15223
15224                 if [ $ctr = write_bytes ]; then
15225                         f0=/dev/zero
15226                         f1=${testdir}/${tfile}
15227                 else
15228                         f0=${testdir}/${tfile}
15229                         f1=/dev/null
15230                 fi
15231
15232                 dd if=$f0 of=$f1 conv=notrunc bs=$bs count=$count || \
15233                         error "dd failed"
15234                 sync
15235                 cancel_lru_locks osc
15236
15237                 sum=$(do_facet ost1 $LCTL get_param \
15238                         "obdfilter.*.exports.*.stats" |
15239                         awk -v ctr=$ctr 'BEGIN { sum = 0 }
15240                                 $1 == ctr { sum += $7 }
15241                                 END { printf("%0.0f", sum) }')
15242
15243                 if ((sum != bs * count)); then
15244                         error "Bad $ctr sum, expected $((bs * count)), got $sum"
15245                 fi
15246         done
15247
15248         rm -rf $DIR/${tdir}
15249 }
15250 run_test 133e "Verifying OST {read,write}_bytes nid stats ================="
15251
15252 test_133f() {
15253         [[ $(lustre_version_code $facet) -ge $(version_code 2.7.65) ]] ||
15254                 skip "too old lustre for get_param -R ($facet_ver)"
15255
15256         # verifying readability.
15257         $LCTL get_param -R '*' &> /dev/null
15258
15259         # Verifing writability with badarea_io.
15260         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
15261         local skipped_params='force_lbug|changelog_mask|daemon_file'
15262         $LCTL list_param -FR '*' | grep '=' | tr -d = |
15263                 egrep -v "$skipped_params" |
15264                 xargs -n 1 find $proc_dirs -name |
15265                 xargs -n 1 badarea_io ||
15266                 error "client badarea_io failed"
15267
15268         # remount the FS in case writes/reads /proc break the FS
15269         cleanup || error "failed to unmount"
15270         setup || error "failed to setup"
15271 }
15272 run_test 133f "Check reads/writes of client lustre proc files with bad area io"
15273
15274 test_133g() {
15275         remote_mds_nodsh && skip "remote MDS with nodsh"
15276         remote_ost_nodsh && skip "remote OST with nodsh"
15277
15278         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
15279         local proc_dirs_str=$(eval echo $proc_dirs)
15280         local skipped_params="'force_lbug|changelog_mask|daemon_file'"
15281         local facet
15282         for facet in mds1 ost1; do
15283                 local facet_ver=$(lustre_version_code $facet)
15284                 if [ $facet_ver -ge $(version_code 2.7.65) ]; then
15285                         do_facet $facet "$LCTL get_param -R '*'" &> /dev/null
15286                 else
15287                         log "$facet: too old lustre for get_param -R"
15288                 fi
15289                 if [ $facet_ver -ge $(version_code 2.5.54) ]; then
15290                         do_facet $facet "$LCTL list_param -FR '*' | grep '=' |
15291                                 tr -d = | egrep -v $skipped_params |
15292                                 xargs -n 1 find $proc_dirs_str -name |
15293                                 xargs -n 1 badarea_io" ||
15294                                         error "$facet badarea_io failed"
15295                 else
15296                         skip_noexit "$facet: too old lustre for get_param -R"
15297                 fi
15298         done
15299
15300         # remount the FS in case writes/reads /proc break the FS
15301         cleanup || error "failed to unmount"
15302         setup || error "failed to setup"
15303 }
15304 run_test 133g "Check reads/writes of server lustre proc files with bad area io"
15305
15306 test_133h() {
15307         remote_mds_nodsh && skip "remote MDS with nodsh"
15308         remote_ost_nodsh && skip "remote OST with nodsh"
15309         [[ $MDS1_VERSION -lt $(version_code 2.9.54) ]] &&
15310                 skip "Need MDS version at least 2.9.54"
15311
15312         local facet
15313         for facet in client mds1 ost1; do
15314                 # Get the list of files that are missing the terminating newline
15315                 local plist=$(do_facet $facet
15316                         $LCTL list_param -FR '*' | grep '=' | tr -d =)
15317                 local ent
15318                 for ent in $plist; do
15319                         local missing=$(do_facet $facet $LCTL get_param $ent \|\
15320                                 awk -v FS='\v' -v RS='\v\v' \
15321                                 "'END { if(NR>0 && \\\$NF !~ /.*\\\n\$/) \
15322                                         print FILENAME}'" 2>/dev/null)
15323                         [ -z $missing ] || {
15324                                 do_facet $facet $LCTL get_param $ent | od -An -tx1
15325                                 error "file does not end with newline: $facet-$ent"
15326                         }
15327                 done
15328         done
15329 }
15330 run_test 133h "Proc files should end with newlines"
15331
15332 test_134a() {
15333         remote_mds_nodsh && skip "remote MDS with nodsh"
15334         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
15335                 skip "Need MDS version at least 2.7.54"
15336
15337         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
15338         cancel_lru_locks mdc
15339
15340         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
15341         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
15342         [ $unused -eq 0 ] || error "$unused locks are not cleared"
15343
15344         local nr=1000
15345         createmany -o $DIR/$tdir/f $nr ||
15346                 error "failed to create $nr files in $DIR/$tdir"
15347         unused=$($LCTL get_param -n $nsdir.lock_unused_count)
15348
15349         #define OBD_FAIL_LDLM_WATERMARK_LOW     0x327
15350         do_facet mds1 $LCTL set_param fail_loc=0x327
15351         do_facet mds1 $LCTL set_param fail_val=500
15352         touch $DIR/$tdir/m
15353
15354         echo "sleep 10 seconds ..."
15355         sleep 10
15356         local lck_cnt=$($LCTL get_param -n $nsdir.lock_unused_count)
15357
15358         do_facet mds1 $LCTL set_param fail_loc=0
15359         do_facet mds1 $LCTL set_param fail_val=0
15360         [ $lck_cnt -lt $unused ] ||
15361                 error "No locks reclaimed, before:$unused, after:$lck_cnt"
15362
15363         rm $DIR/$tdir/m
15364         unlinkmany $DIR/$tdir/f $nr
15365 }
15366 run_test 134a "Server reclaims locks when reaching lock_reclaim_threshold"
15367
15368 test_134b() {
15369         remote_mds_nodsh && skip "remote MDS with nodsh"
15370         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
15371                 skip "Need MDS version at least 2.7.54"
15372
15373         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
15374         cancel_lru_locks mdc
15375
15376         local low_wm=$(do_facet mds1 $LCTL get_param -n \
15377                         ldlm.lock_reclaim_threshold_mb)
15378         # disable reclaim temporarily
15379         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=0
15380
15381         #define OBD_FAIL_LDLM_WATERMARK_HIGH     0x328
15382         do_facet mds1 $LCTL set_param fail_loc=0x328
15383         do_facet mds1 $LCTL set_param fail_val=500
15384
15385         $LCTL set_param debug=+trace
15386
15387         local nr=600
15388         createmany -o $DIR/$tdir/f $nr &
15389         local create_pid=$!
15390
15391         echo "Sleep $TIMEOUT seconds ..."
15392         sleep $TIMEOUT
15393         if ! ps -p $create_pid  > /dev/null 2>&1; then
15394                 do_facet mds1 $LCTL set_param fail_loc=0
15395                 do_facet mds1 $LCTL set_param fail_val=0
15396                 do_facet mds1 $LCTL set_param \
15397                         ldlm.lock_reclaim_threshold_mb=${low_wm}m
15398                 error "createmany finished incorrectly!"
15399         fi
15400         do_facet mds1 $LCTL set_param fail_loc=0
15401         do_facet mds1 $LCTL set_param fail_val=0
15402         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=${low_wm}m
15403         wait $create_pid || return 1
15404
15405         unlinkmany $DIR/$tdir/f $nr
15406 }
15407 run_test 134b "Server rejects lock request when reaching lock_limit_mb"
15408
15409 test_135() {
15410         remote_mds_nodsh && skip "remote MDS with nodsh"
15411         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
15412                 skip "Need MDS version at least 2.13.50"
15413         local fname
15414
15415         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
15416
15417 #define OBD_FAIL_PLAIN_RECORDS 0x1319
15418         #set only one record at plain llog
15419         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1319 fail_val=1
15420
15421         ost_set_temp_seq_width_all $DATA_SEQ_MAX_WIDTH
15422
15423         #fill already existed plain llog each 64767
15424         #wrapping whole catalog
15425         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
15426
15427         createmany -o $DIR/$tdir/$tfile_ 64700
15428         for (( i = 0; i < 64700; i = i + 2 ))
15429         do
15430                 rm $DIR/$tdir/$tfile_$i &
15431                 rm $DIR/$tdir/$tfile_$((i + 1)) &
15432                 local pid=$!
15433                 wait $pid
15434         done
15435
15436         #waiting osp synchronization
15437         wait_delete_completed
15438 }
15439 run_test 135 "Race catalog processing"
15440
15441 test_136() {
15442         remote_mds_nodsh && skip "remote MDS with nodsh"
15443         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
15444                 skip "Need MDS version at least 2.13.50"
15445         local fname
15446
15447         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
15448         $LFS setstripe -c 1 -i 0 $DIR/$tdir || error "failed to set striping"
15449         #set only one record at plain llog
15450 #define OBD_FAIL_CATALOG_FULL_CHECK                0x131a
15451         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x131a fail_val=1
15452
15453         ost_set_temp_seq_width_all $DATA_SEQ_MAX_WIDTH
15454
15455         #fill already existed 2 plain llogs each 64767
15456         #wrapping whole catalog
15457         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
15458         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 3 / 2))
15459         wait_delete_completed
15460
15461         createmany -o $DIR/$tdir/$tfile_ 10
15462         sleep 25
15463
15464         do_facet $SINGLEMDS $LCTL set_param fail_val=3
15465         for (( i = 0; i < 10; i = i + 3 ))
15466         do
15467                 rm $DIR/$tdir/$tfile_$i &
15468                 rm $DIR/$tdir/$tfile_$((i + 1)) &
15469                 local pid=$!
15470                 wait $pid
15471                 sleep 7
15472                 rm $DIR/$tdir/$tfile_$((i + 2)) &
15473         done
15474
15475         #waiting osp synchronization
15476         wait_delete_completed
15477 }
15478 run_test 136 "Race catalog processing 2"
15479
15480 test_140() { #bug-17379
15481         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15482
15483         test_mkdir $DIR/$tdir
15484         cd $DIR/$tdir || error "Changing to $DIR/$tdir"
15485         cp $(which stat) . || error "Copying stat to $DIR/$tdir"
15486
15487         # VFS limits max symlink depth to 5(4KSTACK) or 7(8KSTACK) or 8
15488         # For kernel > 3.5, bellow only tests consecutive symlink (MAX 40)
15489         local i=0
15490         while i=$((i + 1)); do
15491                 test_mkdir $i
15492                 cd $i || error "Changing to $i"
15493                 ln -s ../stat stat || error "Creating stat symlink"
15494                 # Read the symlink until ELOOP present,
15495                 # not LBUGing the system is considered success,
15496                 # we didn't overrun the stack.
15497                 $OPENFILE -f O_RDONLY stat >/dev/null 2>&1; ret=$?
15498                 if [ $ret -ne 0 ]; then
15499                         if [ $ret -eq 40 ]; then
15500                                 break  # -ELOOP
15501                         else
15502                                 error "Open stat symlink"
15503                                         return
15504                         fi
15505                 fi
15506         done
15507         i=$((i - 1))
15508         echo "The symlink depth = $i"
15509         [ $i -eq 5 ] || [ $i -eq 7 ] || [ $i -eq 8 ] || [ $i -eq 40 ] ||
15510                 error "Invalid symlink depth"
15511
15512         # Test recursive symlink
15513         ln -s symlink_self symlink_self
15514         $OPENFILE -f O_RDONLY symlink_self >/dev/null 2>&1; ret=$?
15515         echo "open symlink_self returns $ret"
15516         [ $ret -eq 40 ] || error "recursive symlink doesn't return -ELOOP"
15517 }
15518 run_test 140 "Check reasonable stack depth (shouldn't LBUG) ===="
15519
15520 test_150a() {
15521         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15522
15523         local TF="$TMP/$tfile"
15524
15525         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15526         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
15527         cp $TF $DIR/$tfile
15528         cancel_lru_locks $OSC
15529         cmp $TF $DIR/$tfile || error "$TMP/$tfile $DIR/$tfile differ"
15530         remount_client $MOUNT
15531         df -P $MOUNT
15532         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (remount)"
15533
15534         $TRUNCATE $TF 6000
15535         $TRUNCATE $DIR/$tfile 6000
15536         cancel_lru_locks $OSC
15537         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (truncate1)"
15538
15539         echo "12345" >>$TF
15540         echo "12345" >>$DIR/$tfile
15541         cancel_lru_locks $OSC
15542         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append1)"
15543
15544         echo "12345" >>$TF
15545         echo "12345" >>$DIR/$tfile
15546         cancel_lru_locks $OSC
15547         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append2)"
15548 }
15549 run_test 150a "truncate/append tests"
15550
15551 test_150b() {
15552         check_set_fallocate_or_skip
15553         local out
15554
15555         touch $DIR/$tfile
15556         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15557         out=$(check_fallocate $DIR/$tfile 2>&1) ||
15558                 skip_eopnotsupp "$out|check_fallocate failed"
15559 }
15560 run_test 150b "Verify fallocate (prealloc) functionality"
15561
15562 test_150bb() {
15563         check_set_fallocate_or_skip
15564
15565         touch $DIR/$tfile
15566         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15567         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=20 || error "dd failed"
15568         > $DIR/$tfile
15569         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
15570         # precomputed md5sum for 20MB of zeroes
15571         local expect="8f4e33f3dc3e414ff94e5fb6905cba8c"
15572         local sum=($(md5sum $DIR/$tfile))
15573
15574         [[ "${sum[0]}" == "$expect" ]] || error "fallocate unwritten is not zero"
15575
15576         check_set_fallocate 1
15577
15578         > $DIR/$tfile
15579         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
15580         sum=($(md5sum $DIR/$tfile))
15581
15582         [[ "${sum[0]}" == "$expect" ]] || error "fallocate zero is not zero"
15583 }
15584 run_test 150bb "Verify fallocate modes both zero space"
15585
15586 test_150c() {
15587         check_set_fallocate_or_skip
15588         local striping="-c2"
15589
15590         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15591         $LFS setstripe -c $OSTCOUNT -S1M $DIR/$tfile || error "setstripe failed"
15592         fallocate -l ${OSTCOUNT}m $DIR/$tfile || error "fallocate failed"
15593         local bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
15594         local want=$((OSTCOUNT * 1048576))
15595
15596         # Must allocate all requested space, not more than 5% extra
15597         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
15598                 error "bytes $bytes is not $want"
15599
15600         rm -f $DIR/$tfile
15601
15602         echo "verify fallocate on PFL file"
15603
15604         [[ "x$DOM" == "xyes" ]] && striping="-L mdt"
15605
15606         $LFS setstripe -E1M $striping -E16M -c3 -Eeof -c 4 $DIR/$tfile ||
15607                 error "Create $DIR/$tfile failed"
15608         fallocate -l $((1048576 * 512)) $DIR/$tfile || error "fallocate failed"
15609         bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
15610         want=$((512 * 1048576))
15611
15612         # Must allocate all requested space, not more than 5% extra
15613         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
15614                 error "bytes $bytes is not $want"
15615 }
15616 run_test 150c "Verify fallocate Size and Blocks"
15617
15618 test_150d() {
15619         check_set_fallocate_or_skip
15620         local striping="-c2"
15621
15622         [[ "x$DOM" == "xyes" ]] && striping="-L mdt"
15623
15624         stack_trap "rm -f $DIR/$tdir; wait_delete_completed"
15625         $LFS setstripe -E1M $striping -E eof -c $OSTCOUNT -S1M $DIR/$tdir ||
15626                 error "setstripe failed"
15627         fallocate -o 1G -l ${OSTCOUNT}m $DIR/$tdir || error "fallocate failed"
15628         local bytes=$(($(stat -c '%b * %B' $DIR/$tdir)))
15629         local want=$((OSTCOUNT * 1048576))
15630
15631         # Must allocate all requested space, not more than 5% extra
15632         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
15633                 error "bytes $bytes is not $want"
15634 }
15635 run_test 150d "Verify fallocate Size and Blocks - Non zero start"
15636
15637 test_150e() {
15638         check_set_fallocate_or_skip
15639
15640         echo "df before:"
15641         $LFS df
15642         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15643         $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
15644                 error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
15645
15646         # Find OST with Minimum Size
15647         min_size_ost=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
15648                        sort -un | head -1)
15649
15650         # Get 100MB per OST of the available space to reduce run time
15651         # else 60% of the available space if we are running SLOW tests
15652         if [ $SLOW == "no" ]; then
15653                 local space=$((1024 * 100 * OSTCOUNT))
15654         else
15655                 local space=$(((min_size_ost * 60)/100 * OSTCOUNT))
15656         fi
15657
15658         fallocate -l${space}k $DIR/$tfile ||
15659                 error "fallocate ${space}k $DIR/$tfile failed"
15660         echo "'fallocate -l ${space}k $DIR/$tfile' succeeded"
15661
15662         # get size immediately after fallocate. This should be correctly
15663         # updated
15664         local size=$(stat -c '%s' $DIR/$tfile)
15665         local used=$(( $(stat -c '%b * %B' $DIR/$tfile) / 1024))
15666
15667         # Sleep for a while for statfs to get updated. And not pull from cache.
15668         sleep 2
15669
15670         echo "df after fallocate:"
15671         $LFS df
15672
15673         (( size / 1024 == space )) || error "size $size != requested $space"
15674         [ "$ost1_FSTYPE" != ldiskfs ] || (( used >= space )) ||
15675                 error "used $used < space $space"
15676
15677         rm $DIR/$tfile || error "rm failed"
15678         sync
15679         wait_delete_completed
15680
15681         echo "df after unlink:"
15682         $LFS df
15683 }
15684 run_test 150e "Verify 60% of available OST space consumed by fallocate"
15685
15686 test_150f() {
15687         local size
15688         local blocks
15689         local want_size_before=20480 # in bytes
15690         local want_blocks_before=40 # 512 sized blocks
15691         local want_blocks_after=24  # 512 sized blocks
15692         local length=$(((want_blocks_before - want_blocks_after) * 512))
15693
15694         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
15695                 skip "need at least 2.14.0 for fallocate punch"
15696
15697         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
15698                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
15699         fi
15700
15701         check_set_fallocate_or_skip
15702         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15703
15704         [[ "x$DOM" == "xyes" ]] &&
15705                 $LFS setstripe -E1M -L mdt -E eof $DIR/$tfile
15706
15707         echo "Verify fallocate punch: Range within the file range"
15708         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
15709                 error "dd failed for bs 4096 and count 5"
15710
15711         # Call fallocate with punch range which is within the file range
15712         out=$(fallocate -p --offset 4096 -l $length $DIR/$tfile 2>&1) ||
15713                 skip_eopnotsupp "$out|fallocate: offset 4096 and length $length"
15714         # client must see changes immediately after fallocate
15715         size=$(stat -c '%s' $DIR/$tfile)
15716         blocks=$(stat -c '%b' $DIR/$tfile)
15717
15718         # Verify punch worked.
15719         (( blocks == want_blocks_after )) ||
15720                 error "punch failed: blocks $blocks != $want_blocks_after"
15721
15722         (( size == want_size_before )) ||
15723                 error "punch failed: size $size != $want_size_before"
15724
15725         # Verify there is hole in file
15726         local data_off=$(lseek_test -d 4096 $DIR/$tfile)
15727         # precomputed md5sum
15728         local expect="4a9a834a2db02452929c0a348273b4aa"
15729
15730         cksum=($(md5sum $DIR/$tfile))
15731         [[ "${cksum[0]}" == "$expect" ]] ||
15732                 error "unexpected MD5SUM after punch: ${cksum[0]}"
15733
15734         # Start second sub-case for fallocate punch.
15735         echo "Verify fallocate punch: Range overlapping and less than blocksize"
15736         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
15737                 error "dd failed for bs 4096 and count 5"
15738
15739         # Punch range less than block size will have no change in block count
15740         want_blocks_after=40  # 512 sized blocks
15741
15742         # Punch overlaps two blocks and less than blocksize
15743         out=$(fallocate -p --offset 4000 -l 3000 $DIR/$tfile 2>&1) ||
15744                 skip_eopnotsupp "$out|fallocate: offset 4000 length 3000"
15745         size=$(stat -c '%s' $DIR/$tfile)
15746         blocks=$(stat -c '%b' $DIR/$tfile)
15747
15748         # Verify punch worked.
15749         (( blocks == want_blocks_after )) ||
15750                 error "punch failed: blocks $blocks != $want_blocks_after"
15751
15752         (( size == want_size_before )) ||
15753                 error "punch failed: size $size != $want_size_before"
15754
15755         # Verify if range is really zero'ed out. We expect Zeros.
15756         # precomputed md5sum
15757         expect="c57ec5d769c3dbe3426edc3f7d7e11d3"
15758         cksum=($(md5sum $DIR/$tfile))
15759         [[ "${cksum[0]}" == "$expect" ]] ||
15760                 error "unexpected MD5SUM after punch: ${cksum[0]}"
15761 }
15762 run_test 150f "Verify fallocate punch functionality"
15763
15764 test_150g() {
15765         local space
15766         local size
15767         local blocks
15768         local blocks_after
15769         local size_after
15770         local BS=4096 # Block size in bytes
15771
15772         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
15773                 skip "need at least 2.14.0 for fallocate punch"
15774
15775         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
15776                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
15777         fi
15778
15779         check_set_fallocate_or_skip
15780         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15781
15782         if [[ "x$DOM" == "xyes" ]]; then
15783                 $LFS setstripe -E2M -L mdt -E eof -c${OSTCOUNT} $DIR/$tfile ||
15784                         error "$LFS setstripe DoM + ${OSTCOUNT} OST failed"
15785         else
15786                 $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
15787                         error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
15788         fi
15789
15790         # Get 100MB per OST of the available space to reduce run time
15791         # else 60% of the available space if we are running SLOW tests
15792         if [ $SLOW == "no" ]; then
15793                 space=$((1024 * 100 * OSTCOUNT))
15794         else
15795                 # Find OST with Minimum Size
15796                 space=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
15797                         sort -un | head -1)
15798                 echo "min size OST: $space"
15799                 space=$(((space * 60)/100 * OSTCOUNT))
15800         fi
15801         # space in 1k units, round to 4k blocks
15802         local blkcount=$((space * 1024 / $BS))
15803
15804         echo "Verify fallocate punch: Very large Range"
15805         fallocate -l${space}k $DIR/$tfile ||
15806                 error "fallocate ${space}k $DIR/$tfile failed"
15807         # write 1M at the end, start and in the middle
15808         yes 'A' | dd of=$DIR/$tfile bs=$BS count=256 ||
15809                 error "dd failed: bs $BS count 256"
15810         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount - 256)) count=256 ||
15811                 error "dd failed: bs $BS count 256 seek $((blkcount - 256))"
15812         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount / 2)) count=1024 ||
15813                 error "dd failed: bs $BS count 256 seek $((blkcount / 2))"
15814
15815         # Gather stats.
15816         size=$(stat -c '%s' $DIR/$tfile)
15817
15818         # gather punch length.
15819         local punch_size=$((size - (BS * 2)))
15820
15821         echo "punch_size = $punch_size"
15822         echo "size - punch_size: $((size - punch_size))"
15823         echo "size - punch_size in blocks: $(((size - punch_size)/BS))"
15824
15825         # Call fallocate to punch all except 2 blocks. We leave the
15826         # first and the last block
15827         echo "fallocate -p --offset $BS -l $punch_size $DIR/$tfile"
15828         out=$(fallocate -p --offset $BS -l $punch_size $DIR/$tfile 2>&1) ||
15829                 skip_eopnotsupp "$out|fallocate: offset $BS length $punch_size"
15830
15831         size_after=$(stat -c '%s' $DIR/$tfile)
15832         blocks_after=$(stat -c '%b' $DIR/$tfile)
15833
15834         # Verify punch worked.
15835         # Size should be kept
15836         (( size == size_after )) ||
15837                 error "punch failed: size $size != $size_after"
15838
15839         # two 4k data blocks to remain plus possible 1 extra extent block
15840         (( blocks_after <= ((BS / 512) * 3) )) ||
15841                 error "too many blocks remains: $blocks_after"
15842
15843         # Verify that file has hole between the first and the last blocks
15844         local hole_start=$(lseek_test -l 0 $DIR/$tfile)
15845         local hole_end=$(lseek_test -d $BS $DIR/$tfile)
15846
15847         echo "Hole at [$hole_start, $hole_end)"
15848         (( hole_start == BS )) ||
15849                 error "no hole at offset $BS after punch"
15850
15851         (( hole_end == BS + punch_size )) ||
15852                 error "data at offset $hole_end < $((BS + punch_size))"
15853 }
15854 run_test 150g "Verify fallocate punch on large range"
15855
15856 test_150h() {
15857         local file=$DIR/$tfile
15858         local size
15859
15860         check_set_fallocate_or_skip
15861         statx_supported || skip_env "Test must be statx() syscall supported"
15862
15863         # fallocate() does not update the size information on the MDT
15864         fallocate -l 16K $file || error "failed to fallocate $file"
15865         cancel_lru_locks $OSC
15866         # STATX with cached-always mode will not send glimpse RPCs to OST,
15867         # it uses the caching attrs on the client side as much as possible.
15868         size=$($STATX --cached=always -c %s $file)
15869         [ $size == 16384 ] ||
15870                 error "size after fallocate() is $size, expected 16384"
15871 }
15872 run_test 150h "Verify extend fallocate updates the file size"
15873
15874 #LU-2902 roc_hit was not able to read all values from lproc
15875 function roc_hit_init() {
15876         local list=$(comma_list $(osts_nodes))
15877         local dir=$DIR/$tdir-check
15878         local file=$dir/$tfile
15879         local BEFORE
15880         local AFTER
15881         local idx
15882
15883         test_mkdir $dir
15884         #use setstripe to do a write to every ost
15885         for i in $(seq 0 $((OSTCOUNT-1))); do
15886                 $LFS setstripe -c 1 -i $i $dir || error "$LFS setstripe $file failed"
15887                 dd if=/dev/urandom of=$file bs=4k count=4 2>&1 > /dev/null
15888                 idx=$(printf %04x $i)
15889                 BEFORE=$(get_osd_param $list *OST*$idx stats |
15890                         awk '$1 == "cache_access" {sum += $7}
15891                                 END { printf("%0.0f", sum) }')
15892
15893                 cancel_lru_locks osc
15894                 cat $file >/dev/null
15895
15896                 AFTER=$(get_osd_param $list *OST*$idx stats |
15897                         awk '$1 == "cache_access" {sum += $7}
15898                                 END { printf("%0.0f", sum) }')
15899
15900                 echo BEFORE:$BEFORE AFTER:$AFTER
15901                 if ! let "AFTER - BEFORE == 4"; then
15902                         rm -rf $dir
15903                         error "roc_hit is not safe to use"
15904                 fi
15905                 rm $file
15906         done
15907
15908         rm -rf $dir
15909 }
15910
15911 function roc_hit() {
15912         local list=$(comma_list $(osts_nodes))
15913         echo $(get_osd_param $list '' stats |
15914                 awk '$1 == "cache_hit" {sum += $7}
15915                         END { printf("%0.0f", sum) }')
15916 }
15917
15918 function set_cache() {
15919         local on=1
15920
15921         if [ "$2" == "off" ]; then
15922                 on=0;
15923         fi
15924         local list=$(comma_list $(osts_nodes))
15925         set_osd_param $list '' $1_cache_enable $on
15926
15927         cancel_lru_locks osc
15928 }
15929
15930 test_151() {
15931         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15932         remote_ost_nodsh && skip "remote OST with nodsh"
15933         (( CLIENT_VERSION == OST1_VERSION )) ||
15934                 skip "LU-13081: no interop testing for OSS cache"
15935
15936         local CPAGES=3
15937         local list=$(comma_list $(osts_nodes))
15938
15939         # check whether obdfilter is cache capable at all
15940         if ! get_osd_param $list '' read_cache_enable >/dev/null; then
15941                 skip "not cache-capable obdfilter"
15942         fi
15943
15944         # check cache is enabled on all obdfilters
15945         if get_osd_param $list '' read_cache_enable | grep 0; then
15946                 skip "oss cache is disabled"
15947         fi
15948
15949         set_osd_param $list '' writethrough_cache_enable 1
15950
15951         # check write cache is enabled on all obdfilters
15952         if get_osd_param $list '' writethrough_cache_enable | grep 0; then
15953                 skip "oss write cache is NOT enabled"
15954         fi
15955
15956         roc_hit_init
15957
15958         #define OBD_FAIL_OBD_NO_LRU  0x609
15959         do_nodes $list $LCTL set_param fail_loc=0x609
15960
15961         # pages should be in the case right after write
15962         dd if=/dev/urandom of=$DIR/$tfile bs=4k count=$CPAGES ||
15963                 error "dd failed"
15964
15965         local BEFORE=$(roc_hit)
15966         cancel_lru_locks osc
15967         cat $DIR/$tfile >/dev/null
15968         local AFTER=$(roc_hit)
15969
15970         do_nodes $list $LCTL set_param fail_loc=0
15971
15972         if ! let "AFTER - BEFORE == CPAGES"; then
15973                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
15974         fi
15975
15976         cancel_lru_locks osc
15977         # invalidates OST cache
15978         do_nodes $list "echo 1 > /proc/sys/vm/drop_caches"
15979         set_osd_param $list '' read_cache_enable 0
15980         cat $DIR/$tfile >/dev/null
15981
15982         # now data shouldn't be found in the cache
15983         BEFORE=$(roc_hit)
15984         cancel_lru_locks osc
15985         cat $DIR/$tfile >/dev/null
15986         AFTER=$(roc_hit)
15987         if let "AFTER - BEFORE != 0"; then
15988                 error "IN CACHE: before: $BEFORE, after: $AFTER"
15989         fi
15990
15991         set_osd_param $list '' read_cache_enable 1
15992         rm -f $DIR/$tfile
15993 }
15994 run_test 151 "test cache on oss and controls ==============================="
15995
15996 test_152() {
15997         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15998
15999         local TF="$TMP/$tfile"
16000
16001         # simulate ENOMEM during write
16002 #define OBD_FAIL_OST_NOMEM      0x226
16003         lctl set_param fail_loc=0x80000226
16004         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
16005         cp $TF $DIR/$tfile
16006         sync || error "sync failed"
16007         lctl set_param fail_loc=0
16008
16009         # discard client's cache
16010         cancel_lru_locks osc
16011
16012         # simulate ENOMEM during read
16013         lctl set_param fail_loc=0x80000226
16014         cmp $TF $DIR/$tfile || error "cmp failed"
16015         lctl set_param fail_loc=0
16016
16017         rm -f $TF
16018 }
16019 run_test 152 "test read/write with enomem ============================"
16020
16021 test_153() {
16022         $MULTIOP $DIR/$tfile Ow4096Ycu || error "multiop failed"
16023 }
16024 run_test 153 "test if fdatasync does not crash ======================="
16025
16026 dot_lustre_fid_permission_check() {
16027         local fid=$1
16028         local ffid=$MOUNT/.lustre/fid/$fid
16029         local test_dir=$2
16030
16031         echo "stat fid $fid"
16032         stat $ffid || error "stat $ffid failed."
16033         echo "touch fid $fid"
16034         touch $ffid || error "touch $ffid failed."
16035         echo "write to fid $fid"
16036         cat /etc/hosts > $ffid || error "write $ffid failed."
16037         echo "read fid $fid"
16038         diff /etc/hosts $ffid || error "read $ffid failed."
16039         echo "append write to fid $fid"
16040         cat /etc/hosts >> $ffid || error "append write $ffid failed."
16041         echo "rename fid $fid"
16042         mv $ffid $test_dir/$tfile.1 &&
16043                 error "rename $ffid to $tfile.1 should fail."
16044         touch $test_dir/$tfile.1
16045         mv $test_dir/$tfile.1 $ffid &&
16046                 error "rename $tfile.1 to $ffid should fail."
16047         rm -f $test_dir/$tfile.1
16048         echo "truncate fid $fid"
16049         $TRUNCATE $ffid 777 || error "truncate $ffid failed."
16050         echo "link fid $fid"
16051         ln -f $ffid $test_dir/tfile.lnk || error "link $ffid failed."
16052         if [[ $($LCTL get_param -n mdc.*-mdc-*.connect_flags) =~ acl ]]; then
16053                 echo "setfacl fid $fid"
16054                 setfacl -R -m u:$USER0:rwx $ffid ||
16055                         error "setfacl $ffid failed"
16056                 echo "getfacl fid $fid"
16057                 getfacl $ffid || error "getfacl $ffid failed."
16058         fi
16059         echo "unlink fid $fid"
16060         unlink $MOUNT/.lustre/fid/$fid && error "unlink $ffid should fail."
16061         echo "mknod fid $fid"
16062         mknod $ffid c 1 3 && error "mknod $ffid should fail."
16063
16064         fid=[0xf00000400:0x1:0x0]
16065         ffid=$MOUNT/.lustre/fid/$fid
16066
16067         echo "stat non-exist fid $fid"
16068         stat $ffid > /dev/null && error "stat non-exist $ffid should fail."
16069         echo "write to non-exist fid $fid"
16070         cat /etc/hosts > $ffid && error "write non-exist $ffid should fail."
16071         echo "link new fid $fid"
16072         ln $test_dir/$tfile $ffid && error "link $ffid should fail."
16073
16074         mkdir -p $test_dir/$tdir
16075         touch $test_dir/$tdir/$tfile
16076         fid=$($LFS path2fid $test_dir/$tdir)
16077         rc=$?
16078         [ $rc -ne 0 ] &&
16079                 error "error: could not get fid for $test_dir/$dir/$tfile."
16080
16081         ffid=$MOUNT/.lustre/fid/$fid
16082
16083         echo "ls $fid"
16084         ls $ffid || error "ls $ffid failed."
16085         echo "touch $fid/$tfile.1"
16086         touch $ffid/$tfile.1 || error "touch $ffid/$tfile.1 failed."
16087
16088         echo "touch $MOUNT/.lustre/fid/$tfile"
16089         touch $MOUNT/.lustre/fid/$tfile && \
16090                 error "touch $MOUNT/.lustre/fid/$tfile should fail."
16091
16092         echo "setxattr to $MOUNT/.lustre/fid"
16093         setfattr -n trusted.name1 -v value1 $MOUNT/.lustre/fid
16094
16095         echo "listxattr for $MOUNT/.lustre/fid"
16096         getfattr -d -m "^trusted" $MOUNT/.lustre/fid
16097
16098         echo "delxattr from $MOUNT/.lustre/fid"
16099         setfattr -x trusted.name1 $MOUNT/.lustre/fid
16100
16101         echo "touch invalid fid: $MOUNT/.lustre/fid/[0x200000400:0x2:0x3]"
16102         touch $MOUNT/.lustre/fid/[0x200000400:0x2:0x3] &&
16103                 error "touch invalid fid should fail."
16104
16105         echo "touch non-normal fid: $MOUNT/.lustre/fid/[0x1:0x2:0x0]"
16106         touch $MOUNT/.lustre/fid/[0x1:0x2:0x0] &&
16107                 error "touch non-normal fid should fail."
16108
16109         echo "rename $tdir to $MOUNT/.lustre/fid"
16110         mrename $test_dir/$tdir $MOUNT/.lustre/fid &&
16111                 error "rename to $MOUNT/.lustre/fid should fail."
16112
16113         if [ $MDS1_VERSION -ge $(version_code 2.3.51) ]
16114         then            # LU-3547
16115                 local old_obf_mode=$(stat --format="%a" $DIR/.lustre/fid)
16116                 local new_obf_mode=777
16117
16118                 echo "change mode of $DIR/.lustre/fid to $new_obf_mode"
16119                 chmod $new_obf_mode $DIR/.lustre/fid ||
16120                         error "chmod $new_obf_mode $DIR/.lustre/fid failed"
16121
16122                 local obf_mode=$(stat --format=%a $DIR/.lustre/fid)
16123                 [ $obf_mode -eq $new_obf_mode ] ||
16124                         error "stat $DIR/.lustre/fid returned wrong mode $obf_mode"
16125
16126                 echo "restore mode of $DIR/.lustre/fid to $old_obf_mode"
16127                 chmod $old_obf_mode $DIR/.lustre/fid ||
16128                         error "chmod $old_obf_mode $DIR/.lustre/fid failed"
16129         fi
16130
16131         $OPENFILE -f O_LOV_DELAY_CREATE:O_CREAT $test_dir/$tfile-2
16132         fid=$($LFS path2fid $test_dir/$tfile-2)
16133
16134         if [ $MDS1_VERSION -ge $(version_code 2.6.50) ]
16135         then # LU-5424
16136                 echo "cp /etc/passwd $MOUNT/.lustre/fid/$fid"
16137                 cp /etc/passwd $MOUNT/.lustre/fid/$fid ||
16138                         error "create lov data thru .lustre failed"
16139         fi
16140         echo "cp /etc/passwd $test_dir/$tfile-2"
16141         cp /etc/passwd $test_dir/$tfile-2 ||
16142                 error "copy to $test_dir/$tfile-2 failed."
16143         echo "diff /etc/passwd $MOUNT/.lustre/fid/$fid"
16144         diff /etc/passwd $MOUNT/.lustre/fid/$fid ||
16145                 error "diff /etc/passwd $MOUNT/.lustre/fid/$fid failed."
16146
16147         rm -rf $test_dir/tfile.lnk
16148         rm -rf $test_dir/$tfile-2
16149 }
16150
16151 test_154A() {
16152         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
16153                 skip "Need MDS version at least 2.4.1"
16154
16155         local tf=$DIR/$tfile
16156         touch $tf
16157
16158         local fid=$($LFS path2fid $tf)
16159         [ -z "$fid" ] && error "path2fid unable to get $tf FID"
16160
16161         # check that we get the same pathname back
16162         local rootpath
16163         local found
16164         for rootpath in "$MOUNT" "$MOUNT///" "$MOUNT/$tfile"; do
16165                 echo "$rootpath $fid"
16166                 found=$($LFS fid2path $rootpath "$fid")
16167                 [ -z "$found" ] && error "fid2path unable to get '$fid' path"
16168                 [ "$found" == "$tf" ] || error "fid2path $found != $tf"
16169         done
16170
16171         # check wrong root path format
16172         rootpath=$MOUNT"_wrong"
16173         found=$($LFS fid2path $rootpath "$fid")
16174         [ -z "$found" ] || error "should fail ($rootpath != $MOUNT)"
16175 }
16176 run_test 154A "lfs path2fid and fid2path basic checks"
16177
16178 test_154B() {
16179         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
16180                 skip "Need MDS version at least 2.4.1"
16181
16182         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
16183         touch $DIR/$tdir/$tfile || error "touch $DIR/$tdir/$tfile failed"
16184         local linkea=$($LL_DECODE_LINKEA $DIR/$tdir/$tfile | grep 'pfid')
16185         [ -z "$linkea" ] && error "decode linkea $DIR/$tdir/$tfile failed"
16186
16187         local name=$(echo $linkea | awk '/pfid/ {print $5}' | sed -e "s/'//g")
16188         local PFID=$(echo $linkea | awk '/pfid/ {print $3}' | sed -e "s/,//g")
16189
16190         # check that we get the same pathname
16191         echo "PFID: $PFID, name: $name"
16192         local FOUND=$($LFS fid2path $MOUNT "$PFID")
16193         [ -z "$FOUND" ] && error "fid2path unable to get $PFID path"
16194         [ "$FOUND/$name" != "$DIR/$tdir/$tfile" ] &&
16195                 error "ll_decode_linkea has $FOUND/$name != $DIR/$tdir/$tfile"
16196
16197         rm -rf $DIR/$tdir || error "Can not delete directory $DIR/$tdir"
16198 }
16199 run_test 154B "verify the ll_decode_linkea tool"
16200
16201 test_154a() {
16202         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16203         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
16204         (( $MDS1_VERSION >= $(version_code 2.2.51) )) ||
16205                 skip "Need MDS version at least 2.2.51"
16206         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
16207
16208         cp /etc/hosts $DIR/$tfile
16209
16210         fid=$($LFS path2fid $DIR/$tfile)
16211         rc=$?
16212         [ $rc -ne 0 ] && error "error: could not get fid for $DIR/$tfile."
16213
16214         dot_lustre_fid_permission_check "$fid" $DIR ||
16215                 error "dot lustre permission check $fid failed"
16216
16217         ls -a $MOUNT | grep "\.lustre" && error ".lustre should not be listed"
16218
16219         rm -rf $MOUNT/.lustre && error ".lustre is not allowed to be unlinked"
16220
16221         touch $MOUNT/.lustre/file &&
16222                 error "creation is not allowed under .lustre"
16223
16224         mkdir $MOUNT/.lustre/dir &&
16225                 error "mkdir is not allowed under .lustre"
16226
16227         rm -rf $DIR/$tfile
16228 }
16229 run_test 154a "Open-by-FID"
16230
16231 test_154b() {
16232         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16233         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
16234         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16235         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
16236                 skip "Need MDS version at least 2.2.51"
16237
16238         local remote_dir=$DIR/$tdir/remote_dir
16239         local MDTIDX=1
16240         local rc=0
16241
16242         mkdir -p $DIR/$tdir
16243         $LFS mkdir -i $MDTIDX $remote_dir ||
16244                 error "create remote directory failed"
16245
16246         cp /etc/hosts $remote_dir/$tfile
16247
16248         fid=$($LFS path2fid $remote_dir/$tfile)
16249         rc=$?
16250         [ $rc -ne 0 ] && error "error: could not get fid for $remote_dir/$tfile"
16251
16252         dot_lustre_fid_permission_check "$fid" $remote_dir ||
16253                 error "dot lustre permission check $fid failed"
16254         rm -rf $DIR/$tdir
16255 }
16256 run_test 154b "Open-by-FID for remote directory"
16257
16258 test_154c() {
16259         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
16260                 skip "Need MDS version at least 2.4.1"
16261
16262         touch $DIR/$tfile.1 $DIR/$tfile.2 $DIR/$tfile.3
16263         local FID1=$($LFS path2fid $DIR/$tfile.1)
16264         local FID2=$($LFS path2fid $DIR/$tfile.2)
16265         local FID3=$($LFS path2fid $DIR/$tfile.3)
16266
16267         local N=1
16268         $LFS path2fid $DIR/$tfile.[123] | while read PATHNAME FID; do
16269                 [ "$PATHNAME" = "$DIR/$tfile.$N:" ] ||
16270                         error "path2fid pathname $PATHNAME != $DIR/$tfile.$N:"
16271                 local want=FID$N
16272                 [ "$FID" = "${!want}" ] ||
16273                         error "path2fid $PATHNAME FID $FID != FID$N ${!want}"
16274                 N=$((N + 1))
16275         done
16276
16277         $LFS fid2path $MOUNT "$FID1" "$FID2" "$FID3" | while read PATHNAME;
16278         do
16279                 [ "$PATHNAME" = "$DIR/$tfile.$N" ] ||
16280                         error "fid2path pathname $PATHNAME != $DIR/$tfile.$N:"
16281                 N=$((N + 1))
16282         done
16283 }
16284 run_test 154c "lfs path2fid and fid2path multiple arguments"
16285
16286 test_154d() {
16287         remote_mds_nodsh && skip "remote MDS with nodsh"
16288         [[ $MDS1_VERSION -lt $(version_code 2.5.53) ]] &&
16289                 skip "Need MDS version at least 2.5.53"
16290
16291         if remote_mds; then
16292                 nid=$($LCTL list_nids | sed  "s/\./\\\./g")
16293         else
16294                 nid="0@lo"
16295         fi
16296         local proc_ofile="mdt.*.exports.'$nid'.open_files"
16297         local fd
16298         local cmd
16299
16300         rm -f $DIR/$tfile
16301         touch $DIR/$tfile
16302
16303         local fid=$($LFS path2fid $DIR/$tfile)
16304         # Open the file
16305         fd=$(free_fd)
16306         cmd="exec $fd<$DIR/$tfile"
16307         eval $cmd
16308         local fid_list=$(do_facet $SINGLEMDS $LCTL get_param $proc_ofile)
16309         echo "$fid_list" | grep "$fid"
16310         rc=$?
16311
16312         cmd="exec $fd>/dev/null"
16313         eval $cmd
16314         if [ $rc -ne 0 ]; then
16315                 error "FID $fid not found in open files list $fid_list"
16316         fi
16317 }
16318 run_test 154d "Verify open file fid"
16319
16320 test_154e()
16321 {
16322         [[ $MDS1_VERSION -lt $(version_code 2.6.50) ]] &&
16323                 skip "Need MDS version at least 2.6.50"
16324
16325         if ls -a $MOUNT | grep -q '^\.lustre$'; then
16326                 error ".lustre returned by readdir"
16327         fi
16328 }
16329 run_test 154e ".lustre is not returned by readdir"
16330
16331 test_154f() {
16332         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
16333
16334         # create parent directory on a single MDT to avoid cross-MDT hardlinks
16335         mkdir_on_mdt0 $DIR/$tdir
16336         # test dirs inherit from its stripe
16337         mkdir -p $DIR/$tdir/foo1 || error "mkdir error"
16338         mkdir -p $DIR/$tdir/foo2 || error "mkdir error"
16339         cp /etc/hosts $DIR/$tdir/foo1/$tfile
16340         ln $DIR/$tdir/foo1/$tfile $DIR/$tdir/foo2/link
16341         touch $DIR/f
16342
16343         # get fid of parents
16344         local FID0=$($LFS path2fid $DIR/$tdir)
16345         local FID1=$($LFS path2fid $DIR/$tdir/foo1)
16346         local FID2=$($LFS path2fid $DIR/$tdir/foo2)
16347         local FID3=$($LFS path2fid $DIR)
16348
16349         # check that path2fid --parents returns expected <parent_fid>/name
16350         # 1) test for a directory (single parent)
16351         local parent=$($LFS path2fid --parents $DIR/$tdir/foo1)
16352         [ "$parent" == "$FID0/foo1" ] ||
16353                 error "expected parent: $FID0/foo1, got: $parent"
16354
16355         # 2) test for a file with nlink > 1 (multiple parents)
16356         parent=$($LFS path2fid --parents $DIR/$tdir/foo1/$tfile)
16357         echo "$parent" | grep -F "$FID1/$tfile" ||
16358                 error "$FID1/$tfile not returned in parent list"
16359         echo "$parent" | grep -F "$FID2/link" ||
16360                 error "$FID2/link not returned in parent list"
16361
16362         # 3) get parent by fid
16363         local file_fid=$($LFS path2fid $DIR/$tdir/foo1/$tfile)
16364         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
16365         echo "$parent" | grep -F "$FID1/$tfile" ||
16366                 error "$FID1/$tfile not returned in parent list (by fid)"
16367         echo "$parent" | grep -F "$FID2/link" ||
16368                 error "$FID2/link not returned in parent list (by fid)"
16369
16370         # 4) test for entry in root directory
16371         parent=$($LFS path2fid --parents $DIR/f)
16372         echo "$parent" | grep -F "$FID3/f" ||
16373                 error "$FID3/f not returned in parent list"
16374
16375         # 5) test it on root directory
16376         [ -z "$($LFS path2fid --parents $MOUNT 2>/dev/null)" ] ||
16377                 error "$MOUNT should not have parents"
16378
16379         # enable xattr caching and check that linkea is correctly updated
16380         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
16381         save_lustre_params client "llite.*.xattr_cache" > $save
16382         lctl set_param llite.*.xattr_cache 1
16383
16384         # 6.1) linkea update on rename
16385         mv $DIR/$tdir/foo1/$tfile $DIR/$tdir/foo2/$tfile.moved
16386
16387         # get parents by fid
16388         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
16389         # foo1 should no longer be returned in parent list
16390         echo "$parent" | grep -F "$FID1" &&
16391                 error "$FID1 should no longer be in parent list"
16392         # the new path should appear
16393         echo "$parent" | grep -F "$FID2/$tfile.moved" ||
16394                 error "$FID2/$tfile.moved is not in parent list"
16395
16396         # 6.2) linkea update on unlink
16397         rm -f $DIR/$tdir/foo2/link
16398         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
16399         # foo2/link should no longer be returned in parent list
16400         echo "$parent" | grep -F "$FID2/link" &&
16401                 error "$FID2/link should no longer be in parent list"
16402         true
16403
16404         rm -f $DIR/f
16405         restore_lustre_params < $save
16406         rm -f $save
16407 }
16408 run_test 154f "get parent fids by reading link ea"
16409
16410 test_154g()
16411 {
16412         [[ $MDS1_VERSION -ge $(version_code 2.6.92) &&
16413            $CLIENT_VERSION -gt $(version_code 2.6.99) ]] ||
16414                 skip "Need MDS version at least 2.6.92"
16415
16416         mkdir_on_mdt0 $DIR/$tdir
16417         llapi_fid_test -d $DIR/$tdir
16418 }
16419 run_test 154g "various llapi FID tests"
16420
16421 test_154h()
16422 {
16423         (( $CLIENT_VERSION >= $(version_code 2.15.55.1) )) ||
16424                 skip "Need client at least version 2.15.55.1"
16425
16426         # Create an empty file
16427         touch $DIR/$tfile
16428
16429         # Get FID (interactive mode) and save under $TMP/$tfile.log
16430         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
16431                 path2fid $DIR/$tfile
16432         EOF
16433
16434         fid=$(cat $TMP/$tfile.log)
16435         # $fid should not be empty
16436         [[ ! -z $fid ]] || error "FID is empty"
16437         $LFS rmfid $DIR "$fid" || error "rmfid failed for $fid"
16438 }
16439 run_test 154h "Verify interactive path2fid"
16440
16441 test_155_small_load() {
16442     local temp=$TMP/$tfile
16443     local file=$DIR/$tfile
16444
16445     dd if=/dev/urandom of=$temp bs=6096 count=1 || \
16446         error "dd of=$temp bs=6096 count=1 failed"
16447     cp $temp $file
16448     cancel_lru_locks $OSC
16449     cmp $temp $file || error "$temp $file differ"
16450
16451     $TRUNCATE $temp 6000
16452     $TRUNCATE $file 6000
16453     cmp $temp $file || error "$temp $file differ (truncate1)"
16454
16455     echo "12345" >>$temp
16456     echo "12345" >>$file
16457     cmp $temp $file || error "$temp $file differ (append1)"
16458
16459     echo "12345" >>$temp
16460     echo "12345" >>$file
16461     cmp $temp $file || error "$temp $file differ (append2)"
16462
16463     rm -f $temp $file
16464     true
16465 }
16466
16467 test_155_big_load() {
16468         remote_ost_nodsh && skip "remote OST with nodsh"
16469
16470         local temp=$TMP/$tfile
16471         local file=$DIR/$tfile
16472
16473         free_min_max
16474         local cache_size=$(do_facet ost$((MAXI+1)) \
16475                 "awk '/cache/ {sum+=\\\$4} END {print sum}' /proc/cpuinfo")
16476
16477         # LU-16042: can not get the cache size on Arm64 VM here, fallback to a
16478         # pre-set value
16479         if [ -z "$cache_size" ]; then
16480                 cache_size=256
16481         fi
16482         local large_file_size=$((cache_size * 2))
16483
16484         echo "OSS cache size: $cache_size KB"
16485         echo "Large file size: $large_file_size KB"
16486
16487         [ $MAXV -le $large_file_size ] &&
16488                 skip_env "max available OST size needs > $large_file_size KB"
16489
16490         $LFS setstripe $file -c 1 -i $MAXI || error "$LFS setstripe $file failed"
16491
16492         dd if=/dev/urandom of=$temp bs=$large_file_size count=1k ||
16493                 error "dd of=$temp bs=$large_file_size count=1k failed"
16494         cp $temp $file
16495         ls -lh $temp $file
16496         cancel_lru_locks osc
16497         cmp $temp $file || error "$temp $file differ"
16498
16499         rm -f $temp $file
16500         true
16501 }
16502
16503 save_writethrough() {
16504         local facets=$(get_facets OST)
16505
16506         save_lustre_params $facets "osd-*.*.writethrough_cache_enable" > $1
16507 }
16508
16509 test_155a() {
16510         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16511
16512         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16513
16514         save_writethrough $p
16515
16516         set_cache read on
16517         set_cache writethrough on
16518         test_155_small_load
16519         restore_lustre_params < $p
16520         rm -f $p
16521 }
16522 run_test 155a "Verify small file correctness: read cache:on write_cache:on"
16523
16524 test_155b() {
16525         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16526
16527         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16528
16529         save_writethrough $p
16530
16531         set_cache read on
16532         set_cache writethrough off
16533         test_155_small_load
16534         restore_lustre_params < $p
16535         rm -f $p
16536 }
16537 run_test 155b "Verify small file correctness: read cache:on write_cache:off"
16538
16539 test_155c() {
16540         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16541
16542         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16543
16544         save_writethrough $p
16545
16546         set_cache read off
16547         set_cache writethrough on
16548         test_155_small_load
16549         restore_lustre_params < $p
16550         rm -f $p
16551 }
16552 run_test 155c "Verify small file correctness: read cache:off write_cache:on"
16553
16554 test_155d() {
16555         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16556
16557         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16558
16559         save_writethrough $p
16560
16561         set_cache read off
16562         set_cache writethrough off
16563         test_155_small_load
16564         restore_lustre_params < $p
16565         rm -f $p
16566 }
16567 run_test 155d "Verify small file correctness: read cache:off write_cache:off"
16568
16569 test_155e() {
16570         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16571
16572         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16573
16574         save_writethrough $p
16575
16576         set_cache read on
16577         set_cache writethrough on
16578         test_155_big_load
16579         restore_lustre_params < $p
16580         rm -f $p
16581 }
16582 run_test 155e "Verify big file correctness: read cache:on write_cache:on"
16583
16584 test_155f() {
16585         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16586
16587         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16588
16589         save_writethrough $p
16590
16591         set_cache read on
16592         set_cache writethrough off
16593         test_155_big_load
16594         restore_lustre_params < $p
16595         rm -f $p
16596 }
16597 run_test 155f "Verify big file correctness: read cache:on write_cache:off"
16598
16599 test_155g() {
16600         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16601
16602         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16603
16604         save_writethrough $p
16605
16606         set_cache read off
16607         set_cache writethrough on
16608         test_155_big_load
16609         restore_lustre_params < $p
16610         rm -f $p
16611 }
16612 run_test 155g "Verify big file correctness: read cache:off write_cache:on"
16613
16614 test_155h() {
16615         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16616
16617         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16618
16619         save_writethrough $p
16620
16621         set_cache read off
16622         set_cache writethrough off
16623         test_155_big_load
16624         restore_lustre_params < $p
16625         rm -f $p
16626 }
16627 run_test 155h "Verify big file correctness: read cache:off write_cache:off"
16628
16629 test_156() {
16630         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16631         remote_ost_nodsh && skip "remote OST with nodsh"
16632         [ $OST1_VERSION -lt $(version_code 2.6.93) ] &&
16633                 skip "stats not implemented on old servers"
16634         [ "$ost1_FSTYPE" = "zfs" ] &&
16635                 skip "LU-1956/LU-2261: stats not implemented on OSD ZFS"
16636         (( CLIENT_VERSION == OST1_VERSION )) ||
16637                 skip "LU-13081: no interop testing for OSS cache"
16638
16639         local CPAGES=3
16640         local BEFORE
16641         local AFTER
16642         local file="$DIR/$tfile"
16643         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16644
16645         save_writethrough $p
16646         roc_hit_init
16647
16648         log "Turn on read and write cache"
16649         set_cache read on
16650         set_cache writethrough on
16651
16652         log "Write data and read it back."
16653         log "Read should be satisfied from the cache."
16654         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
16655         BEFORE=$(roc_hit)
16656         cancel_lru_locks osc
16657         cat $file >/dev/null
16658         AFTER=$(roc_hit)
16659         if ! let "AFTER - BEFORE == CPAGES"; then
16660                 error "NOT IN CACHE (2): before: $BEFORE, after: $AFTER"
16661         else
16662                 log "cache hits: before: $BEFORE, after: $AFTER"
16663         fi
16664
16665         log "Read again; it should be satisfied from the cache."
16666         BEFORE=$AFTER
16667         cancel_lru_locks osc
16668         cat $file >/dev/null
16669         AFTER=$(roc_hit)
16670         if ! let "AFTER - BEFORE == CPAGES"; then
16671                 error "NOT IN CACHE (3): before: $BEFORE, after: $AFTER"
16672         else
16673                 log "cache hits:: before: $BEFORE, after: $AFTER"
16674         fi
16675
16676         log "Turn off the read cache and turn on the write cache"
16677         set_cache read off
16678         set_cache writethrough on
16679
16680         log "Read again; it should be satisfied from the cache."
16681         BEFORE=$(roc_hit)
16682         cancel_lru_locks osc
16683         cat $file >/dev/null
16684         AFTER=$(roc_hit)
16685         if ! let "AFTER - BEFORE == CPAGES"; then
16686                 error "NOT IN CACHE (4): before: $BEFORE, after: $AFTER"
16687         else
16688                 log "cache hits:: before: $BEFORE, after: $AFTER"
16689         fi
16690
16691         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
16692                 # > 2.12.56 uses pagecache if cached
16693                 log "Read again; it should not be satisfied from the cache."
16694                 BEFORE=$AFTER
16695                 cancel_lru_locks osc
16696                 cat $file >/dev/null
16697                 AFTER=$(roc_hit)
16698                 if ! let "AFTER - BEFORE == 0"; then
16699                         error "IN CACHE (5): before: $BEFORE, after: $AFTER"
16700                 else
16701                         log "cache hits:: before: $BEFORE, after: $AFTER"
16702                 fi
16703         fi
16704
16705         log "Write data and read it back."
16706         log "Read should be satisfied from the cache."
16707         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
16708         BEFORE=$(roc_hit)
16709         cancel_lru_locks osc
16710         cat $file >/dev/null
16711         AFTER=$(roc_hit)
16712         if ! let "AFTER - BEFORE == CPAGES"; then
16713                 error "NOT IN CACHE (6): before: $BEFORE, after: $AFTER"
16714         else
16715                 log "cache hits:: before: $BEFORE, after: $AFTER"
16716         fi
16717
16718         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
16719                 # > 2.12.56 uses pagecache if cached
16720                 log "Read again; it should not be satisfied from the cache."
16721                 BEFORE=$AFTER
16722                 cancel_lru_locks osc
16723                 cat $file >/dev/null
16724                 AFTER=$(roc_hit)
16725                 if ! let "AFTER - BEFORE == 0"; then
16726                         error "IN CACHE (7): before: $BEFORE, after: $AFTER"
16727                 else
16728                         log "cache hits:: before: $BEFORE, after: $AFTER"
16729                 fi
16730         fi
16731
16732         log "Turn off read and write cache"
16733         set_cache read off
16734         set_cache writethrough off
16735
16736         log "Write data and read it back"
16737         log "It should not be satisfied from the cache."
16738         rm -f $file
16739         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
16740         cancel_lru_locks osc
16741         BEFORE=$(roc_hit)
16742         cat $file >/dev/null
16743         AFTER=$(roc_hit)
16744         if ! let "AFTER - BEFORE == 0"; then
16745                 error_ignore bz20762 "IN CACHE (8):before:$BEFORE,after:$AFTER"
16746         else
16747                 log "cache hits:: before: $BEFORE, after: $AFTER"
16748         fi
16749
16750         log "Turn on the read cache and turn off the write cache"
16751         set_cache read on
16752         set_cache writethrough off
16753
16754         log "Write data and read it back"
16755         log "It should not be satisfied from the cache."
16756         rm -f $file
16757         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
16758         BEFORE=$(roc_hit)
16759         cancel_lru_locks osc
16760         cat $file >/dev/null
16761         AFTER=$(roc_hit)
16762         if ! let "AFTER - BEFORE == 0"; then
16763                 error_ignore bz20762 "IN CACHE (9):before:$BEFORE,after:$AFTER"
16764         else
16765                 log "cache hits:: before: $BEFORE, after: $AFTER"
16766         fi
16767
16768         log "Read again; it should be satisfied from the cache."
16769         BEFORE=$(roc_hit)
16770         cancel_lru_locks osc
16771         cat $file >/dev/null
16772         AFTER=$(roc_hit)
16773         if ! let "AFTER - BEFORE == CPAGES"; then
16774                 error "NOT IN CACHE (1): before: $BEFORE, after: $AFTER"
16775         else
16776                 log "cache hits:: before: $BEFORE, after: $AFTER"
16777         fi
16778
16779         restore_lustre_params < $p
16780         rm -f $p $file
16781 }
16782 run_test 156 "Verification of tunables"
16783
16784 test_160a() {
16785         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16786         remote_mds_nodsh && skip "remote MDS with nodsh"
16787         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
16788                 skip "Need MDS version at least 2.2.0"
16789
16790         changelog_register || error "changelog_register failed"
16791         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16792         changelog_users $SINGLEMDS | grep -q $cl_user ||
16793                 error "User $cl_user not found in changelog_users"
16794
16795         mkdir_on_mdt0 $DIR/$tdir
16796
16797         # change something
16798         test_mkdir -p $DIR/$tdir/pics/2008/zachy
16799         changelog_clear 0 || error "changelog_clear failed"
16800         touch $DIR/$tdir/pics/2008/zachy/$tfile                 # open 1
16801         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg       # open 2
16802         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
16803         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
16804         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
16805         rm $DIR/$tdir/pics/desktop.jpg
16806
16807         echo "verifying changelog mask"
16808         changelog_chmask "-MKDIR"
16809         changelog_chmask "-CLOSE"
16810
16811         test_mkdir -p $DIR/$tdir/pics/zach/sofia                # not logged
16812         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # not logged
16813
16814         changelog_chmask "+MKDIR"
16815         changelog_chmask "+CLOSE"
16816
16817         test_mkdir -p $DIR/$tdir/pics/2008/sofia                # mkdir 1
16818         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # open 3
16819
16820         MKDIRS=$(changelog_dump | grep -c "MKDIR")
16821         CLOSES=$(changelog_dump | grep -c "CLOSE")
16822         [ $MKDIRS -eq 1 ] || error "MKDIR changelog mask count $MKDIRS != 1"
16823         [ $CLOSES -eq 3 ] || error "CLOSE changelog mask count $CLOSES != 3"
16824
16825         # verify contents
16826         echo "verifying target fid"
16827         local fidc=$(changelog_extract_field "CREAT" "$tfile" "t=")
16828         local fidf=$($LFS path2fid $DIR/$tdir/pics/zach/$tfile)
16829         [ "$fidc" == "$fidf" ] ||
16830                 error "changelog '$tfile' fid $fidc != file fid $fidf"
16831         echo "verifying parent fid"
16832         # The FID returned from the Changelog may be the directory shard on
16833         # a different MDT, and not the FID returned by path2fid on the parent.
16834         # Instead of comparing FIDs, verify that fid2path(fidp) is correct,
16835         # since this is what will matter when recreating this file in the tree.
16836         local fidp=$(changelog_extract_field "CREAT" "$tfile" "p=")
16837         local pathp=$($LFS fid2path $MOUNT "$fidp")
16838         [ "${pathp%/}" == "$DIR/$tdir/pics/zach" ] ||
16839                 error "changelog fid2path($fidc) $pathp != $DIR/$tdir/pics/zach"
16840
16841         echo "getting records for $cl_user"
16842         changelog_users $SINGLEMDS
16843         local user_rec1=$(changelog_user_rec $SINGLEMDS $cl_user)
16844         local nclr=3
16845         __changelog_clear $SINGLEMDS $cl_user +$nclr ||
16846                 error "changelog_clear failed"
16847         local user_rec2=$(changelog_user_rec $SINGLEMDS $cl_user)
16848         echo "verifying user clear: $user_rec1 + $nclr == $user_rec2"
16849         [ $user_rec2 == $((user_rec1 + nclr)) ] ||
16850                 error "user index expect $user_rec1 + $nclr != $user_rec2"
16851
16852         local min0_rec=$(changelog_users $SINGLEMDS |
16853                 awk 'min == "" || $2 < min { min = $2 }; END { print min }')
16854         local first_rec=$($LFS changelog $(facet_svc $SINGLEMDS) |
16855                           awk '{ print $1; exit; }')
16856
16857         changelog_dump | tail -n 5
16858         echo "verifying user min purge: $min0_rec + 1 == $first_rec"
16859         [ $first_rec == $((min0_rec + 1)) ] ||
16860                 error "first index should be $min0_rec + 1 not $first_rec"
16861
16862         # LU-3446 changelog index reset on MDT restart
16863         local cur_rec1=$(changelog_users $SINGLEMDS |
16864                          awk '/^current.index:/ { print $NF }')
16865         changelog_clear 0 ||
16866                 error "clear all changelog records for $cl_user failed"
16867         stop $SINGLEMDS || error "Fail to stop $SINGLEMDS"
16868         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
16869                 error "Fail to start $SINGLEMDS"
16870         local cur_rec2=$(changelog_users $SINGLEMDS |
16871                          awk '/^current.index:/ { print $NF }')
16872         echo "verifying index survives MDT restart: $cur_rec1 == $cur_rec2"
16873         [ $cur_rec1 == $cur_rec2 ] ||
16874                 error "current index should be $cur_rec1 not $cur_rec2"
16875
16876         echo "verifying users from this test are deregistered"
16877         changelog_deregister || error "changelog_deregister failed"
16878         changelog_users $SINGLEMDS | grep -q $cl_user &&
16879                 error "User '$cl_user' still in changelog_users"
16880
16881         # lctl get_param -n mdd.*.changelog_users
16882         # current_index: 144
16883         # ID    index (idle seconds)
16884         # cl3   144   (2) mask=<list>
16885         if [ -z "$(changelog_users $SINGLEMDS | grep -v current.index)" ]; then
16886                 # this is the normal case where all users were deregistered
16887                 # make sure no new records are added when no users are present
16888                 local last_rec1=$(changelog_users $SINGLEMDS |
16889                                   awk '/^current.index:/ { print $NF }')
16890                 touch $DIR/$tdir/chloe
16891                 local last_rec2=$(changelog_users $SINGLEMDS |
16892                                   awk '/^current.index:/ { print $NF }')
16893                 echo "verify changelogs are off: $last_rec1 == $last_rec2"
16894                 [ $last_rec1 == $last_rec2 ] || error "changelogs not off"
16895         else
16896                 # any changelog users must be leftovers from a previous test
16897                 changelog_users $SINGLEMDS
16898                 echo "other changelog users; can't verify off"
16899         fi
16900 }
16901 run_test 160a "changelog sanity"
16902
16903 test_160b() { # LU-3587
16904         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16905         remote_mds_nodsh && skip "remote MDS with nodsh"
16906         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
16907                 skip "Need MDS version at least 2.2.0"
16908
16909         changelog_register || error "changelog_register failed"
16910         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16911         changelog_users $SINGLEMDS | grep -q $cl_user ||
16912                 error "User '$cl_user' not found in changelog_users"
16913
16914         local longname1=$(str_repeat a 255)
16915         local longname2=$(str_repeat b 255)
16916
16917         cd $DIR
16918         echo "creating very long named file"
16919         touch $longname1 || error "create of '$longname1' failed"
16920         echo "renaming very long named file"
16921         mv $longname1 $longname2
16922
16923         changelog_dump | grep RENME | tail -n 5
16924         rm -f $longname2
16925 }
16926 run_test 160b "Verify that very long rename doesn't crash in changelog"
16927
16928 test_160c() {
16929         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16930         remote_mds_nodsh && skip "remote MDS with nodsh"
16931
16932         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
16933                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
16934                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
16935                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
16936
16937         local rc=0
16938
16939         # Registration step
16940         changelog_register || error "changelog_register failed"
16941
16942         rm -rf $DIR/$tdir
16943         mkdir -p $DIR/$tdir
16944         $MCREATE $DIR/$tdir/foo_160c
16945         changelog_chmask "-TRUNC"
16946         $TRUNCATE $DIR/$tdir/foo_160c 200
16947         changelog_chmask "+TRUNC"
16948         $TRUNCATE $DIR/$tdir/foo_160c 199
16949         changelog_dump | tail -n 5
16950         local truncs=$(changelog_dump | tail -n 5 | grep -c TRUNC)
16951         [ $truncs -eq 1 ] || error "TRUNC changelog mask count $truncs != 1"
16952 }
16953 run_test 160c "verify that changelog log catch the truncate event"
16954
16955 test_160d() {
16956         remote_mds_nodsh && skip "remote MDS with nodsh"
16957         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16958         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16959         [[ $MDS1_VERSION -ge $(version_code 2.7.60) ]] ||
16960                 skip "Need MDS version at least 2.7.60"
16961
16962         # Registration step
16963         changelog_register || error "changelog_register failed"
16964
16965         mkdir -p $DIR/$tdir/migrate_dir
16966         changelog_clear 0 || error "changelog_clear failed"
16967
16968         $LFS migrate -m 1 $DIR/$tdir/migrate_dir || error "migrate fails"
16969         changelog_dump | tail -n 5
16970         local migrates=$(changelog_dump | grep -c "MIGRT")
16971         [ $migrates -eq 1 ] || error "MIGRATE changelog count $migrates != 1"
16972 }
16973 run_test 160d "verify that changelog log catch the migrate event"
16974
16975 test_160e() {
16976         remote_mds_nodsh && skip "remote MDS with nodsh"
16977
16978         # Create a user
16979         changelog_register || error "changelog_register failed"
16980
16981         local MDT0=$(facet_svc $SINGLEMDS)
16982         local rc
16983
16984         # No user (expect fail)
16985         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister
16986         rc=$?
16987         if [ $rc -eq 0 ]; then
16988                 error "Should fail without user"
16989         elif [ $rc -ne 4 ]; then
16990                 error "changelog_deregister failed with $rc, expect 4(CMD_HELP)"
16991         fi
16992
16993         # Delete a future user (expect fail)
16994         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister "cl77"
16995         rc=$?
16996         if [ $rc -eq 0 ]; then
16997                 error "Deleted non-existant user cl77"
16998         elif [ $rc -ne 2 ]; then
16999                 error "changelog_deregister failed with $rc, expect 2 (ENOENT)"
17000         fi
17001
17002         # Clear to a bad index (1 billion should be safe)
17003         $LFS changelog_clear $MDT0 "${CL_USERS[$SINGLEMDS]%% *}" 1000000000
17004         rc=$?
17005
17006         if [ $rc -eq 0 ]; then
17007                 error "Successfully cleared to invalid CL index"
17008         elif [ $rc -ne 22 ]; then
17009                 error "changelog_clear failed with $rc, expected 22 (EINVAL)"
17010         fi
17011 }
17012 run_test 160e "changelog negative testing (should return errors)"
17013
17014 test_160f() {
17015         remote_mds_nodsh && skip "remote MDS with nodsh" && return
17016         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
17017                 skip "Need MDS version at least 2.10.56"
17018
17019         local mdts=$(comma_list $(mdts_nodes))
17020
17021         # Create a user
17022         changelog_register || error "first changelog_register failed"
17023         changelog_register || error "second changelog_register failed"
17024         local cl_users
17025         declare -A cl_user1
17026         declare -A cl_user2
17027         local user_rec1
17028         local user_rec2
17029         local i
17030
17031         # generate some changelog records to accumulate on each MDT
17032         # use all_char because created files should be evenly distributed
17033         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
17034                 error "test_mkdir $tdir failed"
17035         log "$(date +%s): creating first files"
17036         for ((i = 0; i < MDSCOUNT * 2; i++)); do
17037                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT)) ||
17038                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT)) failed"
17039         done
17040
17041         # check changelogs have been generated
17042         local start=$SECONDS
17043         local idle_time=$((MDSCOUNT * 5 + 5))
17044         local nbcl=$(changelog_dump | wc -l)
17045         [[ $nbcl -eq 0 ]] && error "no changelogs found"
17046
17047         for param in "changelog_max_idle_time=$idle_time" \
17048                      "changelog_gc=1" \
17049                      "changelog_min_gc_interval=2" \
17050                      "changelog_min_free_cat_entries=3"; do
17051                 local MDT0=$(facet_svc $SINGLEMDS)
17052                 local var="${param%=*}"
17053                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
17054
17055                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
17056                 do_nodes $mdts $LCTL set_param mdd.*.$param
17057         done
17058
17059         # force cl_user2 to be idle (1st part), but also cancel the
17060         # cl_user1 records so that it is not evicted later in the test.
17061         local sleep1=$((idle_time / 2))
17062         echo "$(date +%s): sleep1 $sleep1/${idle_time}s"
17063         sleep $sleep1
17064
17065         # simulate changelog catalog almost full
17066         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
17067         do_nodes $mdts "$LCTL set_param fail_loc=0x1313 fail_val=3"
17068
17069         for i in $(seq $MDSCOUNT); do
17070                 cl_users=(${CL_USERS[mds$i]})
17071                 cl_user1[mds$i]="${cl_users[0]}"
17072                 cl_user2[mds$i]="${cl_users[1]}"
17073
17074                 [ -n "${cl_user1[mds$i]}" ] ||
17075                         error "mds$i: no user registered"
17076                 [ -n "${cl_user2[mds$i]}" ] ||
17077                         error "mds$i: only ${cl_user2[mds$i]} is registered"
17078
17079                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17080                 [ -n "$user_rec1" ] ||
17081                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17082                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
17083                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17084                 [ -n "$user_rec2" ] ||
17085                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17086                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
17087                      "$user_rec1 + 2 == $user_rec2"
17088                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
17089                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
17090                               "$user_rec1 + 2, but is $user_rec2"
17091                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
17092                 [ -n "$user_rec2" ] ||
17093                         error "mds$i: User ${cl_user2[mds$i]} not registered"
17094                 [ $user_rec1 == $user_rec2 ] ||
17095                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
17096                               "$user_rec1, but is $user_rec2"
17097         done
17098
17099         # force cl_user2 idle (2nd part) to just exceed changelog_max_idle_time
17100         local sleep2=$((idle_time - (SECONDS - start) + 1))
17101         echo "$(date +%s): sleep2 $sleep2/${idle_time}s"
17102         sleep $sleep2
17103
17104         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
17105         # cl_user1 should be OK because it recently processed records.
17106         echo "$(date +%s): creating $((MDSCOUNT * 2)) files"
17107         for ((i = 0; i < MDSCOUNT * 2; i++)); do
17108                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT+2))||
17109                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT+2)) failed"
17110         done
17111
17112         # ensure gc thread is done
17113         for i in $(mdts_nodes); do
17114                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
17115                         error "$i: GC-thread not done"
17116         done
17117
17118         local first_rec
17119         for (( i = 1; i <= MDSCOUNT; i++ )); do
17120                 # check cl_user1 still registered
17121                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
17122                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17123                 # check cl_user2 unregistered
17124                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
17125                         error "mds$i: User ${cl_user2[mds$i]} still registered"
17126
17127                 # check changelogs are present and starting at $user_rec1 + 1
17128                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17129                 [ -n "$user_rec1" ] ||
17130                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17131                 first_rec=$($LFS changelog $(facet_svc mds$i) |
17132                             awk '{ print $1; exit; }')
17133
17134                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
17135                 [ $((user_rec1 + 1)) == $first_rec ] ||
17136                         error "mds$i: rec $first_rec != $user_rec1 + 1"
17137         done
17138 }
17139 run_test 160f "changelog garbage collect (timestamped users)"
17140
17141 test_160g() {
17142         remote_mds_nodsh && skip "remote MDS with nodsh"
17143         [[ $MDS1_VERSION -ge $(version_code 2.14.55) ]] ||
17144                 skip "Need MDS version at least 2.14.55"
17145
17146         local mdts=$(comma_list $(mdts_nodes))
17147
17148         # Create a user
17149         changelog_register || error "first changelog_register failed"
17150         changelog_register || error "second changelog_register failed"
17151         local cl_users
17152         declare -A cl_user1
17153         declare -A cl_user2
17154         local user_rec1
17155         local user_rec2
17156         local i
17157
17158         # generate some changelog records to accumulate on each MDT
17159         # use all_char because created files should be evenly distributed
17160         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
17161                 error "test_mkdir $tdir failed"
17162         for ((i = 0; i < MDSCOUNT; i++)); do
17163                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
17164                         error "create $DIR/$tdir/d$i.1 failed"
17165         done
17166
17167         # check changelogs have been generated
17168         local nbcl=$(changelog_dump | wc -l)
17169         (( $nbcl > 0 )) || error "no changelogs found"
17170
17171         # reduce the max_idle_indexes value to make sure we exceed it
17172         for param in "changelog_max_idle_indexes=2" \
17173                      "changelog_gc=1" \
17174                      "changelog_min_gc_interval=2"; do
17175                 local MDT0=$(facet_svc $SINGLEMDS)
17176                 local var="${param%=*}"
17177                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
17178
17179                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
17180                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
17181                         error "unable to set mdd.*.$param"
17182         done
17183
17184         local start=$SECONDS
17185         for i in $(seq $MDSCOUNT); do
17186                 cl_users=(${CL_USERS[mds$i]})
17187                 cl_user1[mds$i]="${cl_users[0]}"
17188                 cl_user2[mds$i]="${cl_users[1]}"
17189
17190                 [ -n "${cl_user1[mds$i]}" ] ||
17191                         error "mds$i: user1 is not registered"
17192                 [ -n "${cl_user2[mds$i]}" ] ||
17193                         error "mds$i: only ${cl_user1[mds$i]} is registered"
17194
17195                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17196                 [ -n "$user_rec1" ] ||
17197                         error "mds$i: user1 ${cl_user1[mds$i]} not found"
17198                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
17199                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17200                 [ -n "$user_rec2" ] ||
17201                         error "mds$i: user1 ${cl_user1[mds$i]} not found (2)"
17202                 echo "mds$i: verifying user1 ${cl_user1[mds$i]} clear: " \
17203                      "$user_rec1 + 2 == $user_rec2"
17204                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
17205                         error "mds$i: user1 ${cl_user1[mds$i]} index " \
17206                               "expected $user_rec1 + 2, but is $user_rec2"
17207                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
17208                 [ -n "$user_rec2" ] ||
17209                         error "mds$i: user2 ${cl_user2[mds$i]} not found"
17210                 [ $user_rec1 == $user_rec2 ] ||
17211                         error "mds$i: user2 ${cl_user2[mds$i]} index " \
17212                               "expected $user_rec1, but is $user_rec2"
17213         done
17214
17215         # ensure we are past the previous changelog_min_gc_interval set above
17216         local sleep2=$((start + 2 - SECONDS))
17217         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
17218         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
17219         # cl_user1 should be OK because it recently processed records.
17220         for ((i = 0; i < MDSCOUNT; i++)); do
17221                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 ||
17222                         error "create $DIR/$tdir/d$i.3 failed"
17223         done
17224
17225         # ensure gc thread is done
17226         for i in $(mdts_nodes); do
17227                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
17228                         error "$i: GC-thread not done"
17229         done
17230
17231         local first_rec
17232         for (( i = 1; i <= MDSCOUNT; i++ )); do
17233                 # check cl_user1 still registered
17234                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
17235                         error "mds$i: user1 ${cl_user1[mds$i]} not found (3)"
17236                 # check cl_user2 unregistered
17237                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
17238                         error "mds$i: user2 ${cl_user2[mds$i]} is registered"
17239
17240                 # check changelogs are present and starting at $user_rec1 + 1
17241                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17242                 [ -n "$user_rec1" ] ||
17243                         error "mds$i: user1 ${cl_user1[mds$i]} not found (4)"
17244                 first_rec=$($LFS changelog $(facet_svc mds$i) |
17245                             awk '{ print $1; exit; }')
17246
17247                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
17248                 [ $((user_rec1 + 1)) == $first_rec ] ||
17249                         error "mds$i: rec $first_rec != $user_rec1 + 1"
17250         done
17251 }
17252 run_test 160g "changelog garbage collect on idle records"
17253
17254 test_160h() {
17255         remote_mds_nodsh && skip "remote MDS with nodsh" && return
17256         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
17257                 skip "Need MDS version at least 2.10.56"
17258
17259         local mdts=$(comma_list $(mdts_nodes))
17260
17261         # Create a user
17262         changelog_register || error "first changelog_register failed"
17263         changelog_register || error "second changelog_register failed"
17264         local cl_users
17265         declare -A cl_user1
17266         declare -A cl_user2
17267         local user_rec1
17268         local user_rec2
17269         local i
17270
17271         # generate some changelog records to accumulate on each MDT
17272         # use all_char because created files should be evenly distributed
17273         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
17274                 error "test_mkdir $tdir failed"
17275         for ((i = 0; i < MDSCOUNT; i++)); do
17276                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
17277                         error "create $DIR/$tdir/d$i.1 failed"
17278         done
17279
17280         # check changelogs have been generated
17281         local nbcl=$(changelog_dump | wc -l)
17282         [[ $nbcl -eq 0 ]] && error "no changelogs found"
17283
17284         for param in "changelog_max_idle_time=10" \
17285                      "changelog_gc=1" \
17286                      "changelog_min_gc_interval=2"; do
17287                 local MDT0=$(facet_svc $SINGLEMDS)
17288                 local var="${param%=*}"
17289                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
17290
17291                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
17292                 do_nodes $mdts $LCTL set_param mdd.*.$param
17293         done
17294
17295         # force cl_user2 to be idle (1st part)
17296         sleep 9
17297
17298         for i in $(seq $MDSCOUNT); do
17299                 cl_users=(${CL_USERS[mds$i]})
17300                 cl_user1[mds$i]="${cl_users[0]}"
17301                 cl_user2[mds$i]="${cl_users[1]}"
17302
17303                 [ -n "${cl_user1[mds$i]}" ] ||
17304                         error "mds$i: no user registered"
17305                 [ -n "${cl_user2[mds$i]}" ] ||
17306                         error "mds$i: only ${cl_user2[mds$i]} is registered"
17307
17308                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17309                 [ -n "$user_rec1" ] ||
17310                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17311                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
17312                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17313                 [ -n "$user_rec2" ] ||
17314                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17315                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
17316                      "$user_rec1 + 2 == $user_rec2"
17317                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
17318                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
17319                               "$user_rec1 + 2, but is $user_rec2"
17320                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
17321                 [ -n "$user_rec2" ] ||
17322                         error "mds$i: User ${cl_user2[mds$i]} not registered"
17323                 [ $user_rec1 == $user_rec2 ] ||
17324                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
17325                               "$user_rec1, but is $user_rec2"
17326         done
17327
17328         # force cl_user2 to be idle (2nd part) and to reach
17329         # changelog_max_idle_time
17330         sleep 2
17331
17332         # force each GC-thread start and block then
17333         # one per MDT/MDD, set fail_val accordingly
17334         #define OBD_FAIL_FORCE_GC_THREAD 0x1316
17335         do_nodes $mdts $LCTL set_param fail_loc=0x1316
17336
17337         # generate more changelogs to trigger fail_loc
17338         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
17339                 error "create $DIR/$tdir/${tfile}bis failed"
17340
17341         # stop MDT to stop GC-thread, should be done in back-ground as it will
17342         # block waiting for the thread to be released and exit
17343         declare -A stop_pids
17344         for i in $(seq $MDSCOUNT); do
17345                 stop mds$i &
17346                 stop_pids[mds$i]=$!
17347         done
17348
17349         for i in $(mdts_nodes); do
17350                 local facet
17351                 local nb=0
17352                 local facets=$(facets_up_on_host $i)
17353
17354                 for facet in ${facets//,/ }; do
17355                         if [[ $facet == mds* ]]; then
17356                                 nb=$((nb + 1))
17357                         fi
17358                 done
17359                 # ensure each MDS's gc threads are still present and all in "R"
17360                 # state (OBD_FAIL_FORCE_GC_THREAD effect!)
17361                 [[ $(do_node $i pgrep chlg_gc_thread | wc -l) -eq $nb ]] ||
17362                         error "$i: expected $nb GC-thread"
17363                 wait_update $i \
17364                         "ps -C chlg_gc_thread -o state --no-headers | uniq" \
17365                         "R" 20 ||
17366                         error "$i: GC-thread not found in R-state"
17367                 # check umounts of each MDT on MDS have reached kthread_stop()
17368                 [[ $(do_node $i pgrep umount | wc -l) -eq $nb ]] ||
17369                         error "$i: expected $nb umount"
17370                 wait_update $i \
17371                         "ps -C umount -o state --no-headers | uniq" "D" 20 ||
17372                         error "$i: umount not found in D-state"
17373         done
17374
17375         # release all GC-threads
17376         do_nodes $mdts $LCTL set_param fail_loc=0
17377
17378         # wait for MDT stop to complete
17379         for i in $(seq $MDSCOUNT); do
17380                 wait ${stop_pids[mds$i]} || error "mds$i: stop failed"
17381         done
17382
17383         # XXX
17384         # may try to check if any orphan changelog records are present
17385         # via ldiskfs/zfs and llog_reader...
17386
17387         # re-start/mount MDTs
17388         for i in $(seq $MDSCOUNT); do
17389                 start mds$i $(mdsdevname $i) $MDS_MOUNT_OPTS ||
17390                         error "Fail to start mds$i"
17391         done
17392
17393         local first_rec
17394         for i in $(seq $MDSCOUNT); do
17395                 # check cl_user1 still registered
17396                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
17397                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17398                 # check cl_user2 unregistered
17399                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
17400                         error "mds$i: User ${cl_user2[mds$i]} still registered"
17401
17402                 # check changelogs are present and starting at $user_rec1 + 1
17403                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17404                 [ -n "$user_rec1" ] ||
17405                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17406                 first_rec=$($LFS changelog $(facet_svc mds$i) |
17407                             awk '{ print $1; exit; }')
17408
17409                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
17410                 [ $((user_rec1 + 1)) == $first_rec ] ||
17411                         error "mds$i: first index should be $user_rec1 + 1, " \
17412                               "but is $first_rec"
17413         done
17414 }
17415 run_test 160h "changelog gc thread stop upon umount, orphan records delete " \
17416               "during mount"
17417
17418 test_160i() {
17419
17420         local mdts=$(comma_list $(mdts_nodes))
17421
17422         changelog_register || error "first changelog_register failed"
17423
17424         # generate some changelog records to accumulate on each MDT
17425         # use all_char because created files should be evenly distributed
17426         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
17427                 error "test_mkdir $tdir failed"
17428         for ((i = 0; i < MDSCOUNT; i++)); do
17429                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
17430                         error "create $DIR/$tdir/d$i.1 failed"
17431         done
17432
17433         # check changelogs have been generated
17434         local nbcl=$(changelog_dump | wc -l)
17435         [[ $nbcl -eq 0 ]] && error "no changelogs found"
17436
17437         # simulate race between register and unregister
17438         # XXX as fail_loc is set per-MDS, with DNE configs the race
17439         # simulation will only occur for one MDT per MDS and for the
17440         # others the normal race scenario will take place
17441         #define CFS_FAIL_CHLOG_USER_REG_UNREG_RACE          0x1315
17442         do_nodes $mdts $LCTL set_param fail_loc=0x10001315
17443         do_nodes $mdts $LCTL set_param fail_val=1
17444
17445         # unregister 1st user
17446         changelog_deregister &
17447         local pid1=$!
17448         # wait some time for deregister work to reach race rdv
17449         sleep 2
17450         # register 2nd user
17451         changelog_register || error "2nd user register failed"
17452
17453         wait $pid1 || error "1st user deregister failed"
17454
17455         local i
17456         local last_rec
17457         declare -A LAST_REC
17458         for i in $(seq $MDSCOUNT); do
17459                 if changelog_users mds$i | grep "^cl"; then
17460                         # make sure new records are added with one user present
17461                         LAST_REC[mds$i]=$(changelog_users $SINGLEMDS |
17462                                           awk '/^current.index:/ { print $NF }')
17463                 else
17464                         error "mds$i has no user registered"
17465                 fi
17466         done
17467
17468         # generate more changelog records to accumulate on each MDT
17469         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
17470                 error "create $DIR/$tdir/${tfile}bis failed"
17471
17472         for i in $(seq $MDSCOUNT); do
17473                 last_rec=$(changelog_users $SINGLEMDS |
17474                            awk '/^current.index:/ { print $NF }')
17475                 echo "verify changelogs are on: $last_rec != ${LAST_REC[mds$i]}"
17476                 [ $last_rec != ${LAST_REC[mds$i]} ] ||
17477                         error "changelogs are off on mds$i"
17478         done
17479 }
17480 run_test 160i "changelog user register/unregister race"
17481
17482 test_160j() {
17483         remote_mds_nodsh && skip "remote MDS with nodsh"
17484         [[ $MDS1_VERSION -lt $(version_code 2.12.56) ]] &&
17485                 skip "Need MDS version at least 2.12.56"
17486
17487         mount_client $MOUNT2 || error "mount_client on $MOUNT2 failed"
17488         stack_trap "umount $MOUNT2" EXIT
17489
17490         changelog_register || error "first changelog_register failed"
17491         stack_trap "changelog_deregister" EXIT
17492
17493         # generate some changelog
17494         # use all_char because created files should be evenly distributed
17495         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
17496                 error "mkdir $tdir failed"
17497         for ((i = 0; i < MDSCOUNT; i++)); do
17498                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
17499                         error "create $DIR/$tdir/d$i.1 failed"
17500         done
17501
17502         # open the changelog device
17503         exec 3>/dev/changelog-$FSNAME-MDT0000
17504         stack_trap "exec 3>&-" EXIT
17505         exec 4</dev/changelog-$FSNAME-MDT0000
17506         stack_trap "exec 4<&-" EXIT
17507
17508         # umount the first lustre mount
17509         umount $MOUNT
17510         stack_trap "mount_client $MOUNT" EXIT
17511
17512         # read changelog, which may or may not fail, but should not crash
17513         cat <&4 >/dev/null
17514
17515         # clear changelog
17516         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
17517         changelog_users $SINGLEMDS | grep -q $cl_user ||
17518                 error "User $cl_user not found in changelog_users"
17519
17520         printf 'clear:'$cl_user':0' >&3
17521 }
17522 run_test 160j "client can be umounted while its chanangelog is being used"
17523
17524 test_160k() {
17525         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17526         remote_mds_nodsh && skip "remote MDS with nodsh"
17527
17528         mkdir -p $DIR/$tdir/1/1
17529
17530         changelog_register || error "changelog_register failed"
17531         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
17532
17533         changelog_users $SINGLEMDS | grep -q $cl_user ||
17534                 error "User '$cl_user' not found in changelog_users"
17535 #define OBD_FAIL_MDS_CHANGELOG_REORDER 0x15d
17536         do_facet mds1 $LCTL set_param fail_loc=0x8000015d fail_val=3
17537         rmdir $DIR/$tdir/1/1 & sleep 1
17538         mkdir $DIR/$tdir/2
17539         touch $DIR/$tdir/2/2
17540         rm -rf $DIR/$tdir/2
17541
17542         wait
17543         sleep 4
17544
17545         changelog_dump | grep rmdir || error "rmdir not recorded"
17546 }
17547 run_test 160k "Verify that changelog records are not lost"
17548
17549 # Verifies that a file passed as a parameter has recently had an operation
17550 # performed on it that has generated an MTIME changelog which contains the
17551 # correct parent FID. As files might reside on a different MDT from the
17552 # parent directory in DNE configurations, the FIDs are translated to paths
17553 # before being compared, which should be identical
17554 compare_mtime_changelog() {
17555         local file="${1}"
17556         local mdtidx
17557         local mtime
17558         local cl_fid
17559         local pdir
17560         local dir
17561
17562         mdtidx=$($LFS getstripe --mdt-index $file)
17563         mdtidx=$(printf "%04x" $mdtidx)
17564
17565         # Obtain the parent FID from the MTIME changelog
17566         mtime=$($LFS changelog $FSNAME-MDT$mdtidx | tail -n 1 | grep MTIME)
17567         [ -z "$mtime" ] && error "MTIME changelog not recorded"
17568
17569         cl_fid=$(sed -e 's/.* p=//' -e 's/ .*//' <<<$mtime)
17570         [ -z "$cl_fid" ] && error "parent FID not present"
17571
17572         # Verify that the path for the parent FID is the same as the path for
17573         # the test directory
17574         pdir=$($LFS fid2path $MOUNT "$cl_fid")
17575
17576         dir=$(dirname $1)
17577
17578         [[ "${pdir%/}" == "$dir" ]] ||
17579                 error "MTIME changelog parent FID is wrong, expected $dir, got $pdir"
17580 }
17581
17582 test_160l() {
17583         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17584
17585         remote_mds_nodsh && skip "remote MDS with nodsh"
17586         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
17587                 skip "Need MDS version at least 2.13.55"
17588
17589         local cl_user
17590
17591         changelog_register || error "changelog_register failed"
17592         cl_user="${CL_USERS[$SINGLEMDS]%% *}"
17593
17594         changelog_users $SINGLEMDS | grep -q $cl_user ||
17595                 error "User '$cl_user' not found in changelog_users"
17596
17597         # Clear some types so that MTIME changelogs are generated
17598         changelog_chmask "-CREAT"
17599         changelog_chmask "-CLOSE"
17600
17601         test_mkdir $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
17602
17603         # Test CL_MTIME during setattr
17604         touch $DIR/$tdir/$tfile
17605         compare_mtime_changelog $DIR/$tdir/$tfile
17606
17607         # Test CL_MTIME during close
17608         $MULTIOP $DIR/$tdir/${tfile}_2 O_2w4096c || error "multiop failed"
17609         compare_mtime_changelog $DIR/$tdir/${tfile}_2
17610 }
17611 run_test 160l "Verify that MTIME changelog records contain the parent FID"
17612
17613 test_160m() {
17614         remote_mds_nodsh && skip "remote MDS with nodsh" && return
17615         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
17616                 skip "Need MDS version at least 2.14.51"
17617         local cl_users
17618         local cl_user1
17619         local cl_user2
17620         local pid1
17621
17622         # Create a user
17623         changelog_register || error "first changelog_register failed"
17624         changelog_register || error "second changelog_register failed"
17625
17626         cl_users=(${CL_USERS[mds1]})
17627         cl_user1="${cl_users[0]}"
17628         cl_user2="${cl_users[1]}"
17629         # generate some changelog records to accumulate on MDT0
17630         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
17631         createmany -m $DIR/$tdir/$tfile 50 ||
17632                 error "create $DIR/$tdir/$tfile failed"
17633         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
17634         rm -f $DIR/$tdir
17635
17636         # check changelogs have been generated
17637         local nbcl=$(changelog_dump | wc -l)
17638         [[ $nbcl -eq 0 ]] && error "no changelogs found"
17639
17640 #define OBD_FAIL_MDS_CHANGELOG_RACE      0x15f
17641         do_facet mds1 $LCTL set_param fail_loc=0x8000015f fail_val=0
17642
17643         __changelog_clear mds1 $cl_user1 +10
17644         __changelog_clear mds1 $cl_user2 0 &
17645         pid1=$!
17646         sleep 2
17647         __changelog_clear mds1 $cl_user1 0 ||
17648                 error "fail to cancel record for $cl_user1"
17649         wait $pid1
17650         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
17651 }
17652 run_test 160m "Changelog clear race"
17653
17654 test_160n() {
17655         remote_mds_nodsh && skip "remote MDS with nodsh" && return
17656         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
17657                 skip "Need MDS version at least 2.14.51"
17658         local cl_users
17659         local cl_user1
17660         local cl_user2
17661         local pid1
17662         local first_rec
17663         local last_rec=0
17664
17665         # Create a user
17666         changelog_register || error "first changelog_register failed"
17667
17668         cl_users=(${CL_USERS[mds1]})
17669         cl_user1="${cl_users[0]}"
17670
17671         # generate some changelog records to accumulate on MDT0
17672         test_mkdir -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
17673         first_rec=$(changelog_users $SINGLEMDS |
17674                         awk '/^current.index:/ { print $NF }')
17675         while (( last_rec < (( first_rec + 65000)) )); do
17676                 createmany -m $DIR/$tdir/$tfile 10000 ||
17677                         error "create $DIR/$tdir/$tfile failed"
17678
17679                 for i in $(seq 0 10000); do
17680                         mrename $DIR/$tdir/$tfile$i $DIR/$tdir/$tfile-new$i \
17681                                 > /dev/null
17682                 done
17683
17684                 unlinkmany $DIR/$tdir/$tfile-new 10000 ||
17685                         error "unlinkmany failed unlink"
17686                 last_rec=$(changelog_users $SINGLEMDS |
17687                         awk '/^current.index:/ { print $NF }')
17688                 echo last record $last_rec
17689                 (( last_rec == 0 )) && error "no changelog found"
17690         done
17691
17692 #define OBD_FAIL_MDS_CHANGELOG_DEL       0x16c
17693         do_facet mds1 $LCTL set_param fail_loc=0x8000016c fail_val=0
17694
17695         __changelog_clear mds1 $cl_user1 0 &
17696         pid1=$!
17697         sleep 2
17698         __changelog_clear mds1 $cl_user1 0 ||
17699                 error "fail to cancel record for $cl_user1"
17700         wait $pid1
17701         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
17702 }
17703 run_test 160n "Changelog destroy race"
17704
17705 test_160o() {
17706         local mdt="$(facet_svc $SINGLEMDS)"
17707
17708         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
17709         remote_mds_nodsh && skip "remote MDS with nodsh"
17710         [ $MDS1_VERSION -ge $(version_code 2.14.52) ] ||
17711                 skip "Need MDS version at least 2.14.52"
17712
17713         changelog_register --user test_160o -m unlnk+close+open ||
17714                 error "changelog_register failed"
17715
17716         do_facet $SINGLEMDS $LCTL --device $mdt \
17717                                 changelog_register -u "Tt3_-#" &&
17718                 error "bad symbols in name should fail"
17719
17720         do_facet $SINGLEMDS $LCTL --device $mdt \
17721                                 changelog_register -u test_160o &&
17722                 error "the same name registration should fail"
17723
17724         do_facet $SINGLEMDS $LCTL --device $mdt \
17725                         changelog_register -u test_160toolongname &&
17726                 error "too long name registration should fail"
17727
17728         changelog_chmask "MARK+HSM"
17729         lctl get_param mdd.*.changelog*mask
17730         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
17731         changelog_users $SINGLEMDS | grep -q $cl_user ||
17732                 error "User $cl_user not found in changelog_users"
17733         #verify username
17734         echo $cl_user | grep -q test_160o ||
17735                 error "User $cl_user has no specific name 'test160o'"
17736
17737         # change something
17738         changelog_clear 0 || error "changelog_clear failed"
17739         # generate some changelog records to accumulate on MDT0
17740         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
17741         touch $DIR/$tdir/$tfile                 # open 1
17742
17743         OPENS=$(changelog_dump | grep -c "OPEN")
17744         [[ $OPENS -eq 1 ]] || error "OPEN changelog mask count $OPENS != 1"
17745
17746         # must be no MKDIR it wasn't set as user mask
17747         MKDIR=$(changelog_dump | grep -c "MKDIR")
17748         [[ $MKDIR -eq 0 ]] || error "MKDIR changelog mask found $MKDIR > 0"
17749
17750         oldmask=$(do_facet $SINGLEMDS $LCTL get_param \
17751                                 mdd.$mdt.changelog_current_mask -n)
17752         # register maskless user
17753         changelog_register || error "changelog_register failed"
17754         # effective mask should be not changed because it is not minimal
17755         mask=$(do_facet $SINGLEMDS $LCTL get_param \
17756                                 mdd.$mdt.changelog_current_mask -n)
17757         [[ $mask == $oldmask ]] || error "mask was changed: $mask vs $oldmask"
17758         # set server mask to minimal value
17759         changelog_chmask "MARK"
17760         # check effective mask again, should be treated as DEFMASK now
17761         mask=$(do_facet $SINGLEMDS $LCTL get_param \
17762                                 mdd.$mdt.changelog_current_mask -n)
17763         [[ $mask == *"HLINK"* ]] || error "mask is not DEFMASK as expected"
17764
17765         if (( $MDS1_VERSION >= $(version_code 2.15.52) )) ; then
17766                 # set server mask back to some value
17767                 changelog_chmask "CLOSE,UNLNK"
17768                 # check effective mask again, should not remain as DEFMASK
17769                 mask=$(do_facet $SINGLEMDS $LCTL get_param \
17770                                 mdd.$mdt.changelog_current_mask -n)
17771                 [[ $mask != *"HLINK"* ]] || error "mask is still DEFMASK"
17772         fi
17773
17774         do_facet $SINGLEMDS $LCTL --device $mdt \
17775                                 changelog_deregister -u test_160o ||
17776                 error "cannot deregister by name"
17777 }
17778 run_test 160o "changelog user name and mask"
17779
17780 test_160p() {
17781         remote_mds_nodsh && skip "remote MDS with nodsh" && return
17782         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
17783                 skip "Need MDS version at least 2.14.51"
17784         [[ "$mds1_FSTYPE" == "ldiskfs" ]] || skip "ldiskfs only test"
17785         local cl_users
17786         local cl_user1
17787         local entry_count
17788
17789         # Create a user
17790         changelog_register || error "first changelog_register failed"
17791
17792         cl_users=(${CL_USERS[mds1]})
17793         cl_user1="${cl_users[0]}"
17794
17795         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
17796         createmany -m $DIR/$tdir/$tfile 50 ||
17797                 error "create $DIR/$tdir/$tfile failed"
17798         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
17799         rm -rf $DIR/$tdir
17800
17801         # check changelogs have been generated
17802         entry_count=$(changelog_dump | wc -l)
17803         ((entry_count != 0)) || error "no changelog entries found"
17804
17805         # remove changelog_users and check that orphan entries are removed
17806         stop mds1
17807         local dev=$(mdsdevname 1)
17808         do_facet mds1 "$DEBUGFS -w -R 'rm changelog_users' $dev"
17809         start mds1 $dev $MDS_MOUNT_OPTS || error "cannot start mds1"
17810         entry_count=$(changelog_dump | wc -l)
17811         ((entry_count == 0)) ||
17812                 error "found $entry_count changelog entries, expected none"
17813 }
17814 run_test 160p "Changelog orphan cleanup with no users"
17815
17816 test_160q() {
17817         local mdt="$(facet_svc $SINGLEMDS)"
17818         local clu
17819
17820         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
17821         remote_mds_nodsh && skip "remote MDS with nodsh"
17822         [ $MDS1_VERSION -ge $(version_code 2.14.54) ] ||
17823                 skip "Need MDS version at least 2.14.54"
17824
17825         # set server mask to minimal value like server init does
17826         changelog_chmask "MARK"
17827         clu=$(do_facet $SINGLEMDS $LCTL --device $mdt changelog_register -n) ||
17828                 error "changelog_register failed"
17829         # check effective mask again, should be treated as DEFMASK now
17830         mask=$(do_facet $SINGLEMDS $LCTL get_param \
17831                                 mdd.$mdt.changelog_current_mask -n)
17832         do_facet $SINGLEMDS $LCTL --device $mdt changelog_deregister $clu ||
17833                 error "changelog_deregister failed"
17834         [[ $mask == *"HLINK"* ]] || error "mask is not DEFMASK as expected"
17835 }
17836 run_test 160q "changelog effective mask is DEFMASK if not set"
17837
17838 test_160s() {
17839         remote_mds_nodsh && skip "remote MDS with nodsh"
17840         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
17841                 skip "Need MDS version at least 2.14.55"
17842
17843         local mdts=$(comma_list $(mdts_nodes))
17844
17845         #define OBD_FAIL_TIME_IN_CHLOG_USER     0x1314
17846         do_nodes $mdts $LCTL set_param fail_loc=0x1314 \
17847                                        fail_val=$((24 * 3600 * 10))
17848
17849         # Create a user which is 10 days old
17850         changelog_register || error "first changelog_register failed"
17851         local cl_users
17852         declare -A cl_user1
17853         local i
17854
17855         # generate some changelog records to accumulate on each MDT
17856         # use all_char because created files should be evenly distributed
17857         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
17858                 error "test_mkdir $tdir failed"
17859         for ((i = 0; i < MDSCOUNT; i++)); do
17860                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
17861                         error "create $DIR/$tdir/d$i.1 failed"
17862         done
17863
17864         # check changelogs have been generated
17865         local nbcl=$(changelog_dump | wc -l)
17866         (( nbcl > 0 )) || error "no changelogs found"
17867
17868         # reduce the max_idle_indexes value to make sure we exceed it
17869         for param in "changelog_max_idle_indexes=2097446912" \
17870                      "changelog_max_idle_time=2592000" \
17871                      "changelog_gc=1" \
17872                      "changelog_min_gc_interval=2"; do
17873                 local MDT0=$(facet_svc $SINGLEMDS)
17874                 local var="${param%=*}"
17875                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
17876
17877                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
17878                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
17879                         error "unable to set mdd.*.$param"
17880         done
17881
17882         local start=$SECONDS
17883         for i in $(seq $MDSCOUNT); do
17884                 cl_users=(${CL_USERS[mds$i]})
17885                 cl_user1[mds$i]="${cl_users[0]}"
17886
17887                 [[ -n "${cl_user1[mds$i]}" ]] ||
17888                         error "mds$i: no user registered"
17889         done
17890
17891         #define OBD_FAIL_MDS_CHANGELOG_IDX_PUMP   0x16d
17892         do_nodes $mdts $LCTL set_param fail_loc=0x16d fail_val=500000000
17893
17894         # ensure we are past the previous changelog_min_gc_interval set above
17895         local sleep2=$((start + 2 - SECONDS))
17896         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
17897
17898         # Generate one more changelog to trigger GC
17899         for ((i = 0; i < MDSCOUNT; i++)); do
17900                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 $DIR/$tdir/d$i.4 ||
17901                         error "create $DIR/$tdir/d$i.3 failed"
17902         done
17903
17904         # ensure gc thread is done
17905         for node in $(mdts_nodes); do
17906                 wait_update $node "pgrep chlg_gc_thread" "" 20 ||
17907                         error "$node: GC-thread not done"
17908         done
17909
17910         do_nodes $mdts $LCTL set_param fail_loc=0
17911
17912         for (( i = 1; i <= MDSCOUNT; i++ )); do
17913                 # check cl_user1 is purged
17914                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" &&
17915                         error "mds$i: User ${cl_user1[mds$i]} is registered"
17916         done
17917         return 0
17918 }
17919 run_test 160s "changelog garbage collect on idle records * time"
17920
17921 test_160t() {
17922         remote_mds_nodsh && skip "remote MDS with nodsh"
17923         (( $MDS1_VERSION >= $(version_code 2.15.50) )) ||
17924                 skip "Need MDS version at least 2.15.50"
17925
17926         local MDT0=$(facet_svc $SINGLEMDS)
17927         local cl_users
17928         local cl_user1
17929         local cl_user2
17930         local start
17931
17932         changelog_register --user user1 -m all ||
17933                 error "user1 failed to register"
17934
17935         mkdir_on_mdt0 $DIR/$tdir
17936         # create default overstripe to maximize changelog size
17937         $LFS setstripe  -C 8 $DIR/$tdir || error "setstripe failed"
17938         createmany -o $DIR/$tdir/u1_ 2000 || error "createmany for user1 failed"
17939         llog_size1=$(do_facet mds1 $LCTL get_param -n mdd.$MDT0.changelog_size)
17940
17941         # user2 consumes less records so less space
17942         changelog_register --user user2 || error "user2 failed to register"
17943         createmany -o $DIR/$tdir/u2_ 500 || error "createmany for user2 failed"
17944         llog_size2=$(do_facet mds1 $LCTL get_param -n mdd.$MDT0.changelog_size)
17945
17946         # check changelogs have been generated
17947         local nbcl=$(changelog_dump | wc -l)
17948         (( nbcl > 0 )) || error "no changelogs found"
17949
17950         # reduce the changelog_min_gc_interval to force check
17951         for param in "changelog_gc=1" "changelog_min_gc_interval=2"; do
17952                 local var="${param%=*}"
17953                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
17954
17955                 stack_trap "do_facet mds1 $LCTL set_param mdd.$MDT0.$var=$old"
17956                 do_facet mds1 $LCTL set_param mdd.$MDT0.$param ||
17957                         error "unable to set mdd.*.$param"
17958         done
17959
17960         start=$SECONDS
17961         cl_users=(${CL_USERS[mds1]})
17962         cl_user1="${cl_users[0]}"
17963         cl_user2="${cl_users[1]}"
17964
17965         [[ -n $cl_user1 ]] ||
17966                 error "mds1: user #1 isn't registered"
17967         [[ -n $cl_user2 ]] ||
17968                 error "mds1: user #2 isn't registered"
17969
17970         # ensure we are past the previous changelog_min_gc_interval set above
17971         local sleep2=$((start + 2 - SECONDS))
17972         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
17973
17974         #define OBD_FAIL_MDS_CHANGELOG_ENOSPC 0x018c
17975         do_facet mds1 $LCTL set_param fail_loc=0x018c \
17976                         fail_val=$(((llog_size1 + llog_size2) / 2))
17977
17978         # Generate more changelog to trigger GC
17979         createmany -o $DIR/$tdir/u3_ 4 ||
17980                 error "create failed for more files"
17981
17982         # ensure gc thread is done
17983         wait_update_facet mds1 "pgrep chlg_gc_thread" "" 20 ||
17984                 error "mds1: GC-thread not done"
17985
17986         do_facet mds1 $LCTL set_param fail_loc=0
17987
17988         # check cl_user1 is purged
17989         changelog_users mds1 | grep -q "$cl_user1" &&
17990                 error "User $cl_user1 is registered"
17991         # check cl_user2 is not purged
17992         changelog_users mds1 | grep -q "$cl_user2" ||
17993                 error "User $cl_user2 is not registered"
17994 }
17995 run_test 160t "changelog garbage collect on lack of space"
17996
17997 test_161a() {
17998         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17999
18000         test_mkdir -c1 $DIR/$tdir
18001         cp /etc/hosts $DIR/$tdir/$tfile
18002         test_mkdir -c1 $DIR/$tdir/foo1
18003         test_mkdir -c1 $DIR/$tdir/foo2
18004         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/sofia
18005         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/zachary
18006         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/luna
18007         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/thor
18008         local FID=$($LFS path2fid $DIR/$tdir/$tfile | tr -d '[]')
18009         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
18010                 $LFS fid2path $DIR $FID
18011                 error "bad link ea"
18012         fi
18013         # middle
18014         rm $DIR/$tdir/foo2/zachary
18015         # last
18016         rm $DIR/$tdir/foo2/thor
18017         # first
18018         rm $DIR/$tdir/$tfile
18019         # rename
18020         mv $DIR/$tdir/foo1/sofia $DIR/$tdir/foo2/maggie
18021         [ "$($LFS fid2path $FSNAME --link 1 $FID)" != "$tdir/foo2/maggie" ] &&
18022                 { $LFS fid2path $DIR $FID; error "bad link rename"; }
18023         rm $DIR/$tdir/foo2/maggie
18024
18025         # overflow the EA
18026         local longname=$tfile.avg_len_is_thirty_two_
18027         stack_trap "unlinkmany $DIR/$tdir/foo2/$longname 1000 || \
18028                 error_noexit 'failed to unlink many hardlinks'" EXIT
18029         createmany -l$DIR/$tdir/foo1/luna $DIR/$tdir/foo2/$longname 1000 ||
18030                 error "failed to hardlink many files"
18031         links=$($LFS fid2path $DIR $FID | wc -l)
18032         echo -n "${links}/1000 links in link EA"
18033         [[ $links -gt 60 ]] || error "expected at least 60 links in link EA"
18034 }
18035 run_test 161a "link ea sanity"
18036
18037 test_161b() {
18038         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18039         [ $MDSCOUNT -lt 2 ] && skip_env "skipping remote directory test"
18040
18041         local MDTIDX=1
18042         local remote_dir=$DIR/$tdir/remote_dir
18043
18044         mkdir -p $DIR/$tdir
18045         $LFS mkdir -i $MDTIDX $remote_dir ||
18046                 error "create remote directory failed"
18047
18048         cp /etc/hosts $remote_dir/$tfile
18049         mkdir -p $remote_dir/foo1
18050         mkdir -p $remote_dir/foo2
18051         ln $remote_dir/$tfile $remote_dir/foo1/sofia
18052         ln $remote_dir/$tfile $remote_dir/foo2/zachary
18053         ln $remote_dir/$tfile $remote_dir/foo1/luna
18054         ln $remote_dir/$tfile $remote_dir/foo2/thor
18055
18056         local FID=$($LFS path2fid $remote_dir/$tfile | tr -d '[' |
18057                      tr -d ']')
18058         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
18059                 $LFS fid2path $DIR $FID
18060                 error "bad link ea"
18061         fi
18062         # middle
18063         rm $remote_dir/foo2/zachary
18064         # last
18065         rm $remote_dir/foo2/thor
18066         # first
18067         rm $remote_dir/$tfile
18068         # rename
18069         mv $remote_dir/foo1/sofia $remote_dir/foo2/maggie
18070         local link_path=$($LFS fid2path $FSNAME --link 1 $FID)
18071         if [ "$DIR/$link_path" != "$remote_dir/foo2/maggie" ]; then
18072                 $LFS fid2path $DIR $FID
18073                 error "bad link rename"
18074         fi
18075         rm $remote_dir/foo2/maggie
18076
18077         # overflow the EA
18078         local longname=filename_avg_len_is_thirty_two_
18079         createmany -l$remote_dir/foo1/luna $remote_dir/foo2/$longname 1000 ||
18080                 error "failed to hardlink many files"
18081         links=$($LFS fid2path $DIR $FID | wc -l)
18082         echo -n "${links}/1000 links in link EA"
18083         [[ ${links} -gt 60 ]] ||
18084                 error "expected at least 60 links in link EA"
18085         unlinkmany $remote_dir/foo2/$longname 1000 ||
18086         error "failed to unlink many hardlinks"
18087 }
18088 run_test 161b "link ea sanity under remote directory"
18089
18090 test_161c() {
18091         remote_mds_nodsh && skip "remote MDS with nodsh"
18092         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18093         [[ $MDS1_VERSION -lt $(version_code 2.1.5) ]] &&
18094                 skip "Need MDS version at least 2.1.5"
18095
18096         # define CLF_RENAME_LAST 0x0001
18097         # rename overwrite a target having nlink = 1 (changelog flag 0x1)
18098         changelog_register || error "changelog_register failed"
18099
18100         rm -rf $DIR/$tdir
18101         test_mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir
18102         touch $DIR/$tdir/foo_161c
18103         touch $DIR/$tdir/bar_161c
18104         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
18105         changelog_dump | grep RENME | tail -n 5
18106         local flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
18107         changelog_clear 0 || error "changelog_clear failed"
18108         if [ x$flags != "x0x1" ]; then
18109                 error "flag $flags is not 0x1"
18110         fi
18111
18112         echo "rename overwrite target with nlink = 1, changelog flags=$flags"
18113         # rename overwrite a target having nlink > 1 (changelog flag 0x0)
18114         touch $DIR/$tdir/foo_161c
18115         touch $DIR/$tdir/bar_161c
18116         ln $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
18117         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
18118         changelog_dump | grep RENME | tail -n 5
18119         flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
18120         changelog_clear 0 || error "changelog_clear failed"
18121         if [ x$flags != "x0x0" ]; then
18122                 error "flag $flags is not 0x0"
18123         fi
18124         echo "rename overwrite a target having nlink > 1," \
18125                 "changelog record has flags of $flags"
18126
18127         # rename doesn't overwrite a target (changelog flag 0x0)
18128         touch $DIR/$tdir/foo_161c
18129         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/foo2_161c
18130         changelog_dump | grep RENME | tail -n 5
18131         flags=$(changelog_dump | grep RENME | tail -1 | cut -f5 -d' ')
18132         changelog_clear 0 || error "changelog_clear failed"
18133         if [ x$flags != "x0x0" ]; then
18134                 error "flag $flags is not 0x0"
18135         fi
18136         echo "rename doesn't overwrite a target," \
18137                 "changelog record has flags of $flags"
18138
18139         # define CLF_UNLINK_LAST 0x0001
18140         # unlink a file having nlink = 1 (changelog flag 0x1)
18141         rm -f $DIR/$tdir/foo2_161c
18142         changelog_dump | grep UNLNK | tail -n 5
18143         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
18144         changelog_clear 0 || error "changelog_clear failed"
18145         if [ x$flags != "x0x1" ]; then
18146                 error "flag $flags is not 0x1"
18147         fi
18148         echo "unlink a file having nlink = 1," \
18149                 "changelog record has flags of $flags"
18150
18151         # unlink a file having nlink > 1 (changelog flag 0x0)
18152         ln -f $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
18153         rm -f $DIR/$tdir/foobar_161c
18154         changelog_dump | grep UNLNK | tail -n 5
18155         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
18156         changelog_clear 0 || error "changelog_clear failed"
18157         if [ x$flags != "x0x0" ]; then
18158                 error "flag $flags is not 0x0"
18159         fi
18160         echo "unlink a file having nlink > 1, changelog record flags '$flags'"
18161 }
18162 run_test 161c "check CL_RENME[UNLINK] changelog record flags"
18163
18164 test_161d() {
18165         remote_mds_nodsh && skip "remote MDS with nodsh"
18166         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
18167
18168         local pid
18169         local fid
18170
18171         changelog_register || error "changelog_register failed"
18172
18173         # work in a standalone dir to avoid locking on $DIR/$MOUNT to
18174         # interfer with $MOUNT/.lustre/fid/ access
18175         mkdir $DIR/$tdir
18176         [[ $? -eq 0 ]] || error "mkdir failed"
18177
18178         #define OBD_FAIL_LLITE_CREATE_NODE_PAUSE 0x140c | CFS_FAIL_ONCE
18179         $LCTL set_param fail_loc=0x8000140c
18180         # 5s pause
18181         $LCTL set_param fail_val=5
18182
18183         # create file
18184         echo foofoo > $DIR/$tdir/$tfile &
18185         pid=$!
18186
18187         # wait for create to be delayed
18188         sleep 2
18189
18190         ps -p $pid
18191         [[ $? -eq 0 ]] || error "create should be blocked"
18192
18193         local tempfile="$(mktemp --tmpdir $tfile.XXXXXX)"
18194         stack_trap "rm -f $tempfile"
18195         fid=$(changelog_extract_field "CREAT" "$tfile" "t=")
18196         cat $MOUNT/.lustre/fid/$fid 2>/dev/null >$tempfile || error "cat failed"
18197         # some delay may occur during ChangeLog publishing and file read just
18198         # above, that could allow file write to happen finally
18199         [[ -s $tempfile ]] && echo "file should be empty"
18200
18201         $LCTL set_param fail_loc=0
18202
18203         wait $pid
18204         [[ $? -eq 0 ]] || error "create failed"
18205 }
18206 run_test 161d "create with concurrent .lustre/fid access"
18207
18208 check_path() {
18209         local expected="$1"
18210         shift
18211         local fid="$2"
18212
18213         local path
18214         path=$($LFS fid2path "$@")
18215         local rc=$?
18216
18217         if [ $rc -ne 0 ]; then
18218                 error "path looked up of '$expected' failed: rc=$rc"
18219         elif [ "$path" != "$expected" ]; then
18220                 error "path looked up '$path' instead of '$expected'"
18221         else
18222                 echo "FID '$fid' resolves to path '$path' as expected"
18223         fi
18224 }
18225
18226 test_162a() { # was test_162
18227         test_mkdir -p -c1 $DIR/$tdir/d2
18228         touch $DIR/$tdir/d2/$tfile
18229         touch $DIR/$tdir/d2/x1
18230         touch $DIR/$tdir/d2/x2
18231         test_mkdir -p -c1 $DIR/$tdir/d2/a/b/c
18232         test_mkdir -p -c1 $DIR/$tdir/d2/p/q/r
18233         # regular file
18234         local fid=$($LFS path2fid $DIR/$tdir/d2/$tfile | tr -d '[]')
18235         check_path "$tdir/d2/$tfile" $FSNAME "$fid" --link 0
18236
18237         # softlink
18238         ln -s $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/slink
18239         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink | tr -d '[]')
18240         check_path "$tdir/d2/p/q/r/slink" $FSNAME "$fid" --link 0
18241
18242         # softlink to wrong file
18243         ln -s /this/is/garbage $DIR/$tdir/d2/p/q/r/slink.wrong
18244         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink.wrong | tr -d '[]')
18245         check_path "$tdir/d2/p/q/r/slink.wrong" $FSNAME "$fid" --link 0
18246
18247         # hardlink
18248         ln $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/hlink
18249         mv $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/a/b/c/new_file
18250         fid=$($LFS path2fid $DIR/$tdir/d2/a/b/c/new_file | tr -d '[]')
18251         # fid2path dir/fsname should both work
18252         check_path "$tdir/d2/a/b/c/new_file" $FSNAME "$fid" --link 1
18253         check_path "$DIR/$tdir/d2/p/q/r/hlink" $DIR "$fid" --link 0
18254
18255         # hardlink count: check that there are 2 links
18256         local nlinks=$($LFS fid2path $DIR "$fid" | wc -l)
18257         [ $nlinks -eq 2 ] || error "expect 2 links, found $nlinks"
18258
18259         # hardlink indexing: remove the first link
18260         rm $DIR/$tdir/d2/p/q/r/hlink
18261         check_path "$tdir/d2/a/b/c/new_file" $FSNAME $fid --link 0
18262 }
18263 run_test 162a "path lookup sanity"
18264
18265 test_162b() {
18266         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18267         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18268
18269         mkdir $DIR/$tdir
18270         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
18271                                 error "create striped dir failed"
18272
18273         local FID=$($LFS getdirstripe $DIR/$tdir/striped_dir |
18274                                         tail -n 1 | awk '{print $2}')
18275         stat $MOUNT/.lustre/fid/$FID && error "sub_stripe can be accessed"
18276
18277         touch $DIR/$tdir/striped_dir/f{0..4} || error "touch f0..4 failed"
18278         mkdir $DIR/$tdir/striped_dir/d{0..4} || error "mkdir d0..4 failed"
18279
18280         # regular file
18281         for ((i=0;i<5;i++)); do
18282                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/f$i | tr -d '[]') ||
18283                         error "get fid for f$i failed"
18284                 check_path "$tdir/striped_dir/f$i" $FSNAME $FID --link 0
18285
18286                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/d$i | tr -d '[]') ||
18287                         error "get fid for d$i failed"
18288                 check_path "$tdir/striped_dir/d$i" $FSNAME $FID --link 0
18289         done
18290
18291         return 0
18292 }
18293 run_test 162b "striped directory path lookup sanity"
18294
18295 # LU-4239: Verify fid2path works with paths 100 or more directories deep
18296 test_162c() {
18297         [[ $MDS1_VERSION -lt $(version_code 2.7.51) ]] &&
18298                 skip "Need MDS version at least 2.7.51"
18299
18300         local lpath=$tdir.local
18301         local rpath=$tdir.remote
18302
18303         test_mkdir $DIR/$lpath
18304         test_mkdir $DIR/$rpath
18305
18306         for ((i = 0; i <= 101; i++)); do
18307                 lpath="$lpath/$i"
18308                 mkdir $DIR/$lpath
18309                 FID=$($LFS path2fid $DIR/$lpath | tr -d '[]') ||
18310                         error "get fid for local directory $DIR/$lpath failed"
18311                 check_path "$DIR/$lpath" $MOUNT $FID --link 0
18312
18313                 rpath="$rpath/$i"
18314                 test_mkdir $DIR/$rpath
18315                 FID=$($LFS path2fid $DIR/$rpath | tr -d '[]') ||
18316                         error "get fid for remote directory $DIR/$rpath failed"
18317                 check_path "$DIR/$rpath" $MOUNT $FID --link 0
18318         done
18319
18320         return 0
18321 }
18322 run_test 162c "fid2path works with paths 100 or more directories deep"
18323
18324 oalr_event_count() {
18325         local event="${1}"
18326         local trace="${2}"
18327
18328         awk -v name="${FSNAME}-OST0000" \
18329             -v event="${event}" \
18330             '$1 == "TRACE" && $2 == event && $3 == name' \
18331             "${trace}" |
18332         wc -l
18333 }
18334
18335 oalr_expect_event_count() {
18336         local event="${1}"
18337         local trace="${2}"
18338         local expect="${3}"
18339         local count
18340
18341         count=$(oalr_event_count "${event}" "${trace}")
18342         if ((count == expect)); then
18343                 return 0
18344         fi
18345
18346         error_noexit "${event} event count was '${count}', expected ${expect}"
18347         cat "${trace}" >&2
18348         exit 1
18349 }
18350
18351 cleanup_165() {
18352         do_facet ost1 killall --quiet -KILL ofd_access_log_reader || true
18353         stop ost1
18354         start ost1 "$(ostdevname 1)" $OST_MOUNT_OPTS
18355 }
18356
18357 setup_165() {
18358         sync # Flush previous IOs so we can count log entries.
18359         do_facet ost1 $LCTL set_param "obdfilter.${FSNAME}-OST0000.access_log_size=4096"
18360         stack_trap cleanup_165 EXIT
18361 }
18362
18363 test_165a() {
18364         local trace="/tmp/${tfile}.trace"
18365         local rc
18366         local count
18367
18368         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
18369                 skip "OFD access log unsupported"
18370
18371         setup_165
18372         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
18373         sleep 5
18374
18375         do_facet ost1 ofd_access_log_reader --list
18376         stop ost1
18377
18378         do_facet ost1 killall -TERM ofd_access_log_reader
18379         wait
18380         rc=$?
18381
18382         if ((rc != 0)); then
18383                 error "ofd_access_log_reader exited with rc = '${rc}'"
18384         fi
18385
18386         # Parse trace file for discovery events:
18387         oalr_expect_event_count alr_log_add "${trace}" 1
18388         oalr_expect_event_count alr_log_eof "${trace}" 1
18389         oalr_expect_event_count alr_log_free "${trace}" 1
18390 }
18391 run_test 165a "ofd access log discovery"
18392
18393 test_165b() {
18394         local trace="/tmp/${tfile}.trace"
18395         local file="${DIR}/${tfile}"
18396         local pfid1
18397         local pfid2
18398         local -a entry
18399         local rc
18400         local count
18401         local size
18402         local flags
18403
18404         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
18405                 skip "OFD access log unsupported"
18406
18407         setup_165
18408         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
18409         sleep 5
18410
18411         do_facet ost1 ofd_access_log_reader --list
18412
18413         lfs setstripe -c 1 -i 0 "${file}"
18414         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
18415                 error "cannot create '${file}'"
18416
18417         sleep 5
18418         do_facet ost1 killall -TERM ofd_access_log_reader
18419         wait
18420         rc=$?
18421
18422         if ((rc != 0)); then
18423                 error "ofd_access_log_reader exited with rc = '${rc}'"
18424         fi
18425
18426         oalr_expect_event_count alr_log_entry "${trace}" 1
18427
18428         pfid1=$($LFS path2fid "${file}")
18429
18430         # 1     2             3   4    5     6   7    8    9     10
18431         # TRACE alr_log_entry OST PFID BEGIN END TIME SIZE COUNT FLAGS
18432         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
18433
18434         echo "entry = '${entry[*]}'" >&2
18435
18436         pfid2=${entry[4]}
18437         if [[ "${pfid1}" != "${pfid2}" ]]; then
18438                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
18439         fi
18440
18441         size=${entry[8]}
18442         if ((size != 1048576)); then
18443                 error "entry '${entry[*]}' has invalid io size '${size}', expected 1048576"
18444         fi
18445
18446         flags=${entry[10]}
18447         if [[ "${flags}" != "w" ]]; then
18448                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'w'"
18449         fi
18450
18451         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
18452         sleep 5
18453
18454         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r524288c ||
18455                 error "cannot read '${file}'"
18456         sleep 5
18457
18458         do_facet ost1 killall -TERM ofd_access_log_reader
18459         wait
18460         rc=$?
18461
18462         if ((rc != 0)); then
18463                 error "ofd_access_log_reader exited with rc = '${rc}'"
18464         fi
18465
18466         oalr_expect_event_count alr_log_entry "${trace}" 1
18467
18468         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
18469         echo "entry = '${entry[*]}'" >&2
18470
18471         pfid2=${entry[4]}
18472         if [[ "${pfid1}" != "${pfid2}" ]]; then
18473                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
18474         fi
18475
18476         size=${entry[8]}
18477         if ((size != 524288)); then
18478                 error "entry '${entry[*]}' has invalid io size '${size}', 524288"
18479         fi
18480
18481         flags=${entry[10]}
18482         if [[ "${flags}" != "r" ]]; then
18483                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'r'"
18484         fi
18485 }
18486 run_test 165b "ofd access log entries are produced and consumed"
18487
18488 test_165c() {
18489         local trace="/tmp/${tfile}.trace"
18490         local file="${DIR}/${tdir}/${tfile}"
18491
18492         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
18493                 skip "OFD access log unsupported"
18494
18495         test_mkdir "${DIR}/${tdir}"
18496
18497         setup_165
18498         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
18499         sleep 5
18500
18501         lfs setstripe -c 1 -i 0 "${DIR}/${tdir}"
18502
18503         # 4096 / 64 = 64. Create twice as many entries.
18504         for ((i = 0; i < 128; i++)); do
18505                 $MULTIOP "${file}-${i}" oO_CREAT:O_WRONLY:w512c ||
18506                         error "cannot create file"
18507         done
18508
18509         sync
18510
18511         do_facet ost1 killall -TERM ofd_access_log_reader
18512         wait
18513         rc=$?
18514         if ((rc != 0)); then
18515                 error "ofd_access_log_reader exited with rc = '${rc}'"
18516         fi
18517
18518         unlinkmany  "${file}-%d" 128
18519 }
18520 run_test 165c "full ofd access logs do not block IOs"
18521
18522 oal_get_read_count() {
18523         local stats="$1"
18524
18525         # STATS lustre-OST0001 alr_read_count 1
18526
18527         do_facet ost1 cat "${stats}" |
18528         awk '$1 == "STATS" && $3 == "alr_read_count" { count = $4; }
18529              END { print count; }'
18530 }
18531
18532 oal_expect_read_count() {
18533         local stats="$1"
18534         local count
18535         local expect="$2"
18536
18537         # Ask ofd_access_log_reader to write stats.
18538         do_facet ost1 killall -USR1 ofd_access_log_reader
18539
18540         # Allow some time for things to happen.
18541         sleep 1
18542
18543         count=$(oal_get_read_count "${stats}")
18544         if ((count == expect)); then
18545                 return 0
18546         fi
18547
18548         error_noexit "bad read count, got ${count}, expected ${expect}"
18549         do_facet ost1 cat "${stats}" >&2
18550         exit 1
18551 }
18552
18553 test_165d() {
18554         local stats="/tmp/${tfile}.stats"
18555         local file="${DIR}/${tdir}/${tfile}"
18556         local param="obdfilter.${FSNAME}-OST0000.access_log_mask"
18557
18558         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
18559                 skip "OFD access log unsupported"
18560
18561         test_mkdir "${DIR}/${tdir}"
18562
18563         setup_165
18564         do_facet ost1 ofd_access_log_reader --stats="${stats}" &
18565         sleep 5
18566
18567         lfs setstripe -c 1 -i 0 "${file}"
18568
18569         do_facet ost1 lctl set_param "${param}=rw"
18570         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
18571                 error "cannot create '${file}'"
18572         oal_expect_read_count "${stats}" 1
18573
18574         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
18575                 error "cannot read '${file}'"
18576         oal_expect_read_count "${stats}" 2
18577
18578         do_facet ost1 lctl set_param "${param}=r"
18579         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
18580                 error "cannot create '${file}'"
18581         oal_expect_read_count "${stats}" 2
18582
18583         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
18584                 error "cannot read '${file}'"
18585         oal_expect_read_count "${stats}" 3
18586
18587         do_facet ost1 lctl set_param "${param}=w"
18588         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
18589                 error "cannot create '${file}'"
18590         oal_expect_read_count "${stats}" 4
18591
18592         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
18593                 error "cannot read '${file}'"
18594         oal_expect_read_count "${stats}" 4
18595
18596         do_facet ost1 lctl set_param "${param}=0"
18597         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
18598                 error "cannot create '${file}'"
18599         oal_expect_read_count "${stats}" 4
18600
18601         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
18602                 error "cannot read '${file}'"
18603         oal_expect_read_count "${stats}" 4
18604
18605         do_facet ost1 killall -TERM ofd_access_log_reader
18606         wait
18607         rc=$?
18608         if ((rc != 0)); then
18609                 error "ofd_access_log_reader exited with rc = '${rc}'"
18610         fi
18611 }
18612 run_test 165d "ofd_access_log mask works"
18613
18614 test_165e() {
18615         local stats="/tmp/${tfile}.stats"
18616         local file0="${DIR}/${tdir}-0/${tfile}"
18617         local file1="${DIR}/${tdir}-1/${tfile}"
18618
18619         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
18620                 skip "OFD access log unsupported"
18621
18622         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
18623
18624         test_mkdir -c 1 -i 0 "${DIR}/${tdir}-0"
18625         test_mkdir -c 1 -i 1 "${DIR}/${tdir}-1"
18626
18627         lfs setstripe -c 1 -i 0 "${file0}"
18628         lfs setstripe -c 1 -i 0 "${file1}"
18629
18630         setup_165
18631         do_facet ost1 ofd_access_log_reader -I 1 --stats="${stats}" &
18632         sleep 5
18633
18634         $MULTIOP "${file0}" oO_CREAT:O_WRONLY:w512c ||
18635                 error "cannot create '${file0}'"
18636         sync
18637         oal_expect_read_count "${stats}" 0
18638
18639         $MULTIOP "${file1}" oO_CREAT:O_WRONLY:w512c ||
18640                 error "cannot create '${file1}'"
18641         sync
18642         oal_expect_read_count "${stats}" 1
18643
18644         do_facet ost1 killall -TERM ofd_access_log_reader
18645         wait
18646         rc=$?
18647         if ((rc != 0)); then
18648                 error "ofd_access_log_reader exited with rc = '${rc}'"
18649         fi
18650 }
18651 run_test 165e "ofd_access_log MDT index filter works"
18652
18653 test_165f() {
18654         local trace="/tmp/${tfile}.trace"
18655         local rc
18656         local count
18657
18658         setup_165
18659         do_facet ost1 timeout 60 ofd_access_log_reader \
18660                 --exit-on-close --debug=- --trace=- > "${trace}" &
18661         sleep 5
18662         stop ost1
18663
18664         wait
18665         rc=$?
18666
18667         if ((rc != 0)); then
18668                 error_noexit "ofd_access_log_reader exited with rc = '${rc}'"
18669                 cat "${trace}"
18670                 exit 1
18671         fi
18672 }
18673 run_test 165f "ofd_access_log_reader --exit-on-close works"
18674
18675 test_169() {
18676         # do directio so as not to populate the page cache
18677         log "creating a 10 Mb file"
18678         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c ||
18679                 error "multiop failed while creating a file"
18680         log "starting reads"
18681         dd if=$DIR/$tfile of=/dev/null bs=4096 &
18682         log "truncating the file"
18683         $MULTIOP $DIR/$tfile oO_TRUNC:c ||
18684                 error "multiop failed while truncating the file"
18685         log "killing dd"
18686         kill %+ || true # reads might have finished
18687         echo "wait until dd is finished"
18688         wait
18689         log "removing the temporary file"
18690         rm -rf $DIR/$tfile || error "tmp file removal failed"
18691 }
18692 run_test 169 "parallel read and truncate should not deadlock"
18693
18694 test_170() {
18695         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18696
18697         $LCTL clear     # bug 18514
18698         $LCTL debug_daemon start $TMP/${tfile}_log_good
18699         touch $DIR/$tfile
18700         $LCTL debug_daemon stop
18701         sed -e "s/^...../a/g" $TMP/${tfile}_log_good > $TMP/${tfile}_log_bad ||
18702                 error "sed failed to read log_good"
18703
18704         $LCTL debug_daemon start $TMP/${tfile}_log_good
18705         rm -rf $DIR/$tfile
18706         $LCTL debug_daemon stop
18707
18708         $LCTL df $TMP/${tfile}_log_bad > $TMP/${tfile}_log_bad.out 2>&1 ||
18709                error "lctl df log_bad failed"
18710
18711         local bad_line=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
18712         local good_line1=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
18713
18714         $LCTL df $TMP/${tfile}_log_good > $TMP/${tfile}_log_good.out 2>&1
18715         local good_line2=$(tail -n 1 $TMP/${tfile}_log_good.out | awk '{print $5}')
18716
18717         [ "$bad_line" ] && [ "$good_line1" ] && [ "$good_line2" ] ||
18718                 error "bad_line good_line1 good_line2 are empty"
18719
18720         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
18721         cat $TMP/${tfile}_log_bad >> $TMP/${tfile}_logs_corrupt
18722         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
18723
18724         $LCTL df $TMP/${tfile}_logs_corrupt > $TMP/${tfile}_log_bad.out 2>&1
18725         local bad_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
18726         local good_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
18727
18728         [ "$bad_line_new" ] && [ "$good_line_new" ] ||
18729                 error "bad_line_new good_line_new are empty"
18730
18731         local expected_good=$((good_line1 + good_line2*2))
18732
18733         rm -f $TMP/${tfile}*
18734         # LU-231, short malformed line may not be counted into bad lines
18735         if [ $bad_line -ne $bad_line_new ] &&
18736                    [ $bad_line -ne $((bad_line_new - 1)) ]; then
18737                 error "expected $bad_line bad lines, but got $bad_line_new"
18738                 return 1
18739         fi
18740
18741         if [ $expected_good -ne $good_line_new ]; then
18742                 error "expected $expected_good good lines, but got $good_line_new"
18743                 return 2
18744         fi
18745         true
18746 }
18747 run_test 170 "test lctl df to handle corrupted log ====================="
18748
18749 test_171() { # bug20592
18750         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18751
18752         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
18753         $LCTL set_param fail_loc=0x50e
18754         $LCTL set_param fail_val=3000
18755         multiop_bg_pause $DIR/$tfile O_s || true
18756         local MULTIPID=$!
18757         kill -USR1 $MULTIPID
18758         # cause log dump
18759         sleep 3
18760         wait $MULTIPID
18761         if dmesg | grep "recursive fault"; then
18762                 error "caught a recursive fault"
18763         fi
18764         $LCTL set_param fail_loc=0
18765         true
18766 }
18767 run_test 171 "test libcfs_debug_dumplog_thread stuck in do_exit() ======"
18768
18769 test_172() {
18770
18771         #define OBD_FAIL_OBD_CLEANUP  0x60e
18772         $LCTL set_param fail_loc=0x60e
18773         umount $MOUNT || error "umount $MOUNT failed"
18774         stack_trap "mount_client $MOUNT"
18775
18776         (( $($LCTL dl | egrep -c " osc | lov | lmv | mdc ") > 0 )) ||
18777                 error "no client OBDs are remained"
18778
18779         $LCTL dl | while read devno state type name foo; do
18780                 case $type in
18781                 lov|osc|lmv|mdc)
18782                         $LCTL --device $name cleanup
18783                         $LCTL --device $name detach
18784                         ;;
18785                 *)
18786                         # skip server devices
18787                         ;;
18788                 esac
18789         done
18790
18791         if (( $($LCTL dl | egrep -c " osc | lov | lmv | mdc ") > 0 )); then
18792                 $LCTL dl | egrep " osc | lov | lmv | mdc "
18793                 error "some client OBDs are still remained"
18794         fi
18795
18796 }
18797 run_test 172 "manual device removal with lctl cleanup/detach ======"
18798
18799 # it would be good to share it with obdfilter-survey/iokit-libecho code
18800 setup_obdecho_osc () {
18801         local rc=0
18802         local ost_nid=$1
18803         local obdfilter_name=$2
18804         echo "Creating new osc for $obdfilter_name on $ost_nid"
18805         # make sure we can find loopback nid
18806         $LCTL add_uuid $ost_nid $ost_nid >/dev/null 2>&1
18807
18808         [ $rc -eq 0 ] && { $LCTL attach osc ${obdfilter_name}_osc     \
18809                            ${obdfilter_name}_osc_UUID || rc=2; }
18810         [ $rc -eq 0 ] && { $LCTL --device ${obdfilter_name}_osc setup \
18811                            ${obdfilter_name}_UUID  $ost_nid || rc=3; }
18812         return $rc
18813 }
18814
18815 cleanup_obdecho_osc () {
18816         local obdfilter_name=$1
18817         $LCTL --device ${obdfilter_name}_osc cleanup >/dev/null
18818         $LCTL --device ${obdfilter_name}_osc detach  >/dev/null
18819         return 0
18820 }
18821
18822 obdecho_test() {
18823         local OBD=$1
18824         local node=$2
18825         local pages=${3:-64}
18826         local rc=0
18827         local id
18828
18829         local count=10
18830         local obd_size=$(get_obd_size $node $OBD)
18831         local page_size=$(get_page_size $node)
18832         if [[ -n "$obd_size" ]]; then
18833                 local new_count=$((obd_size / (pages * page_size / 1024)))
18834                 [[ $new_count -ge $count ]] || count=$new_count
18835         fi
18836
18837         do_facet $node "$LCTL attach echo_client ec ec_uuid" || rc=1
18838         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec setup $OBD" ||
18839                            rc=2; }
18840         if [ $rc -eq 0 ]; then
18841             id=$(do_facet $node "$LCTL --device ec create 1"  | awk '/object id/ {print $6}')
18842             [ ${PIPESTATUS[0]} -eq 0 -a -n "$id" ] || rc=3
18843         fi
18844         echo "New object id is $id"
18845         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec getattr $id" ||
18846                            rc=4; }
18847         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec "                 \
18848                            "test_brw $count w v $pages $id" || rc=4; }
18849         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec destroy $id 1" ||
18850                            rc=4; }
18851         [ $rc -eq 0 ] || [ $rc -gt 2 ] &&
18852                 { do_facet $node "$LCTL --device ec cleanup" || rc=5; }
18853         [ $rc -eq 0 ] || [ $rc -gt 1 ] &&
18854                 { do_facet $node "$LCTL --device ec detach" || rc=6; }
18855         [ $rc -ne 0 ] && echo "obecho_create_test failed: $rc"
18856         return $rc
18857 }
18858
18859 test_180a() {
18860         skip "obdecho on osc is no longer supported"
18861 }
18862 run_test 180a "test obdecho on osc"
18863
18864 test_180b() {
18865         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18866         remote_ost_nodsh && skip "remote OST with nodsh"
18867
18868         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
18869                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
18870                 error "failed to load module obdecho"
18871
18872         local target=$(do_facet ost1 $LCTL dl |
18873                        awk '/obdfilter/ { print $4; exit; }')
18874
18875         if [ -n "$target" ]; then
18876                 obdecho_test $target ost1 || error "obdecho_test failed with $?"
18877         else
18878                 do_facet ost1 $LCTL dl
18879                 error "there is no obdfilter target on ost1"
18880         fi
18881 }
18882 run_test 180b "test obdecho directly on obdfilter"
18883
18884 test_180c() { # LU-2598
18885         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18886         remote_ost_nodsh && skip "remote OST with nodsh"
18887         [[ $MDS1_VERSION -lt $(version_code 2.4.0) ]] &&
18888                 skip "Need MDS version at least 2.4.0"
18889
18890         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
18891                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
18892                 error "failed to load module obdecho"
18893
18894         local target=$(do_facet ost1 $LCTL dl |
18895                        awk '/obdfilter/ { print $4; exit; }')
18896
18897         if [ -n "$target" ]; then
18898                 local pages=16384 # 64MB bulk I/O RPC size
18899
18900                 obdecho_test "$target" ost1 "$pages" ||
18901                         error "obdecho_test with pages=$pages failed with $?"
18902         else
18903                 do_facet ost1 $LCTL dl
18904                 error "there is no obdfilter target on ost1"
18905         fi
18906 }
18907 run_test 180c "test huge bulk I/O size on obdfilter, don't LASSERT"
18908
18909 test_181() { # bug 22177
18910         test_mkdir $DIR/$tdir
18911         # create enough files to index the directory
18912         createmany -o $DIR/$tdir/foobar 4000
18913         # print attributes for debug purpose
18914         lsattr -d .
18915         # open dir
18916         multiop_bg_pause $DIR/$tdir D_Sc || return 1
18917         MULTIPID=$!
18918         # remove the files & current working dir
18919         unlinkmany $DIR/$tdir/foobar 4000
18920         rmdir $DIR/$tdir
18921         kill -USR1 $MULTIPID
18922         wait $MULTIPID
18923         stat $DIR/$tdir && error "open-unlinked dir was not removed!"
18924         return 0
18925 }
18926 run_test 181 "Test open-unlinked dir ========================"
18927
18928 test_182a() {
18929         local fcount=1000
18930         local tcount=10
18931
18932         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
18933
18934         $LCTL set_param mdc.*.rpc_stats=clear
18935
18936         for (( i = 0; i < $tcount; i++ )) ; do
18937                 mkdir $DIR/$tdir/$i
18938         done
18939
18940         for (( i = 0; i < $tcount; i++ )) ; do
18941                 createmany -o $DIR/$tdir/$i/f- $fcount &
18942         done
18943         wait
18944
18945         for (( i = 0; i < $tcount; i++ )) ; do
18946                 unlinkmany $DIR/$tdir/$i/f- $fcount &
18947         done
18948         wait
18949
18950         $LCTL get_param mdc.*.rpc_stats
18951
18952         rm -rf $DIR/$tdir
18953 }
18954 run_test 182a "Test parallel modify metadata operations from mdc"
18955
18956 test_182b() {
18957         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
18958         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
18959         local dcount=1000
18960         local tcount=10
18961         local stime
18962         local etime
18963         local delta
18964
18965         do_facet mds1 $LCTL list_param \
18966                 osp.$FSNAME-MDT*-osp-MDT*.rpc_stats ||
18967                 skip "MDS lacks parallel RPC handling"
18968
18969         $LFS mkdir -i 0 $DIR/$tdir || error "creating dir $DIR/$tdir"
18970
18971         rpc_count=$(do_facet mds1 $LCTL get_param -n \
18972                     osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight)
18973
18974         stime=$(date +%s)
18975         createmany -i 0 -d $DIR/$tdir/t- $tcount
18976
18977         for (( i = 0; i < $tcount; i++ )) ; do
18978                 createmany -i 0 -d $DIR/$tdir/t-$i/d- 0 $dcount &
18979         done
18980         wait
18981         etime=$(date +%s)
18982         delta=$((etime - stime))
18983         echo "Time for file creation $delta sec for $rpc_count parallel RPCs"
18984
18985         stime=$(date +%s)
18986         for (( i = 0; i < $tcount; i++ )) ; do
18987                 unlinkmany -d $DIR/$tdir/$i/d- $dcount &
18988         done
18989         wait
18990         etime=$(date +%s)
18991         delta=$((etime - stime))
18992         echo "Time for file removal $delta sec for $rpc_count parallel RPCs"
18993
18994         rm -rf $DIR/$tdir
18995
18996         $LFS mkdir -i 0 $DIR/$tdir || error "creating dir $DIR/$tdir"
18997
18998         do_facet mds1 $LCTL set_param osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight=1
18999
19000         stime=$(date +%s)
19001         createmany -i 0 -d $DIR/$tdir/t- $tcount
19002
19003         for (( i = 0; i < $tcount; i++ )) ; do
19004                 createmany -i 0 -d $DIR/$tdir/t-$i/d- 0 $dcount &
19005         done
19006         wait
19007         etime=$(date +%s)
19008         delta=$((etime - stime))
19009         echo "Time for file creation $delta sec for 1 RPC sent at a time"
19010
19011         stime=$(date +%s)
19012         for (( i = 0; i < $tcount; i++ )) ; do
19013                 unlinkmany -d $DIR/$tdir/t-$i/d- $dcount &
19014         done
19015         wait
19016         etime=$(date +%s)
19017         delta=$((etime - stime))
19018         echo "Time for file removal $delta sec for 1 RPC sent at a time"
19019
19020         do_facet mds1 $LCTL set_param osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight=$rpc_count
19021 }
19022 run_test 182b "Test parallel modify metadata operations from osp"
19023
19024 test_183() { # LU-2275
19025         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19026         remote_mds_nodsh && skip "remote MDS with nodsh"
19027         [[ $MDS1_VERSION -lt $(version_code 2.3.56) ]] &&
19028                 skip "Need MDS version at least 2.3.56"
19029
19030         mkdir_on_mdt0 $DIR/$tdir || error "creating dir $DIR/$tdir"
19031         echo aaa > $DIR/$tdir/$tfile
19032
19033 #define OBD_FAIL_MDS_NEGATIVE_POSITIVE  0x148
19034         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x148
19035
19036         ls -l $DIR/$tdir && error "ls succeeded, should have failed"
19037         cat $DIR/$tdir/$tfile && error "cat succeeded, should have failed"
19038
19039         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
19040
19041         # Flush negative dentry cache
19042         touch $DIR/$tdir/$tfile
19043
19044         # We are not checking for any leaked references here, they'll
19045         # become evident next time we do cleanup with module unload.
19046         rm -rf $DIR/$tdir
19047 }
19048 run_test 183 "No crash or request leak in case of strange dispositions ========"
19049
19050 # test suite 184 is for LU-2016, LU-2017
19051 test_184a() {
19052         check_swap_layouts_support
19053
19054         dir0=$DIR/$tdir/$testnum
19055         test_mkdir -p -c1 $dir0
19056         ref1=/etc/passwd
19057         ref2=/etc/group
19058         file1=$dir0/f1
19059         file2=$dir0/f2
19060         $LFS setstripe -c1 $file1
19061         cp $ref1 $file1
19062         $LFS setstripe -c2 $file2
19063         cp $ref2 $file2
19064         gen1=$($LFS getstripe -g $file1)
19065         gen2=$($LFS getstripe -g $file2)
19066
19067         $LFS swap_layouts $file1 $file2 || error "swap of file layout failed"
19068         gen=$($LFS getstripe -g $file1)
19069         [[ $gen1 != $gen ]] ||
19070                 error "Layout generation on $file1 does not change"
19071         gen=$($LFS getstripe -g $file2)
19072         [[ $gen2 != $gen ]] ||
19073                 error "Layout generation on $file2 does not change"
19074
19075         cmp $ref1 $file2 || error "content compare failed ($ref1 != $file2)"
19076         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
19077
19078         lfsck_verify_pfid $file1 $file2 || error "PFID are not transferred"
19079 }
19080 run_test 184a "Basic layout swap"
19081
19082 test_184b() {
19083         check_swap_layouts_support
19084
19085         dir0=$DIR/$tdir/$testnum
19086         mkdir -p $dir0 || error "creating dir $dir0"
19087         file1=$dir0/f1
19088         file2=$dir0/f2
19089         file3=$dir0/f3
19090         dir1=$dir0/d1
19091         dir2=$dir0/d2
19092         mkdir $dir1 $dir2
19093         $LFS setstripe -c1 $file1
19094         $LFS setstripe -c2 $file2
19095         $LFS setstripe -c1 $file3
19096         chown $RUNAS_ID $file3
19097         gen1=$($LFS getstripe -g $file1)
19098         gen2=$($LFS getstripe -g $file2)
19099
19100         $LFS swap_layouts $dir1 $dir2 &&
19101                 error "swap of directories layouts should fail"
19102         $LFS swap_layouts $dir1 $file1 &&
19103                 error "swap of directory and file layouts should fail"
19104         $RUNAS $LFS swap_layouts $file1 $file2 &&
19105                 error "swap of file we cannot write should fail"
19106         $LFS swap_layouts $file1 $file3 &&
19107                 error "swap of file with different owner should fail"
19108         /bin/true # to clear error code
19109 }
19110 run_test 184b "Forbidden layout swap (will generate errors)"
19111
19112 test_184c() {
19113         local cmpn_arg=$(cmp -n 2>&1 | grep "invalid option")
19114         [ -n "$cmpn_arg" ] && skip_env "cmp does not support -n"
19115         check_swap_layouts_support
19116         check_swap_layout_no_dom $DIR
19117
19118         local dir0=$DIR/$tdir/$testnum
19119         mkdir -p $dir0 || error "creating dir $dir0"
19120
19121         local ref1=$dir0/ref1
19122         local ref2=$dir0/ref2
19123         local file1=$dir0/file1
19124         local file2=$dir0/file2
19125         # create a file large enough for the concurrent test
19126         dd if=/dev/urandom of=$ref1 bs=1M count=$((RANDOM % 50 + 20))
19127         dd if=/dev/urandom of=$ref2 bs=1M count=$((RANDOM % 50 + 20))
19128         echo "ref file size: ref1($(stat -c %s $ref1))," \
19129              "ref2($(stat -c %s $ref2))"
19130
19131         cp $ref2 $file2
19132         dd if=$ref1 of=$file1 bs=16k &
19133         local DD_PID=$!
19134
19135         # Make sure dd starts to copy file, but wait at most 5 seconds
19136         local loops=0
19137         while [ ! -s $file1 -a $((loops++)) -lt 50 ]; do sleep 0.1; done
19138
19139         $LFS swap_layouts $file1 $file2
19140         local rc=$?
19141         wait $DD_PID
19142         [[ $? == 0 ]] || error "concurrent write on $file1 failed"
19143         [[ $rc == 0 ]] || error "swap of $file1 and $file2 failed"
19144
19145         # how many bytes copied before swapping layout
19146         local copied=$(stat -c %s $file2)
19147         local remaining=$(stat -c %s $ref1)
19148         remaining=$((remaining - copied))
19149         echo "Copied $copied bytes before swapping layout..."
19150
19151         cmp -n $copied $file1 $ref2 | grep differ &&
19152                 error "Content mismatch [0, $copied) of ref2 and file1"
19153         cmp -n $copied $file2 $ref1 ||
19154                 error "Content mismatch [0, $copied) of ref1 and file2"
19155         cmp -i $copied:$copied -n $remaining $file1 $ref1 ||
19156                 error "Content mismatch [$copied, EOF) of ref1 and file1"
19157
19158         # clean up
19159         rm -f $ref1 $ref2 $file1 $file2
19160 }
19161 run_test 184c "Concurrent write and layout swap"
19162
19163 test_184d() {
19164         check_swap_layouts_support
19165         check_swap_layout_no_dom $DIR
19166         [ -z "$(which getfattr 2>/dev/null)" ] &&
19167                 skip_env "no getfattr command"
19168
19169         local file1=$DIR/$tdir/$tfile-1
19170         local file2=$DIR/$tdir/$tfile-2
19171         local file3=$DIR/$tdir/$tfile-3
19172         local lovea1
19173         local lovea2
19174
19175         mkdir -p $DIR/$tdir
19176         touch $file1 || error "create $file1 failed"
19177         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
19178                 error "create $file2 failed"
19179         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
19180                 error "create $file3 failed"
19181         lovea1=$(get_layout_param $file1)
19182
19183         $LFS swap_layouts $file2 $file3 ||
19184                 error "swap $file2 $file3 layouts failed"
19185         $LFS swap_layouts $file1 $file2 ||
19186                 error "swap $file1 $file2 layouts failed"
19187
19188         lovea2=$(get_layout_param $file2)
19189         echo "$lovea1"
19190         echo "$lovea2"
19191         [ "$lovea1" == "$lovea2" ] || error "lovea $lovea1 != $lovea2"
19192
19193         lovea1=$(getfattr -n trusted.lov $file1 | grep ^trusted)
19194         [[ -z "$lovea1" ]] || error "$file1 shouldn't have lovea"
19195 }
19196 run_test 184d "allow stripeless layouts swap"
19197
19198 test_184e() {
19199         [[ $MDS1_VERSION -ge $(version_code 2.6.94) ]] ||
19200                 skip "Need MDS version at least 2.6.94"
19201         check_swap_layouts_support
19202         check_swap_layout_no_dom $DIR
19203         [ -z "$(which getfattr 2>/dev/null)" ] &&
19204                 skip_env "no getfattr command"
19205
19206         local file1=$DIR/$tdir/$tfile-1
19207         local file2=$DIR/$tdir/$tfile-2
19208         local file3=$DIR/$tdir/$tfile-3
19209         local lovea
19210
19211         mkdir -p $DIR/$tdir
19212         touch $file1 || error "create $file1 failed"
19213         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
19214                 error "create $file2 failed"
19215         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
19216                 error "create $file3 failed"
19217
19218         $LFS swap_layouts $file1 $file2 ||
19219                 error "swap $file1 $file2 layouts failed"
19220
19221         lovea=$(getfattr -n trusted.lov $file1 | grep ^trusted)
19222         [[ -z "$lovea" ]] || error "$file1 shouldn't have lovea"
19223
19224         echo 123 > $file1 || error "Should be able to write into $file1"
19225
19226         $LFS swap_layouts $file1 $file3 ||
19227                 error "swap $file1 $file3 layouts failed"
19228
19229         echo 123 > $file1 || error "Should be able to write into $file1"
19230
19231         rm -rf $file1 $file2 $file3
19232 }
19233 run_test 184e "Recreate layout after stripeless layout swaps"
19234
19235 test_184f() {
19236         # Create a file with name longer than sizeof(struct stat) ==
19237         # 144 to see if we can get chars from the file name to appear
19238         # in the returned striping. Note that 'f' == 0x66.
19239         local file=$(for ((i = 0; i < 200; i++)); do echo -n f; done)
19240
19241         mkdir -p $DIR/$tdir
19242         mcreate $DIR/$tdir/$file
19243         if lfs find --stripe-count 0x6666 $DIR/$tdir | grep $file; then
19244                 error "IOC_MDC_GETFILEINFO returned garbage striping"
19245         fi
19246 }
19247 run_test 184f "IOC_MDC_GETFILEINFO for files with long names but no striping"
19248
19249 test_185() { # LU-2441
19250         # LU-3553 - no volatile file support in old servers
19251         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
19252                 skip "Need MDS version at least 2.3.60"
19253
19254         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
19255         touch $DIR/$tdir/spoo
19256         local mtime1=$(stat -c "%Y" $DIR/$tdir)
19257         local fid=$($MULTIOP $DIR/$tdir VFw4096c) ||
19258                 error "cannot create/write a volatile file"
19259         [ "$FILESET" == "" ] &&
19260         $CHECKSTAT -t file $MOUNT/.lustre/fid/$fid 2>/dev/null &&
19261                 error "FID is still valid after close"
19262
19263         multiop_bg_pause $DIR/$tdir vVw4096_c
19264         local multi_pid=$!
19265
19266         local OLD_IFS=$IFS
19267         IFS=":"
19268         local fidv=($fid)
19269         IFS=$OLD_IFS
19270         # assume that the next FID for this client is sequential, since stdout
19271         # is unfortunately eaten by multiop_bg_pause
19272         local n=$((${fidv[1]} + 1))
19273         local next_fid="${fidv[0]}:$(printf "0x%x" $n):${fidv[2]}"
19274         if [ "$FILESET" == "" ]; then
19275                 $CHECKSTAT -t file $MOUNT/.lustre/fid/$next_fid ||
19276                         error "FID is missing before close"
19277         fi
19278         kill -USR1 $multi_pid
19279         # 1 second delay, so if mtime change we will see it
19280         sleep 1
19281         local mtime2=$(stat -c "%Y" $DIR/$tdir)
19282         [[ $mtime1 == $mtime2 ]] || error "mtime has changed"
19283 }
19284 run_test 185 "Volatile file support"
19285
19286 function create_check_volatile() {
19287         local idx=$1
19288         local tgt
19289
19290         $MULTIOP $MOUNT/.lustre/fid V${idx}Fw4096_c >&/tmp/${tfile}.fid &
19291         local PID=$!
19292         sleep 1
19293         local FID=$(cat /tmp/${tfile}.fid)
19294         [ "$FID" == "" ] && error "can't get FID for volatile"
19295         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID || error "can't stat $FID"
19296         tgt=$($LFS getstripe -m $MOUNT/.lustre/fid/$FID)
19297         [ "$tgt" != "$idx" ] && error "wrong MDS $tgt, expected $idx"
19298         kill -USR1 $PID
19299         wait
19300         sleep 1
19301         cancel_lru_locks mdc # flush opencache
19302         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID && error "can stat $FID"
19303         return 0
19304 }
19305
19306 test_185a(){
19307         # LU-12516 - volatile creation via .lustre
19308         [[ $MDS1_VERSION -ge $(version_code 2.12.55) ]] ||
19309                 skip "Need MDS version at least 2.3.55"
19310
19311         create_check_volatile 0
19312         [ $MDSCOUNT -lt 2 ] && return 0
19313
19314         # DNE case
19315         create_check_volatile 1
19316
19317         return 0
19318 }
19319 run_test 185a "Volatile file creation in .lustre/fid/"
19320
19321 test_187a() {
19322         remote_mds_nodsh && skip "remote MDS with nodsh"
19323         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
19324                 skip "Need MDS version at least 2.3.0"
19325
19326         local dir0=$DIR/$tdir/$testnum
19327         mkdir -p $dir0 || error "creating dir $dir0"
19328
19329         local file=$dir0/file1
19330         dd if=/dev/urandom of=$file count=10 bs=1M conv=fsync
19331         stack_trap "rm -f $file"
19332         local dv1=$($LFS data_version $file)
19333         dd if=/dev/urandom of=$file seek=10 count=1 bs=1M conv=fsync
19334         local dv2=$($LFS data_version $file)
19335         [[ $dv1 != $dv2 ]] ||
19336                 error "data version did not change on write $dv1 == $dv2"
19337 }
19338 run_test 187a "Test data version change"
19339
19340 test_187b() {
19341         remote_mds_nodsh && skip "remote MDS with nodsh"
19342         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
19343                 skip "Need MDS version at least 2.3.0"
19344
19345         local dir0=$DIR/$tdir/$testnum
19346         mkdir -p $dir0 || error "creating dir $dir0"
19347
19348         declare -a DV=$($MULTIOP $dir0 Vw1000xYw1000xY | cut -f3 -d" ")
19349         [[ ${DV[0]} != ${DV[1]} ]] ||
19350                 error "data version did not change on write"\
19351                       " ${DV[0]} == ${DV[1]}"
19352
19353         # clean up
19354         rm -f $file1
19355 }
19356 run_test 187b "Test data version change on volatile file"
19357
19358 test_200() {
19359         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19360         remote_mgs_nodsh && skip "remote MGS with nodsh"
19361         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
19362
19363         local POOL=${POOL:-cea1}
19364         local POOL_ROOT=${POOL_ROOT:-$DIR/d200.pools}
19365         local POOL_DIR_NAME=${POOL_DIR_NAME:-dir_tst}
19366         # Pool OST targets
19367         local first_ost=0
19368         local last_ost=$(($OSTCOUNT - 1))
19369         local ost_step=2
19370         local ost_list=$(seq $first_ost $ost_step $last_ost)
19371         local ost_range="$first_ost $last_ost $ost_step"
19372         local test_path=$POOL_ROOT/$POOL_DIR_NAME
19373         local file_dir=$POOL_ROOT/file_tst
19374         local subdir=$test_path/subdir
19375         local rc=0
19376
19377         while : ; do
19378                 # former test_200a test_200b
19379                 pool_add $POOL                          || { rc=$? ; break; }
19380                 pool_add_targets  $POOL $ost_range      || { rc=$? ; break; }
19381                 # former test_200c test_200d
19382                 mkdir -p $test_path
19383                 pool_set_dir      $POOL $test_path      || { rc=$? ; break; }
19384                 pool_check_dir    $POOL $test_path      || { rc=$? ; break; }
19385                 mkdir -p $subdir
19386                 pool_check_dir    $POOL $subdir         || { rc=$? ; break; }
19387                 pool_dir_rel_path $POOL $POOL_DIR_NAME $POOL_ROOT \
19388                                                         || { rc=$? ; break; }
19389                 # former test_200e test_200f
19390                 local files=$((OSTCOUNT*3))
19391                 pool_alloc_files  $POOL $test_path $files "$ost_list" \
19392                                                         || { rc=$? ; break; }
19393                 pool_create_files $POOL $file_dir $files "$ost_list" \
19394                                                         || { rc=$? ; break; }
19395                 # former test_200g test_200h
19396                 pool_lfs_df $POOL                       || { rc=$? ; break; }
19397                 pool_file_rel_path $POOL $test_path     || { rc=$? ; break; }
19398
19399                 # former test_201a test_201b test_201c
19400                 pool_remove_first_target $POOL          || { rc=$? ; break; }
19401
19402                 local f=$test_path/$tfile
19403                 pool_remove_all_targets $POOL $f        || { rc=$? ; break; }
19404                 pool_remove $POOL $f                    || { rc=$? ; break; }
19405                 break
19406         done
19407
19408         destroy_test_pools
19409
19410         return $rc
19411 }
19412 run_test 200 "OST pools"
19413
19414 # usage: default_attr <count | size | offset>
19415 default_attr() {
19416         $LCTL get_param -n lov.$FSNAME-clilov-\*.stripe${1}
19417 }
19418
19419 # usage: check_default_stripe_attr
19420 check_default_stripe_attr() {
19421         ACTUAL=$($LFS getstripe $* $DIR/$tdir)
19422         case $1 in
19423         --stripe-count|-c)
19424                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr count);;
19425         --stripe-size|-S)
19426                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr size);;
19427         --stripe-index|-i)
19428                 EXPECTED=-1;;
19429         *)
19430                 error "unknown getstripe attr '$1'"
19431         esac
19432
19433         [ $ACTUAL == $EXPECTED ] ||
19434                 error "$DIR/$tdir has $1 '$ACTUAL', not '$EXPECTED'"
19435 }
19436
19437 test_204a() {
19438         test_mkdir $DIR/$tdir
19439         $LFS setstripe --stripe-count 0 --stripe-size 0 --stripe-index -1 $DIR/$tdir
19440
19441         check_default_stripe_attr --stripe-count
19442         check_default_stripe_attr --stripe-size
19443         check_default_stripe_attr --stripe-index
19444 }
19445 run_test 204a "Print default stripe attributes"
19446
19447 test_204b() {
19448         test_mkdir $DIR/$tdir
19449         $LFS setstripe --stripe-count 1 $DIR/$tdir
19450
19451         check_default_stripe_attr --stripe-size
19452         check_default_stripe_attr --stripe-index
19453 }
19454 run_test 204b "Print default stripe size and offset"
19455
19456 test_204c() {
19457         test_mkdir $DIR/$tdir
19458         $LFS setstripe --stripe-size 65536 $DIR/$tdir
19459
19460         check_default_stripe_attr --stripe-count
19461         check_default_stripe_attr --stripe-index
19462 }
19463 run_test 204c "Print default stripe count and offset"
19464
19465 test_204d() {
19466         test_mkdir $DIR/$tdir
19467         $LFS setstripe --stripe-index 0 $DIR/$tdir
19468
19469         check_default_stripe_attr --stripe-count
19470         check_default_stripe_attr --stripe-size
19471 }
19472 run_test 204d "Print default stripe count and size"
19473
19474 test_204e() {
19475         test_mkdir $DIR/$tdir
19476         $LFS setstripe -d $DIR/$tdir
19477
19478         check_default_stripe_attr --stripe-count --raw
19479         check_default_stripe_attr --stripe-size --raw
19480         check_default_stripe_attr --stripe-index --raw
19481 }
19482 run_test 204e "Print raw stripe attributes"
19483
19484 test_204f() {
19485         test_mkdir $DIR/$tdir
19486         $LFS setstripe --stripe-count 1 $DIR/$tdir
19487
19488         check_default_stripe_attr --stripe-size --raw
19489         check_default_stripe_attr --stripe-index --raw
19490 }
19491 run_test 204f "Print raw stripe size and offset"
19492
19493 test_204g() {
19494         test_mkdir $DIR/$tdir
19495         $LFS setstripe --stripe-size 65536 $DIR/$tdir
19496
19497         check_default_stripe_attr --stripe-count --raw
19498         check_default_stripe_attr --stripe-index --raw
19499 }
19500 run_test 204g "Print raw stripe count and offset"
19501
19502 test_204h() {
19503         test_mkdir $DIR/$tdir
19504         $LFS setstripe --stripe-index 0 $DIR/$tdir
19505
19506         check_default_stripe_attr --stripe-count --raw
19507         check_default_stripe_attr --stripe-size --raw
19508 }
19509 run_test 204h "Print raw stripe count and size"
19510
19511 # Figure out which job scheduler is being used, if any,
19512 # or use a fake one
19513 if [ -n "$SLURM_JOB_ID" ]; then # SLURM
19514         JOBENV=SLURM_JOB_ID
19515 elif [ -n "$LSB_JOBID" ]; then # Load Sharing Facility
19516         JOBENV=LSB_JOBID
19517 elif [ -n "$PBS_JOBID" ]; then # PBS/Maui/Moab
19518         JOBENV=PBS_JOBID
19519 elif [ -n "$LOADL_STEPID" ]; then # LoadLeveller
19520         JOBENV=LOADL_STEP_ID
19521 elif [ -n "$JOB_ID" ]; then # Sun Grid Engine
19522         JOBENV=JOB_ID
19523 else
19524         $LCTL list_param jobid_name > /dev/null 2>&1
19525         if [ $? -eq 0 ]; then
19526                 JOBENV=nodelocal
19527         else
19528                 JOBENV=FAKE_JOBID
19529         fi
19530 fi
19531 LUSTRE_JOBID_SIZE=31 # plus NUL terminator
19532
19533 verify_jobstats() {
19534         local cmd=($1)
19535         shift
19536         local facets="$@"
19537
19538 # we don't really need to clear the stats for this test to work, since each
19539 # command has a unique jobid, but it makes debugging easier if needed.
19540 #       for facet in $facets; do
19541 #               local dev=$(convert_facet2label $facet)
19542 #               # clear old jobstats
19543 #               do_facet $facet lctl set_param *.$dev.job_stats="clear"
19544 #       done
19545
19546         # use a new JobID for each test, or we might see an old one
19547         [ "$JOBENV" = "FAKE_JOBID" ] &&
19548                 FAKE_JOBID=id.$testnum.$(basename ${cmd[0]}).$RANDOM
19549
19550         JOBVAL=${!JOBENV:0:$LUSTRE_JOBID_SIZE}
19551
19552         [ "$JOBENV" = "nodelocal" ] && {
19553                 FAKE_JOBID=id.$testnum.%e.$RANDOM
19554                 $LCTL set_param jobid_name=$FAKE_JOBID
19555                 JOBVAL=${FAKE_JOBID/\%e/$(basename ${cmd[0]})}
19556         }
19557
19558         log "Test: ${cmd[*]}"
19559         log "Using JobID environment $($LCTL get_param -n jobid_var)=$JOBVAL"
19560
19561         if [ $JOBENV = "FAKE_JOBID" ]; then
19562                 FAKE_JOBID=$JOBVAL ${cmd[*]}
19563         else
19564                 ${cmd[*]}
19565         fi
19566
19567         # all files are created on OST0000
19568         for facet in $facets; do
19569                 local stats="*.$(convert_facet2label $facet).job_stats"
19570
19571                 # strip out libtool wrappers for in-tree executables
19572                 if (( $(do_facet $facet lctl get_param $stats |
19573                         sed -e 's/\.lt-/./' | grep -cw $JOBVAL) != 1 )); then
19574                         do_facet $facet lctl get_param $stats
19575                         error "No jobstats for $JOBVAL found on $facet::$stats"
19576                 fi
19577         done
19578 }
19579
19580 jobstats_set() {
19581         local new_jobenv=$1
19582
19583         set_persistent_param_and_check client "jobid_var" \
19584                 "$FSNAME.sys.jobid_var" $new_jobenv
19585 }
19586
19587 test_205a() { # Job stats
19588         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19589         [[ $MDS1_VERSION -ge $(version_code 2.7.1) ]] ||
19590                 skip "Need MDS version with at least 2.7.1"
19591         remote_mgs_nodsh && skip "remote MGS with nodsh"
19592         remote_mds_nodsh && skip "remote MDS with nodsh"
19593         remote_ost_nodsh && skip "remote OST with nodsh"
19594         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep jobstats)" ] &&
19595                 skip "Server doesn't support jobstats"
19596         [[ $JOBID_VAR = disable ]] && skip_env "jobstats is disabled"
19597
19598         local old_jobenv=$($LCTL get_param -n jobid_var)
19599         [ $old_jobenv != $JOBENV ] && jobstats_set $JOBENV
19600         stack_trap "jobstats_set $old_jobenv" EXIT
19601
19602         changelog_register
19603
19604         local old_jobid_name=$($LCTL get_param jobid_name)
19605         stack_trap "$LCTL set_param $old_jobid_name" EXIT
19606
19607         local old_interval=$(do_facet $SINGLEMDS lctl get_param -n \
19608                                 mdt.*.job_cleanup_interval | head -n 1)
19609         local new_interval=5
19610         do_facet $SINGLEMDS \
19611                 $LCTL set_param mdt.*.job_cleanup_interval=$new_interval
19612         stack_trap "do_facet $SINGLEMDS \
19613                 $LCTL set_param mdt.*.job_cleanup_interval=$old_interval" EXIT
19614         local start=$SECONDS
19615
19616         local cmd
19617         # mkdir
19618         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir"
19619         verify_jobstats "$cmd" "$SINGLEMDS"
19620         # rmdir
19621         cmd="rmdir $DIR/$tdir"
19622         verify_jobstats "$cmd" "$SINGLEMDS"
19623         # mkdir on secondary MDT
19624         if [ $MDSCOUNT -gt 1 ]; then
19625                 cmd="lfs mkdir -i 1 $DIR/$tdir.remote"
19626                 verify_jobstats "$cmd" "mds2"
19627         fi
19628         # mknod
19629         cmd="mknod $DIR/$tfile c 1 3"
19630         verify_jobstats "$cmd" "$SINGLEMDS"
19631         # unlink
19632         cmd="rm -f $DIR/$tfile"
19633         verify_jobstats "$cmd" "$SINGLEMDS"
19634         # create all files on OST0000 so verify_jobstats can find OST stats
19635         # open & close
19636         cmd="$LFS setstripe -i 0 -c 1 $DIR/$tfile"
19637         verify_jobstats "$cmd" "$SINGLEMDS"
19638         # setattr
19639         cmd="touch $DIR/$tfile"
19640         verify_jobstats "$cmd" "$SINGLEMDS ost1"
19641         # write
19642         cmd="dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=sync"
19643         verify_jobstats "$cmd" "ost1"
19644         # read
19645         cancel_lru_locks osc
19646         cmd="dd if=$DIR/$tfile of=/dev/null bs=1M count=1 iflag=direct"
19647         verify_jobstats "$cmd" "ost1"
19648         # truncate
19649         cmd="$TRUNCATE $DIR/$tfile 0"
19650         verify_jobstats "$cmd" "$SINGLEMDS ost1"
19651         # rename
19652         cmd="mv -f $DIR/$tfile $DIR/$tdir.rename"
19653         verify_jobstats "$cmd" "$SINGLEMDS"
19654         # jobstats expiry - sleep until old stats should be expired
19655         local left=$((new_interval + 5 - (SECONDS - start)))
19656         [ $left -ge 0 ] && wait_update_facet $SINGLEMDS \
19657                 "lctl get_param *.*.job_stats | grep -c 'job_id.*mkdir'" \
19658                         "0" $left
19659         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir.expire"
19660         verify_jobstats "$cmd" "$SINGLEMDS"
19661         [ $(do_facet $SINGLEMDS lctl get_param *.*.job_stats |
19662             grep -c "job_id.*mkdir") -gt 1 ] && error "old jobstats not expired"
19663
19664         # Ensure that jobid are present in changelog (if supported by MDS)
19665         if [ $MDS1_VERSION -ge $(version_code 2.6.52) ];then
19666                 changelog_dump | tail -10
19667                 jobids=$(changelog_dump | tail -9 | grep -c "j=")
19668                 [ $jobids -eq 9 ] ||
19669                         error "Wrong changelog jobid count $jobids != 9"
19670
19671                 # LU-5862
19672                 JOBENV="disable"
19673                 jobstats_set $JOBENV
19674                 touch $DIR/$tfile
19675                 changelog_dump | grep $tfile
19676                 jobids=$(changelog_dump | grep $tfile | tail -1 | grep -c "j=")
19677                 [ $jobids -eq 0 ] ||
19678                         error "Unexpected jobids when jobid_var=$JOBENV"
19679         fi
19680
19681         # test '%j' access to environment variable - if supported
19682         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%h.E"; then
19683                 JOBENV="JOBCOMPLEX"
19684                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
19685
19686                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
19687         fi
19688
19689         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%H.E"; then
19690                 JOBENV="JOBCOMPLEX"
19691                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname -s).E"
19692
19693                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
19694         fi
19695
19696         # test '%j' access to per-session jobid - if supported
19697         if lctl list_param jobid_this_session > /dev/null 2>&1
19698         then
19699                 lctl set_param jobid_var=session jobid_name="S.%j.%e.%u.%h.E"
19700                 lctl set_param jobid_this_session=$USER
19701
19702                 JOBENV="JOBCOMPLEX"
19703                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
19704
19705                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
19706         fi
19707 }
19708 run_test 205a "Verify job stats"
19709
19710 # LU-13117, LU-13597, LU-16599
19711 test_205b() {
19712         (( $MDS1_VERSION >= $(version_code 2.13.54.91) )) ||
19713                 skip "Need MDS version at least 2.13.54.91"
19714
19715         local job_stats="mdt.*.job_stats"
19716         local old_jobid=$(do_facet mds1 $LCTL get_param jobid_var)
19717
19718         do_facet mds1 $LCTL set_param $job_stats=clear
19719
19720         # Setting jobid_var to USER might not be supported
19721         [[ -n "$old_jobid" ]] && stack_trap "$LCTL set_param $old_jobid"
19722         $LCTL set_param jobid_var=USER || true
19723         stack_trap "$LCTL set_param $($LCTL get_param jobid_name)"
19724         $LCTL set_param jobid_name="%j.%e.%u"
19725
19726         env -i USERTESTJOBSTATS=foolish touch $DIR/$tfile.1
19727         do_facet mds1 $LCTL get_param $job_stats | grep "job_id:.*foolish" &&
19728                 { do_facet mds1 $LCTL get_param $job_stats;
19729                   error "Unexpected jobid found"; }
19730         do_facet mds1 $LCTL get_param $job_stats | grep "open:.*min.*max.*sum"||
19731                 { do_facet mds1 $LCTL get_param $job_stats;
19732                   error "wrong job_stats format found"; }
19733
19734         (( $MDS1_VERSION <= $(version_code 2.15.0) )) &&
19735                 echo "MDS does not yet escape jobid" && return 0
19736
19737         mkdir_on_mdt0 $DIR/$tdir
19738         $LCTL set_param jobid_var=TEST205b
19739         env -i TEST205b="has sp" touch $DIR/$tdir/$tfile.2
19740         local jobid=$(do_facet mds1 $LCTL get_param $job_stats |
19741                       awk '/has\\x20sp/ {print $3}')
19742         [[ -n "$jobid" ]] || { do_facet mds1 $LCTL get_param $job_stats;
19743                   error "jobid not escaped"; }
19744
19745         if (( $MDS1_VERSION >= $(version_code 2.15.53.139) )); then
19746                 # need to run such a command on mds1:
19747                 # lctl set_param mdt.$FSNAME-MDT0000.job_stats='"has\x20sp.touch.0"'
19748                 #
19749                 # there might be multiple MDTs on single mds server, so need to
19750                 # specifiy MDT0000. Or the command will fail due to other MDTs
19751                 do_facet_vp mds1 $LCTL set_param mdt.$FSNAME-MDT0000.job_stats=$jobid ||
19752                         error "cannot clear escaped jobid in job_stats";
19753         else
19754                 echo "MDS does not support clearing escaped jobid"
19755         fi
19756 }
19757 run_test 205b "Verify job stats jobid and output format"
19758
19759 # LU-13733
19760 test_205c() {
19761         $LCTL set_param llite.*.stats=0
19762         dd if=/dev/zero of=$DIR/$tfile.1 bs=4k count=1
19763         $LCTL get_param llite.*.stats
19764         $LCTL get_param llite.*.stats | grep \
19765                 "write_bytes *1 samples \[bytes\] 4096 4096 4096 16777216" ||
19766                         error "wrong client stats format found"
19767 }
19768 run_test 205c "Verify client stats format"
19769
19770 test_205d() {
19771         local file=$DIR/$tdir/$tfile
19772
19773         (( $MDS1_VERSION >= $(version_code 2.15.53) )) ||
19774                 skip "need lustre >= 2.15.53 for lljobstat"
19775         (( $OST1_VERSION >= $(version_code 2.15.53) )) ||
19776                 skip "need lustre >= 2.15.53 for lljobstat"
19777         verify_yaml_available || skip_env "YAML verification not installed"
19778
19779         test_mkdir -i 0 $DIR/$tdir
19780         $LFS setstripe -E 1M -L mdt -E -1 $file || error "create file failed"
19781         stack_trap "rm -rf $DIR/$tdir"
19782
19783         dd if=/dev/zero of=$file bs=1M count=10 conv=sync ||
19784                 error "failed to write data to $file"
19785         mv $file $file.2
19786
19787         do_facet mds1 "$LCTL get_param -n mdt.$FSNAME-MDT0000.rename_stats"
19788         echo -n 'verify rename_stats...'
19789         do_facet mds1 "$LCTL get_param -n mdt.$FSNAME-MDT0000.rename_stats" |
19790                 verify_yaml || error "rename_stats is not valid YAML"
19791         echo " OK"
19792
19793         echo -n 'verify mdt job_stats...'
19794         do_facet mds1 "$LCTL get_param -n mdt.$FSNAME-MDT0000.job_stats" |
19795                 verify_yaml || error "job_stats on mds1 is not valid YAML"
19796         echo " OK"
19797
19798         echo -n 'verify ost job_stats...'
19799         do_facet ost1 "$LCTL get_param -n obdfilter.$FSNAME-OST0000.job_stats" |
19800                 verify_yaml || error "job_stats on ost1 is not valid YAML"
19801         echo " OK"
19802 }
19803 run_test 205d "verify the format of some stats files"
19804
19805 test_205e() {
19806         local ops_comma
19807         local file=$DIR/$tdir/$tfile
19808         local -a cli_params
19809
19810         (( $MDS1_VERSION >= $(version_code 2.15.53) )) ||
19811                 skip "need lustre >= 2.15.53 for lljobstat"
19812         (( $OST1_VERSION >= $(version_code 2.15.53) )) ||
19813                 skip "need lustre >= 2.15.53 for lljobstat"
19814         verify_yaml_available || skip_env "YAML verification not installed"
19815
19816         cli_params=( $($LCTL get_param jobid_name jobid_var) )
19817         $LCTL set_param jobid_var=nodelocal jobid_name=205e.%e.%u
19818         stack_trap "$LCTL set_param ${cli_params[*]}" EXIT
19819
19820         mkdir_on_mdt0 $DIR/$tdir || error "failed to create dir"
19821         stack_trap "rm -rf $DIR/$tdir"
19822
19823         $LFS setstripe -E EOF -i 0 -c 1 $file ||
19824                 error "failed to create $file on ost1"
19825         dd if=/dev/zero of=$file bs=1M count=10 oflag=sync ||
19826                 error "failed to write data to $file"
19827
19828         do_facet mds1 "$LCTL get_param *.*.job_stats"
19829         do_facet ost1 "$LCTL get_param *.*.job_stats"
19830
19831         do_facet ost1 "lljobstat -n 1 -i 0 -c 1000"
19832         do_facet ost1 "lljobstat -n 1 -i 0 -c 1000" | verify_yaml ||
19833                 error "The output of lljobstat is not an valid YAML"
19834
19835         # verify that job dd.0 does exist and has some ops on ost1
19836         # typically this line is like:
19837         # - 205e.dd.0:            {ops: 20, ...}
19838         ops_comma=$(do_facet ost1 "lljobstat -n 1 -i 0 -c 1000" |
19839                     awk '$2=="205e.dd.0:" {print $4}')
19840
19841         (( ${ops_comma%,} >= 10 )) ||
19842                 error "cannot find job 205e.dd.0 with ops >= 10"
19843 }
19844 run_test 205e "verify the output of lljobstat"
19845
19846 test_205f() {
19847         verify_yaml_available || skip_env "YAML verification not installed"
19848
19849         # check both qos_ost_weights and qos_mdt_weights
19850         do_facet mds1 $LCTL get_param -n lod.*.qos*weights
19851         do_facet mds1 $LCTL get_param -n lod.*.qos*weights | verify_yaml ||
19852                 error "qos_ost_weights is not valid YAML"
19853 }
19854 run_test 205f "verify qos_ost_weights YAML format "
19855
19856 __test_205_jobstats_dump() {
19857         local -a pids
19858         local nbr_instance=$1
19859
19860         while true; do
19861                 if (( ${#pids[@]} >= nbr_instance )); then
19862                         wait ${pids[@]}
19863                         pids=()
19864                 fi
19865
19866                 do_facet mds1 "$LCTL get_param mdt.*.job_stats > /dev/null" &
19867                 pids+=( $! )
19868         done
19869 }
19870
19871 __test_205_cleanup() {
19872         kill $@
19873         # Clear all job entries
19874         do_facet mds1 "$LCTL set_param mdt.*.job_stats=clear"
19875 }
19876
19877 test_205g() {
19878         local -a mds1_params
19879         local -a cli_params
19880         local pids
19881         local interval=5
19882
19883         mds1_params=( $(do_facet mds1 $LCTL get_param mdt.*.job_cleanup_interval) )
19884         do_facet mds1 $LCTL set_param mdt.*.job_cleanup_interval=$interval
19885         stack_trap "do_facet mds1 $LCTL set_param ${mds1_params[*]}" EXIT
19886
19887         cli_params=( $($LCTL get_param jobid_name jobid_var) )
19888         $LCTL set_param jobid_var=TEST205G_ID jobid_name=%j.%p
19889         stack_trap "$LCTL set_param ${cli_params[*]}" EXIT
19890
19891         # start jobs loop
19892         export TEST205G_ID=205g
19893         stack_trap "unset TEST205G_ID" EXIT
19894         while true; do
19895                 printf $DIR/$tfile.{0001..1000} | xargs -P10 -n1 touch
19896         done & pids="$! "
19897
19898         __test_205_jobstats_dump 4 & pids+="$! "
19899         stack_trap "__test_205_cleanup $pids" EXIT INT
19900
19901         [[ $SLOW == "no" ]] && sleep 90 || sleep 240
19902 }
19903 run_test 205g "stress test for job_stats procfile"
19904
19905 # LU-1480, LU-1773 and LU-1657
19906 test_206() {
19907         mkdir -p $DIR/$tdir
19908         $LFS setstripe -c -1 $DIR/$tdir
19909 #define OBD_FAIL_LOV_INIT 0x1403
19910         $LCTL set_param fail_loc=0xa0001403
19911         $LCTL set_param fail_val=1
19912         touch $DIR/$tdir/$tfile || true
19913 }
19914 run_test 206 "fail lov_init_raid0() doesn't lbug"
19915
19916 test_207a() {
19917         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
19918         local fsz=`stat -c %s $DIR/$tfile`
19919         cancel_lru_locks mdc
19920
19921         # do not return layout in getattr intent
19922 #define OBD_FAIL_MDS_NO_LL_GETATTR 0x170
19923         $LCTL set_param fail_loc=0x170
19924         local sz=`stat -c %s $DIR/$tfile`
19925
19926         [ $fsz -eq $sz ] || error "file size expected $fsz, actual $sz"
19927
19928         rm -rf $DIR/$tfile
19929 }
19930 run_test 207a "can refresh layout at glimpse"
19931
19932 test_207b() {
19933         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
19934         local cksum=`md5sum $DIR/$tfile`
19935         local fsz=`stat -c %s $DIR/$tfile`
19936         cancel_lru_locks mdc
19937         cancel_lru_locks osc
19938
19939         # do not return layout in getattr intent
19940 #define OBD_FAIL_MDS_NO_LL_OPEN 0x171
19941         $LCTL set_param fail_loc=0x171
19942
19943         # it will refresh layout after the file is opened but before read issues
19944         echo checksum is "$cksum"
19945         echo "$cksum" |md5sum -c --quiet || error "file differs"
19946
19947         rm -rf $DIR/$tfile
19948 }
19949 run_test 207b "can refresh layout at open"
19950
19951 test_208() {
19952         # FIXME: in this test suite, only RD lease is used. This is okay
19953         # for now as only exclusive open is supported. After generic lease
19954         # is done, this test suite should be revised. - Jinshan
19955
19956         remote_mds_nodsh && skip "remote MDS with nodsh"
19957         [[ $MDS1_VERSION -ge $(version_code 2.4.52) ]] ||
19958                 skip "Need MDS version at least 2.4.52"
19959
19960         echo "==== test 1: verify get lease work"
19961         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eRE+eU || error "get lease error"
19962
19963         echo "==== test 2: verify lease can be broken by upcoming open"
19964         $MULTIOP $DIR/$tfile oO_RDWR:eR_E-eUc &
19965         local PID=$!
19966         sleep 2
19967
19968         $MULTIOP $DIR/$tfile oO_RDWR:c
19969         kill -USR1 $PID && wait $PID || error "break lease error"
19970
19971         echo "==== test 3: verify lease can't be granted if an open already exists"
19972         $MULTIOP $DIR/$tfile oO_RDWR:_c &
19973         local PID=$!
19974         sleep 2
19975
19976         $MULTIOP $DIR/$tfile oO_RDWR:eReUc && error "apply lease should fail"
19977         kill -USR1 $PID && wait $PID || error "open file error"
19978
19979         echo "==== test 4: lease can sustain over recovery"
19980         $MULTIOP $DIR/$tfile oO_RDWR:eR_E+eUc &
19981         PID=$!
19982         sleep 2
19983
19984         fail mds1
19985
19986         kill -USR1 $PID && wait $PID || error "lease broken over recovery"
19987
19988         echo "==== test 5: lease broken can't be regained by replay"
19989         $MULTIOP $DIR/$tfile oO_RDWR:eR_E-eUc &
19990         PID=$!
19991         sleep 2
19992
19993         # open file to break lease and then recovery
19994         $MULTIOP $DIR/$tfile oO_RDWR:c || error "open file error"
19995         fail mds1
19996
19997         kill -USR1 $PID && wait $PID || error "lease not broken over recovery"
19998
19999         rm -f $DIR/$tfile
20000 }
20001 run_test 208 "Exclusive open"
20002
20003 test_209() {
20004         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep disp_stripe)" ] &&
20005                 skip_env "must have disp_stripe"
20006
20007         touch $DIR/$tfile
20008         sync; sleep 5; sync;
20009
20010         echo 3 > /proc/sys/vm/drop_caches
20011         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
20012                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
20013         req_before=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
20014
20015         # open/close 500 times
20016         for i in $(seq 500); do
20017                 cat $DIR/$tfile
20018         done
20019
20020         echo 3 > /proc/sys/vm/drop_caches
20021         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
20022                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
20023         req_after=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
20024
20025         echo "before: $req_before, after: $req_after"
20026         [ $((req_after - req_before)) -ge 300 ] &&
20027                 error "open/close requests are not freed"
20028         return 0
20029 }
20030 run_test 209 "read-only open/close requests should be freed promptly"
20031
20032 test_210() {
20033         local pid
20034
20035         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eW_E+eUc &
20036         pid=$!
20037         sleep 1
20038
20039         $LFS getstripe $DIR/$tfile
20040         kill -USR1 $pid
20041         wait $pid || error "multiop failed"
20042
20043         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
20044         pid=$!
20045         sleep 1
20046
20047         $LFS getstripe $DIR/$tfile
20048         kill -USR1 $pid
20049         wait $pid || error "multiop failed"
20050 }
20051 run_test 210 "lfs getstripe does not break leases"
20052
20053 test_212() {
20054         size=`date +%s`
20055         size=$((size % 8192 + 1))
20056         dd if=/dev/urandom of=$DIR/f212 bs=1k count=$size
20057         sendfile $DIR/f212 $DIR/f212.xyz || error "sendfile wrong"
20058         rm -f $DIR/f212 $DIR/f212.xyz
20059 }
20060 run_test 212 "Sendfile test ============================================"
20061
20062 test_213() {
20063         dd if=/dev/zero of=$DIR/$tfile bs=4k count=4
20064         cancel_lru_locks osc
20065         lctl set_param fail_loc=0x8000040f
20066         # generate a read lock
20067         cat $DIR/$tfile > /dev/null
20068         # write to the file, it will try to cancel the above read lock.
20069         cat /etc/hosts >> $DIR/$tfile
20070 }
20071 run_test 213 "OSC lock completion and cancel race don't crash - bug 18829"
20072
20073 test_214() { # for bug 20133
20074         mkdir -p $DIR/$tdir/d214c || error "mkdir $DIR/$tdir/d214c failed"
20075         for (( i=0; i < 340; i++ )) ; do
20076                 touch $DIR/$tdir/d214c/a$i
20077         done
20078
20079         ls -l $DIR/$tdir || error "ls -l $DIR/d214p failed"
20080         mv $DIR/$tdir/d214c $DIR/ || error "mv $DIR/d214p/d214c $DIR/ failed"
20081         ls $DIR/d214c || error "ls $DIR/d214c failed"
20082         rm -rf $DIR/$tdir || error "rm -rf $DIR/d214* failed"
20083         rm -rf $DIR/d214* || error "rm -rf $DIR/d214* failed"
20084 }
20085 run_test 214 "hash-indexed directory test - bug 20133"
20086
20087 # having "abc" as 1st arg, creates $TMP/lnet_abc.out and $TMP/lnet_abc.sys
20088 create_lnet_proc_files() {
20089         lctl get_param -n $1 >$TMP/lnet_$1.sys || error "cannot read lnet.$1"
20090 }
20091
20092 # counterpart of create_lnet_proc_files
20093 remove_lnet_proc_files() {
20094         rm -f $TMP/lnet_$1.sys
20095 }
20096
20097 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
20098 # 3rd arg as regexp for body
20099 check_lnet_proc_stats() {
20100         local l=$(cat "$TMP/lnet_$1" |wc -l)
20101         [ $l = 1 ] || (cat "$TMP/lnet_$1" && error "$2 is not of 1 line: $l")
20102
20103         grep -E "$3" "$TMP/lnet_$1" || (cat "$TMP/lnet_$1" && error "$2 misformatted")
20104 }
20105
20106 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
20107 # 3rd arg as regexp for body, 4th arg as regexp for 1st line, 5th arg is
20108 # optional and can be regexp for 2nd line (lnet.routes case)
20109 check_lnet_proc_entry() {
20110         local blp=2          # blp stands for 'position of 1st line of body'
20111         [ -z "$5" ] || blp=3 # lnet.routes case
20112
20113         local l=$(cat "$TMP/lnet_$1" |wc -l)
20114         # subtracting one from $blp because the body can be empty
20115         [ "$l" -ge "$(($blp - 1))" ] || (cat "$TMP/lnet_$1" && error "$2 is too short: $l")
20116
20117         sed -n '1 p' "$TMP/lnet_$1" |grep -E "$4" >/dev/null ||
20118                 (cat "$TMP/lnet_$1" && error "1st line of $2 misformatted")
20119
20120         [ "$5" = "" ] || sed -n '2 p' "$TMP/lnet_$1" |grep -E "$5" >/dev/null ||
20121                 (cat "$TMP/lnet_$1" && error "2nd line of $2 misformatted")
20122
20123         # bail out if any unexpected line happened
20124         sed -n "$blp p" "$TMP/lnet_$1" | grep -Ev "$3"
20125         [ "$?" != 0 ] || error "$2 misformatted"
20126 }
20127
20128 test_215() { # for bugs 18102, 21079, 21517
20129         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20130
20131         local N='(0|[1-9][0-9]*)'       # non-negative numeric
20132         local P='[1-9][0-9]*'           # positive numeric
20133         local I='(0|-?[1-9][0-9]*|NA)'  # any numeric (0 | >0 | <0) or NA if no value
20134         local NET='[a-z][a-z0-9]*'      # LNET net like o2ib2
20135         local ADDR='[0-9.]+'            # LNET addr like 10.0.0.1
20136         local NID="$ADDR@$NET"          # LNET nid like 10.0.0.1@o2ib2
20137
20138         local L1 # regexp for 1st line
20139         local L2 # regexp for 2nd line (optional)
20140         local BR # regexp for the rest (body)
20141
20142         # lnet.stats should look as 11 space-separated non-negative numerics
20143         BR="^$N $N $N $N $N $N $N $N $N $N $N$"
20144         create_lnet_proc_files "stats"
20145         check_lnet_proc_stats "stats.sys" "lnet.stats" "$BR"
20146         remove_lnet_proc_files "stats"
20147
20148         # lnet.routes should look like this:
20149         # Routing disabled/enabled
20150         # net hops priority state router
20151         # where net is a string like tcp0, hops > 0, priority >= 0,
20152         # state is up/down,
20153         # router is a string like 192.168.1.1@tcp2
20154         L1="^Routing (disabled|enabled)$"
20155         L2="^net +hops +priority +state +router$"
20156         BR="^$NET +$N +(0|1) +(up|down) +$NID$"
20157         create_lnet_proc_files "routes"
20158         check_lnet_proc_entry "routes.sys" "lnet.routes" "$BR" "$L1" "$L2"
20159         remove_lnet_proc_files "routes"
20160
20161         # lnet.routers should look like this:
20162         # ref rtr_ref alive_cnt state last_ping ping_sent deadline down_ni router
20163         # where ref > 0, rtr_ref > 0, alive_cnt >= 0, state is up/down,
20164         # last_ping >= 0, ping_sent is boolean (0/1), deadline and down_ni are
20165         # numeric (0 or >0 or <0), router is a string like 192.168.1.1@tcp2
20166         L1="^ref +rtr_ref +alive +router$"
20167         BR="^$P +$P +(up|down) +$NID$"
20168         create_lnet_proc_files "routers"
20169         check_lnet_proc_entry "routers.sys" "lnet.routers" "$BR" "$L1"
20170         remove_lnet_proc_files "routers"
20171
20172         # lnet.peers should look like this:
20173         # nid refs state last max rtr min tx min queue
20174         # where nid is a string like 192.168.1.1@tcp2, refs > 0,
20175         # state is up/down/NA, max >= 0. last, rtr, min, tx, min are
20176         # numeric (0 or >0 or <0), queue >= 0.
20177         L1="^nid +refs +state +last +max +rtr +min +tx +min +queue$"
20178         BR="^$NID +$P +(up|down|NA) +$I +$N +$I +$I +$I +$I +$N$"
20179         create_lnet_proc_files "peers"
20180         check_lnet_proc_entry "peers.sys" "lnet.peers" "$BR" "$L1"
20181         remove_lnet_proc_files "peers"
20182
20183         # lnet.buffers  should look like this:
20184         # pages count credits min
20185         # where pages >=0, count >=0, credits and min are numeric (0 or >0 or <0)
20186         L1="^pages +count +credits +min$"
20187         BR="^ +$N +$N +$I +$I$"
20188         create_lnet_proc_files "buffers"
20189         check_lnet_proc_entry "buffers.sys" "lnet.buffers" "$BR" "$L1"
20190         remove_lnet_proc_files "buffers"
20191
20192         # lnet.nis should look like this:
20193         # nid status alive refs peer rtr max tx min
20194         # where nid is a string like 192.168.1.1@tcp2, status is up/down,
20195         # alive is numeric (0 or >0 or <0), refs >= 0, peer >= 0,
20196         # rtr >= 0, max >=0, tx and min are numeric (0 or >0 or <0).
20197         L1="^nid +status +alive +refs +peer +rtr +max +tx +min$"
20198         BR="^$NID +(up|down) +$I +$N +$N +$N +$N +$I +$I$"
20199         create_lnet_proc_files "nis"
20200         check_lnet_proc_entry "nis.sys" "lnet.nis" "$BR" "$L1"
20201         remove_lnet_proc_files "nis"
20202
20203         # can we successfully write to lnet.stats?
20204         lctl set_param -n stats=0 || error "cannot write to lnet.stats"
20205 }
20206 run_test 215 "lnet exists and has proper content - bugs 18102, 21079, 21517"
20207
20208 test_216() { # bug 20317
20209         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20210         remote_ost_nodsh && skip "remote OST with nodsh"
20211
20212         local node
20213         local facets=$(get_facets OST)
20214         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
20215
20216         save_lustre_params client "osc.*.contention_seconds" > $p
20217         save_lustre_params $facets \
20218                 "ldlm.namespaces.filter-*.max_nolock_bytes" >> $p
20219         save_lustre_params $facets \
20220                 "ldlm.namespaces.filter-*.contended_locks" >> $p
20221         save_lustre_params $facets \
20222                 "ldlm.namespaces.filter-*.contention_seconds" >> $p
20223         clear_stats osc.*.osc_stats
20224
20225         # agressive lockless i/o settings
20226         do_nodes $(comma_list $(osts_nodes)) \
20227                 "lctl set_param -n ldlm.namespaces.*.max_nolock_bytes=2000000 \
20228                         ldlm.namespaces.filter-*.contended_locks=0 \
20229                         ldlm.namespaces.filter-*.contention_seconds=60"
20230         lctl set_param -n osc.*.contention_seconds=60
20231
20232         $DIRECTIO write $DIR/$tfile 0 10 4096
20233         $CHECKSTAT -s 40960 $DIR/$tfile
20234
20235         # disable lockless i/o
20236         do_nodes $(comma_list $(osts_nodes)) \
20237                 "lctl set_param -n ldlm.namespaces.filter-*.max_nolock_bytes=0 \
20238                         ldlm.namespaces.filter-*.contended_locks=32 \
20239                         ldlm.namespaces.filter-*.contention_seconds=0"
20240         lctl set_param -n osc.*.contention_seconds=0
20241         clear_stats osc.*.osc_stats
20242
20243         dd if=/dev/zero of=$DIR/$tfile count=0
20244         $CHECKSTAT -s 0 $DIR/$tfile
20245
20246         restore_lustre_params <$p
20247         rm -f $p
20248         rm $DIR/$tfile
20249 }
20250 run_test 216 "check lockless direct write updates file size and kms correctly"
20251
20252 test_217() { # bug 22430
20253         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20254
20255         local node
20256
20257         for node in $(nodes_list); do
20258                 local nid=$(host_nids_address $node $NETTYPE)
20259                 local node_ip=$(do_node $node getent ahostsv4 $node |
20260                                 awk '{ print $1; exit; }')
20261
20262                 echo "node: '$node', nid: '$nid', node_ip='$node_ip'"
20263                 # if hostname matches any NID, use hostname for better testing
20264                 if [[ -z "$nid" || "$nid" =~ "$node_ip" ]]; then
20265                         echo "lctl ping node $node@$NETTYPE"
20266                         lctl ping $node@$NETTYPE
20267                 else # otherwise, at least test 'lctl ping' is working
20268                         echo "lctl ping nid $(h2nettype $nid)"
20269                         lctl ping $(h2nettype $nid)
20270                         echo "skipping $node (no hyphen detected)"
20271                 fi
20272         done
20273 }
20274 run_test 217 "check lctl ping for hostnames with embedded hyphen ('-')"
20275
20276 test_218() {
20277         # do directio so as not to populate the page cache
20278         log "creating a 10 Mb file"
20279         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c ||
20280                 error "multiop failed while creating a file"
20281         log "starting reads"
20282         dd if=$DIR/$tfile of=/dev/null bs=4096 &
20283         log "truncating the file"
20284         $MULTIOP $DIR/$tfile oO_TRUNC:c ||
20285                 error "multiop failed while truncating the file"
20286         log "killing dd"
20287         kill %+ || true # reads might have finished
20288         echo "wait until dd is finished"
20289         wait
20290         log "removing the temporary file"
20291         rm -rf $DIR/$tfile || error "tmp file removal failed"
20292 }
20293 run_test 218 "parallel read and truncate should not deadlock"
20294
20295 test_219() {
20296         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20297
20298         # write one partial page
20299         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1
20300         # set no grant so vvp_io_commit_write will do sync write
20301         $LCTL set_param fail_loc=0x411
20302         # write a full page at the end of file
20303         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=1 conv=notrunc
20304
20305         $LCTL set_param fail_loc=0
20306         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=3
20307         $LCTL set_param fail_loc=0x411
20308         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1 seek=2 conv=notrunc
20309
20310         # LU-4201
20311         dd if=/dev/zero of=$DIR/$tfile-2 bs=1024 count=1
20312         $CHECKSTAT -s 1024 $DIR/$tfile-2 || error "checkstat wrong size"
20313 }
20314 run_test 219 "LU-394: Write partial won't cause uncontiguous pages vec at LND"
20315
20316 test_220() { #LU-325
20317         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20318         remote_ost_nodsh && skip "remote OST with nodsh"
20319         remote_mds_nodsh && skip "remote MDS with nodsh"
20320         remote_mgs_nodsh && skip "remote MGS with nodsh"
20321
20322         local OSTIDX=0
20323
20324         # create on MDT0000 so the last_id and next_id are correct
20325         mkdir_on_mdt0 $DIR/$tdir
20326         local OST=$($LFS df $DIR | awk '/OST:'$OSTIDX'/ { print $1 }')
20327         OST=${OST%_UUID}
20328
20329         # on the mdt's osc
20330         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $OST)
20331         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
20332                         osp.$mdtosc_proc1.prealloc_last_id)
20333         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
20334                         osp.$mdtosc_proc1.prealloc_next_id)
20335
20336         $LFS df -i
20337
20338         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=-1
20339         #define OBD_FAIL_OST_ENOINO              0x229
20340         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0x229
20341         create_pool $FSNAME.$TESTNAME || return 1
20342         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $OST || return 2
20343
20344         $LFS setstripe $DIR/$tdir -i $OSTIDX -c 1 -p $FSNAME.$TESTNAME
20345
20346         MDSOBJS=$((last_id - next_id))
20347         echo "preallocated objects on MDS is $MDSOBJS" "($last_id - $next_id)"
20348
20349         blocks=$($LFS df $MOUNT | awk '($1 == '$OSTIDX') { print $4 }')
20350         echo "OST still has $count kbytes free"
20351
20352         echo "create $MDSOBJS files @next_id..."
20353         createmany -o $DIR/$tdir/f $MDSOBJS || return 3
20354
20355         local last_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
20356                         osp.$mdtosc_proc1.prealloc_last_id)
20357         local next_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
20358                         osp.$mdtosc_proc1.prealloc_next_id)
20359
20360         echo "after creation, last_id=$last_id2, next_id=$next_id2"
20361         $LFS df -i
20362
20363         echo "cleanup..."
20364
20365         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=0
20366         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0
20367
20368         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $OST ||
20369                 error "$LCTL pool_remove $FSNAME.$TESTNAME $OST failed"
20370         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
20371                 error "$LCTL pool_destroy $FSNAME.$TESTNAME failed"
20372         echo "unlink $MDSOBJS files @$next_id..."
20373         unlinkmany $DIR/$tdir/f $MDSOBJS || error "unlinkmany failed"
20374 }
20375 run_test 220 "preallocated MDS objects still used if ENOSPC from OST"
20376
20377 test_221() {
20378         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20379
20380         dd if=`which date` of=$MOUNT/date oflag=sync
20381         chmod +x $MOUNT/date
20382
20383         #define OBD_FAIL_LLITE_FAULT_TRUNC_RACE  0x1401
20384         $LCTL set_param fail_loc=0x80001401
20385
20386         $MOUNT/date > /dev/null
20387         rm -f $MOUNT/date
20388 }
20389 run_test 221 "make sure fault and truncate race to not cause OOM"
20390
20391 test_222a () {
20392         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20393
20394         rm -rf $DIR/$tdir
20395         test_mkdir $DIR/$tdir
20396         $LFS setstripe -c 1 -i 0 $DIR/$tdir
20397         createmany -o $DIR/$tdir/$tfile 10
20398         cancel_lru_locks mdc
20399         cancel_lru_locks osc
20400         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
20401         $LCTL set_param fail_loc=0x31a
20402         ls -l $DIR/$tdir > /dev/null || error "AGL for ls failed"
20403         $LCTL set_param fail_loc=0
20404         rm -r $DIR/$tdir
20405 }
20406 run_test 222a "AGL for ls should not trigger CLIO lock failure"
20407
20408 test_222b () {
20409         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20410
20411         rm -rf $DIR/$tdir
20412         test_mkdir $DIR/$tdir
20413         $LFS setstripe -c 1 -i 0 $DIR/$tdir
20414         createmany -o $DIR/$tdir/$tfile 10
20415         cancel_lru_locks mdc
20416         cancel_lru_locks osc
20417         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
20418         $LCTL set_param fail_loc=0x31a
20419         rm -r $DIR/$tdir || error "AGL for rmdir failed"
20420         $LCTL set_param fail_loc=0
20421 }
20422 run_test 222b "AGL for rmdir should not trigger CLIO lock failure"
20423
20424 test_223 () {
20425         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20426
20427         rm -rf $DIR/$tdir
20428         test_mkdir $DIR/$tdir
20429         $LFS setstripe -c 1 -i 0 $DIR/$tdir
20430         createmany -o $DIR/$tdir/$tfile 10
20431         cancel_lru_locks mdc
20432         cancel_lru_locks osc
20433         #define OBD_FAIL_LDLM_AGL_NOLOCK          0x31b
20434         $LCTL set_param fail_loc=0x31b
20435         ls -l $DIR/$tdir > /dev/null || error "reenqueue failed"
20436         $LCTL set_param fail_loc=0
20437         rm -r $DIR/$tdir
20438 }
20439 run_test 223 "osc reenqueue if without AGL lock granted ======================="
20440
20441 test_224a() { # LU-1039, MRP-303
20442         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20443         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB   0x508
20444         $LCTL set_param fail_loc=0x508
20445         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 conv=fsync
20446         $LCTL set_param fail_loc=0
20447         df $DIR
20448 }
20449 run_test 224a "Don't panic on bulk IO failure"
20450
20451 test_224bd_sub() { # LU-1039, MRP-303
20452         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20453         local timeout=$1
20454
20455         shift
20456         dd if=/dev/urandom of=$TMP/$tfile bs=1M count=1
20457
20458         $LFS setstripe -c 1 -i 0 $DIR/$tfile
20459
20460         dd if=$TMP/$tfile of=$DIR/$tfile bs=1M count=1
20461         cancel_lru_locks osc
20462         set_checksums 0
20463         stack_trap "set_checksums $ORIG_CSUM" EXIT
20464         local at_max_saved=0
20465
20466         # adaptive timeouts may prevent seeing the issue
20467         if at_is_enabled; then
20468                 at_max_saved=$(at_max_get mds)
20469                 at_max_set 0 mds client
20470                 stack_trap "at_max_set $at_max_saved mds client" EXIT
20471         fi
20472
20473         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB2   0x515
20474         do_facet ost1 $LCTL set_param fail_val=$timeout fail_loc=0x80000515
20475         dd of=$TMP/$tfile.new if=$DIR/$tfile bs=1M count=1 || "$@"
20476
20477         do_facet ost1 $LCTL set_param fail_loc=0
20478         cmp $TMP/$tfile $TMP/$tfile.new || error "file contents wrong"
20479         df $DIR
20480 }
20481
20482 test_224b() {
20483         test_224bd_sub 3 error "dd failed"
20484 }
20485 run_test 224b "Don't panic on bulk IO failure"
20486
20487 test_224c() { # LU-6441
20488         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20489         remote_mds_nodsh && skip "remote MDS with nodsh"
20490
20491         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
20492         save_writethrough $p
20493         set_cache writethrough on
20494
20495         local pages_per_rpc=$($LCTL get_param osc.*.max_pages_per_rpc)
20496         local at_max=$($LCTL get_param -n at_max)
20497         local timeout=$($LCTL get_param -n timeout)
20498         local test_at="at_max"
20499         local param_at="$FSNAME.sys.at_max"
20500         local test_timeout="timeout"
20501         local param_timeout="$FSNAME.sys.timeout"
20502
20503         $LCTL set_param -n osc.*.max_pages_per_rpc=1024
20504
20505         set_persistent_param_and_check client "$test_at" "$param_at" 0
20506         set_persistent_param_and_check client "$test_timeout" "$param_timeout" 5
20507
20508         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB3 0x520
20509         do_facet ost1 "$LCTL set_param fail_loc=0x520"
20510         $LFS setstripe -c 1 -i 0 $DIR/$tfile
20511         stack_trap "rm -f $DIR/$tfile"
20512         dd if=/dev/zero of=$DIR/$tfile bs=8MB count=1
20513         sync
20514         do_facet ost1 "$LCTL set_param fail_loc=0"
20515
20516         set_persistent_param_and_check client "$test_at" "$param_at" $at_max
20517         set_persistent_param_and_check client "$test_timeout" "$param_timeout" \
20518                 $timeout
20519
20520         $LCTL set_param -n $pages_per_rpc
20521         restore_lustre_params < $p
20522         rm -f $p
20523 }
20524 run_test 224c "Don't hang if one of md lost during large bulk RPC"
20525
20526 test_224d() { # LU-11169
20527         test_224bd_sub $((TIMEOUT + 2)) error "dd failed"
20528 }
20529 run_test 224d "Don't corrupt data on bulk IO timeout"
20530
20531 MDSSURVEY=${MDSSURVEY:-$(which mds-survey 2>/dev/null || true)}
20532 test_225a () {
20533         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20534         if [ -z ${MDSSURVEY} ]; then
20535                 skip_env "mds-survey not found"
20536         fi
20537         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
20538                 skip "Need MDS version at least 2.2.51"
20539
20540         local mds=$(facet_host $SINGLEMDS)
20541         local target=$(do_nodes $mds 'lctl dl' |
20542                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
20543
20544         local cmd1="file_count=1000 thrhi=4"
20545         local cmd2="dir_count=2 layer=mdd stripe_count=0"
20546         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
20547         local cmd="$cmd1 $cmd2 $cmd3"
20548
20549         rm -f ${TMP}/mds_survey*
20550         echo + $cmd
20551         eval $cmd || error "mds-survey with zero-stripe failed"
20552         cat ${TMP}/mds_survey*
20553         rm -f ${TMP}/mds_survey*
20554 }
20555 run_test 225a "Metadata survey sanity with zero-stripe"
20556
20557 test_225b () {
20558         if [ -z ${MDSSURVEY} ]; then
20559                 skip_env "mds-survey not found"
20560         fi
20561         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
20562                 skip "Need MDS version at least 2.2.51"
20563         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20564         remote_mds_nodsh && skip "remote MDS with nodsh"
20565         if [ $($LCTL dl | grep -c osc) -eq 0 ]; then
20566                 skip_env "Need to mount OST to test"
20567         fi
20568
20569         local mds=$(facet_host $SINGLEMDS)
20570         local target=$(do_nodes $mds 'lctl dl' |
20571                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
20572
20573         local cmd1="file_count=1000 thrhi=4"
20574         local cmd2="dir_count=2 layer=mdd stripe_count=1"
20575         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
20576         local cmd="$cmd1 $cmd2 $cmd3"
20577
20578         rm -f ${TMP}/mds_survey*
20579         echo + $cmd
20580         eval $cmd || error "mds-survey with stripe_count failed"
20581         cat ${TMP}/mds_survey*
20582         rm -f ${TMP}/mds_survey*
20583 }
20584 run_test 225b "Metadata survey sanity with stripe_count = 1"
20585
20586 mcreate_path2fid () {
20587         local mode=$1
20588         local major=$2
20589         local minor=$3
20590         local name=$4
20591         local desc=$5
20592         local path=$DIR/$tdir/$name
20593         local fid
20594         local rc
20595         local fid_path
20596
20597         $MCREATE --mode=$1 --major=$2 --minor=$3 $path ||
20598                 error "cannot create $desc"
20599
20600         fid=$($LFS path2fid $path | tr -d '[' | tr -d ']')
20601         rc=$?
20602         [ $rc -ne 0 ] && error "cannot get fid of a $desc"
20603
20604         fid_path=$($LFS fid2path $MOUNT $fid)
20605         rc=$?
20606         [ $rc -ne 0 ] && error "cannot get path of $desc by $DIR $path $fid"
20607
20608         [ "$path" == "$fid_path" ] ||
20609                 error "fid2path returned $fid_path, expected $path"
20610
20611         echo "pass with $path and $fid"
20612 }
20613
20614 test_226a () {
20615         rm -rf $DIR/$tdir
20616         mkdir -p $DIR/$tdir
20617
20618         mcreate_path2fid 0010666 0 0 fifo "FIFO"
20619         mcreate_path2fid 0020666 1 3 null "character special file (null)"
20620         mcreate_path2fid 0020666 1 255 none "character special file (no device)"
20621         mcreate_path2fid 0040666 0 0 dir "directory"
20622         mcreate_path2fid 0060666 7 0 loop0 "block special file (loop)"
20623         mcreate_path2fid 0100666 0 0 file "regular file"
20624         mcreate_path2fid 0120666 0 0 link "symbolic link"
20625         mcreate_path2fid 0140666 0 0 sock "socket"
20626 }
20627 run_test 226a "call path2fid and fid2path on files of all type"
20628
20629 test_226b () {
20630         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20631
20632         local MDTIDX=1
20633
20634         rm -rf $DIR/$tdir
20635         mkdir -p $DIR/$tdir
20636         $LFS setdirstripe -i $MDTIDX $DIR/$tdir/remote_dir ||
20637                 error "create remote directory failed"
20638         mcreate_path2fid 0010666 0 0 "remote_dir/fifo" "FIFO"
20639         mcreate_path2fid 0020666 1 3 "remote_dir/null" \
20640                                 "character special file (null)"
20641         mcreate_path2fid 0020666 1 255 "remote_dir/none" \
20642                                 "character special file (no device)"
20643         mcreate_path2fid 0040666 0 0 "remote_dir/dir" "directory"
20644         mcreate_path2fid 0060666 7 0 "remote_dir/loop0" \
20645                                 "block special file (loop)"
20646         mcreate_path2fid 0100666 0 0 "remote_dir/file" "regular file"
20647         mcreate_path2fid 0120666 0 0 "remote_dir/link" "symbolic link"
20648         mcreate_path2fid 0140666 0 0 "remote_dir/sock" "socket"
20649 }
20650 run_test 226b "call path2fid and fid2path on files of all type under remote dir"
20651
20652 test_226c () {
20653         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20654         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
20655                 skip "Need MDS version at least 2.13.55"
20656
20657         local submnt=/mnt/submnt
20658         local srcfile=/etc/passwd
20659         local dstfile=$submnt/passwd
20660         local path
20661         local fid
20662
20663         rm -rf $DIR/$tdir
20664         rm -rf $submnt
20665         $LFS setdirstripe -c -1 -i 1 $DIR/$tdir ||
20666                 error "create remote directory failed"
20667         mkdir -p $submnt || error "create $submnt failed"
20668         $MOUNT_CMD $MGSNID:/$FSNAME/$tdir $submnt ||
20669                 error "mount $submnt failed"
20670         stack_trap "umount $submnt" EXIT
20671
20672         cp $srcfile $dstfile
20673         fid=$($LFS path2fid $dstfile)
20674         path=$($LFS fid2path $submnt "$fid")
20675         [ "$path" = "$dstfile" ] ||
20676                 error "fid2path $submnt $fid failed ($path != $dstfile)"
20677 }
20678 run_test 226c "call path2fid and fid2path under remote dir with subdir mount"
20679
20680 # LU-1299 Executing or running ldd on a truncated executable does not
20681 # cause an out-of-memory condition.
20682 test_227() {
20683         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20684         [ -z "$(which ldd)" ] && skip_env "should have ldd tool"
20685
20686         dd if=$(which date) of=$MOUNT/date bs=1k count=1
20687         chmod +x $MOUNT/date
20688
20689         $MOUNT/date > /dev/null
20690         ldd $MOUNT/date > /dev/null
20691         rm -f $MOUNT/date
20692 }
20693 run_test 227 "running truncated executable does not cause OOM"
20694
20695 # LU-1512 try to reuse idle OI blocks
20696 test_228a() {
20697         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20698         remote_mds_nodsh && skip "remote MDS with nodsh"
20699         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
20700
20701         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
20702         local myDIR=$DIR/$tdir
20703
20704         mkdir -p $myDIR
20705         #define OBD_FAIL_SEQ_EXHAUST             0x1002
20706         $LCTL set_param fail_loc=0x80001002
20707         createmany -o $myDIR/t- 10000
20708         $LCTL set_param fail_loc=0
20709         # The guard is current the largest FID holder
20710         touch $myDIR/guard
20711         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
20712                     tr -d '[')
20713         local IDX=$(($SEQ % 64))
20714
20715         do_facet $SINGLEMDS sync
20716         # Make sure journal flushed.
20717         sleep 6
20718         local blk1=$(do_facet $SINGLEMDS \
20719                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
20720                      grep Blockcount | awk '{print $4}')
20721
20722         # Remove old files, some OI blocks will become idle.
20723         unlinkmany $myDIR/t- 10000
20724         # Create new files, idle OI blocks should be reused.
20725         createmany -o $myDIR/t- 2000
20726         do_facet $SINGLEMDS sync
20727         # Make sure journal flushed.
20728         sleep 6
20729         local blk2=$(do_facet $SINGLEMDS \
20730                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
20731                      grep Blockcount | awk '{print $4}')
20732
20733         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
20734 }
20735 run_test 228a "try to reuse idle OI blocks"
20736
20737 test_228b() {
20738         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20739         remote_mds_nodsh && skip "remote MDS with nodsh"
20740         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
20741
20742         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
20743         local myDIR=$DIR/$tdir
20744
20745         mkdir -p $myDIR
20746         #define OBD_FAIL_SEQ_EXHAUST             0x1002
20747         $LCTL set_param fail_loc=0x80001002
20748         createmany -o $myDIR/t- 10000
20749         $LCTL set_param fail_loc=0
20750         # The guard is current the largest FID holder
20751         touch $myDIR/guard
20752         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
20753                     tr -d '[')
20754         local IDX=$(($SEQ % 64))
20755
20756         do_facet $SINGLEMDS sync
20757         # Make sure journal flushed.
20758         sleep 6
20759         local blk1=$(do_facet $SINGLEMDS \
20760                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
20761                      grep Blockcount | awk '{print $4}')
20762
20763         # Remove old files, some OI blocks will become idle.
20764         unlinkmany $myDIR/t- 10000
20765
20766         # stop the MDT
20767         stop $SINGLEMDS || error "Fail to stop MDT."
20768         # remount the MDT
20769         start $SINGLEMDS $(facet_device $SINGLEMDS) $MDS_MOUNT_OPTS ||
20770                 error "Fail to start MDT."
20771
20772         client_up || error "Fail to df."
20773         # Create new files, idle OI blocks should be reused.
20774         createmany -o $myDIR/t- 2000
20775         do_facet $SINGLEMDS sync
20776         # Make sure journal flushed.
20777         sleep 6
20778         local blk2=$(do_facet $SINGLEMDS \
20779                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
20780                      grep Blockcount | awk '{print $4}')
20781
20782         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
20783 }
20784 run_test 228b "idle OI blocks can be reused after MDT restart"
20785
20786 #LU-1881
20787 test_228c() {
20788         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20789         remote_mds_nodsh && skip "remote MDS with nodsh"
20790         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
20791
20792         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
20793         local myDIR=$DIR/$tdir
20794
20795         mkdir -p $myDIR
20796         #define OBD_FAIL_SEQ_EXHAUST             0x1002
20797         $LCTL set_param fail_loc=0x80001002
20798         # 20000 files can guarantee there are index nodes in the OI file
20799         createmany -o $myDIR/t- 20000
20800         $LCTL set_param fail_loc=0
20801         # The guard is current the largest FID holder
20802         touch $myDIR/guard
20803         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
20804                     tr -d '[')
20805         local IDX=$(($SEQ % 64))
20806
20807         do_facet $SINGLEMDS sync
20808         # Make sure journal flushed.
20809         sleep 6
20810         local blk1=$(do_facet $SINGLEMDS \
20811                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
20812                      grep Blockcount | awk '{print $4}')
20813
20814         # Remove old files, some OI blocks will become idle.
20815         unlinkmany $myDIR/t- 20000
20816         rm -f $myDIR/guard
20817         # The OI file should become empty now
20818
20819         # Create new files, idle OI blocks should be reused.
20820         createmany -o $myDIR/t- 2000
20821         do_facet $SINGLEMDS sync
20822         # Make sure journal flushed.
20823         sleep 6
20824         local blk2=$(do_facet $SINGLEMDS \
20825                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
20826                      grep Blockcount | awk '{print $4}')
20827
20828         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
20829 }
20830 run_test 228c "NOT shrink the last entry in OI index node to recycle idle leaf"
20831
20832 test_229() { # LU-2482, LU-3448
20833         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20834         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
20835         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
20836                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
20837
20838         rm -f $DIR/$tfile
20839
20840         # Create a file with a released layout and stripe count 2.
20841         $MULTIOP $DIR/$tfile H2c ||
20842                 error "failed to create file with released layout"
20843
20844         $LFS getstripe -v $DIR/$tfile
20845
20846         local pattern=$($LFS getstripe -L $DIR/$tfile)
20847         [ X"$pattern" = X"released" ] || error "pattern error ($pattern)"
20848
20849         local stripe_count=$($LFS getstripe -c $DIR/$tfile) ||
20850                 error "getstripe"
20851         [ $stripe_count -eq 2 ] || error "stripe count not 2 ($stripe_count)"
20852         stat $DIR/$tfile || error "failed to stat released file"
20853
20854         chown $RUNAS_ID $DIR/$tfile ||
20855                 error "chown $RUNAS_ID $DIR/$tfile failed"
20856
20857         chgrp $RUNAS_ID $DIR/$tfile ||
20858                 error "chgrp $RUNAS_ID $DIR/$tfile failed"
20859
20860         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
20861         rm $DIR/$tfile || error "failed to remove released file"
20862 }
20863 run_test 229 "getstripe/stat/rm/attr changes work on released files"
20864
20865 test_230a() {
20866         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20867         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20868         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20869                 skip "Need MDS version at least 2.11.52"
20870
20871         local MDTIDX=1
20872
20873         test_mkdir $DIR/$tdir
20874         test_mkdir -i0 -c1 $DIR/$tdir/test_230_local
20875         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230_local)
20876         [ $mdt_idx -ne 0 ] &&
20877                 error "create local directory on wrong MDT $mdt_idx"
20878
20879         $LFS mkdir -i $MDTIDX $DIR/$tdir/test_230 ||
20880                         error "create remote directory failed"
20881         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230)
20882         [ $mdt_idx -ne $MDTIDX ] &&
20883                 error "create remote directory on wrong MDT $mdt_idx"
20884
20885         createmany -o $DIR/$tdir/test_230/t- 10 ||
20886                 error "create files on remote directory failed"
20887         mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230/t-0)
20888         [ $mdt_idx -ne $MDTIDX ] && error "create files on wrong MDT $mdt_idx"
20889         rm -r $DIR/$tdir || error "unlink remote directory failed"
20890 }
20891 run_test 230a "Create remote directory and files under the remote directory"
20892
20893 test_230b() {
20894         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20895         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20896         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20897                 skip "Need MDS version at least 2.11.52"
20898
20899         local MDTIDX=1
20900         local mdt_index
20901         local i
20902         local file
20903         local pid
20904         local stripe_count
20905         local migrate_dir=$DIR/$tdir/migrate_dir
20906         local other_dir=$DIR/$tdir/other_dir
20907
20908         test_mkdir $DIR/$tdir
20909         test_mkdir -i0 -c1 $migrate_dir
20910         test_mkdir -i0 -c1 $other_dir
20911         for ((i=0; i<10; i++)); do
20912                 mkdir -p $migrate_dir/dir_${i}
20913                 createmany -o $migrate_dir/dir_${i}/f 10 ||
20914                         error "create files under remote dir failed $i"
20915         done
20916
20917         cp /etc/passwd $migrate_dir/$tfile
20918         cp /etc/passwd $other_dir/$tfile
20919         chattr +SAD $migrate_dir
20920         chattr +SAD $migrate_dir/$tfile
20921
20922         local old_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
20923         local old_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
20924         local old_dir_mode=$(stat -c%f $migrate_dir)
20925         local old_file_mode=$(stat -c%f $migrate_dir/$tfile)
20926
20927         mkdir -p $migrate_dir/dir_default_stripe2
20928         $LFS setstripe -c 2 $migrate_dir/dir_default_stripe2
20929         $LFS setstripe -c 2 $migrate_dir/${tfile}_stripe2
20930
20931         mkdir -p $other_dir
20932         ln $migrate_dir/$tfile $other_dir/luna
20933         ln $migrate_dir/$tfile $migrate_dir/sofia
20934         ln $other_dir/$tfile $migrate_dir/david
20935         ln -s $migrate_dir/$tfile $other_dir/zachary
20936         ln -s $migrate_dir/$tfile $migrate_dir/${tfile}_ln
20937         ln -s $other_dir/$tfile $migrate_dir/${tfile}_ln_other
20938
20939         local len
20940         local lnktgt
20941
20942         # inline symlink
20943         for len in 58 59 60; do
20944                 lnktgt=$(str_repeat 'l' $len)
20945                 touch $migrate_dir/$lnktgt
20946                 ln -s $lnktgt $migrate_dir/${len}char_ln
20947         done
20948
20949         # PATH_MAX
20950         for len in 4094 4095; do
20951                 lnktgt=$(str_repeat 'l' $len)
20952                 ln -s $lnktgt $migrate_dir/${len}char_ln
20953         done
20954
20955         # NAME_MAX
20956         for len in 254 255; do
20957                 touch $migrate_dir/$(str_repeat 'l' $len)
20958         done
20959
20960         $LFS migrate -m $MDTIDX $migrate_dir ||
20961                 error "fails on migrating remote dir to MDT1"
20962
20963         echo "migratate to MDT1, then checking.."
20964         for ((i = 0; i < 10; i++)); do
20965                 for file in $(find $migrate_dir/dir_${i}); do
20966                         mdt_index=$($LFS getstripe -m $file)
20967                         # broken symlink getstripe will fail
20968                         [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
20969                                 error "$file is not on MDT${MDTIDX}"
20970                 done
20971         done
20972
20973         # the multiple link file should still in MDT0
20974         mdt_index=$($LFS getstripe -m $migrate_dir/$tfile)
20975         [ $mdt_index == 0 ] ||
20976                 error "$file is not on MDT${MDTIDX}"
20977
20978         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
20979         [ "$old_dir_flag" = "$new_dir_flag" ] ||
20980                 error " expect $old_dir_flag get $new_dir_flag"
20981
20982         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
20983         [ "$old_file_flag" = "$new_file_flag" ] ||
20984                 error " expect $old_file_flag get $new_file_flag"
20985
20986         local new_dir_mode=$(stat -c%f $migrate_dir)
20987         [ "$old_dir_mode" = "$new_dir_mode" ] ||
20988                 error "expect mode $old_dir_mode get $new_dir_mode"
20989
20990         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
20991         [ "$old_file_mode" = "$new_file_mode" ] ||
20992                 error "expect mode $old_file_mode get $new_file_mode"
20993
20994         diff /etc/passwd $migrate_dir/$tfile ||
20995                 error "$tfile different after migration"
20996
20997         diff /etc/passwd $other_dir/luna ||
20998                 error "luna different after migration"
20999
21000         diff /etc/passwd $migrate_dir/sofia ||
21001                 error "sofia different after migration"
21002
21003         diff /etc/passwd $migrate_dir/david ||
21004                 error "david different after migration"
21005
21006         diff /etc/passwd $other_dir/zachary ||
21007                 error "zachary different after migration"
21008
21009         diff /etc/passwd $migrate_dir/${tfile}_ln ||
21010                 error "${tfile}_ln different after migration"
21011
21012         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
21013                 error "${tfile}_ln_other different after migration"
21014
21015         stripe_count=$($LFS getstripe -c $migrate_dir/dir_default_stripe2)
21016         [ $stripe_count = 2 ] ||
21017                 error "dir strpe_count $d != 2 after migration."
21018
21019         stripe_count=$($LFS getstripe -c $migrate_dir/${tfile}_stripe2)
21020         [ $stripe_count = 2 ] ||
21021                 error "file strpe_count $d != 2 after migration."
21022
21023         #migrate back to MDT0
21024         MDTIDX=0
21025
21026         $LFS migrate -m $MDTIDX $migrate_dir ||
21027                 error "fails on migrating remote dir to MDT0"
21028
21029         echo "migrate back to MDT0, checking.."
21030         for file in $(find $migrate_dir); do
21031                 mdt_index=$($LFS getstripe -m $file)
21032                 [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
21033                         error "$file is not on MDT${MDTIDX}"
21034         done
21035
21036         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
21037         [ "$old_dir_flag" = "$new_dir_flag" ] ||
21038                 error " expect $old_dir_flag get $new_dir_flag"
21039
21040         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
21041         [ "$old_file_flag" = "$new_file_flag" ] ||
21042                 error " expect $old_file_flag get $new_file_flag"
21043
21044         local new_dir_mode=$(stat -c%f $migrate_dir)
21045         [ "$old_dir_mode" = "$new_dir_mode" ] ||
21046                 error "expect mode $old_dir_mode get $new_dir_mode"
21047
21048         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
21049         [ "$old_file_mode" = "$new_file_mode" ] ||
21050                 error "expect mode $old_file_mode get $new_file_mode"
21051
21052         diff /etc/passwd ${migrate_dir}/$tfile ||
21053                 error "$tfile different after migration"
21054
21055         diff /etc/passwd ${other_dir}/luna ||
21056                 error "luna different after migration"
21057
21058         diff /etc/passwd ${migrate_dir}/sofia ||
21059                 error "sofia different after migration"
21060
21061         diff /etc/passwd ${other_dir}/zachary ||
21062                 error "zachary different after migration"
21063
21064         diff /etc/passwd $migrate_dir/${tfile}_ln ||
21065                 error "${tfile}_ln different after migration"
21066
21067         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
21068                 error "${tfile}_ln_other different after migration"
21069
21070         stripe_count=$($LFS getstripe -c ${migrate_dir}/dir_default_stripe2)
21071         [ $stripe_count = 2 ] ||
21072                 error "dir strpe_count $d != 2 after migration."
21073
21074         stripe_count=$($LFS getstripe -c ${migrate_dir}/${tfile}_stripe2)
21075         [ $stripe_count = 2 ] ||
21076                 error "file strpe_count $d != 2 after migration."
21077
21078         rm -rf $DIR/$tdir || error "rm dir failed after migration"
21079 }
21080 run_test 230b "migrate directory"
21081
21082 test_230c() {
21083         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21084         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21085         remote_mds_nodsh && skip "remote MDS with nodsh"
21086         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21087                 skip "Need MDS version at least 2.11.52"
21088
21089         local MDTIDX=1
21090         local total=3
21091         local mdt_index
21092         local file
21093         local migrate_dir=$DIR/$tdir/migrate_dir
21094
21095         #If migrating directory fails in the middle, all entries of
21096         #the directory is still accessiable.
21097         test_mkdir $DIR/$tdir
21098         test_mkdir -i0 -c1 $migrate_dir
21099         test_mkdir -i1 -c1 $DIR/$tdir/remote_dir
21100         stat $migrate_dir
21101         createmany -o $migrate_dir/f $total ||
21102                 error "create files under ${migrate_dir} failed"
21103
21104         # fail after migrating top dir, and this will fail only once, so the
21105         # first sub file migration will fail (currently f3), others succeed.
21106         #OBD_FAIL_MIGRATE_ENTRIES       0x1801
21107         do_facet mds1 lctl set_param fail_loc=0x1801
21108         local t=$(ls $migrate_dir | wc -l)
21109         $LFS migrate --mdt-index $MDTIDX $migrate_dir &&
21110                 error "migrate should fail"
21111         local u=$(ls $migrate_dir | wc -l)
21112         [ "$u" == "$t" ] || error "$u != $t during migration"
21113
21114         # add new dir/file should succeed
21115         mkdir $migrate_dir/dir ||
21116                 error "mkdir failed under migrating directory"
21117         touch $migrate_dir/file ||
21118                 error "create file failed under migrating directory"
21119
21120         # add file with existing name should fail
21121         for file in $migrate_dir/f*; do
21122                 stat $file > /dev/null || error "stat $file failed"
21123                 $OPENFILE -f O_CREAT:O_EXCL $file &&
21124                         error "open(O_CREAT|O_EXCL) $file should fail"
21125                 $MULTIOP $file m && error "create $file should fail"
21126                 touch $DIR/$tdir/remote_dir/$tfile ||
21127                         error "touch $tfile failed"
21128                 ln $DIR/$tdir/remote_dir/$tfile $file &&
21129                         error "link $file should fail"
21130                 mdt_index=$($LFS getstripe -m $file)
21131                 if [ $mdt_index == 0 ]; then
21132                         # file failed to migrate is not allowed to rename to
21133                         mv $DIR/$tdir/remote_dir/$tfile $file &&
21134                                 error "rename to $file should fail"
21135                 else
21136                         mv $DIR/$tdir/remote_dir/$tfile $file ||
21137                                 error "rename to $file failed"
21138                 fi
21139                 echo hello >> $file || error "write $file failed"
21140         done
21141
21142         # resume migration with different options should fail
21143         $LFS migrate -m 0 $migrate_dir &&
21144                 error "migrate -m 0 $migrate_dir should fail"
21145
21146         $LFS migrate -m $MDTIDX -c 2 $migrate_dir &&
21147                 error "migrate -c 2 $migrate_dir should fail"
21148
21149         # resume migration should succeed
21150         $LFS migrate -m $MDTIDX $migrate_dir ||
21151                 error "migrate $migrate_dir failed"
21152
21153         echo "Finish migration, then checking.."
21154         for file in $(find $migrate_dir); do
21155                 mdt_index=$($LFS getstripe -m $file)
21156                 [ $mdt_index == $MDTIDX ] ||
21157                         error "$file is not on MDT${MDTIDX}"
21158         done
21159
21160         rm -rf $DIR/$tdir || error "rm dir failed after migration"
21161 }
21162 run_test 230c "check directory accessiblity if migration failed"
21163
21164 test_230d() {
21165         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21166         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21167         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21168                 skip "Need MDS version at least 2.11.52"
21169         # LU-11235
21170         [ "$mds1_FSTYPE" == "zfs" ] && skip "skip ZFS backend"
21171
21172         local migrate_dir=$DIR/$tdir/migrate_dir
21173         local old_index
21174         local new_index
21175         local old_count
21176         local new_count
21177         local new_hash
21178         local mdt_index
21179         local i
21180         local j
21181
21182         old_index=$((RANDOM % MDSCOUNT))
21183         old_count=$((MDSCOUNT - old_index))
21184         new_index=$((RANDOM % MDSCOUNT))
21185         new_count=$((MDSCOUNT - new_index))
21186         new_hash=1 # for all_char
21187
21188         [ $old_count -gt 1 ] && old_count=$((old_count - RANDOM % old_count))
21189         [ $new_count -gt 1 ] && new_count=$((new_count - RANDOM % new_count))
21190
21191         test_mkdir $DIR/$tdir
21192         test_mkdir -i $old_index -c $old_count $migrate_dir
21193
21194         for ((i=0; i<100; i++)); do
21195                 test_mkdir -i0 -c1 $migrate_dir/dir_${i}
21196                 createmany -o $migrate_dir/dir_${i}/f 100 ||
21197                         error "create files under remote dir failed $i"
21198         done
21199
21200         echo -n "Migrate from MDT$old_index "
21201         [ $old_count -gt 1 ] && echo -n "... MDT$((old_index + old_count - 1)) "
21202         echo -n "to MDT$new_index"
21203         [ $new_count -gt 1 ] && echo -n " ... MDT$((new_index + new_count - 1))"
21204         echo
21205
21206         echo "$LFS migrate -m$new_index -c$new_count -H $new_hash $migrate_dir"
21207         $LFS migrate -m $new_index -c $new_count -H $new_hash $migrate_dir ||
21208                 error "migrate remote dir error"
21209
21210         echo "Finish migration, then checking.."
21211         for file in $(find $migrate_dir -maxdepth 1); do
21212                 mdt_index=$($LFS getstripe -m $file)
21213                 if [ $mdt_index -lt $new_index ] ||
21214                    [ $mdt_index -gt $((new_index + new_count - 1)) ]; then
21215                         error "$file is on MDT$mdt_index"
21216                 fi
21217         done
21218
21219         rm -rf $DIR/$tdir || error "rm dir failed after migration"
21220 }
21221 run_test 230d "check migrate big directory"
21222
21223 test_230e() {
21224         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21225         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21226         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21227                 skip "Need MDS version at least 2.11.52"
21228
21229         local i
21230         local j
21231         local a_fid
21232         local b_fid
21233
21234         mkdir_on_mdt0 $DIR/$tdir
21235         mkdir $DIR/$tdir/migrate_dir
21236         mkdir $DIR/$tdir/other_dir
21237         touch $DIR/$tdir/migrate_dir/a
21238         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/b
21239         ls $DIR/$tdir/other_dir
21240
21241         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
21242                 error "migrate dir fails"
21243
21244         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
21245         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
21246
21247         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
21248         [ $mdt_index == 0 ] || error "a is not on MDT0"
21249
21250         $LFS migrate -m 1 $DIR/$tdir/other_dir ||
21251                 error "migrate dir fails"
21252
21253         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir)
21254         [ $mdt_index == 1 ] || error "other_dir is not on MDT1"
21255
21256         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
21257         [ $mdt_index == 1 ] || error "a is not on MDT1"
21258
21259         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir/b)
21260         [ $mdt_index == 1 ] || error "b is not on MDT1"
21261
21262         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
21263         b_fid=$($LFS path2fid $DIR/$tdir/other_dir/b)
21264
21265         [ "$a_fid" = "$b_fid" ] || error "different fid after migration"
21266
21267         rm -rf $DIR/$tdir || error "rm dir failed after migration"
21268 }
21269 run_test 230e "migrate mulitple local link files"
21270
21271 test_230f() {
21272         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21273         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21274         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21275                 skip "Need MDS version at least 2.11.52"
21276
21277         local a_fid
21278         local ln_fid
21279
21280         mkdir -p $DIR/$tdir
21281         mkdir $DIR/$tdir/migrate_dir
21282         $LFS mkdir -i1 $DIR/$tdir/other_dir
21283         touch $DIR/$tdir/migrate_dir/a
21284         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln1
21285         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln2
21286         ls $DIR/$tdir/other_dir
21287
21288         # a should be migrated to MDT1, since no other links on MDT0
21289         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
21290                 error "#1 migrate dir fails"
21291         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
21292         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
21293         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
21294         [ $mdt_index == 1 ] || error "a is not on MDT1"
21295
21296         # a should stay on MDT1, because it is a mulitple link file
21297         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
21298                 error "#2 migrate dir fails"
21299         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
21300         [ $mdt_index == 1 ] || error "a is not on MDT1"
21301
21302         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
21303                 error "#3 migrate dir fails"
21304
21305         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
21306         ln_fid=$($LFS path2fid $DIR/$tdir/other_dir/ln1)
21307         [ "$a_fid" = "$ln_fid" ] || error "different fid after migrate to MDT1"
21308
21309         rm -rf $DIR/$tdir/other_dir/ln1 || error "unlink ln1 fails"
21310         rm -rf $DIR/$tdir/other_dir/ln2 || error "unlink ln2 fails"
21311
21312         # a should be migrated to MDT0, since no other links on MDT1
21313         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
21314                 error "#4 migrate dir fails"
21315         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
21316         [ $mdt_index == 0 ] || error "a is not on MDT0"
21317
21318         rm -rf $DIR/$tdir || error "rm dir failed after migration"
21319 }
21320 run_test 230f "migrate mulitple remote link files"
21321
21322 test_230g() {
21323         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21324         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21325         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21326                 skip "Need MDS version at least 2.11.52"
21327
21328         mkdir -p $DIR/$tdir/migrate_dir
21329
21330         $LFS migrate -m 1000 $DIR/$tdir/migrate_dir &&
21331                 error "migrating dir to non-exist MDT succeeds"
21332         true
21333 }
21334 run_test 230g "migrate dir to non-exist MDT"
21335
21336 test_230h() {
21337         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21338         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21339         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21340                 skip "Need MDS version at least 2.11.52"
21341
21342         local mdt_index
21343
21344         mkdir -p $DIR/$tdir/migrate_dir
21345
21346         $LFS migrate -m1 $DIR &&
21347                 error "migrating mountpoint1 should fail"
21348
21349         $LFS migrate -m1 $DIR/$tdir/.. &&
21350                 error "migrating mountpoint2 should fail"
21351
21352         # same as mv
21353         $LFS migrate -m1 $DIR/$tdir/migrate_dir/.. &&
21354                 error "migrating $tdir/migrate_dir/.. should fail"
21355
21356         true
21357 }
21358 run_test 230h "migrate .. and root"
21359
21360 test_230i() {
21361         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21362         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21363         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21364                 skip "Need MDS version at least 2.11.52"
21365
21366         mkdir -p $DIR/$tdir/migrate_dir
21367
21368         $LFS migrate -m 1 $DIR/$tdir/migrate_dir/ ||
21369                 error "migration fails with a tailing slash"
21370
21371         $LFS migrate -m 0 $DIR/$tdir/migrate_dir// ||
21372                 error "migration fails with two tailing slashes"
21373 }
21374 run_test 230i "lfs migrate -m tolerates trailing slashes"
21375
21376 test_230j() {
21377         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
21378         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
21379                 skip "Need MDS version at least 2.11.52"
21380
21381         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
21382         $LFS setstripe -E 1M -L mdt $DIR/$tdir/$tfile ||
21383                 error "create $tfile failed"
21384         cat /etc/passwd > $DIR/$tdir/$tfile
21385
21386         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
21387
21388         cmp /etc/passwd $DIR/$tdir/$tfile ||
21389                 error "DoM file mismatch after migration"
21390 }
21391 run_test 230j "DoM file data not changed after dir migration"
21392
21393 test_230k() {
21394         [ $MDSCOUNT -lt 4 ] && skip "needs >= 4 MDTs"
21395         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
21396                 skip "Need MDS version at least 2.11.56"
21397
21398         local total=20
21399         local files_on_starting_mdt=0
21400
21401         $LFS mkdir -i -1 -c 2 $DIR/$tdir || error "mkdir failed"
21402         $LFS getdirstripe $DIR/$tdir
21403         for i in $(seq $total); do
21404                 echo $((i*i - i)) > $DIR/$tdir/$tfile.$i || error "write failed"
21405                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
21406                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
21407         done
21408
21409         echo "$files_on_starting_mdt files on MDT0"
21410
21411         $LFS migrate -m 1,3 $DIR/$tdir || error "migrate -m 1,3 failed"
21412         $LFS getdirstripe $DIR/$tdir
21413
21414         files_on_starting_mdt=0
21415         for i in $(seq $total); do
21416                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
21417                         error "file $tfile.$i mismatch after migration"
21418                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 1 ]] &&
21419                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
21420         done
21421
21422         echo "$files_on_starting_mdt files on MDT1 after migration"
21423         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT1"
21424
21425         $LFS migrate -m 0 -c 2 $DIR/$tdir || error "migrate -m 0 -c 2 failed"
21426         $LFS getdirstripe $DIR/$tdir
21427
21428         files_on_starting_mdt=0
21429         for i in $(seq $total); do
21430                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
21431                         error "file $tfile.$i mismatch after 2nd migration"
21432                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
21433                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
21434         done
21435
21436         echo "$files_on_starting_mdt files on MDT0 after 2nd migration"
21437         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT0"
21438
21439         true
21440 }
21441 run_test 230k "file data not changed after dir migration"
21442
21443 test_230l() {
21444         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
21445         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
21446                 skip "Need MDS version at least 2.11.56"
21447
21448         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir failed"
21449         createmany -o $DIR/$tdir/f___________________________________ 1000 ||
21450                 error "create files under remote dir failed $i"
21451         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
21452 }
21453 run_test 230l "readdir between MDTs won't crash"
21454
21455 test_230m() {
21456         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
21457         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
21458                 skip "Need MDS version at least 2.11.56"
21459
21460         local MDTIDX=1
21461         local mig_dir=$DIR/$tdir/migrate_dir
21462         local longstr="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
21463         local shortstr="b"
21464         local val
21465
21466         echo "Creating files and dirs with xattrs"
21467         test_mkdir $DIR/$tdir
21468         test_mkdir -i0 -c1 $mig_dir
21469         mkdir $mig_dir/dir
21470         setfattr -n user.attr1 -v $longstr $mig_dir/dir ||
21471                 error "cannot set xattr attr1 on dir"
21472         setfattr -n user.attr2 -v $shortstr $mig_dir/dir ||
21473                 error "cannot set xattr attr2 on dir"
21474         touch $mig_dir/dir/f0
21475         setfattr -n user.attr1 -v $longstr $mig_dir/dir/f0 ||
21476                 error "cannot set xattr attr1 on file"
21477         setfattr -n user.attr2 -v $shortstr $mig_dir/dir/f0 ||
21478                 error "cannot set xattr attr2 on file"
21479         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
21480         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
21481         [ "$val" = $longstr ] || error "xattr attr1 not set properly on dir"
21482         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
21483         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on dir"
21484         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
21485         [ "$val" = $longstr ] || error "xattr attr1 not set properly on file"
21486         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
21487         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on file"
21488
21489         echo "Migrating to MDT1"
21490         $LFS migrate -m $MDTIDX $mig_dir ||
21491                 error "fails on migrating dir to MDT1"
21492
21493         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
21494         echo "Checking xattrs"
21495         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
21496         [ "$val" = $longstr ] ||
21497                 error "expecting xattr1 $longstr on dir, found $val"
21498         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
21499         [ "$val" = $shortstr ] ||
21500                 error "expecting xattr2 $shortstr on dir, found $val"
21501         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
21502         [ "$val" = $longstr ] ||
21503                 error "expecting xattr1 $longstr on file, found $val"
21504         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
21505         [ "$val" = $shortstr ] ||
21506                 error "expecting xattr2 $shortstr on file, found $val"
21507 }
21508 run_test 230m "xattrs not changed after dir migration"
21509
21510 test_230n() {
21511         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
21512         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
21513                 skip "Need MDS version at least 2.13.53"
21514
21515         $LFS mkdir -i 0 $DIR/$tdir || error "mkdir $tdir failed"
21516         cat /etc/hosts > $DIR/$tdir/$tfile
21517         $LFS mirror extend -N1 $DIR/$tdir/$tfile || error "Mirroring failed"
21518         $LFS migrate -m 1 $DIR/$tdir || error "Migration failed"
21519
21520         cmp /etc/hosts $DIR/$tdir/$tfile ||
21521                 error "File data mismatch after migration"
21522 }
21523 run_test 230n "Dir migration with mirrored file"
21524
21525 test_230o() {
21526         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
21527         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
21528                 skip "Need MDS version at least 2.13.52"
21529
21530         local mdts=$(comma_list $(mdts_nodes))
21531         local timeout=100
21532         local restripe_status
21533         local delta
21534         local i
21535
21536         [[ $mds1_FSTYPE == zfs ]] && timeout=300
21537
21538         # in case "crush" hash type is not set
21539         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
21540
21541         restripe_status=$(do_facet mds1 $LCTL get_param -n \
21542                            mdt.*MDT0000.enable_dir_restripe)
21543         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
21544         stack_trap "do_nodes $mdts $LCTL set_param \
21545                     mdt.*.enable_dir_restripe=$restripe_status"
21546
21547         mkdir $DIR/$tdir
21548         createmany -m $DIR/$tdir/f 100 ||
21549                 error "create files under remote dir failed $i"
21550         createmany -d $DIR/$tdir/d 100 ||
21551                 error "create dirs under remote dir failed $i"
21552
21553         for i in $(seq 2 $MDSCOUNT); do
21554                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
21555                 $LFS setdirstripe -c $i $DIR/$tdir ||
21556                         error "split -c $i $tdir failed"
21557                 wait_update $HOSTNAME \
21558                         "$LFS getdirstripe -H $DIR/$tdir" "crush" $timeout ||
21559                         error "dir split not finished"
21560                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
21561                         awk '/migrate/ {sum += $2} END { print sum }')
21562                 echo "$delta migrated when dir split $((i - 1)) to $i stripes"
21563                 # delta is around total_files/stripe_count
21564                 (( $delta < 200 / (i - 1) + 4 )) ||
21565                         error "$delta files migrated >= $((200 / (i - 1) + 4))"
21566         done
21567 }
21568 run_test 230o "dir split"
21569
21570 test_230p() {
21571         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
21572         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
21573                 skip "Need MDS version at least 2.13.52"
21574
21575         local mdts=$(comma_list $(mdts_nodes))
21576         local timeout=100
21577         local restripe_status
21578         local delta
21579         local c
21580
21581         [[ $mds1_FSTYPE == zfs ]] && timeout=300
21582
21583         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
21584
21585         restripe_status=$(do_facet mds1 $LCTL get_param -n \
21586                            mdt.*MDT0000.enable_dir_restripe)
21587         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
21588         stack_trap "do_nodes $mdts $LCTL set_param \
21589                     mdt.*.enable_dir_restripe=$restripe_status"
21590
21591         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir
21592         createmany -m $DIR/$tdir/f 100 ||
21593                 error "create files under remote dir failed"
21594         createmany -d $DIR/$tdir/d 100 ||
21595                 error "create dirs under remote dir failed"
21596
21597         for c in $(seq $((MDSCOUNT - 1)) -1 1); do
21598                 local mdt_hash="crush"
21599
21600                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
21601                 $LFS setdirstripe -c $c $DIR/$tdir ||
21602                         error "split -c $c $tdir failed"
21603                 if (( MDS1_VERSION >= $(version_code 2.14.51) )); then
21604                         mdt_hash="$mdt_hash,fixed"
21605                 elif [ $c -eq 1 ]; then
21606                         mdt_hash="none"
21607                 fi
21608                 wait_update $HOSTNAME \
21609                         "$LFS getdirstripe -H $DIR/$tdir" $mdt_hash $timeout ||
21610                         error "dir merge not finished"
21611                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
21612                         awk '/migrate/ {sum += $2} END { print sum }')
21613                 echo "$delta migrated when dir merge $((c + 1)) to $c stripes"
21614                 # delta is around total_files/stripe_count
21615                 (( delta < 200 / c + 4 )) ||
21616                         error "$delta files migrated >= $((200 / c + 4))"
21617         done
21618 }
21619 run_test 230p "dir merge"
21620
21621 test_230q() {
21622         (( MDSCOUNT > 1)) || skip "needs >= 2 MDTs"
21623         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
21624                 skip "Need MDS version at least 2.13.52"
21625
21626         local mdts=$(comma_list $(mdts_nodes))
21627         local saved_threshold=$(do_facet mds1 \
21628                         $LCTL get_param -n mdt.*-MDT0000.dir_split_count)
21629         local saved_delta=$(do_facet mds1 \
21630                         $LCTL get_param -n mdt.*-MDT0000.dir_split_delta)
21631         local threshold=100
21632         local delta=2
21633         local total=0
21634         local stripe_count=0
21635         local stripe_index
21636         local nr_files
21637         local create
21638
21639         # test with fewer files on ZFS
21640         [ "$mds1_FSTYPE" == "zfs" ] && threshold=40
21641
21642         stack_trap "do_nodes $mdts $LCTL set_param \
21643                     mdt.*.dir_split_count=$saved_threshold"
21644         stack_trap "do_nodes $mdts $LCTL set_param \
21645                     mdt.*.dir_split_delta=$saved_delta"
21646         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.dir_restripe_nsonly=1"
21647         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_auto_split=1"
21648         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_count=$threshold"
21649         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_delta=$delta"
21650         do_nodes $mdts "$LCTL set_param mdt.*.dir_restripe_nsonly=0"
21651         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
21652
21653         $LFS mkdir -i -1 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
21654         stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
21655
21656         create=$((threshold * 3 / 2))
21657         while [ $stripe_count -lt $MDSCOUNT ]; do
21658                 createmany -m $DIR/$tdir/f $total $create ||
21659                         error "create sub files failed"
21660                 stat $DIR/$tdir > /dev/null
21661                 total=$((total + create))
21662                 stripe_count=$((stripe_count + delta))
21663                 [ $stripe_count -gt $MDSCOUNT ] && stripe_count=$MDSCOUNT
21664
21665                 wait_update $HOSTNAME \
21666                         "$LFS getdirstripe -c $DIR/$tdir" "$stripe_count" 40 ||
21667                         error "stripe count $($LFS getdirstripe -c $DIR/$tdir) != $stripe_count"
21668
21669                 wait_update $HOSTNAME \
21670                         "$LFS getdirstripe -H $DIR/$tdir" "crush" 200 ||
21671                         error "stripe hash $($LFS getdirstripe -H $DIR/$tdir) != crush"
21672
21673                 nr_files=$($LFS find -m 1 $DIR/$tdir | grep -c -w $stripe_index)
21674                 echo "$nr_files/$total files on MDT$stripe_index after split"
21675                 # allow 10% margin of imbalance with crush hash
21676                 (( $nr_files <= $total / $stripe_count + $create / 10)) ||
21677                         error "$nr_files files on MDT$stripe_index after split"
21678
21679                 nr_files=$($LFS find -type f $DIR/$tdir | wc -l)
21680                 [ $nr_files -eq $total ] ||
21681                         error "total sub files $nr_files != $total"
21682         done
21683
21684         (( MDS1_VERSION >= $(version_code 2.14.51) )) || return 0
21685
21686         echo "fixed layout directory won't auto split"
21687         $LFS migrate -m 0 $DIR/$tdir || error "migrate $tdir failed"
21688         wait_update $HOSTNAME "$LFS getdirstripe -H $DIR/$tdir" "crush,fixed" \
21689                 10 || error "stripe hash $($LFS getdirstripe -H $DIR/$tdir)"
21690         wait_update $HOSTNAME "$LFS getdirstripe -c $DIR/$tdir" 1 10 ||
21691                 error "stripe count $($LFS getdirstripe -c $DIR/$tdir)"
21692 }
21693 run_test 230q "dir auto split"
21694
21695 test_230r() {
21696         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
21697         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
21698         [[ $MDS1_VERSION -ge $(version_code 2.13.54) ]] ||
21699                 skip "Need MDS version at least 2.13.54"
21700
21701         # maximum amount of local locks:
21702         # parent striped dir - 2 locks
21703         # new stripe in parent to migrate to - 1 lock
21704         # source and target - 2 locks
21705         # Total 5 locks for regular file
21706         mkdir -p $DIR/$tdir
21707         $LFS mkdir -i1 -c2 $DIR/$tdir/dir1
21708         touch $DIR/$tdir/dir1/eee
21709
21710         # create 4 hardlink for 4 more locks
21711         # Total: 9 locks > RS_MAX_LOCKS (8)
21712         $LFS mkdir -i1 -c1 $DIR/$tdir/dir2
21713         $LFS mkdir -i1 -c1 $DIR/$tdir/dir3
21714         $LFS mkdir -i1 -c1 $DIR/$tdir/dir4
21715         $LFS mkdir -i1 -c1 $DIR/$tdir/dir5
21716         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir2/eee
21717         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir3/eee
21718         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir4/eee
21719         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir5/eee
21720
21721         cancel_lru_locks mdc
21722
21723         $LFS migrate -m1 -c1 $DIR/$tdir/dir1 ||
21724                 error "migrate dir fails"
21725
21726         rm -rf $DIR/$tdir || error "rm dir failed after migration"
21727 }
21728 run_test 230r "migrate with too many local locks"
21729
21730 test_230s() {
21731         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
21732                 skip "Need MDS version at least 2.14.52"
21733
21734         local mdts=$(comma_list $(mdts_nodes))
21735         local restripe_status=$(do_facet mds1 $LCTL get_param -n \
21736                                 mdt.*MDT0000.enable_dir_restripe)
21737
21738         stack_trap "do_nodes $mdts $LCTL set_param \
21739                     mdt.*.enable_dir_restripe=$restripe_status"
21740
21741         local st
21742         for st in 0 1; do
21743                 do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=$st"
21744                 test_mkdir $DIR/$tdir
21745                 $LFS mkdir $DIR/$tdir |& grep "File exists" ||
21746                         error "$LFS mkdir should return EEXIST if target exists"
21747                 rmdir $DIR/$tdir
21748         done
21749 }
21750 run_test 230s "lfs mkdir should return -EEXIST if target exists"
21751
21752 test_230t()
21753 {
21754         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
21755         [[ $MDS1_VERSION -ge $(version_code 2.14.50) ]] ||
21756                 skip "Need MDS version at least 2.14.50"
21757
21758         test_mkdir $DIR/$tdir || error "mkdir $tdir failed"
21759         test_mkdir $DIR/$tdir/subdir || error "mkdir subdir failed"
21760         $LFS project -p 1 -s $DIR/$tdir ||
21761                 error "set $tdir project id failed"
21762         $LFS project -p 2 -s $DIR/$tdir/subdir ||
21763                 error "set subdir project id failed"
21764         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir || error "migrate failed"
21765 }
21766 run_test 230t "migrate directory with project ID set"
21767
21768 test_230u()
21769 {
21770         (( MDSCOUNT > 3 )) || skip_env "needs >= 4 MDTs"
21771         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
21772                 skip "Need MDS version at least 2.14.53"
21773
21774         local count
21775
21776         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
21777         mkdir $DIR/$tdir/sub{0..99} || error "mkdir sub failed"
21778         $LFS migrate -m -1 $DIR/$tdir/sub{0..99} || error "migrate sub failed"
21779         for i in $(seq 0 $((MDSCOUNT - 1))); do
21780                 count=$($LFS getstripe -m $DIR/$tdir/sub* | grep -c ^$i)
21781                 echo "$count dirs migrated to MDT$i"
21782         done
21783         count=$($LFS getstripe -m $DIR/$tdir/sub* | sort -u | wc -l)
21784         (( count >= MDSCOUNT - 1 )) || error "dirs migrated to $count MDTs"
21785 }
21786 run_test 230u "migrate directory by QOS"
21787
21788 test_230v()
21789 {
21790         (( MDSCOUNT > 3 )) || skip_env "needs >= 4 MDTs"
21791         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
21792                 skip "Need MDS version at least 2.14.53"
21793
21794         local count
21795
21796         mkdir $DIR/$tdir || error "mkdir $tdir failed"
21797         mkdir $DIR/$tdir/sub{0..99} || error "mkdir sub failed"
21798         $LFS migrate -m 0,2,1 $DIR/$tdir || error "migrate $tdir failed"
21799         for i in $(seq 0 $((MDSCOUNT - 1))); do
21800                 count=$($LFS getstripe -m $DIR/$tdir/sub* | grep -c ^$i)
21801                 echo "$count subdirs migrated to MDT$i"
21802                 (( i == 3 )) && (( count > 0 )) &&
21803                         error "subdir shouldn't be migrated to MDT3"
21804         done
21805         count=$($LFS getstripe -m $DIR/$tdir/sub* | sort -u | wc -l)
21806         (( count == 3 )) || error "dirs migrated to $count MDTs"
21807 }
21808 run_test 230v "subdir migrated to the MDT where its parent is located"
21809
21810 test_230w() {
21811         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
21812         (( MDS1_VERSION >= $(version_code 2.15.0) )) ||
21813                 skip "Need MDS version at least 2.15.0"
21814
21815         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
21816         createmany -o $DIR/$tdir/f 10 || error "create files failed"
21817         createmany -d $DIR/$tdir/d 10 || error "create dirs failed"
21818
21819         $LFS migrate -m 1 -c $MDSCOUNT -d $DIR/$tdir ||
21820                 error "migrate failed"
21821
21822         (( $($LFS getdirstripe -c $DIR/$tdir) == MDSCOUNT )) ||
21823                 error "$tdir stripe count mismatch"
21824
21825         for i in $(seq 0 9); do
21826                 (( $($LFS getdirstripe -c $DIR/$tdir/d$i) == 0 )) ||
21827                         error "d$i is striped"
21828         done
21829 }
21830 run_test 230w "non-recursive mode dir migration"
21831
21832 test_230x() {
21833         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
21834         (( MDS1_VERSION >= $(version_code 2.15.0) )) ||
21835                 skip "Need MDS version at least 2.15.0"
21836
21837         mkdir -p $DIR/$tdir || error "mkdir failed"
21838         createmany -d $DIR/$tdir/sub 100 || error "createmany failed"
21839
21840         local mdt_name=$(mdtname_from_index 0)
21841         local low=$(do_facet mds2 $LCTL get_param -n \
21842                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low)
21843         local high=$(do_facet mds2 $LCTL get_param -n \
21844                 osp.*$mdt_name-osp-MDT0001.reserved_ino_high)
21845         local ffree=$($LFS df -i $MOUNT | awk "/$mdt_name/ { print \$4 }")
21846         local maxage=$(do_facet mds2 $LCTL get_param -n \
21847                 osp.*$mdt_name-osp-MDT0001.maxage)
21848
21849         stack_trap "do_facet mds2 $LCTL set_param -n \
21850                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low=$low \
21851                 osp.*$mdt_name-osp-MDT0001.reserved_ino_high=$high" EXIT
21852         stack_trap "do_facet mds2 $LCTL set_param -n \
21853                 osp.*$mdt_name-osp-MDT0001.maxage=$maxage" EXIT
21854
21855         do_facet mds2 $LCTL set_param -n \
21856                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low=$((ffree + 1))
21857         do_facet mds2 $LCTL set_param -n osp.*$mdt_name-osp-MDT0001.maxage=1
21858         sleep 4
21859         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir &&
21860                 error "migrate $tdir should fail"
21861
21862         do_facet mds2 $LCTL set_param -n \
21863                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low=$low
21864         do_facet mds2 $LCTL set_param -n \
21865                 osp.*$mdt_name-osp-MDT0001.reserved_ino_high=$high
21866         sleep 4
21867         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir ||
21868                 error "migrate failed"
21869         (( $($LFS getdirstripe -c $DIR/$tdir) == $MDSCOUNT )) ||
21870                 error "$tdir stripe count mismatch"
21871 }
21872 run_test 230x "dir migration check space"
21873
21874 test_230y() {
21875         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
21876         (( MDS1_VERSION >= $(version_code 2.15.55.45) )) ||
21877                 skip "Need MDS version at least 2.15.55.45"
21878
21879         local pid
21880
21881         test_mkdir -c -1 $DIR/$tdir || error "mkdir $tdir failed"
21882         $LFS getdirstripe $DIR/$tdir
21883         createmany -d $DIR/$tdir/d 100 || error "createmany failed"
21884         $LFS migrate -m 1 -c 2 $DIR/$tdir &
21885         pid=$!
21886         sleep 1
21887
21888         #OBD_FAIL_MIGRATE_BAD_HASH      0x1802
21889         do_facet mds2 lctl set_param fail_loc=0x1802
21890
21891         wait $pid
21892         do_facet mds2 lctl set_param fail_loc=0
21893         $LFS getdirstripe $DIR/$tdir
21894         unlinkmany -d $DIR/$tdir/d 100 || error "unlinkmany failed"
21895         rmdir $DIR/$tdir || error "rmdir $tdir failed"
21896 }
21897 run_test 230y "unlink dir with bad hash type"
21898
21899 test_230z() {
21900         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
21901         (( MDS1_VERSION >= $(version_code 2.15.55.45) )) ||
21902                 skip "Need MDS version at least 2.15.55.45"
21903
21904         local pid
21905
21906         test_mkdir -c -1 $DIR/$tdir || error "mkdir $tdir failed"
21907         $LFS getdirstripe $DIR/$tdir
21908         createmany -d $DIR/$tdir/d 100 || error "createmany failed"
21909         $LFS migrate -m 1 -c 2 -H fnv_1a_64 $DIR/$tdir &
21910         pid=$!
21911         sleep 1
21912
21913         #OBD_FAIL_MIGRATE_BAD_HASH      0x1802
21914         do_facet mds2 lctl set_param fail_loc=0x1802
21915
21916         wait $pid
21917         do_facet mds2 lctl set_param fail_loc=0
21918         $LFS getdirstripe $DIR/$tdir
21919
21920         # resume migration
21921         $LFS migrate -m 1 -c 2 -H fnv_1a_64 $DIR/$tdir ||
21922                 error "resume migration failed"
21923         $LFS getdirstripe $DIR/$tdir
21924         [ $($LFS getdirstripe -H $DIR/$tdir) == "fnv_1a_64,fixed" ] ||
21925                 error "migration is not finished"
21926 }
21927 run_test 230z "resume dir migration with bad hash type"
21928
21929 test_231a()
21930 {
21931         # For simplicity this test assumes that max_pages_per_rpc
21932         # is the same across all OSCs
21933         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
21934         local bulk_size=$((max_pages * PAGE_SIZE))
21935         local brw_size=$(do_facet ost1 $LCTL get_param -n obdfilter.*.brw_size |
21936                                        head -n 1)
21937
21938         mkdir -p $DIR/$tdir
21939         $LFS setstripe -S ${brw_size}M $DIR/$tdir ||
21940                 error "failed to set stripe with -S ${brw_size}M option"
21941         stack_trap "rm -rf $DIR/$tdir"
21942
21943         # clear the OSC stats
21944         $LCTL set_param osc.*.stats=0 &>/dev/null
21945         stop_writeback
21946
21947         # Client writes $bulk_size - there must be 1 rpc for $max_pages.
21948         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=$bulk_size count=1 \
21949                 oflag=direct &>/dev/null || error "dd failed"
21950
21951         sync; sleep 1; sync # just to be safe
21952         local nrpcs=$($LCTL get_param osc.*.stats |awk '/ost_write/ {print $2}')
21953         if [ x$nrpcs != "x1" ]; then
21954                 $LCTL get_param osc.*.stats
21955                 error "found $nrpcs ost_write RPCs, not 1 as expected"
21956         fi
21957
21958         start_writeback
21959         # Drop the OSC cache, otherwise we will read from it
21960         cancel_lru_locks osc
21961
21962         # clear the OSC stats
21963         $LCTL set_param osc.*.stats=0 &>/dev/null
21964
21965         # Client reads $bulk_size.
21966         dd if=$DIR/$tdir/$tfile of=/dev/null bs=$bulk_size count=1 \
21967                 iflag=direct &>/dev/null || error "dd failed"
21968
21969         nrpcs=$($LCTL get_param osc.*.stats | awk '/ost_read/ { print $2 }')
21970         if [ x$nrpcs != "x1" ]; then
21971                 $LCTL get_param osc.*.stats
21972                 error "found $nrpcs ost_read RPCs, not 1 as expected"
21973         fi
21974 }
21975 run_test 231a "checking that reading/writing of BRW RPC size results in one RPC"
21976
21977 test_231b() {
21978         mkdir -p $DIR/$tdir
21979         stack_trap "rm -rf $DIR/$tdir"
21980         local i
21981         for i in {0..1023}; do
21982                 dd if=/dev/zero of=$DIR/$tdir/$tfile conv=notrunc \
21983                         seek=$((2 * i)) bs=4096 count=1 &>/dev/null ||
21984                         error "dd of=$DIR/$tdir/$tfile seek=$((2 * i)) failed"
21985         done
21986         sync
21987 }
21988 run_test 231b "must not assert on fully utilized OST request buffer"
21989
21990 test_232a() {
21991         mkdir -p $DIR/$tdir
21992         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
21993
21994         #define OBD_FAIL_LDLM_OST_LVB            0x31c
21995         do_facet ost1 $LCTL set_param fail_loc=0x31c
21996
21997         # ignore dd failure
21998         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1 || true
21999         stack_trap "rm -f $DIR/$tdir/$tfile"
22000
22001         do_facet ost1 $LCTL set_param fail_loc=0
22002         umount_client $MOUNT || error "umount failed"
22003         mount_client $MOUNT || error "mount failed"
22004         stop ost1 || error "cannot stop ost1"
22005         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
22006 }
22007 run_test 232a "failed lock should not block umount"
22008
22009 test_232b() {
22010         [ $MDS1_VERSION -ge $(version_code 2.10.58) ] ||
22011                 skip "Need MDS version at least 2.10.58"
22012
22013         mkdir -p $DIR/$tdir
22014         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
22015         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1
22016         stack_trap "rm -f $DIR/$tdir/$tfile"
22017         sync
22018         cancel_lru_locks osc
22019
22020         #define OBD_FAIL_LDLM_OST_LVB            0x31c
22021         do_facet ost1 $LCTL set_param fail_loc=0x31c
22022
22023         # ignore failure
22024         $LFS data_version $DIR/$tdir/$tfile || true
22025
22026         do_facet ost1 $LCTL set_param fail_loc=0
22027         umount_client $MOUNT || error "umount failed"
22028         mount_client $MOUNT || error "mount failed"
22029         stop ost1 || error "cannot stop ost1"
22030         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
22031 }
22032 run_test 232b "failed data version lock should not block umount"
22033
22034 test_233a() {
22035         [ $MDS1_VERSION -ge $(version_code 2.3.64) ] ||
22036                 skip "Need MDS version at least 2.3.64"
22037         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
22038
22039         local fid=$($LFS path2fid $MOUNT)
22040
22041         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
22042                 error "cannot access $MOUNT using its FID '$fid'"
22043 }
22044 run_test 233a "checking that OBF of the FS root succeeds"
22045
22046 test_233b() {
22047         [ $MDS1_VERSION -ge $(version_code 2.5.90) ] ||
22048                 skip "Need MDS version at least 2.5.90"
22049         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
22050
22051         local fid=$($LFS path2fid $MOUNT/.lustre)
22052
22053         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
22054                 error "cannot access $MOUNT/.lustre using its FID '$fid'"
22055
22056         fid=$($LFS path2fid $MOUNT/.lustre/fid)
22057         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
22058                 error "cannot access $MOUNT/.lustre/fid using its FID '$fid'"
22059 }
22060 run_test 233b "checking that OBF of the FS .lustre succeeds"
22061
22062 test_234() {
22063         local p="$TMP/sanityN-$TESTNAME.parameters"
22064         save_lustre_params client "llite.*.xattr_cache" > $p
22065         lctl set_param llite.*.xattr_cache 1 ||
22066                 skip_env "xattr cache is not supported"
22067
22068         mkdir -p $DIR/$tdir || error "mkdir failed"
22069         touch $DIR/$tdir/$tfile || error "touch failed"
22070         # OBD_FAIL_LLITE_XATTR_ENOMEM
22071         $LCTL set_param fail_loc=0x1405
22072         getfattr -n user.attr $DIR/$tdir/$tfile &&
22073                 error "getfattr should have failed with ENOMEM"
22074         $LCTL set_param fail_loc=0x0
22075         rm -rf $DIR/$tdir
22076
22077         restore_lustre_params < $p
22078         rm -f $p
22079 }
22080 run_test 234 "xattr cache should not crash on ENOMEM"
22081
22082 test_235() {
22083         [ $MDS1_VERSION -lt $(version_code 2.4.52) ] &&
22084                 skip "Need MDS version at least 2.4.52"
22085
22086         flock_deadlock $DIR/$tfile
22087         local RC=$?
22088         case $RC in
22089                 0)
22090                 ;;
22091                 124) error "process hangs on a deadlock"
22092                 ;;
22093                 *) error "error executing flock_deadlock $DIR/$tfile"
22094                 ;;
22095         esac
22096 }
22097 run_test 235 "LU-1715: flock deadlock detection does not work properly"
22098
22099 #LU-2935
22100 test_236() {
22101         check_swap_layouts_support
22102
22103         local ref1=/etc/passwd
22104         local ref2=/etc/group
22105         local file1=$DIR/$tdir/f1
22106         local file2=$DIR/$tdir/f2
22107
22108         test_mkdir -c1 $DIR/$tdir
22109         $LFS setstripe -c 1 $file1 || error "cannot setstripe on '$file1': rc = $?"
22110         cp $ref1 $file1 || error "cp $ref1 $file1 failed: rc = $?"
22111         $LFS setstripe -c 2 $file2 || error "cannot setstripe on '$file2': rc = $?"
22112         cp $ref2 $file2 || error "cp $ref2 $file2 failed: rc = $?"
22113         local fd=$(free_fd)
22114         local cmd="exec $fd<>$file2"
22115         eval $cmd
22116         rm $file2
22117         $LFS swap_layouts $file1 /proc/self/fd/${fd} ||
22118                 error "cannot swap layouts of '$file1' and /proc/self/fd/${fd}"
22119         cmd="exec $fd>&-"
22120         eval $cmd
22121         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
22122
22123         #cleanup
22124         rm -rf $DIR/$tdir
22125 }
22126 run_test 236 "Layout swap on open unlinked file"
22127
22128 # LU-4659 linkea consistency
22129 test_238() {
22130         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
22131                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
22132                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
22133                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
22134
22135         touch $DIR/$tfile
22136         ln $DIR/$tfile $DIR/$tfile.lnk
22137         touch $DIR/$tfile.new
22138         mv $DIR/$tfile.new $DIR/$tfile
22139         local fid1=$($LFS path2fid $DIR/$tfile)
22140         local fid2=$($LFS path2fid $DIR/$tfile.lnk)
22141         local path1=$($LFS fid2path $FSNAME "$fid1")
22142         [ $tfile == $path1 ] || error "linkea inconsistent: $tfile $fid1 $path1"
22143         local path2=$($LFS fid2path $FSNAME "$fid2")
22144         [ $tfile.lnk == $path2 ] ||
22145                 error "linkea inconsistent: $tfile.lnk $fid2 $path2!"
22146         rm -f $DIR/$tfile*
22147 }
22148 run_test 238 "Verify linkea consistency"
22149
22150 test_239A() { # was test_239
22151         [ $MDS1_VERSION -lt $(version_code 2.5.60) ] &&
22152                 skip "Need MDS version at least 2.5.60"
22153
22154         local list=$(comma_list $(mdts_nodes))
22155
22156         mkdir -p $DIR/$tdir
22157         createmany -o $DIR/$tdir/f- 5000
22158         unlinkmany $DIR/$tdir/f- 5000
22159         [ $MDS1_VERSION -gt $(version_code 2.10.4) ] &&
22160                 do_nodes $list "lctl set_param -n osp.*.force_sync=1"
22161         changes=$(do_nodes $list "lctl get_param -n osp.*MDT*.sync_changes \
22162                         osp.*MDT*.sync_in_flight" | calc_sum)
22163         [ "$changes" -eq 0 ] || error "$changes not synced"
22164 }
22165 run_test 239A "osp_sync test"
22166
22167 test_239a() { #LU-5297
22168         remote_mds_nodsh && skip "remote MDS with nodsh"
22169
22170         touch $DIR/$tfile
22171         #define OBD_FAIL_OSP_CHECK_INVALID_REC     0x2100
22172         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2100
22173         chgrp $RUNAS_GID $DIR/$tfile
22174         wait_delete_completed
22175 }
22176 run_test 239a "process invalid osp sync record correctly"
22177
22178 test_239b() { #LU-5297
22179         remote_mds_nodsh && skip "remote MDS with nodsh"
22180
22181         touch $DIR/$tfile1
22182         #define OBD_FAIL_OSP_CHECK_ENOMEM     0x2101
22183         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2101
22184         chgrp $RUNAS_GID $DIR/$tfile1
22185         wait_delete_completed
22186         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
22187         touch $DIR/$tfile2
22188         chgrp $RUNAS_GID $DIR/$tfile2
22189         wait_delete_completed
22190 }
22191 run_test 239b "process osp sync record with ENOMEM error correctly"
22192
22193 test_240() {
22194         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22195         remote_mds_nodsh && skip "remote MDS with nodsh"
22196
22197         mkdir -p $DIR/$tdir
22198
22199         $LFS mkdir -i 0 $DIR/$tdir/d0 ||
22200                 error "failed to mkdir $DIR/$tdir/d0 on MDT0"
22201         $LFS mkdir -i 1 $DIR/$tdir/d0/d1 ||
22202                 error "failed to mkdir $DIR/$tdir/d0/d1 on MDT1"
22203
22204         umount_client $MOUNT || error "umount failed"
22205         #define OBD_FAIL_TGT_DELAY_CONDITIONAL   0x713
22206         do_facet mds2 lctl set_param fail_loc=0x713 fail_val=1
22207         mount_client $MOUNT || error "failed to mount client"
22208
22209         echo "stat $DIR/$tdir/d0/d1, should not fail/ASSERT"
22210         stat $DIR/$tdir/d0/d1 || error "fail to stat $DIR/$tdir/d0/d1"
22211 }
22212 run_test 240 "race between ldlm enqueue and the connection RPC (no ASSERT)"
22213
22214 test_241_bio() {
22215         local count=$1
22216         local bsize=$2
22217
22218         for LOOP in $(seq $count); do
22219                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 2>/dev/null
22220                 cancel_lru_locks $OSC || true
22221         done
22222 }
22223
22224 test_241_dio() {
22225         local count=$1
22226         local bsize=$2
22227
22228         for LOOP in $(seq $1); do
22229                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 iflag=direct \
22230                         2>/dev/null
22231         done
22232 }
22233
22234 test_241a() { # was test_241
22235         local bsize=$PAGE_SIZE
22236
22237         (( bsize < 40960 )) && bsize=40960
22238         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
22239         ls -la $DIR/$tfile
22240         cancel_lru_locks $OSC
22241         test_241_bio 1000 $bsize &
22242         PID=$!
22243         test_241_dio 1000 $bsize
22244         wait $PID
22245 }
22246 run_test 241a "bio vs dio"
22247
22248 test_241b() {
22249         local bsize=$PAGE_SIZE
22250
22251         (( bsize < 40960 )) && bsize=40960
22252         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
22253         ls -la $DIR/$tfile
22254         test_241_dio 1000 $bsize &
22255         PID=$!
22256         test_241_dio 1000 $bsize
22257         wait $PID
22258 }
22259 run_test 241b "dio vs dio"
22260
22261 test_242() {
22262         remote_mds_nodsh && skip "remote MDS with nodsh"
22263
22264         mkdir_on_mdt0 $DIR/$tdir
22265         touch $DIR/$tdir/$tfile
22266
22267         #define OBD_FAIL_MDS_READPAGE_PACK      0x105
22268         do_facet mds1 lctl set_param fail_loc=0x105
22269         /bin/ls $DIR/$tdir && error "ls $DIR/$tdir should fail"
22270
22271         do_facet mds1 lctl set_param fail_loc=0
22272         /bin/ls $DIR/$tdir || error "ls $DIR/$tdir failed"
22273 }
22274 run_test 242 "mdt_readpage failure should not cause directory unreadable"
22275
22276 test_243()
22277 {
22278         test_mkdir $DIR/$tdir
22279         group_lock_test -d $DIR/$tdir || error "A group lock test failed"
22280 }
22281 run_test 243 "various group lock tests"
22282
22283 test_244a()
22284 {
22285         test_mkdir $DIR/$tdir
22286         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=35
22287         sendfile_grouplock $DIR/$tdir/$tfile || \
22288                 error "sendfile+grouplock failed"
22289         rm -rf $DIR/$tdir
22290 }
22291 run_test 244a "sendfile with group lock tests"
22292
22293 test_244b()
22294 {
22295         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
22296
22297         local threads=50
22298         local size=$((1024*1024))
22299
22300         test_mkdir $DIR/$tdir
22301         for i in $(seq 1 $threads); do
22302                 local file=$DIR/$tdir/file_$((i / 10))
22303                 $MULTIOP $file OG1234w$size_$((i % 3))w$size_$((i % 4))g1234c &
22304                 local pids[$i]=$!
22305         done
22306         for i in $(seq 1 $threads); do
22307                 wait ${pids[$i]}
22308         done
22309 }
22310 run_test 244b "multi-threaded write with group lock"
22311
22312 test_245a() {
22313         local flagname="multi_mod_rpcs"
22314         local connect_data_name="max_mod_rpcs"
22315         local out
22316
22317         # check if multiple modify RPCs flag is set
22318         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import |
22319                 grep "connect_flags:")
22320         echo "$out"
22321
22322         echo "$out" | grep -qw $flagname
22323         if [ $? -ne 0 ]; then
22324                 echo "connect flag $flagname is not set"
22325                 return
22326         fi
22327
22328         # check if multiple modify RPCs data is set
22329         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import)
22330         echo "$out"
22331
22332         echo "$out" | grep -qw $connect_data_name ||
22333                 error "import should have connect data $connect_data_name"
22334 }
22335 run_test 245a "check mdc connection flag/data: multiple modify RPCs"
22336
22337 test_245b() {
22338         local flagname="multi_mod_rpcs"
22339         local connect_data_name="max_mod_rpcs"
22340         local out
22341
22342         remote_mds_nodsh && skip "remote MDS with nodsh"
22343         [[ $MDSCOUNT -ge 2 ]] || skip "needs >= 2 MDTs"
22344
22345         # check if multiple modify RPCs flag is set
22346         out=$(do_facet mds1 \
22347               $LCTL get_param osp.$FSNAME-MDT0001-osp-MDT0000.import |
22348               grep "connect_flags:")
22349         echo "$out"
22350
22351         [[ "$out" =~ $flagname ]] || skip "connect flag $flagname is not set"
22352
22353         # check if multiple modify RPCs data is set
22354         out=$(do_facet mds1 \
22355               $LCTL get_param osp.$FSNAME-MDT0001-osp-MDT0000.import)
22356
22357         [[ "$out" =~ $connect_data_name ]] ||
22358                 {
22359                         echo "$out"
22360                         error "missing connect data $connect_data_name"
22361                 }
22362 }
22363 run_test 245b "check osp connection flag/data: multiple modify RPCs"
22364
22365 cleanup_247() {
22366         local submount=$1
22367
22368         trap 0
22369         umount_client $submount
22370         rmdir $submount
22371 }
22372
22373 test_247a() {
22374         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
22375                 grep -q subtree ||
22376                 skip_env "Fileset feature is not supported"
22377
22378         local submount=${MOUNT}_$tdir
22379
22380         mkdir $MOUNT/$tdir
22381         mkdir -p $submount || error "mkdir $submount failed"
22382         FILESET="$FILESET/$tdir" mount_client $submount ||
22383                 error "mount $submount failed"
22384         trap "cleanup_247 $submount" EXIT
22385         echo foo > $submount/$tfile || error "write $submount/$tfile failed"
22386         [ $(cat $MOUNT/$tdir/$tfile) = "foo" ] ||
22387                 error "read $MOUNT/$tdir/$tfile failed"
22388         cleanup_247 $submount
22389 }
22390 run_test 247a "mount subdir as fileset"
22391
22392 test_247b() {
22393         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
22394                 skip_env "Fileset feature is not supported"
22395
22396         local submount=${MOUNT}_$tdir
22397
22398         rm -rf $MOUNT/$tdir
22399         mkdir -p $submount || error "mkdir $submount failed"
22400         SKIP_FILESET=1
22401         FILESET="$FILESET/$tdir" mount_client $submount &&
22402                 error "mount $submount should fail"
22403         rmdir $submount
22404 }
22405 run_test 247b "mount subdir that dose not exist"
22406
22407 test_247c() {
22408         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
22409                 skip_env "Fileset feature is not supported"
22410
22411         local submount=${MOUNT}_$tdir
22412
22413         mkdir -p $MOUNT/$tdir/dir1
22414         mkdir -p $submount || error "mkdir $submount failed"
22415         trap "cleanup_247 $submount" EXIT
22416         FILESET="$FILESET/$tdir" mount_client $submount ||
22417                 error "mount $submount failed"
22418         local fid=$($LFS path2fid $MOUNT/)
22419         $LFS fid2path $submount $fid && error "fid2path should fail"
22420         cleanup_247 $submount
22421 }
22422 run_test 247c "running fid2path outside subdirectory root"
22423
22424 test_247d() {
22425         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
22426                 skip "Fileset feature is not supported"
22427
22428         local submount=${MOUNT}_$tdir
22429
22430         mkdir -p $MOUNT/$tdir/dir1
22431         mkdir -p $submount || error "mkdir $submount failed"
22432         FILESET="$FILESET/$tdir" mount_client $submount ||
22433                 error "mount $submount failed"
22434         trap "cleanup_247 $submount" EXIT
22435
22436         local td=$submount/dir1
22437         local fid=$($LFS path2fid $td)
22438         [ -z "$fid" ] && error "path2fid unable to get $td FID"
22439
22440         # check that we get the same pathname back
22441         local rootpath
22442         local found
22443         for rootpath in "$submount" "$submount///" "$submount/dir1"; do
22444                 echo "$rootpath $fid"
22445                 found=$($LFS fid2path $rootpath "$fid")
22446                 [ -n "$found" ] || error "fid2path should succeed"
22447                 [ "$found" == "$td" ] || error "fid2path $found != $td"
22448         done
22449         # check wrong root path format
22450         rootpath=$submount"_wrong"
22451         found=$($LFS fid2path $rootpath "$fid")
22452         [ -z "$found" ] || error "fid2path should fail ($rootpath != $submount)"
22453
22454         cleanup_247 $submount
22455 }
22456 run_test 247d "running fid2path inside subdirectory root"
22457
22458 # LU-8037
22459 test_247e() {
22460         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
22461                 grep -q subtree ||
22462                 skip "Fileset feature is not supported"
22463
22464         local submount=${MOUNT}_$tdir
22465
22466         mkdir $MOUNT/$tdir
22467         mkdir -p $submount || error "mkdir $submount failed"
22468         FILESET="$FILESET/.." mount_client $submount &&
22469                 error "mount $submount should fail"
22470         rmdir $submount
22471 }
22472 run_test 247e "mount .. as fileset"
22473
22474 test_247f() {
22475         (( $MDSCOUNT > 1 )) || skip_env "needs >= 2 MDTs"
22476         (( $MDS1_VERSION >= $(version_code 2.14.50.162) )) ||
22477                 skip "Need at least version 2.14.50.162"
22478         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
22479                 skip "Fileset feature is not supported"
22480
22481         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
22482         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote ||
22483                 error "mkdir remote failed"
22484         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote/subdir ||
22485                 error "mkdir remote/subdir failed"
22486         $LFS mkdir -i 0 -c $MDSCOUNT $DIR/$tdir/striped ||
22487                 error "mkdir striped failed"
22488         mkdir $DIR/$tdir/striped/subdir || error "mkdir striped/subdir failed"
22489
22490         local submount=${MOUNT}_$tdir
22491
22492         mkdir -p $submount || error "mkdir $submount failed"
22493         stack_trap "rmdir $submount"
22494
22495         local dir
22496         local fileset=$FILESET
22497         local mdts=$(comma_list $(mdts_nodes))
22498
22499         do_nodes $mdts "$LCTL set_param mdt.*.enable_remote_subdir_mount=1"
22500         for dir in $tdir/remote $tdir/remote/subdir $tdir/striped \
22501                 $tdir/striped/subdir $tdir/striped/.; do
22502                 FILESET="$fileset/$dir" mount_client $submount ||
22503                         error "mount $dir failed"
22504                 umount_client $submount
22505         done
22506 }
22507 run_test 247f "mount striped or remote directory as fileset"
22508
22509 test_subdir_mount_lock()
22510 {
22511         local testdir=$1
22512         local submount=${MOUNT}_$(basename $testdir)
22513
22514         touch $DIR/$testdir/$tfile || error "touch $tfile failed"
22515
22516         mkdir -p $submount || error "mkdir $submount failed"
22517         stack_trap "rmdir $submount"
22518
22519         FILESET="$fileset/$testdir" mount_client $submount ||
22520                 error "mount $FILESET failed"
22521         stack_trap "umount $submount"
22522
22523         local mdts=$(comma_list $(mdts_nodes))
22524
22525         local nrpcs
22526
22527         stat $submount > /dev/null || error "stat $submount failed"
22528         cancel_lru_locks $MDC
22529         stat $submount > /dev/null || error "stat $submount failed"
22530         stat $submount/$tfile > /dev/null || error "stat $tfile failed"
22531         do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear > /dev/null"
22532         stat $submount/$tfile > /dev/null || error "stat $tfile failed"
22533         nrpcs=$(do_nodes $mdts "lctl get_param -n mdt.*.md_stats" |
22534                 awk '/getattr/ {sum += $2} END {print sum}')
22535
22536         [ -z "$nrpcs" ] || error "$nrpcs extra getattr sent"
22537 }
22538
22539 test_247g() {
22540         (( $MDSCOUNT > 1 )) || skip_env "needs > 1 MDTs"
22541
22542         $LFS mkdir -i 0 -c 4 -H fnv_1a_64 $DIR/$tdir ||
22543                 error "mkdir $tdir failed"
22544         test_subdir_mount_lock $tdir
22545 }
22546 run_test 247g "striped directory submount revalidate ROOT from cache"
22547
22548 test_247h() {
22549         (( $MDSCOUNT > 1 )) || skip_env "needs > 1 MDTs"
22550         (( $MDS1_VERSION >= $(version_code 2.15.51) )) ||
22551                 skip "Need MDS version at least 2.15.51"
22552
22553         $LFS mkdir -i 1 -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
22554         test_subdir_mount_lock $tdir
22555         mkdir_on_mdt -i 0 $DIR/$tdir/$tdir.0 || error "mkdir $tdir.0 failed"
22556         mkdir_on_mdt -i 1 $DIR/$tdir/$tdir.0/$tdir.1 ||
22557                 error "mkdir $tdir.1 failed"
22558         test_subdir_mount_lock $tdir/$tdir.0/$tdir.1
22559 }
22560 run_test 247h "remote directory submount revalidate ROOT from cache"
22561
22562 test_248a() {
22563         local fast_read_sav=$($LCTL get_param -n llite.*.fast_read 2>/dev/null)
22564         [ -z "$fast_read_sav" ] && skip "no fast read support"
22565
22566         # create a large file for fast read verification
22567         dd if=/dev/zero of=$DIR/$tfile bs=1M count=128 > /dev/null 2>&1
22568
22569         # make sure the file is created correctly
22570         $CHECKSTAT -s $((128*1024*1024)) $DIR/$tfile ||
22571                 { rm -f $DIR/$tfile; skip "file creation error"; }
22572
22573         echo "Test 1: verify that fast read is 4 times faster on cache read"
22574
22575         # small read with fast read enabled
22576         $LCTL set_param -n llite.*.fast_read=1
22577         local t_fast=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
22578                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
22579                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
22580         # small read with fast read disabled
22581         $LCTL set_param -n llite.*.fast_read=0
22582         local t_slow=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
22583                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
22584                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
22585
22586         # verify that fast read is 4 times faster for cache read
22587         [ $(bc <<< "4 * $t_fast < $t_slow") -eq 1 ] ||
22588                 error_not_in_vm "fast read was not 4 times faster: " \
22589                            "$t_fast vs $t_slow"
22590
22591         echo "Test 2: verify the performance between big and small read"
22592         $LCTL set_param -n llite.*.fast_read=1
22593
22594         # 1k non-cache read
22595         cancel_lru_locks osc
22596         local t_1k=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
22597                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
22598                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
22599
22600         # 1M non-cache read
22601         cancel_lru_locks osc
22602         local t_1m=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
22603                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
22604                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
22605
22606         # verify that big IO is not 4 times faster than small IO
22607         [ $(bc <<< "4 * $t_1k >= $t_1m") -eq 1 ] ||
22608                 error_not_in_vm "bigger IO is way too fast: $t_1k vs $t_1m"
22609
22610         $LCTL set_param -n llite.*.fast_read=$fast_read_sav
22611         rm -f $DIR/$tfile
22612 }
22613 run_test 248a "fast read verification"
22614
22615 test_248b() {
22616         # Default short_io_bytes=16384, try both smaller and larger sizes.
22617         # Lustre O_DIRECT read and write needs to be a multiple of PAGE_SIZE.
22618         # 6017024 = 2^12*13*113 = 47008*128 = 11752*512 = 4096*1469 = 53248*113
22619         echo "bs=53248 count=113 normal buffered write"
22620         dd if=/dev/urandom of=$TMP/$tfile.0 bs=53248 count=113 ||
22621                 error "dd of initial data file failed"
22622         stack_trap "rm -f $DIR/$tfile.[0-3] $TMP/$tfile.[0-3]" EXIT
22623
22624         echo "bs=47008 count=128 oflag=dsync normal write $tfile.0"
22625         dd if=$TMP/$tfile.0 of=$DIR/$tfile.0 bs=47008 count=128 oflag=dsync ||
22626                 error "dd with sync normal writes failed"
22627         cmp $TMP/$tfile.0 $DIR/$tfile.0 || error "compare $DIR/$tfile.0 failed"
22628
22629         echo "bs=11752 count=512 oflag=dsync small write $tfile.1"
22630         dd if=$TMP/$tfile.0 of=$DIR/$tfile.1 bs=11752 count=512 oflag=dsync ||
22631                 error "dd with sync small writes failed"
22632         cmp $TMP/$tfile.0 $DIR/$tfile.1 || error "compare $DIR/$tfile.1 failed"
22633
22634         cancel_lru_locks osc
22635
22636         # calculate the small O_DIRECT size and count for the client PAGE_SIZE
22637         local num=$((13 * 113 / (PAGE_SIZE / 4096)))
22638         echo "bs=$PAGE_SIZE count=$num iflag=direct small read $tfile.1"
22639         dd if=$DIR/$tfile.1 of=$TMP/$tfile.1 bs=$PAGE_SIZE count=$num \
22640                 iflag=direct || error "dd with O_DIRECT small read failed"
22641         # adjust bytes checked to handle larger PAGE_SIZE for ARM/PPC
22642         cmp --bytes=$((PAGE_SIZE * num)) $TMP/$tfile.0 $TMP/$tfile.1 ||
22643                 error "compare $TMP/$tfile.1 failed"
22644
22645         local save=$($LCTL get_param -n osc.*OST000*.short_io_bytes | head -n 1)
22646         stack_trap "$LCTL set_param osc.$FSNAME-*.short_io_bytes=$save" EXIT
22647
22648         # just to see what the maximum tunable value is, and test parsing
22649         echo "test invalid parameter 2MB"
22650         $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=2M &&
22651                 error "too-large short_io_bytes allowed"
22652         echo "test maximum parameter 512KB"
22653         # if we can set a larger short_io_bytes, run test regardless of version
22654         if ! $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=512K; then
22655                 # older clients may not allow setting it this large, that's OK
22656                 [ $CLIENT_VERSION -ge $(version_code 2.13.50) ] ||
22657                         skip "Need at least client version 2.13.50"
22658                 error "medium short_io_bytes failed"
22659         fi
22660         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
22661         size=$($LCTL get_param -n osc.$FSNAME-OST0000*.short_io_bytes)
22662
22663         echo "test large parameter 64KB"
22664         $LCTL set_param osc.$FSNAME-*.short_io_bytes=65536
22665         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
22666
22667         echo "bs=47008 count=128 oflag=dsync large write $tfile.2"
22668         dd if=$TMP/$tfile.0 of=$DIR/$tfile.2 bs=47008 count=128 oflag=dsync ||
22669                 error "dd with sync large writes failed"
22670         cmp $TMP/$tfile.0 $DIR/$tfile.2 || error "compare $DIR/$tfile.2 failed"
22671
22672         # calculate the large O_DIRECT size and count for the client PAGE_SIZE
22673         local size=$(((4096 * 13 + PAGE_SIZE - 1) / PAGE_SIZE * PAGE_SIZE))
22674         num=$((113 * 4096 / PAGE_SIZE))
22675         echo "bs=$size count=$num oflag=direct large write $tfile.3"
22676         dd if=$TMP/$tfile.0 of=$DIR/$tfile.3 bs=$size count=$num oflag=direct ||
22677                 error "dd with O_DIRECT large writes failed"
22678         cmp --bytes=$((size * num)) $TMP/$tfile.0 $DIR/$tfile.3 ||
22679                 error "compare $DIR/$tfile.3 failed"
22680
22681         cancel_lru_locks osc
22682
22683         echo "bs=$size count=$num iflag=direct large read $tfile.2"
22684         dd if=$DIR/$tfile.2 of=$TMP/$tfile.2 bs=$size count=$num iflag=direct ||
22685                 error "dd with O_DIRECT large read failed"
22686         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.2 ||
22687                 error "compare $TMP/$tfile.2 failed"
22688
22689         echo "bs=$size count=$num iflag=direct large read $tfile.3"
22690         dd if=$DIR/$tfile.3 of=$TMP/$tfile.3 bs=$size count=$num iflag=direct ||
22691                 error "dd with O_DIRECT large read failed"
22692         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.3 ||
22693                 error "compare $TMP/$tfile.3 failed"
22694 }
22695 run_test 248b "test short_io read and write for both small and large sizes"
22696
22697 test_249() { # LU-7890
22698         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
22699                 skip "Need at least version 2.8.54"
22700
22701         rm -f $DIR/$tfile
22702         $LFS setstripe -c 1 $DIR/$tfile
22703         # Offset 2T == 4k * 512M
22704         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 seek=512M ||
22705                 error "dd to 2T offset failed"
22706 }
22707 run_test 249 "Write above 2T file size"
22708
22709 test_250() {
22710         [ "$(facet_fstype ost$(($($LFS getstripe -i $DIR/$tfile) + 1)))" = "zfs" ] \
22711          && skip "no 16TB file size limit on ZFS"
22712
22713         $LFS setstripe -c 1 $DIR/$tfile
22714         # ldiskfs extent file size limit is (16TB - 4KB - 1) bytes
22715         local size=$((16 * 1024 * 1024 * 1024 * 1024 - 4096 - 1))
22716         $TRUNCATE $DIR/$tfile $size || error "truncate $tfile to $size failed"
22717         dd if=/dev/zero of=$DIR/$tfile bs=10 count=1 oflag=append \
22718                 conv=notrunc,fsync && error "append succeeded"
22719         return 0
22720 }
22721 run_test 250 "Write above 16T limit"
22722
22723 test_251() {
22724         $LFS setstripe -c -1 -S 1048576 $DIR/$tfile
22725
22726         #define OBD_FAIL_LLITE_LOST_LAYOUT 0x1407
22727         #Skip once - writing the first stripe will succeed
22728         $LCTL set_param fail_loc=0xa0001407 fail_val=1
22729         $MULTIOP $DIR/$tfile o:O_RDWR:w2097152c 2>&1 | grep -q "short write" &&
22730                 error "short write happened"
22731
22732         $LCTL set_param fail_loc=0xa0001407 fail_val=1
22733         $MULTIOP $DIR/$tfile or2097152c 2>&1 | grep -q "short read" &&
22734                 error "short read happened"
22735
22736         rm -f $DIR/$tfile
22737 }
22738 run_test 251 "Handling short read and write correctly"
22739
22740 test_252() {
22741         remote_mds_nodsh && skip "remote MDS with nodsh"
22742         remote_ost_nodsh && skip "remote OST with nodsh"
22743         if [ "$ost1_FSTYPE" != ldiskfs ] || [ "$mds1_FSTYPE" != ldiskfs ]; then
22744                 skip_env "ldiskfs only test"
22745         fi
22746
22747         local tgt
22748         local dev
22749         local out
22750         local uuid
22751         local num
22752         local gen
22753
22754         # check lr_reader on OST0000
22755         tgt=ost1
22756         dev=$(facet_device $tgt)
22757         out=$(do_facet $tgt $LR_READER $dev)
22758         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
22759         echo "$out"
22760         uuid=$(echo "$out" | grep -i uuid | awk '{ print $2 }')
22761         [ "$uuid" == "$(ostuuid_from_index 0)" ] ||
22762                 error "Invalid uuid returned by $LR_READER on target $tgt"
22763         echo -e "uuid returned by $LR_READER is '$uuid'\n"
22764
22765         # check lr_reader -c on MDT0000
22766         tgt=mds1
22767         dev=$(facet_device $tgt)
22768         if ! do_facet $tgt $LR_READER -h | grep -q OPTIONS; then
22769                 skip "$LR_READER does not support additional options"
22770         fi
22771         out=$(do_facet $tgt $LR_READER -c $dev)
22772         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
22773         echo "$out"
22774         num=$(echo "$out" | grep -c "mdtlov")
22775         [ "$num" -eq $((MDSCOUNT - 1)) ] ||
22776                 error "Invalid number of mdtlov clients returned by $LR_READER"
22777         echo -e "Number of mdtlov clients returned by $LR_READER is '$num'\n"
22778
22779         # check lr_reader -cr on MDT0000
22780         out=$(do_facet $tgt $LR_READER -cr $dev)
22781         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
22782         echo "$out"
22783         echo "$out" | grep -q "^reply_data:$" ||
22784                 error "$LR_READER should have returned 'reply_data' section"
22785         num=$(echo "$out" | grep -c "client_generation")
22786         echo -e "Number of reply data returned by $LR_READER is '$num'\n"
22787 }
22788 run_test 252 "check lr_reader tool"
22789
22790 test_253() {
22791         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22792         remote_mds_nodsh && skip "remote MDS with nodsh"
22793         remote_mgs_nodsh && skip "remote MGS with nodsh"
22794
22795         local ostidx=0
22796         local rc=0
22797         local ost_name=$(ostname_from_index $ostidx)
22798
22799         # on the mdt's osc
22800         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $ost_name)
22801         do_facet $SINGLEMDS $LCTL get_param -n \
22802                 osp.$mdtosc_proc1.reserved_mb_high ||
22803                 skip  "remote MDS does not support reserved_mb_high"
22804
22805         rm -rf $DIR/$tdir
22806         wait_mds_ost_sync
22807         wait_delete_completed
22808         mkdir $DIR/$tdir
22809         stack_trap "rm -rf $DIR/$tdir"
22810
22811         pool_add $TESTNAME || error "Pool creation failed"
22812         pool_add_targets $TESTNAME 0 || error "Pool add targets failed"
22813
22814         $LFS setstripe $DIR/$tdir -i $ostidx -c 1 -p $FSNAME.$TESTNAME ||
22815                 error "Setstripe failed"
22816
22817         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M count=10
22818
22819         local wms=$(ost_watermarks_set_enospc $tfile $ostidx |
22820                     grep "watermarks")
22821         stack_trap "ost_watermarks_clear_enospc $tfile $ostidx $wms" EXIT
22822
22823         local oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
22824                         osp.$mdtosc_proc1.prealloc_status)
22825         echo "prealloc_status $oa_status"
22826
22827         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1M count=1 &&
22828                 error "File creation should fail"
22829
22830         #object allocation was stopped, but we still able to append files
22831         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M seek=6 count=5 \
22832                 oflag=append || error "Append failed"
22833
22834         rm -f $DIR/$tdir/$tfile.0
22835
22836         # For this test, we want to delete the files we created to go out of
22837         # space but leave the watermark, so we remain nearly out of space
22838         ost_watermarks_enospc_delete_files $tfile $ostidx
22839
22840         wait_delete_completed
22841
22842         sleep_maxage
22843
22844         for i in $(seq 10 12); do
22845                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$i bs=1M count=1 \
22846                         2>/dev/null || error "File creation failed after rm"
22847         done
22848
22849         oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
22850                         osp.$mdtosc_proc1.prealloc_status)
22851         echo "prealloc_status $oa_status"
22852
22853         if (( oa_status != 0 )); then
22854                 error "Object allocation still disable after rm"
22855         fi
22856 }
22857 run_test 253 "Check object allocation limit"
22858
22859 test_254() {
22860         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22861         remote_mds_nodsh && skip "remote MDS with nodsh"
22862
22863         local mdt=$(facet_svc $SINGLEMDS)
22864
22865         do_facet $SINGLEMDS $LCTL get_param -n mdd.$mdt.changelog_size ||
22866                 skip "MDS does not support changelog_size"
22867
22868         local cl_user
22869
22870         changelog_register || error "changelog_register failed"
22871
22872         changelog_clear 0 || error "changelog_clear failed"
22873
22874         local size1=$(do_facet $SINGLEMDS \
22875                       $LCTL get_param -n mdd.$mdt.changelog_size)
22876         echo "Changelog size $size1"
22877
22878         rm -rf $DIR/$tdir
22879         $LFS mkdir -i 0 $DIR/$tdir
22880         # change something
22881         mkdir -p $DIR/$tdir/pics/2008/zachy
22882         touch $DIR/$tdir/pics/2008/zachy/timestamp
22883         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg
22884         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
22885         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
22886         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
22887         rm $DIR/$tdir/pics/desktop.jpg
22888
22889         local size2=$(do_facet $SINGLEMDS \
22890                       $LCTL get_param -n mdd.$mdt.changelog_size)
22891         echo "Changelog size after work $size2"
22892
22893         (( $size2 > $size1 )) ||
22894                 error "new Changelog size=$size2 less than old size=$size1"
22895 }
22896 run_test 254 "Check changelog size"
22897
22898 ladvise_no_type()
22899 {
22900         local type=$1
22901         local file=$2
22902
22903         lfs ladvise -a invalid $file 2>&1 | grep "Valid types" |
22904                 awk -F: '{print $2}' | grep $type > /dev/null
22905         if [ $? -ne 0 ]; then
22906                 return 0
22907         fi
22908         return 1
22909 }
22910
22911 ladvise_no_ioctl()
22912 {
22913         local file=$1
22914
22915         lfs ladvise -a willread $file > /dev/null 2>&1
22916         if [ $? -eq 0 ]; then
22917                 return 1
22918         fi
22919
22920         lfs ladvise -a willread $file 2>&1 |
22921                 grep "Inappropriate ioctl for device" > /dev/null
22922         if [ $? -eq 0 ]; then
22923                 return 0
22924         fi
22925         return 1
22926 }
22927
22928 percent() {
22929         bc <<<"scale=2; ($1 - $2) * 100 / $2"
22930 }
22931
22932 # run a random read IO workload
22933 # usage: random_read_iops <filename> <filesize> <iosize>
22934 random_read_iops() {
22935         local file=$1
22936         local fsize=$2
22937         local iosize=${3:-4096}
22938
22939         $READS -f $file -s $fsize -b $iosize -n $((fsize / iosize)) -t 60 |
22940                 sed -e '/^$/d' -e 's#.*s, ##' -e 's#MB/s##'
22941 }
22942
22943 drop_file_oss_cache() {
22944         local file="$1"
22945         local nodes="$2"
22946
22947         $LFS ladvise -a dontneed $file 2>/dev/null ||
22948                 do_nodes $nodes "echo 3 > /proc/sys/vm/drop_caches"
22949 }
22950
22951 ladvise_willread_performance()
22952 {
22953         local repeat=10
22954         local average_origin=0
22955         local average_cache=0
22956         local average_ladvise=0
22957
22958         for ((i = 1; i <= $repeat; i++)); do
22959                 echo "Iter $i/$repeat: reading without willread hint"
22960                 cancel_lru_locks osc
22961                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
22962                 local speed_origin=$(random_read_iops $DIR/$tfile $size)
22963                 echo "Iter $i/$repeat: uncached speed: $speed_origin"
22964                 average_origin=$(bc <<<"$average_origin + $speed_origin")
22965
22966                 cancel_lru_locks osc
22967                 local speed_cache=$(random_read_iops $DIR/$tfile $size)
22968                 echo "Iter $i/$repeat: OSS cache speed: $speed_cache"
22969                 average_cache=$(bc <<<"$average_cache + $speed_cache")
22970
22971                 cancel_lru_locks osc
22972                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
22973                 $LFS ladvise -a willread $DIR/$tfile || error "ladvise failed"
22974                 local speed_ladvise=$(random_read_iops $DIR/$tfile $size)
22975                 echo "Iter $i/$repeat: ladvise speed: $speed_ladvise"
22976                 average_ladvise=$(bc <<<"$average_ladvise + $speed_ladvise")
22977         done
22978         average_origin=$(bc <<<"scale=2; $average_origin / $repeat")
22979         average_cache=$(bc <<<"scale=2; $average_cache / $repeat")
22980         average_ladvise=$(bc <<<"scale=2; $average_ladvise / $repeat")
22981
22982         speedup_cache=$(percent $average_cache $average_origin)
22983         speedup_ladvise=$(percent $average_ladvise $average_origin)
22984
22985         echo "Average uncached read: $average_origin"
22986         echo "Average speedup with OSS cached read: " \
22987                 "$average_cache = +$speedup_cache%"
22988         echo "Average speedup with ladvise willread: " \
22989                 "$average_ladvise = +$speedup_ladvise%"
22990
22991         local lowest_speedup=20
22992         if (( ${average_cache%.*} < $lowest_speedup )); then
22993                 echo "Speedup with OSS cached read less than $lowest_speedup%,"\
22994                      " got $average_cache%. Skipping ladvise willread check."
22995                 return 0
22996         fi
22997
22998         # the test won't work on ZFS until it supports 'ladvise dontneed', but
22999         # it is still good to run until then to exercise 'ladvise willread'
23000         ! $LFS ladvise -a dontneed $DIR/$tfile &&
23001                 [ "$ost1_FSTYPE" = "zfs" ] &&
23002                 echo "osd-zfs does not support dontneed or drop_caches" &&
23003                 return 0
23004
23005         lowest_speedup=$(bc <<<"scale=2; $average_cache / 2")
23006         (( ${average_ladvise%.*} > ${lowest_speedup%.*} )) ||
23007                 error_not_in_vm "Speedup with willread is less than " \
23008                         "$lowest_speedup%, got $average_ladvise%"
23009 }
23010
23011 test_255a() {
23012         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
23013                 skip "lustre < 2.8.54 does not support ladvise "
23014         remote_ost_nodsh && skip "remote OST with nodsh"
23015
23016         stack_trap "rm -f $DIR/$tfile"
23017         lfs setstripe -c -1 -i 0 $DIR/$tfile || error "$tfile failed"
23018
23019         ladvise_no_type willread $DIR/$tfile &&
23020                 skip "willread ladvise is not supported"
23021
23022         ladvise_no_ioctl $DIR/$tfile &&
23023                 skip "ladvise ioctl is not supported"
23024
23025         local size_mb=100
23026         local size=$((size_mb * 1048576))
23027         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
23028                 error "dd to $DIR/$tfile failed"
23029
23030         lfs ladvise -a willread $DIR/$tfile ||
23031                 error "Ladvise failed with no range argument"
23032
23033         lfs ladvise -a willread -s 0 $DIR/$tfile ||
23034                 error "Ladvise failed with no -l or -e argument"
23035
23036         lfs ladvise -a willread -e 1 $DIR/$tfile ||
23037                 error "Ladvise failed with only -e argument"
23038
23039         lfs ladvise -a willread -l 1 $DIR/$tfile ||
23040                 error "Ladvise failed with only -l argument"
23041
23042         lfs ladvise -a willread -s 2 -e 1 $DIR/$tfile &&
23043                 error "End offset should not be smaller than start offset"
23044
23045         lfs ladvise -a willread -s 2 -e 2 $DIR/$tfile &&
23046                 error "End offset should not be equal to start offset"
23047
23048         lfs ladvise -a willread -s $size -l 1 $DIR/$tfile ||
23049                 error "Ladvise failed with overflowing -s argument"
23050
23051         lfs ladvise -a willread -s 1 -e $((size + 1)) $DIR/$tfile ||
23052                 error "Ladvise failed with overflowing -e argument"
23053
23054         lfs ladvise -a willread -s 1 -l $size $DIR/$tfile ||
23055                 error "Ladvise failed with overflowing -l argument"
23056
23057         lfs ladvise -a willread -l 1 -e 2 $DIR/$tfile &&
23058                 error "Ladvise succeeded with conflicting -l and -e arguments"
23059
23060         echo "Synchronous ladvise should wait"
23061         local delay=8
23062 #define OBD_FAIL_OST_LADVISE_PAUSE       0x237
23063         do_nodes $(comma_list $(osts_nodes)) \
23064                 $LCTL set_param fail_val=$delay fail_loc=0x237
23065         stack_trap "do_nodes $(comma_list $(osts_nodes)) \
23066                 $LCTL set_param fail_loc=0"
23067
23068         local start_ts=$SECONDS
23069         lfs ladvise -a willread $DIR/$tfile ||
23070                 error "Ladvise failed with no range argument"
23071         local end_ts=$SECONDS
23072         local inteval_ts=$((end_ts - start_ts))
23073
23074         if [ $inteval_ts -lt $(($delay - 1)) ]; then
23075                 error "Synchronous advice didn't wait reply"
23076         fi
23077
23078         echo "Asynchronous ladvise shouldn't wait"
23079         local start_ts=$SECONDS
23080         lfs ladvise -a willread -b $DIR/$tfile ||
23081                 error "Ladvise failed with no range argument"
23082         local end_ts=$SECONDS
23083         local inteval_ts=$((end_ts - start_ts))
23084
23085         if [ $inteval_ts -gt $(($delay / 2)) ]; then
23086                 error "Asynchronous advice blocked"
23087         fi
23088
23089         ladvise_willread_performance
23090 }
23091 run_test 255a "check 'lfs ladvise -a willread'"
23092
23093 facet_meminfo() {
23094         local facet=$1
23095         local info=$2
23096
23097         do_facet $facet "cat /proc/meminfo | grep ^${info}:" | awk '{print $2}'
23098 }
23099
23100 test_255b() {
23101         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
23102                 skip "lustre < 2.8.54 does not support ladvise "
23103         remote_ost_nodsh && skip "remote OST with nodsh"
23104
23105         stack_trap "rm -f $DIR/$tfile"
23106         lfs setstripe -c 1 -i 0 $DIR/$tfile
23107
23108         ladvise_no_type dontneed $DIR/$tfile &&
23109                 skip "dontneed ladvise is not supported"
23110
23111         ladvise_no_ioctl $DIR/$tfile &&
23112                 skip "ladvise ioctl is not supported"
23113
23114         ! $LFS ladvise -a dontneed $DIR/$tfile &&
23115                 [ "$ost1_FSTYPE" = "zfs" ] &&
23116                 skip "zfs-osd does not support 'ladvise dontneed'"
23117
23118         local size_mb=100
23119         local size=$((size_mb * 1048576))
23120         # In order to prevent disturbance of other processes, only check 3/4
23121         # of the memory usage
23122         local kibibytes=$((size_mb * 1024 * 3 / 4))
23123
23124         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
23125                 error "dd to $DIR/$tfile failed"
23126
23127         #force write to complete before dropping OST cache & checking memory
23128         sync
23129
23130         local total=$(facet_meminfo ost1 MemTotal)
23131         echo "Total memory: $total KiB"
23132
23133         do_facet ost1 "sync && echo 3 > /proc/sys/vm/drop_caches"
23134         local before_read=$(facet_meminfo ost1 Cached)
23135         echo "Cache used before read: $before_read KiB"
23136
23137         lfs ladvise -a willread $DIR/$tfile ||
23138                 error "Ladvise willread failed"
23139         local after_read=$(facet_meminfo ost1 Cached)
23140         echo "Cache used after read: $after_read KiB"
23141
23142         lfs ladvise -a dontneed $DIR/$tfile ||
23143                 error "Ladvise dontneed again failed"
23144         local no_read=$(facet_meminfo ost1 Cached)
23145         echo "Cache used after dontneed ladvise: $no_read KiB"
23146
23147         if [ $total -lt $((before_read + kibibytes)) ]; then
23148                 echo "Memory is too small, abort checking"
23149                 return 0
23150         fi
23151
23152         if [ $((before_read + kibibytes)) -gt $after_read ]; then
23153                 error "Ladvise willread should use more memory" \
23154                         "than $kibibytes KiB"
23155         fi
23156
23157         if [ $((no_read + kibibytes)) -gt $after_read ]; then
23158                 error "Ladvise dontneed should release more memory" \
23159                         "than $kibibytes KiB"
23160         fi
23161 }
23162 run_test 255b "check 'lfs ladvise -a dontneed'"
23163
23164 test_255c() {
23165         [ $OST1_VERSION -lt $(version_code 2.10.50) ] &&
23166                 skip "lustre < 2.10.50 does not support lockahead"
23167
23168         local ost1_imp=$(get_osc_import_name client ost1)
23169         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
23170                          cut -d'.' -f2)
23171         local count
23172         local new_count
23173         local difference
23174         local i
23175         local rc
23176
23177         test_mkdir -p $DIR/$tdir
23178         $LFS setstripe -i 0 -c 1 $DIR/$tdir
23179
23180         #test 10 returns only success/failure
23181         i=10
23182         lockahead_test -d $DIR/$tdir -t $i -f $tfile
23183         rc=$?
23184         if [ $rc -eq 255 ]; then
23185                 error "Ladvise test${i} failed, ${rc}"
23186         fi
23187
23188         #test 11 counts lock enqueue requests, all others count new locks
23189         i=11
23190         count=$(do_facet ost1 \
23191                 $LCTL get_param -n ost.OSS.ost.stats)
23192         count=$(echo "$count" | grep ldlm_extent_enqueue | awk '{ print $2 }')
23193
23194         lockahead_test -d $DIR/$tdir -t $i -f $tfile
23195         rc=$?
23196         if [ $rc -eq 255 ]; then
23197                 error "Ladvise test${i} failed, ${rc}"
23198         fi
23199
23200         new_count=$(do_facet ost1 \
23201                 $LCTL get_param -n ost.OSS.ost.stats)
23202         new_count=$(echo "$new_count" | grep ldlm_extent_enqueue | \
23203                    awk '{ print $2 }')
23204
23205         difference="$((new_count - count))"
23206         if [ $difference -ne $rc ]; then
23207                 error "Ladvise test${i}, bad enqueue count, returned " \
23208                       "${rc}, actual ${difference}"
23209         fi
23210
23211         for i in $(seq 12 21); do
23212                 # If we do not do this, we run the risk of having too many
23213                 # locks and starting lock cancellation while we are checking
23214                 # lock counts.
23215                 cancel_lru_locks osc
23216
23217                 count=$($LCTL get_param -n \
23218                        ldlm.namespaces.$imp_name.lock_unused_count)
23219
23220                 lockahead_test -d $DIR/$tdir -t $i -f $tfile
23221                 rc=$?
23222                 if [ $rc -eq 255 ]; then
23223                         error "Ladvise test ${i} failed, ${rc}"
23224                 fi
23225
23226                 new_count=$($LCTL get_param -n \
23227                        ldlm.namespaces.$imp_name.lock_unused_count)
23228                 difference="$((new_count - count))"
23229
23230                 # Test 15 output is divided by 100 to map down to valid return
23231                 if [ $i -eq 15 ]; then
23232                         rc="$((rc * 100))"
23233                 fi
23234
23235                 if [ $difference -ne $rc ]; then
23236                         error "Ladvise test ${i}, bad lock count, returned " \
23237                               "${rc}, actual ${difference}"
23238                 fi
23239         done
23240
23241         #test 22 returns only success/failure
23242         i=22
23243         lockahead_test -d $DIR/$tdir -t $i -f $tfile
23244         rc=$?
23245         if [ $rc -eq 255 ]; then
23246                 error "Ladvise test${i} failed, ${rc}"
23247         fi
23248 }
23249 run_test 255c "suite of ladvise lockahead tests"
23250
23251 test_256() {
23252         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23253         remote_mds_nodsh && skip "remote MDS with nodsh"
23254         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
23255         changelog_users $SINGLEMDS | grep "^cl" &&
23256                 skip "active changelog user"
23257
23258         local cl_user
23259         local cat_sl
23260         local mdt_dev
23261
23262         mdt_dev=$(facet_device $SINGLEMDS)
23263         echo $mdt_dev
23264
23265         changelog_register || error "changelog_register failed"
23266
23267         rm -rf $DIR/$tdir
23268         mkdir_on_mdt -i$(($(facet_number $SINGLEMDS) - 1)) $DIR/$tdir
23269
23270         changelog_clear 0 || error "changelog_clear failed"
23271
23272         # change something
23273         touch $DIR/$tdir/{1..10}
23274
23275         # stop the MDT
23276         stop $SINGLEMDS || error "Fail to stop MDT"
23277
23278         # remount the MDT
23279         start $SINGLEMDS $(facet_device $SINGLEMDS) $MDS_MOUNT_OPTS ||
23280                 error "Fail to start MDT"
23281
23282         #after mount new plainllog is used
23283         touch $DIR/$tdir/{11..19}
23284         local tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
23285         stack_trap "rm -f $tmpfile"
23286         cat_sl=$(do_facet $SINGLEMDS "sync; \
23287                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
23288                  llog_reader $tmpfile | grep -c type=1064553b")
23289         do_facet $SINGLEMDS llog_reader $tmpfile
23290
23291         [ $cat_sl != 2 ] && error "Changelog catalog has $cat_sl != 2 slots"
23292
23293         changelog_clear 0 || error "changelog_clear failed"
23294
23295         cat_sl=$(do_facet $SINGLEMDS "sync; \
23296                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
23297                  llog_reader $tmpfile | grep -c type=1064553b")
23298
23299         if (( cat_sl == 2 )); then
23300                 error "Empty plain llog was not deleted from changelog catalog"
23301         elif (( cat_sl != 1 )); then
23302                 error "Active plain llog shouldn't be deleted from catalog"
23303         fi
23304 }
23305 run_test 256 "Check llog delete for empty and not full state"
23306
23307 test_257() {
23308         remote_mds_nodsh && skip "remote MDS with nodsh"
23309         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
23310                 skip "Need MDS version at least 2.8.55"
23311
23312         test_mkdir $DIR/$tdir
23313
23314         setfattr -n trusted.name1 -v value1 $DIR/$tdir ||
23315                 error "setfattr -n trusted.name1=value1 $DIR/$tdir failed"
23316         stat $DIR/$tdir
23317
23318 #define OBD_FAIL_MDS_XATTR_REP                  0x161
23319         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
23320         local facet=mds$((mdtidx + 1))
23321         set_nodes_failloc $(facet_active_host $facet) 0x80000161
23322         getfattr -n trusted.name1 $DIR/$tdir 2> /dev/null
23323
23324         stop $facet || error "stop MDS failed"
23325         start $facet $(mdsdevname $((mdtidx + 1))) $MDS_MOUNT_OPTS ||
23326                 error "start MDS fail"
23327         wait_recovery_complete $facet
23328 }
23329 run_test 257 "xattr locks are not lost"
23330
23331 # Verify we take the i_mutex when security requires it
23332 test_258a() {
23333 #define OBD_FAIL_IMUTEX_SEC 0x141c
23334         $LCTL set_param fail_loc=0x141c
23335         touch $DIR/$tfile
23336         chmod u+s $DIR/$tfile
23337         chmod a+rwx $DIR/$tfile
23338         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
23339         RC=$?
23340         if [ $RC -ne 0 ]; then
23341                 error "error, failed to take i_mutex, rc=$?"
23342         fi
23343         rm -f $DIR/$tfile
23344 }
23345 run_test 258a "verify i_mutex security behavior when suid attributes is set"
23346
23347 # Verify we do NOT take the i_mutex in the normal case
23348 test_258b() {
23349 #define OBD_FAIL_IMUTEX_NOSEC 0x141d
23350         $LCTL set_param fail_loc=0x141d
23351         touch $DIR/$tfile
23352         chmod a+rwx $DIR
23353         chmod a+rw $DIR/$tfile
23354         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
23355         RC=$?
23356         if [ $RC -ne 0 ]; then
23357                 error "error, took i_mutex unnecessarily, rc=$?"
23358         fi
23359         rm -f $DIR/$tfile
23360
23361 }
23362 run_test 258b "verify i_mutex security behavior"
23363
23364 test_259() {
23365         local file=$DIR/$tfile
23366         local before
23367         local after
23368
23369         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
23370
23371         stack_trap "rm -f $file" EXIT
23372
23373         wait_delete_completed
23374         before=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
23375         echo "before: $before"
23376
23377         $LFS setstripe -i 0 -c 1 $file
23378         dd if=/dev/zero of=$file bs=1M count=10 || error "couldn't write"
23379         sync_all_data
23380         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
23381         echo "after write: $after"
23382
23383 #define OBD_FAIL_OSD_FAIL_AT_TRUNCATE          0x2301
23384         do_facet ost1 $LCTL set_param fail_loc=0x2301
23385         $TRUNCATE $file 0
23386         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
23387         echo "after truncate: $after"
23388
23389         stop ost1
23390         do_facet ost1 $LCTL set_param fail_loc=0
23391         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
23392         sleep 2
23393         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
23394         echo "after restart: $after"
23395         [ $((after - before)) -ge $(fs_log_size ost1) ] &&
23396                 error "missing truncate?"
23397
23398         return 0
23399 }
23400 run_test 259 "crash at delayed truncate"
23401
23402 test_260() {
23403 #define OBD_FAIL_MDC_CLOSE               0x806
23404         $LCTL set_param fail_loc=0x80000806
23405         touch $DIR/$tfile
23406
23407 }
23408 run_test 260 "Check mdc_close fail"
23409
23410 ### Data-on-MDT sanity tests ###
23411 test_270a() {
23412         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23413                 skip "Need MDS version at least 2.10.55 for DoM"
23414
23415         # create DoM file
23416         local dom=$DIR/$tdir/dom_file
23417         local tmp=$DIR/$tdir/tmp_file
23418
23419         mkdir_on_mdt0 $DIR/$tdir
23420
23421         # basic checks for DoM component creation
23422         $LFS setstripe -E 1024K -E 2048K -L mdt $dom 2>/dev/null &&
23423                 error "Can set MDT layout to non-first entry"
23424
23425         $LFS setstripe -E 1024K -L mdt -E 2048K -L mdt $dom 2>/dev/null &&
23426                 error "Can define multiple entries as MDT layout"
23427
23428         $LFS setstripe -E 1M -L mdt $dom || error "Can't create DoM layout"
23429
23430         [ $($LFS getstripe -L $dom) == "mdt" ] || error "bad pattern"
23431         [ $($LFS getstripe -c $dom) == 0 ] || error "bad stripe count"
23432         [ $($LFS getstripe -S $dom) == 1048576 ] || error "bad stripe size"
23433
23434         local mdtidx=$($LFS getstripe -m $dom)
23435         local mdtname=MDT$(printf %04x $mdtidx)
23436         local facet=mds$((mdtidx + 1))
23437         local space_check=1
23438
23439         # Skip free space checks with ZFS
23440         [ "$(facet_fstype $facet)" == "zfs" ] && space_check=0
23441
23442         # write
23443         sync
23444         local size_tmp=$((65536 * 3))
23445         local mdtfree1=$(do_facet $facet \
23446                          lctl get_param -n osd*.*$mdtname.kbytesfree)
23447
23448         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
23449         # check also direct IO along write
23450         # IO size must be a multiple of PAGE_SIZE on all platforms (ARM=64KB)
23451         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
23452         sync
23453         cmp $tmp $dom || error "file data is different"
23454         [ $(stat -c%s $dom) == $size_tmp ] ||
23455                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
23456         if [ $space_check == 1 ]; then
23457                 local mdtfree2=$(do_facet $facet \
23458                                  lctl get_param -n osd*.*$mdtname.kbytesfree)
23459
23460                 # increase in usage from by $size_tmp
23461                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
23462                         error "MDT free space wrong after write: " \
23463                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
23464         fi
23465
23466         # truncate
23467         local size_dom=10000
23468
23469         $TRUNCATE $dom $size_dom
23470         [ $(stat -c%s $dom) == $size_dom ] ||
23471                 error "bad size after truncate: $(stat -c%s $dom) != $size_dom"
23472         if [ $space_check == 1 ]; then
23473                 mdtfree1=$(do_facet $facet \
23474                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23475                 # decrease in usage from $size_tmp to new $size_dom
23476                 [ $(($mdtfree1 - $mdtfree2)) -ge \
23477                   $(((size_tmp - size_dom) / 1024)) ] ||
23478                         error "MDT free space is wrong after truncate: " \
23479                               "$mdtfree1 >= $mdtfree2 + ($size_tmp - $size_dom) / 1024"
23480         fi
23481
23482         # append
23483         cat $tmp >> $dom
23484         sync
23485         size_dom=$((size_dom + size_tmp))
23486         [ $(stat -c%s $dom) == $size_dom ] ||
23487                 error "bad size after append: $(stat -c%s $dom) != $size_dom"
23488         if [ $space_check == 1 ]; then
23489                 mdtfree2=$(do_facet $facet \
23490                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23491                 # increase in usage by $size_tmp from previous
23492                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
23493                         error "MDT free space is wrong after append: " \
23494                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
23495         fi
23496
23497         # delete
23498         rm $dom
23499         if [ $space_check == 1 ]; then
23500                 mdtfree1=$(do_facet $facet \
23501                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23502                 # decrease in usage by $size_dom from previous
23503                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_dom / 1024)) ] ||
23504                         error "MDT free space is wrong after removal: " \
23505                               "$mdtfree1 >= $mdtfree2 + $size_dom/1024"
23506         fi
23507
23508         # combined striping
23509         $LFS setstripe -E 1024K -L mdt -E EOF $dom ||
23510                 error "Can't create DoM + OST striping"
23511
23512         size_tmp=2031616 # must be a multiple of PAGE_SIZE=65536 on ARM
23513         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
23514         # check also direct IO along write
23515         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
23516         sync
23517         cmp $tmp $dom || error "file data is different"
23518         [ $(stat -c%s $dom) == $size_tmp ] ||
23519                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
23520         rm $dom $tmp
23521
23522         return 0
23523 }
23524 run_test 270a "DoM: basic functionality tests"
23525
23526 test_270b() {
23527         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23528                 skip "Need MDS version at least 2.10.55"
23529
23530         local dom=$DIR/$tdir/dom_file
23531         local max_size=1048576
23532
23533         mkdir -p $DIR/$tdir
23534         $LFS setstripe -E $max_size -L mdt $dom
23535
23536         # truncate over the limit
23537         $TRUNCATE $dom $(($max_size + 1)) &&
23538                 error "successful truncate over the maximum size"
23539         # write over the limit
23540         dd if=/dev/zero of=$dom bs=$max_size seek=1 count=1 &&
23541                 error "successful write over the maximum size"
23542         # append over the limit
23543         dd if=/dev/zero of=$dom bs=$(($max_size - 3)) count=1
23544         echo "12345" >> $dom && error "successful append over the maximum size"
23545         rm $dom
23546
23547         return 0
23548 }
23549 run_test 270b "DoM: maximum size overflow checks for DoM-only file"
23550
23551 test_270c() {
23552         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23553                 skip "Need MDS version at least 2.10.55"
23554
23555         mkdir -p $DIR/$tdir
23556         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
23557
23558         # check files inherit DoM EA
23559         touch $DIR/$tdir/first
23560         [ $($LFS getstripe -L $DIR/$tdir/first) == "mdt" ] ||
23561                 error "bad pattern"
23562         [ $($LFS getstripe -c $DIR/$tdir/first) == 0 ] ||
23563                 error "bad stripe count"
23564         [ $($LFS getstripe -S $DIR/$tdir/first) == 1048576 ] ||
23565                 error "bad stripe size"
23566
23567         # check directory inherits DoM EA and uses it as default
23568         mkdir $DIR/$tdir/subdir
23569         touch $DIR/$tdir/subdir/second
23570         [ $($LFS getstripe -L $DIR/$tdir/subdir/second) == "mdt" ] ||
23571                 error "bad pattern in sub-directory"
23572         [ $($LFS getstripe -c $DIR/$tdir/subdir/second) == 0 ] ||
23573                 error "bad stripe count in sub-directory"
23574         [ $($LFS getstripe -S $DIR/$tdir/subdir/second) == 1048576 ] ||
23575                 error "bad stripe size in sub-directory"
23576         return 0
23577 }
23578 run_test 270c "DoM: DoM EA inheritance tests"
23579
23580 test_270d() {
23581         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23582                 skip "Need MDS version at least 2.10.55"
23583
23584         mkdir -p $DIR/$tdir
23585         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
23586
23587         # inherit default DoM striping
23588         mkdir $DIR/$tdir/subdir
23589         touch $DIR/$tdir/subdir/f1
23590
23591         # change default directory striping
23592         $LFS setstripe -c 1 $DIR/$tdir/subdir
23593         touch $DIR/$tdir/subdir/f2
23594         [ $($LFS getstripe -c $DIR/$tdir/subdir/f2) == 1 ] ||
23595                 error "wrong default striping in file 2"
23596         [ $($LFS getstripe -L $DIR/$tdir/subdir/f2) == "raid0" ] ||
23597                 error "bad pattern in file 2"
23598         return 0
23599 }
23600 run_test 270d "DoM: change striping from DoM to RAID0"
23601
23602 test_270e() {
23603         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23604                 skip "Need MDS version at least 2.10.55"
23605
23606         mkdir -p $DIR/$tdir/dom
23607         mkdir -p $DIR/$tdir/norm
23608         DOMFILES=20
23609         NORMFILES=10
23610         $LFS setstripe -E 1M -L mdt $DIR/$tdir/dom
23611         $LFS setstripe -i 0 -S 2M $DIR/$tdir/norm
23612
23613         createmany -o $DIR/$tdir/dom/dom- $DOMFILES
23614         createmany -o $DIR/$tdir/norm/norm- $NORMFILES
23615
23616         # find DoM files by layout
23617         NUM=$($LFS find -L mdt -type f $DIR/$tdir 2>/dev/null | wc -l)
23618         [ $NUM -eq  $DOMFILES ] ||
23619                 error "lfs find -L: found $NUM, expected $DOMFILES"
23620         echo "Test 1: lfs find 20 DOM files by layout: OK"
23621
23622         # there should be 1 dir with default DOM striping
23623         NUM=$($LFS find -L mdt -type d $DIR/$tdir 2>/dev/null | wc -l)
23624         [ $NUM -eq  1 ] ||
23625                 error "lfs find -L: found $NUM, expected 1 dir"
23626         echo "Test 2: lfs find 1 DOM dir by layout: OK"
23627
23628         # find DoM files by stripe size
23629         NUM=$($LFS find -S -1200K -type f $DIR/$tdir 2>/dev/null | wc -l)
23630         [ $NUM -eq  $DOMFILES ] ||
23631                 error "lfs find -S: found $NUM, expected $DOMFILES"
23632         echo "Test 4: lfs find 20 DOM files by stripe size: OK"
23633
23634         # find files by stripe offset except DoM files
23635         NUM=$($LFS find -i 0 -type f $DIR/$tdir 2>/dev/null | wc -l)
23636         [ $NUM -eq  $NORMFILES ] ||
23637                 error "lfs find -i: found $NUM, expected $NORMFILES"
23638         echo "Test 5: lfs find no DOM files by stripe index: OK"
23639         return 0
23640 }
23641 run_test 270e "DoM: lfs find with DoM files test"
23642
23643 test_270f() {
23644         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23645                 skip "Need MDS version at least 2.10.55"
23646
23647         local mdtname=${FSNAME}-MDT0000-mdtlov
23648         local dom=$DIR/$tdir/dom_file
23649         local dom_limit_saved=$(do_facet mds1 $LCTL get_param -n \
23650                                                 lod.$mdtname.dom_stripesize)
23651         local dom_limit=131072
23652
23653         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=$dom_limit
23654         local dom_current=$(do_facet mds1 $LCTL get_param -n \
23655                                                 lod.$mdtname.dom_stripesize)
23656         [ ${dom_limit} -eq ${dom_current} ] ||
23657                 error "Cannot change per-MDT DoM stripe limit to $dom_limit"
23658
23659         $LFS mkdir -i 0 -c 1 $DIR/$tdir
23660         $LFS setstripe -d $DIR/$tdir
23661         $LFS setstripe -E $dom_limit -L mdt $DIR/$tdir ||
23662                 error "Can't set directory default striping"
23663
23664         # exceed maximum stripe size
23665         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
23666                 error "Can't create file with $((dom_limit * 2)) DoM stripe"
23667         [ $($LFS getstripe -S $dom) -eq $((dom_limit * 2)) ] &&
23668                 error "Able to create DoM component size more than LOD limit"
23669
23670         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
23671         dom_current=$(do_facet mds1 $LCTL get_param -n \
23672                                                 lod.$mdtname.dom_stripesize)
23673         [ 0 -eq ${dom_current} ] ||
23674                 error "Can't set zero DoM stripe limit"
23675         rm $dom
23676
23677         # attempt to create DoM file on server with disabled DoM should
23678         # remove DoM entry from layout and be succeed
23679         $LFS setstripe -E $dom_limit -L mdt -E -1 $dom ||
23680                 error "Can't create DoM file (DoM is disabled)"
23681         [ $($LFS getstripe -L $dom) == "mdt" ] &&
23682                 error "File has DoM component while DoM is disabled"
23683         rm $dom
23684
23685         # attempt to create DoM file with only DoM stripe should return error
23686         $LFS setstripe -E $dom_limit -L mdt $dom &&
23687                 error "Able to create DoM-only file while DoM is disabled"
23688
23689         # too low values to be aligned with smallest stripe size 64K
23690         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=30000
23691         dom_current=$(do_facet mds1 $LCTL get_param -n \
23692                                                 lod.$mdtname.dom_stripesize)
23693         [ 30000 -eq ${dom_current} ] &&
23694                 error "Can set too small DoM stripe limit"
23695
23696         # 64K is a minimal stripe size in Lustre, expect limit of that size
23697         [ 65536 -eq ${dom_current} ] ||
23698                 error "Limit is not set to 64K but ${dom_current}"
23699
23700         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=2147483648
23701         dom_current=$(do_facet mds1 $LCTL get_param -n \
23702                                                 lod.$mdtname.dom_stripesize)
23703         echo $dom_current
23704         [ 2147483648 -eq ${dom_current} ] &&
23705                 error "Can set too large DoM stripe limit"
23706
23707         do_facet mds1 $LCTL set_param -n \
23708                                 lod.$mdtname.dom_stripesize=$((dom_limit * 2))
23709         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
23710                 error "Can't create DoM component size after limit change"
23711         do_facet mds1 $LCTL set_param -n \
23712                                 lod.$mdtname.dom_stripesize=$((dom_limit / 2))
23713         $LFS setstripe -E $dom_limit -L mdt ${dom}_big ||
23714                 error "Can't create DoM file after limit decrease"
23715         [ $($LFS getstripe -S ${dom}_big) -eq $((dom_limit / 2)) ] ||
23716                 error "Can create big DoM component after limit decrease"
23717         touch ${dom}_def ||
23718                 error "Can't create file with old default layout"
23719
23720         do_facet mds1 $LCTL set_param -n lod.*.dom_stripesize=$dom_limit_saved
23721         return 0
23722 }
23723 run_test 270f "DoM: maximum DoM stripe size checks"
23724
23725 test_270g() {
23726         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
23727                 skip "Need MDS version at least 2.13.52"
23728         local dom=$DIR/$tdir/$tfile
23729
23730         $LFS mkdir -i 0 -c 1 $DIR/$tdir
23731         local lodname=${FSNAME}-MDT0000-mdtlov
23732
23733         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
23734         save_lustre_params mds1 "lod.${lodname}.dom_stripesize_max_kb" > $save
23735         save_lustre_params mds1 "lod.${lodname}.dom_threshold_free_mb" >> $save
23736         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
23737
23738         local dom_limit=1024
23739         local dom_threshold="50%"
23740
23741         $LFS setstripe -d $DIR/$tdir
23742         $LFS setstripe -E ${dom_limit}K -L mdt $DIR/$tdir ||
23743                 error "Can't set directory default striping"
23744
23745         do_facet mds1 $LCTL set_param -n \
23746                                 lod.${lodname}.dom_stripesize_max_kb=$dom_limit
23747         # set 0 threshold and create DOM file to change tunable stripesize
23748         do_facet mds1 $LCTL set_param -n lod.${lodname}.dom_threshold_free_mb=0
23749         $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
23750                 error "Failed to create $dom file"
23751         # now tunable dom_cur_stripesize should reach maximum
23752         local dom_current=$(do_facet mds1 $LCTL get_param -n \
23753                                         lod.${lodname}.dom_stripesize_cur_kb)
23754         [[ $dom_current == $dom_limit ]] ||
23755                 error "Current DOM stripesize is not maximum"
23756         rm $dom
23757
23758         # set threshold for further tests
23759         do_facet mds1 $LCTL set_param -n \
23760                         lod.${lodname}.dom_threshold_free_mb=$dom_threshold
23761         echo "DOM threshold is $dom_threshold free space"
23762         local dom_def
23763         local dom_set
23764         # Spoof bfree to exceed threshold
23765         #define OBD_FAIL_MDS_STATFS_SPOOF   0x168
23766         do_facet mds1 $LCTL set_param -n fail_loc=0x0168
23767         for spfree in 40 20 0 15 30 55; do
23768                 do_facet mds1 $LCTL set_param -n fail_val=$spfree
23769                 $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
23770                         error "Failed to create $dom file"
23771                 dom_def=$(do_facet mds1 $LCTL get_param -n \
23772                                         lod.${lodname}.dom_stripesize_cur_kb)
23773                 echo "Free space: ${spfree}%, default DOM stripe: ${dom_def}K"
23774                 [[ $dom_def != $dom_current ]] ||
23775                         error "Default stripe size was not changed"
23776                 if (( spfree > 0 )) ; then
23777                         dom_set=$($LFS getstripe -S $dom)
23778                         (( dom_set == dom_def * 1024 )) ||
23779                                 error "DOM component size is still old"
23780                 else
23781                         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
23782                                 error "DoM component is set with no free space"
23783                 fi
23784                 rm $dom
23785                 dom_current=$dom_def
23786         done
23787 }
23788 run_test 270g "DoM: default DoM stripe size depends on free space"
23789
23790 test_270h() {
23791         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
23792                 skip "Need MDS version at least 2.13.53"
23793
23794         local mdtname=${FSNAME}-MDT0000-mdtlov
23795         local dom=$DIR/$tdir/$tfile
23796         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
23797
23798         save_lustre_params mds1 "lod.*.dom_stripesize" > $save
23799         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
23800
23801         $LFS mkdir -i 0 -c 1 $DIR/$tdir
23802         $LFS setstripe -E 1M -c1  -E -1 -c2 ${dom}_1 ||
23803                 error "can't create OST file"
23804         # mirrored file with DOM entry in the second mirror
23805         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 ${dom}_1 ||
23806                 error "can't create mirror with DoM component"
23807
23808         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
23809
23810         # DOM component in the middle and has other enries in the same mirror,
23811         # should succeed but lost DoM component
23812         $LFS setstripe --copy=${dom}_1 $dom ||
23813                 error "Can't create file from OST|DOM mirror layout"
23814         # check new file has no DoM layout after all
23815         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
23816                 error "File has DoM component while DoM is disabled"
23817 }
23818 run_test 270h "DoM: DoM stripe removal when disabled on server"
23819
23820 test_270i() {
23821         (( $MDS1_VERSION >= $(version_code 2.14.54) )) ||
23822                 skip "Need MDS version at least 2.14.54"
23823
23824         mkdir $DIR/$tdir
23825         # DoM with plain layout
23826         $LFS setstripe -L mdt -S 128k -c -1 $DIR/$tdir &&
23827                 error "default plain layout with DoM must fail"
23828         $LFS setstripe -L mdt -S 128k -c -1 $DIR/$tdir/$tfile &&
23829                 error "setstripe plain file layout with DoM must fail"
23830         $LFS setstripe -E 1M -L mdt -S 128k -c -1 -E eof $DIR/$tdir &&
23831                 error "default DoM layout with bad striping must fail"
23832         $LFS setstripe -E 1M -L mdt -S 128k -c -1 -E eof $DIR/$tdir/$tfile &&
23833                 error "setstripe to DoM layout with bad striping must fail"
23834         return 0
23835 }
23836 run_test 270i "DoM: setting invalid DoM striping should fail"
23837
23838 test_271a() {
23839         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23840                 skip "Need MDS version at least 2.10.55"
23841
23842         local dom=$DIR/$tdir/dom
23843
23844         mkdir -p $DIR/$tdir
23845
23846         $LFS setstripe -E 1024K -L mdt $dom
23847
23848         lctl set_param -n mdc.*.stats=clear
23849         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
23850         cat $dom > /dev/null
23851         local reads=$(lctl get_param -n mdc.*.stats | grep -c ost_read)
23852         [ $reads -eq 0 ] || error "Unexpected $reads READ RPCs"
23853         ls $dom
23854         rm -f $dom
23855 }
23856 run_test 271a "DoM: data is cached for read after write"
23857
23858 test_271b() {
23859         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23860                 skip "Need MDS version at least 2.10.55"
23861
23862         local dom=$DIR/$tdir/dom
23863
23864         mkdir -p $DIR/$tdir
23865
23866         $LFS setstripe -E 1024K -L mdt -E EOF $dom
23867
23868         lctl set_param -n mdc.*.stats=clear
23869         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
23870         cancel_lru_locks mdc
23871         $CHECKSTAT -t file -s 4096 $dom || error "stat #1 fails"
23872         # second stat to check size is cached on client
23873         $CHECKSTAT -t file -s 4096 $dom || error "stat #2 fails"
23874         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
23875         [ $gls -eq 0 ] || error "Unexpected $gls glimpse RPCs"
23876         rm -f $dom
23877 }
23878 run_test 271b "DoM: no glimpse RPC for stat (DoM only file)"
23879
23880 test_271ba() {
23881         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23882                 skip "Need MDS version at least 2.10.55"
23883
23884         local dom=$DIR/$tdir/dom
23885
23886         mkdir -p $DIR/$tdir
23887
23888         $LFS setstripe -E 1024K -L mdt -E EOF $dom
23889
23890         lctl set_param -n mdc.*.stats=clear
23891         lctl set_param -n osc.*.stats=clear
23892         dd if=/dev/zero of=$dom bs=2048K count=1 || return 1
23893         cancel_lru_locks mdc
23894         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
23895         # second stat to check size is cached on client
23896         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
23897         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
23898         [ $gls == 0 ] || error "Unexpected $gls glimpse RPCs"
23899         local gls=$(lctl get_param -n osc.*.stats | grep -c ldlm_glimpse)
23900         [ $gls == 0 ] || error "Unexpected $gls OSC glimpse RPCs"
23901         rm -f $dom
23902 }
23903 run_test 271ba "DoM: no glimpse RPC for stat (combined file)"
23904
23905
23906 get_mdc_stats() {
23907         local mdtidx=$1
23908         local param=$2
23909         local mdt=MDT$(printf %04x $mdtidx)
23910
23911         if [ -z $param ]; then
23912                 lctl get_param -n mdc.*$mdt*.stats
23913         else
23914                 lctl get_param -n mdc.*$mdt*.stats | awk "/$param/"'{print $2}'
23915         fi
23916 }
23917
23918 test_271c() {
23919         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23920                 skip "Need MDS version at least 2.10.55"
23921
23922         local dom=$DIR/$tdir/dom
23923
23924         mkdir -p $DIR/$tdir
23925
23926         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
23927
23928         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
23929         local facet=mds$((mdtidx + 1))
23930
23931         cancel_lru_locks mdc
23932         do_facet $facet lctl set_param -n mdt.*.dom_lock=0
23933         createmany -o $dom 1000
23934         lctl set_param -n mdc.*.stats=clear
23935         smalliomany -w $dom 1000 200
23936         get_mdc_stats $mdtidx
23937         local enq=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
23938         # Each file has 1 open, 1 IO enqueues, total 2000
23939         # but now we have also +1 getxattr for security.capability, total 3000
23940         [ $enq -ge 2000 ] || error "Too few enqueues $enq, expected > 2000"
23941         unlinkmany $dom 1000
23942
23943         cancel_lru_locks mdc
23944         do_facet $facet lctl set_param -n mdt.*.dom_lock=1
23945         createmany -o $dom 1000
23946         lctl set_param -n mdc.*.stats=clear
23947         smalliomany -w $dom 1000 200
23948         local enq_2=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
23949         # Expect to see reduced amount of RPCs by 1000 due to single enqueue
23950         # for OPEN and IO lock.
23951         [ $((enq - enq_2)) -ge 1000 ] ||
23952                 error "Too many enqueues $enq_2, expected about $((enq - 1000))"
23953         unlinkmany $dom 1000
23954         return 0
23955 }
23956 run_test 271c "DoM: IO lock at open saves enqueue RPCs"
23957
23958 cleanup_271def_tests() {
23959         trap 0
23960         rm -f $1
23961 }
23962
23963 test_271d() {
23964         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
23965                 skip "Need MDS version at least 2.10.57"
23966
23967         local dom=$DIR/$tdir/dom
23968         local tmp=$TMP/$tfile
23969         trap "cleanup_271def_tests $tmp" EXIT
23970
23971         mkdir -p $DIR/$tdir
23972
23973         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
23974
23975         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
23976
23977         cancel_lru_locks mdc
23978         dd if=/dev/urandom of=$tmp bs=1000 count=1
23979         dd if=$tmp of=$dom bs=1000 count=1
23980         cancel_lru_locks mdc
23981
23982         cat /etc/hosts >> $tmp
23983         lctl set_param -n mdc.*.stats=clear
23984
23985         # append data to the same file it should update local page
23986         echo "Append to the same page"
23987         cat /etc/hosts >> $dom
23988         local num=$(get_mdc_stats $mdtidx ost_read)
23989         local ra=$(get_mdc_stats $mdtidx req_active)
23990         local rw=$(get_mdc_stats $mdtidx req_waittime)
23991
23992         [ -z $num ] || error "$num READ RPC occured"
23993         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
23994         echo "... DONE"
23995
23996         # compare content
23997         cmp $tmp $dom || error "file miscompare"
23998
23999         cancel_lru_locks mdc
24000         lctl set_param -n mdc.*.stats=clear
24001
24002         echo "Open and read file"
24003         cat $dom > /dev/null
24004         local num=$(get_mdc_stats $mdtidx ost_read)
24005         local ra=$(get_mdc_stats $mdtidx req_active)
24006         local rw=$(get_mdc_stats $mdtidx req_waittime)
24007
24008         [ -z $num ] || error "$num READ RPC occured"
24009         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
24010         echo "... DONE"
24011
24012         # compare content
24013         cmp $tmp $dom || error "file miscompare"
24014
24015         return 0
24016 }
24017 run_test 271d "DoM: read on open (1K file in reply buffer)"
24018
24019 test_271f() {
24020         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
24021                 skip "Need MDS version at least 2.10.57"
24022
24023         local dom=$DIR/$tdir/dom
24024         local tmp=$TMP/$tfile
24025         trap "cleanup_271def_tests $tmp" EXIT
24026
24027         mkdir -p $DIR/$tdir
24028
24029         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
24030
24031         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
24032
24033         cancel_lru_locks mdc
24034         dd if=/dev/urandom of=$tmp bs=265000 count=1
24035         dd if=$tmp of=$dom bs=265000 count=1
24036         cancel_lru_locks mdc
24037         cat /etc/hosts >> $tmp
24038         lctl set_param -n mdc.*.stats=clear
24039
24040         echo "Append to the same page"
24041         cat /etc/hosts >> $dom
24042         local num=$(get_mdc_stats $mdtidx ost_read)
24043         local ra=$(get_mdc_stats $mdtidx req_active)
24044         local rw=$(get_mdc_stats $mdtidx req_waittime)
24045
24046         [ -z $num ] || error "$num READ RPC occured"
24047         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
24048         echo "... DONE"
24049
24050         # compare content
24051         cmp $tmp $dom || error "file miscompare"
24052
24053         cancel_lru_locks mdc
24054         lctl set_param -n mdc.*.stats=clear
24055
24056         echo "Open and read file"
24057         cat $dom > /dev/null
24058         local num=$(get_mdc_stats $mdtidx ost_read)
24059         local ra=$(get_mdc_stats $mdtidx req_active)
24060         local rw=$(get_mdc_stats $mdtidx req_waittime)
24061
24062         [ -z $num ] && num=0
24063         [ $num -eq 1 ] || error "expect 1 READ RPC, $num occured"
24064         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
24065         echo "... DONE"
24066
24067         # compare content
24068         cmp $tmp $dom || error "file miscompare"
24069
24070         return 0
24071 }
24072 run_test 271f "DoM: read on open (200K file and read tail)"
24073
24074 test_271g() {
24075         [[ $($LCTL get_param mdc.*.import) =~ async_discard ]] ||
24076                 skip "Skipping due to old client or server version"
24077
24078         $LFS setstripe -E 1024K -L mdt -E EOF $DIR1/$tfile
24079         # to get layout
24080         $CHECKSTAT -t file $DIR1/$tfile
24081
24082         $MULTIOP $DIR1/$tfile Ow40960_w4096c &
24083         MULTIOP_PID=$!
24084         sleep 1
24085         #define OBD_FAIL_LDLM_CANCEL_BL_CB_RACE
24086         $LCTL set_param fail_loc=0x80000314
24087         rm $DIR1/$tfile || error "Unlink fails"
24088         RC=$?
24089         kill -USR1 $MULTIOP_PID && wait $MULTIOP_PID || error "multiop failure"
24090         [ $RC -eq 0 ] || error "Failed write to stale object"
24091 }
24092 run_test 271g "Discard DoM data vs client flush race"
24093
24094 test_272a() {
24095         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
24096                 skip "Need MDS version at least 2.11.50"
24097
24098         local dom=$DIR/$tdir/dom
24099         mkdir -p $DIR/$tdir
24100
24101         $LFS setstripe -E 256K -L mdt -E -1 -c1 $dom
24102         dd if=/dev/urandom of=$dom bs=512K count=1 ||
24103                 error "failed to write data into $dom"
24104         local old_md5=$(md5sum $dom)
24105
24106         $LFS migrate -E 256K -L mdt -E -1 -c2 $dom ||
24107                 error "failed to migrate to the same DoM component"
24108
24109         local new_md5=$(md5sum $dom)
24110
24111         [ "$old_md5" == "$new_md5" ] ||
24112                 error "md5sum differ: $old_md5, $new_md5"
24113
24114         [ $($LFS getstripe -c $dom) -eq 2 ] ||
24115                 error "bad final stripe count: $($LFS getstripe -c $dom) != 2"
24116 }
24117 run_test 272a "DoM migration: new layout with the same DOM component"
24118
24119 test_272b() {
24120         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
24121                 skip "Need MDS version at least 2.11.50"
24122
24123         local dom=$DIR/$tdir/dom
24124         mkdir -p $DIR/$tdir
24125         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
24126         stack_trap "rm -rf $DIR/$tdir"
24127
24128         local mdtidx=$($LFS getstripe -m $dom)
24129         local mdtname=MDT$(printf %04x $mdtidx)
24130         local facet=mds$((mdtidx + 1))
24131
24132         local mdtfree1=$(do_facet $facet \
24133                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24134         dd if=/dev/urandom of=$dom bs=2M count=1 ||
24135                 error "failed to write data into $dom"
24136         local old_md5=$(md5sum $dom)
24137         cancel_lru_locks mdc
24138         local mdtfree1=$(do_facet $facet \
24139                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24140
24141         $LFS migrate -c2 $dom ||
24142                 error "failed to migrate to the new composite layout"
24143         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
24144                 error "MDT stripe was not removed"
24145
24146         cancel_lru_locks mdc
24147         local new_md5=$(md5sum $dom)
24148         [ "$old_md5" == "$new_md5" ] ||
24149                 error "$old_md5 != $new_md5"
24150
24151         # Skip free space checks with ZFS
24152         if [ "$(facet_fstype $facet)" != "zfs" ]; then
24153                 local mdtfree2=$(do_facet $facet \
24154                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24155                 [ $mdtfree2 -gt $mdtfree1 ] ||
24156                         error "MDT space is not freed after migration"
24157         fi
24158         return 0
24159 }
24160 run_test 272b "DoM migration: DOM file to the OST-striped file (plain)"
24161
24162 test_272c() {
24163         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
24164                 skip "Need MDS version at least 2.11.50"
24165
24166         local dom=$DIR/$tdir/$tfile
24167         mkdir -p $DIR/$tdir
24168         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
24169         stack_trap "rm -rf $DIR/$tdir"
24170
24171         local mdtidx=$($LFS getstripe -m $dom)
24172         local mdtname=MDT$(printf %04x $mdtidx)
24173         local facet=mds$((mdtidx + 1))
24174
24175         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
24176                 error "failed to write data into $dom"
24177         local old_md5=$(md5sum $dom)
24178         cancel_lru_locks mdc
24179         local mdtfree1=$(do_facet $facet \
24180                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24181
24182         $LFS migrate -E 2M -c1 -E -1 -c2 $dom ||
24183                 error "failed to migrate to the new composite layout"
24184         [ $($LFS getstripe -L $dom) == 'mdt' ] &&
24185                 error "MDT stripe was not removed"
24186
24187         cancel_lru_locks mdc
24188         local new_md5=$(md5sum $dom)
24189         [ "$old_md5" == "$new_md5" ] ||
24190                 error "$old_md5 != $new_md5"
24191
24192         # Skip free space checks with ZFS
24193         if [ "$(facet_fstype $facet)" != "zfs" ]; then
24194                 local mdtfree2=$(do_facet $facet \
24195                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24196                 [ $mdtfree2 -gt $mdtfree1 ] ||
24197                         error "MDS space is not freed after migration"
24198         fi
24199         return 0
24200 }
24201 run_test 272c "DoM migration: DOM file to the OST-striped file (composite)"
24202
24203 test_272d() {
24204         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
24205                 skip "Need MDS version at least 2.12.55"
24206
24207         local dom=$DIR/$tdir/$tfile
24208         mkdir -p $DIR/$tdir
24209         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
24210
24211         local mdtidx=$($LFS getstripe -m $dom)
24212         local mdtname=MDT$(printf %04x $mdtidx)
24213         local facet=mds$((mdtidx + 1))
24214
24215         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
24216                 error "failed to write data into $dom"
24217         local old_md5=$(md5sum $dom)
24218         cancel_lru_locks mdc
24219         local mdtfree1=$(do_facet $facet \
24220                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24221
24222         $LFS mirror extend -N -E 2M -c1 -E -1 -c2 $dom ||
24223                 error "failed mirroring to the new composite layout"
24224         $LFS mirror resync $dom ||
24225                 error "failed mirror resync"
24226         $LFS mirror split --mirror-id 1 -d $dom ||
24227                 error "failed mirror split"
24228
24229         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
24230                 error "MDT stripe was not removed"
24231
24232         cancel_lru_locks mdc
24233         local new_md5=$(md5sum $dom)
24234         [ "$old_md5" == "$new_md5" ] ||
24235                 error "$old_md5 != $new_md5"
24236
24237         # Skip free space checks with ZFS
24238         if [ "$(facet_fstype $facet)" != "zfs" ]; then
24239                 local mdtfree2=$(do_facet $facet \
24240                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24241                 [ $mdtfree2 -gt $mdtfree1 ] ||
24242                         error "MDS space is not freed after DOM mirror deletion"
24243         fi
24244         return 0
24245 }
24246 run_test 272d "DoM mirroring: OST-striped mirror to DOM file"
24247
24248 test_272e() {
24249         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
24250                 skip "Need MDS version at least 2.12.55"
24251
24252         local dom=$DIR/$tdir/$tfile
24253         mkdir -p $DIR/$tdir
24254         $LFS setstripe -c 2 $dom
24255
24256         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
24257                 error "failed to write data into $dom"
24258         local old_md5=$(md5sum $dom)
24259         cancel_lru_locks
24260
24261         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 $dom ||
24262                 error "failed mirroring to the DOM layout"
24263         $LFS mirror resync $dom ||
24264                 error "failed mirror resync"
24265         $LFS mirror split --mirror-id 1 -d $dom ||
24266                 error "failed mirror split"
24267
24268         [[ $($LFS getstripe -L --component-start=0 $dom) == 'mdt' ]] ||
24269                 error "MDT stripe wasn't set"
24270
24271         cancel_lru_locks
24272         local new_md5=$(md5sum $dom)
24273         [ "$old_md5" == "$new_md5" ] ||
24274                 error "$old_md5 != $new_md5"
24275
24276         return 0
24277 }
24278 run_test 272e "DoM mirroring: DOM mirror to the OST-striped file"
24279
24280 test_272f() {
24281         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
24282                 skip "Need MDS version at least 2.12.55"
24283
24284         local dom=$DIR/$tdir/$tfile
24285         mkdir -p $DIR/$tdir
24286         $LFS setstripe -c 2 $dom
24287
24288         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
24289                 error "failed to write data into $dom"
24290         local old_md5=$(md5sum $dom)
24291         cancel_lru_locks
24292
24293         $LFS migrate -E 1M -L mdt -E eof -c2 -v $dom ||
24294                 error "failed migrating to the DOM file"
24295
24296         [[ $($LFS getstripe -L --component-start=0 $dom) == 'mdt' ]] ||
24297                 error "MDT stripe wasn't set"
24298
24299         cancel_lru_locks
24300         local new_md5=$(md5sum $dom)
24301         [ "$old_md5" != "$new_md5" ] &&
24302                 error "$old_md5 != $new_md5"
24303
24304         return 0
24305 }
24306 run_test 272f "DoM migration: OST-striped file to DOM file"
24307
24308 test_273a() {
24309         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
24310                 skip "Need MDS version at least 2.11.50"
24311
24312         # Layout swap cannot be done if either file has DOM component,
24313         # this will never be supported, migration should be used instead
24314
24315         local dom=$DIR/$tdir/$tfile
24316         mkdir -p $DIR/$tdir
24317
24318         $LFS setstripe -c2 ${dom}_plain
24319         $LFS setstripe -E 1M -L mdt -E -1 -c2 ${dom}_dom
24320         $LFS swap_layouts ${dom}_plain ${dom}_dom &&
24321                 error "can swap layout with DoM component"
24322         $LFS swap_layouts ${dom}_dom ${dom}_plain &&
24323                 error "can swap layout with DoM component"
24324
24325         $LFS setstripe -E 1M -c1 -E -1 -c2 ${dom}_comp
24326         $LFS swap_layouts ${dom}_comp ${dom}_dom &&
24327                 error "can swap layout with DoM component"
24328         $LFS swap_layouts ${dom}_dom ${dom}_comp &&
24329                 error "can swap layout with DoM component"
24330         return 0
24331 }
24332 run_test 273a "DoM: layout swapping should fail with DOM"
24333
24334 test_273b() {
24335         mkdir -p $DIR/$tdir
24336         $LFS setstripe -E 1M -L mdt -E -1 -c -1 $DIR/$tdir
24337
24338 #define OBD_FAIL_MDS_COMMITRW_DELAY      0x16b
24339         do_facet mds1 $LCTL set_param fail_loc=0x8000016b fail_val=2
24340
24341         $MULTIOP $DIR/$tdir/$tfile Ouw2097152c
24342 }
24343 run_test 273b "DoM: race writeback and object destroy"
24344
24345 test_273c() {
24346         mkdir -p $DIR/$tdir
24347         $LFS setstripe -E 1M -E-1 -c-1 $DIR/$tdir
24348
24349         #define OBD_FAIL_OFD_COMMITRW_DELAY      0x1e1
24350         do_facet ost1 $LCTL set_param fail_loc=0x800001e1 fail_val=2
24351
24352         $MULTIOP $DIR/$tdir/$tfile Ouw2097152c
24353 }
24354 run_test 273c "race writeback and object destroy"
24355
24356 test_275() {
24357         remote_ost_nodsh && skip "remote OST with nodsh"
24358         [ $OST1_VERSION -lt $(version_code 2.10.57) ] &&
24359                 skip "Need OST version >= 2.10.57"
24360
24361         local file=$DIR/$tfile
24362         local oss
24363
24364         oss=$(comma_list $(osts_nodes))
24365
24366         dd if=/dev/urandom of=$file bs=1M count=2 ||
24367                 error "failed to create a file"
24368         stack_trap "rm -f $file"
24369         cancel_lru_locks osc
24370
24371         #lock 1
24372         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
24373                 error "failed to read a file"
24374
24375 #define OBD_FAIL_LDLM_PAUSE_CANCEL2      0x31f
24376         $LCTL set_param fail_loc=0x8000031f
24377
24378         cancel_lru_locks osc &
24379         sleep 1
24380
24381 #define OBD_FAIL_LDLM_PROLONG_PAUSE      0x32b
24382         do_nodes $oss $LCTL set_param fail_loc=0x8000032b
24383         #IO takes another lock, but matches the PENDING one
24384         #and places it to the IO RPC
24385         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
24386                 error "failed to read a file with PENDING lock"
24387 }
24388 run_test 275 "Read on a canceled duplicate lock"
24389
24390 test_276() {
24391         remote_ost_nodsh && skip "remote OST with nodsh"
24392         local pid
24393
24394         do_facet ost1 "(while true; do \
24395                 $LCTL get_param obdfilter.*.filesfree > /dev/null 2>&1; \
24396                 done) & pid=\\\$!; echo \\\$pid > $TMP/sanity_276_pid" &
24397         pid=$!
24398
24399         for LOOP in $(seq 20); do
24400                 stop ost1
24401                 start ost1 $(ostdevname 1) $OST_MOUNT_OPTS
24402         done
24403         kill -9 $pid
24404         do_facet ost1 "pid=\\\$(cat $TMP/sanity_276_pid); kill -9 \\\$pid; \
24405                 rm $TMP/sanity_276_pid"
24406 }
24407 run_test 276 "Race between mount and obd_statfs"
24408
24409 test_277() {
24410         $LCTL set_param ldlm.namespaces.*.lru_size=0
24411         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
24412         local cached_mb=$($LCTL get_param llite.*.max_cached_mb |
24413                         grep ^used_mb | awk '{print $2}')
24414         [ $cached_mb -eq 1 ] || error "expected mb 1 got $cached_mb"
24415         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 \
24416                 oflag=direct conv=notrunc
24417         cached_mb=$($LCTL get_param llite.*.max_cached_mb |
24418                         grep ^used_mb | awk '{print $2}')
24419         [ $cached_mb -eq 0 ] || error "expected mb 0 got $cached_mb"
24420 }
24421 run_test 277 "Direct IO shall drop page cache"
24422
24423 test_278() {
24424         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
24425         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
24426         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] &&
24427                 skip "needs the same host for mdt1 mdt2" && return
24428
24429         local pid1
24430         local pid2
24431
24432 #define OBD_FAIL_OBD_STOP_MDS_RACE     0x60b
24433         do_facet mds2 $LCTL set_param fail_loc=0x8000060c
24434         stop mds2 &
24435         pid2=$!
24436
24437         stop mds1
24438
24439         echo "Starting MDTs"
24440         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
24441         wait $pid2
24442 #For the error assertion will happen. lu_env_get_key(..., &mdt_thread_key)
24443 #will return NULL
24444         do_facet mds2 $LCTL set_param fail_loc=0
24445
24446         start mds2 $(mdsdevname 2) $MDS_MOUNT_OPTS
24447         wait_recovery_complete mds2
24448 }
24449 run_test 278 "Race starting MDS between MDTs stop/start"
24450
24451 test_280() {
24452         [ $MGS_VERSION -lt $(version_code 2.13.52) ] &&
24453                 skip "Need MGS version at least 2.13.52"
24454         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24455         combined_mgs_mds || skip "needs combined MGS/MDT"
24456
24457         umount_client $MOUNT
24458 #define OBD_FAIL_MDS_LLOG_UMOUNT_RACE   0x15e
24459         do_facet mgs $LCTL set_param fail_loc=0x8000015e fail_val=0
24460
24461         mount_client $MOUNT &
24462         sleep 1
24463         stop mgs || error "stop mgs failed"
24464         #for a race mgs would crash
24465         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
24466         # make sure we unmount client before remounting
24467         wait
24468         umount_client $MOUNT
24469         mount_client $MOUNT || error "mount client failed"
24470 }
24471 run_test 280 "Race between MGS umount and client llog processing"
24472
24473 cleanup_test_300() {
24474         trap 0
24475         umask $SAVE_UMASK
24476 }
24477 test_striped_dir() {
24478         local mdt_index=$1
24479         local stripe_count
24480         local stripe_index
24481
24482         mkdir -p $DIR/$tdir
24483
24484         SAVE_UMASK=$(umask)
24485         trap cleanup_test_300 RETURN EXIT
24486
24487         $LFS setdirstripe -i $mdt_index -c 2 -H all_char -o 755 \
24488                                                 $DIR/$tdir/striped_dir ||
24489                 error "set striped dir error"
24490
24491         local mode=$(stat -c%a $DIR/$tdir/striped_dir)
24492         [ "$mode" = "755" ] || error "expect 755 got $mode"
24493
24494         $LFS getdirstripe $DIR/$tdir/striped_dir > /dev/null 2>&1 ||
24495                 error "getdirstripe failed"
24496         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir)
24497         if [ "$stripe_count" != "2" ]; then
24498                 error "1:stripe_count is $stripe_count, expect 2"
24499         fi
24500         stripe_count=$($LFS getdirstripe -T $DIR/$tdir/striped_dir)
24501         if [ "$stripe_count" != "2" ]; then
24502                 error "2:stripe_count is $stripe_count, expect 2"
24503         fi
24504
24505         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir)
24506         if [ "$stripe_index" != "$mdt_index" ]; then
24507                 error "stripe_index is $stripe_index, expect $mdt_index"
24508         fi
24509
24510         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
24511                 error "nlink error after create striped dir"
24512
24513         mkdir $DIR/$tdir/striped_dir/a
24514         mkdir $DIR/$tdir/striped_dir/b
24515
24516         stat $DIR/$tdir/striped_dir/a ||
24517                 error "create dir under striped dir failed"
24518         stat $DIR/$tdir/striped_dir/b ||
24519                 error "create dir under striped dir failed"
24520
24521         [ $(stat -c%h $DIR/$tdir/striped_dir) == '4' ] ||
24522                 error "nlink error after mkdir"
24523
24524         rmdir $DIR/$tdir/striped_dir/a
24525         [ $(stat -c%h $DIR/$tdir/striped_dir) == '3' ] ||
24526                 error "nlink error after rmdir"
24527
24528         rmdir $DIR/$tdir/striped_dir/b
24529         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
24530                 error "nlink error after rmdir"
24531
24532         chattr +i $DIR/$tdir/striped_dir
24533         createmany -o $DIR/$tdir/striped_dir/f 10 &&
24534                 error "immutable flags not working under striped dir!"
24535         chattr -i $DIR/$tdir/striped_dir
24536
24537         rmdir $DIR/$tdir/striped_dir ||
24538                 error "rmdir striped dir error"
24539
24540         cleanup_test_300
24541
24542         true
24543 }
24544
24545 test_300a() {
24546         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
24547                 skip "skipped for lustre < 2.7.0"
24548         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24549         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24550
24551         test_striped_dir 0 || error "failed on striped dir on MDT0"
24552         test_striped_dir 1 || error "failed on striped dir on MDT0"
24553 }
24554 run_test 300a "basic striped dir sanity test"
24555
24556 test_300b() {
24557         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
24558                 skip "skipped for lustre < 2.7.0"
24559         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24560         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24561
24562         local i
24563         local mtime1
24564         local mtime2
24565         local mtime3
24566
24567         test_mkdir $DIR/$tdir || error "mkdir fail"
24568         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
24569                 error "set striped dir error"
24570         for i in {0..9}; do
24571                 mtime1=$(stat -c %Y $DIR/$tdir/striped_dir)
24572                 sleep 1
24573                 touch $DIR/$tdir/striped_dir/file_$i || error "touch error $i"
24574                 mtime2=$(stat -c %Y $DIR/$tdir/striped_dir)
24575                 [ $mtime1 -eq $mtime2 ] && error "mtime unchanged after create"
24576                 sleep 1
24577                 rm -f $DIR/$tdir/striped_dir/file_$i || error "unlink error $i"
24578                 mtime3=$(stat -c %Y $DIR/$tdir/striped_dir)
24579                 [ $mtime2 -eq $mtime3 ] && error "mtime unchanged after unlink"
24580         done
24581         true
24582 }
24583 run_test 300b "check ctime/mtime for striped dir"
24584
24585 test_300c() {
24586         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
24587                 skip "skipped for lustre < 2.7.0"
24588         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24589         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24590
24591         local file_count
24592
24593         mkdir_on_mdt0 $DIR/$tdir
24594         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir ||
24595                 error "set striped dir error"
24596
24597         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/striped_dir ||
24598                 error "chown striped dir failed"
24599
24600         $RUNAS createmany -o $DIR/$tdir/striped_dir/f 5000 ||
24601                 error "create 5k files failed"
24602
24603         file_count=$(ls $DIR/$tdir/striped_dir | wc -l)
24604
24605         [ "$file_count" = 5000 ] || error "file count $file_count != 5000"
24606
24607         rm -rf $DIR/$tdir
24608 }
24609 run_test 300c "chown && check ls under striped directory"
24610
24611 test_300d() {
24612         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
24613                 skip "skipped for lustre < 2.7.0"
24614         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24615         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24616
24617         local stripe_count
24618         local file
24619
24620         mkdir -p $DIR/$tdir
24621         $LFS setstripe -c 2 $DIR/$tdir
24622
24623         #local striped directory
24624         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
24625                 error "set striped dir error"
24626         #look at the directories for debug purposes
24627         ls -l $DIR/$tdir
24628         $LFS getdirstripe $DIR/$tdir
24629         ls -l $DIR/$tdir/striped_dir
24630         $LFS getdirstripe $DIR/$tdir/striped_dir
24631         createmany -o $DIR/$tdir/striped_dir/f 10 ||
24632                 error "create 10 files failed"
24633
24634         #remote striped directory
24635         $LFS setdirstripe -i 1 -c 2 $DIR/$tdir/remote_striped_dir ||
24636                 error "set striped dir error"
24637         #look at the directories for debug purposes
24638         ls -l $DIR/$tdir
24639         $LFS getdirstripe $DIR/$tdir
24640         ls -l $DIR/$tdir/remote_striped_dir
24641         $LFS getdirstripe $DIR/$tdir/remote_striped_dir
24642         createmany -o $DIR/$tdir/remote_striped_dir/f 10 ||
24643                 error "create 10 files failed"
24644
24645         for file in $(find $DIR/$tdir); do
24646                 stripe_count=$($LFS getstripe -c $file)
24647                 [ $stripe_count -eq 2 ] ||
24648                         error "wrong stripe $stripe_count for $file"
24649         done
24650
24651         rm -rf $DIR/$tdir
24652 }
24653 run_test 300d "check default stripe under striped directory"
24654
24655 test_300e() {
24656         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24657                 skip "Need MDS version at least 2.7.55"
24658         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24659         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24660
24661         local stripe_count
24662         local file
24663
24664         mkdir -p $DIR/$tdir
24665
24666         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
24667                 error "set striped dir error"
24668
24669         touch $DIR/$tdir/striped_dir/a
24670         touch $DIR/$tdir/striped_dir/b
24671         touch $DIR/$tdir/striped_dir/c
24672
24673         mkdir $DIR/$tdir/striped_dir/dir_a
24674         mkdir $DIR/$tdir/striped_dir/dir_b
24675         mkdir $DIR/$tdir/striped_dir/dir_c
24676
24677         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_a ||
24678                 error "set striped adir under striped dir error"
24679
24680         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_b ||
24681                 error "set striped bdir under striped dir error"
24682
24683         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_c ||
24684                 error "set striped cdir under striped dir error"
24685
24686         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir/dir_b ||
24687                 error "rename dir under striped dir fails"
24688
24689         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir/stp_b ||
24690                 error "rename dir under different stripes fails"
24691
24692         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir/c ||
24693                 error "rename file under striped dir should succeed"
24694
24695         mrename $DIR/$tdir/striped_dir/dir_b $DIR/$tdir/striped_dir/dir_c ||
24696                 error "rename dir under striped dir should succeed"
24697
24698         rm -rf $DIR/$tdir
24699 }
24700 run_test 300e "check rename under striped directory"
24701
24702 test_300f() {
24703         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24704         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24705         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24706                 skip "Need MDS version at least 2.7.55"
24707
24708         local stripe_count
24709         local file
24710
24711         rm -rf $DIR/$tdir
24712         mkdir -p $DIR/$tdir
24713
24714         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
24715                 error "set striped dir error"
24716
24717         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir1 ||
24718                 error "set striped dir error"
24719
24720         touch $DIR/$tdir/striped_dir/a
24721         mkdir $DIR/$tdir/striped_dir/dir_a
24722         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_a ||
24723                 error "create striped dir under striped dir fails"
24724
24725         touch $DIR/$tdir/striped_dir1/b
24726         mkdir $DIR/$tdir/striped_dir1/dir_b
24727         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_b ||
24728                 error "create striped dir under striped dir fails"
24729
24730         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir1/dir_b ||
24731                 error "rename dir under different striped dir should fail"
24732
24733         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir1/stp_b ||
24734                 error "rename striped dir under diff striped dir should fail"
24735
24736         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir1/a ||
24737                 error "rename file under diff striped dirs fails"
24738
24739         rm -rf $DIR/$tdir
24740 }
24741 run_test 300f "check rename cross striped directory"
24742
24743 test_300_check_default_striped_dir()
24744 {
24745         local dirname=$1
24746         local default_count=$2
24747         local default_index=$3
24748         local stripe_count
24749         local stripe_index
24750         local dir_stripe_index
24751         local dir
24752
24753         echo "checking $dirname $default_count $default_index"
24754         $LFS setdirstripe -D -c $default_count -i $default_index \
24755                                 -H all_char $DIR/$tdir/$dirname ||
24756                 error "set default stripe on striped dir error"
24757         stripe_count=$($LFS getdirstripe -D -c $DIR/$tdir/$dirname)
24758         [ $stripe_count -eq $default_count ] ||
24759                 error "expect $default_count get $stripe_count for $dirname"
24760
24761         stripe_index=$($LFS getdirstripe -D -i $DIR/$tdir/$dirname)
24762         [ $stripe_index -eq $default_index ] ||
24763                 error "expect $default_index get $stripe_index for $dirname"
24764
24765         mkdir $DIR/$tdir/$dirname/{test1,test2,test3,test4} ||
24766                                                 error "create dirs failed"
24767
24768         createmany -o $DIR/$tdir/$dirname/f- 10 || error "create files failed"
24769         unlinkmany $DIR/$tdir/$dirname/f- 10    || error "unlink files failed"
24770         for dir in $(find $DIR/$tdir/$dirname/*); do
24771                 stripe_count=$($LFS getdirstripe -c $dir)
24772                 (( $stripe_count == $default_count )) ||
24773                 (( $stripe_count == $MDSCOUNT && $default_count == -1 )) ||
24774                 (( $stripe_count == 0 )) || (( $default_count == 1 )) ||
24775                 error "stripe count $default_count != $stripe_count for $dir"
24776
24777                 stripe_index=$($LFS getdirstripe -i $dir)
24778                 [ $default_index -eq -1 ] ||
24779                         [ $stripe_index -eq $default_index ] ||
24780                         error "$stripe_index != $default_index for $dir"
24781
24782                 #check default stripe
24783                 stripe_count=$($LFS getdirstripe -D -c $dir)
24784                 [ $stripe_count -eq $default_count ] ||
24785                 error "default count $default_count != $stripe_count for $dir"
24786
24787                 stripe_index=$($LFS getdirstripe -D -i $dir)
24788                 [ $stripe_index -eq $default_index ] ||
24789                 error "default index $default_index != $stripe_index for $dir"
24790         done
24791         rmdir $DIR/$tdir/$dirname/* || error "rmdir failed"
24792 }
24793
24794 test_300g() {
24795         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24796         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24797                 skip "Need MDS version at least 2.7.55"
24798
24799         local dir
24800         local stripe_count
24801         local stripe_index
24802
24803         mkdir_on_mdt0 $DIR/$tdir
24804         mkdir $DIR/$tdir/normal_dir
24805
24806         #Checking when client cache stripe index
24807         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
24808         $LFS setdirstripe -D -i1 $DIR/$tdir/striped_dir ||
24809                 error "create striped_dir failed"
24810
24811         $LFS setdirstripe -i0 $DIR/$tdir/striped_dir/dir0 ||
24812                 error "create dir0 fails"
24813         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir0)
24814         [ $stripe_index -eq 0 ] ||
24815                 error "dir0 expect index 0 got $stripe_index"
24816
24817         mkdir $DIR/$tdir/striped_dir/dir1 ||
24818                 error "create dir1 fails"
24819         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir1)
24820         [ $stripe_index -eq 1 ] ||
24821                 error "dir1 expect index 1 got $stripe_index"
24822
24823         #check default stripe count/stripe index
24824         test_300_check_default_striped_dir normal_dir $MDSCOUNT 1
24825         test_300_check_default_striped_dir normal_dir 1 0
24826         test_300_check_default_striped_dir normal_dir -1 1
24827         test_300_check_default_striped_dir normal_dir 2 -1
24828
24829         #delete default stripe information
24830         echo "delete default stripeEA"
24831         $LFS setdirstripe -d $DIR/$tdir/normal_dir ||
24832                 error "set default stripe on striped dir error"
24833
24834         mkdir -p $DIR/$tdir/normal_dir/{test1,test2,test3,test4}
24835         for dir in $(find $DIR/$tdir/normal_dir/*); do
24836                 stripe_count=$($LFS getdirstripe -c $dir)
24837                 [ $stripe_count -eq 0 ] ||
24838                         error "expect 1 get $stripe_count for $dir"
24839         done
24840 }
24841 run_test 300g "check default striped directory for normal directory"
24842
24843 test_300h() {
24844         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24845         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24846                 skip "Need MDS version at least 2.7.55"
24847
24848         local dir
24849         local stripe_count
24850
24851         mkdir $DIR/$tdir
24852         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
24853                 error "set striped dir error"
24854
24855         test_300_check_default_striped_dir striped_dir $MDSCOUNT 1
24856         test_300_check_default_striped_dir striped_dir 1 0
24857         test_300_check_default_striped_dir striped_dir -1 1
24858         test_300_check_default_striped_dir striped_dir 2 -1
24859
24860         #delete default stripe information
24861         $LFS setdirstripe -d $DIR/$tdir/striped_dir ||
24862                 error "set default stripe on striped dir error"
24863
24864         mkdir -p $DIR/$tdir/striped_dir/{test1,test2,test3,test4}
24865         for dir in $(find $DIR/$tdir/striped_dir/*); do
24866                 stripe_count=$($LFS getdirstripe -c $dir)
24867                 [ $stripe_count -eq 0 ] ||
24868                         error "expect 1 get $stripe_count for $dir"
24869         done
24870 }
24871 run_test 300h "check default striped directory for striped directory"
24872
24873 test_300i() {
24874         [[ $PARALLEL == "yes" ]] && skip "skip parallel run"
24875         (( $MDSCOUNT >= 2 )) || skip_env "needs >= 2 MDTs"
24876         (( $MDS1_VERSION >= $(version_code 2.7.55) )) ||
24877                 skip "Need MDS version at least 2.7.55"
24878
24879         local stripe_count
24880         local file
24881
24882         mkdir $DIR/$tdir
24883
24884         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
24885                 error "set striped dir error"
24886
24887         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
24888                 error "create files under striped dir failed"
24889
24890         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir ||
24891                 error "set striped hashdir error"
24892
24893         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir/d0 ||
24894                 error "create dir0 under hash dir failed"
24895         $LFS setdirstripe -i0 -c$MDSCOUNT -H fnv_1a_64 $DIR/$tdir/hashdir/d1 ||
24896                 error "create dir1 under hash dir failed"
24897         $LFS setdirstripe -i0 -c$MDSCOUNT -H crush $DIR/$tdir/hashdir/d2 ||
24898                 error "create dir2 under hash dir failed"
24899
24900         # unfortunately, we need to umount to clear dir layout cache for now
24901         # once we fully implement dir layout, we can drop this
24902         umount_client $MOUNT || error "umount failed"
24903         mount_client $MOUNT || error "mount failed"
24904
24905         $LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir
24906         local dircnt=$($LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir | wc -l)
24907         (( $dircnt == 2 )) || error "lfs find striped dir got $dircnt != 2"
24908
24909         if (( $MDS1_VERSION > $(version_code 2.15.0) )); then
24910                 $LFS mkdir -i0 -c$MDSCOUNT -H crush2 $DIR/$tdir/hashdir/d3 ||
24911                         error "create crush2 dir $tdir/hashdir/d3 failed"
24912                 $LFS find -H crush2 $DIR/$tdir/hashdir
24913                 dircnt=$($LFS find -H crush2 $DIR/$tdir/hashdir | wc -l)
24914                 (( $dircnt == 1 )) || error "find crush2 dir got $dircnt != 1"
24915
24916                 # mkdir with an invalid hash type (hash=fail_val) from client
24917                 # should be replaced on MDS with a valid (default) hash type
24918                 #define OBD_FAIL_LMV_UNKNOWN_STRIPE     0x1901
24919                 $LCTL set_param fail_loc=0x1901 fail_val=99
24920                 $LFS mkdir -c2 $DIR/$tdir/hashdir/d99
24921
24922                 local hash=$($LFS getdirstripe -H $DIR/$tdir/hashdir/d99)
24923                 local expect=$(do_facet mds1 \
24924                         $LCTL get_param -n lod.$FSNAME-MDT0000-mdtlov.mdt_hash)
24925                 [[ $hash == $expect ]] ||
24926                         error "d99 hash '$hash' != expected hash '$expect'"
24927         fi
24928
24929         #set the stripe to be unknown hash type on read
24930         #define OBD_FAIL_LMV_UNKNOWN_STRIPE     0x1901
24931         $LCTL set_param fail_loc=0x1901 fail_val=99
24932         for ((i = 0; i < 10; i++)); do
24933                 $CHECKSTAT -t file $DIR/$tdir/striped_dir/f-$i ||
24934                         error "stat f-$i failed"
24935                 rm $DIR/$tdir/striped_dir/f-$i || error "unlink f-$i failed"
24936         done
24937
24938         touch $DIR/$tdir/striped_dir/f0 &&
24939                 error "create under striped dir with unknown hash should fail"
24940
24941         $LCTL set_param fail_loc=0
24942
24943         umount_client $MOUNT || error "umount failed"
24944         mount_client $MOUNT || error "mount failed"
24945
24946         return 0
24947 }
24948 run_test 300i "client handle unknown hash type striped directory"
24949
24950 test_300j() {
24951         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24952         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24953         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24954                 skip "Need MDS version at least 2.7.55"
24955
24956         local stripe_count
24957         local file
24958
24959         mkdir $DIR/$tdir
24960
24961         #define OBD_FAIL_SPLIT_UPDATE_REC       0x1702
24962         $LCTL set_param fail_loc=0x1702
24963         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
24964                 error "set striped dir error"
24965
24966         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
24967                 error "create files under striped dir failed"
24968
24969         $LCTL set_param fail_loc=0
24970
24971         rm -rf $DIR/$tdir || error "unlink striped dir fails"
24972
24973         return 0
24974 }
24975 run_test 300j "test large update record"
24976
24977 test_300k() {
24978         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24979         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24980         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24981                 skip "Need MDS version at least 2.7.55"
24982
24983         # this test needs a huge transaction
24984         local kb
24985         kb=$(do_facet $SINGLEMDS "$LCTL get_param -n \
24986              osd*.$FSNAME-MDT0000.kbytestotal")
24987         [ $kb -lt $((1024*1024)) ] && skip "MDT0 too small: $kb"
24988
24989         local stripe_count
24990         local file
24991
24992         mkdir $DIR/$tdir
24993
24994         #define OBD_FAIL_LARGE_STRIPE   0x1703
24995         $LCTL set_param fail_loc=0x1703
24996         $LFS setdirstripe -i 0 -c192 $DIR/$tdir/striped_dir ||
24997                 error "set striped dir error"
24998         $LCTL set_param fail_loc=0
24999
25000         $LFS getdirstripe $DIR/$tdir/striped_dir ||
25001                 error "getstripeddir fails"
25002         rm -rf $DIR/$tdir/striped_dir ||
25003                 error "unlink striped dir fails"
25004
25005         return 0
25006 }
25007 run_test 300k "test large striped directory"
25008
25009 test_300l() {
25010         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25011         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25012         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25013                 skip "Need MDS version at least 2.7.55"
25014
25015         local stripe_index
25016
25017         test_mkdir -p $DIR/$tdir/striped_dir
25018         chown $RUNAS_ID $DIR/$tdir/striped_dir ||
25019                         error "chown $RUNAS_ID failed"
25020         $LFS setdirstripe -i 1 -D $DIR/$tdir/striped_dir ||
25021                 error "set default striped dir failed"
25022
25023         #define OBD_FAIL_MDS_STALE_DIR_LAYOUT    0x158
25024         $LCTL set_param fail_loc=0x80000158
25025         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir || error "create dir fails"
25026
25027         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/test_dir)
25028         [ $stripe_index -eq 1 ] ||
25029                 error "expect 1 get $stripe_index for $dir"
25030 }
25031 run_test 300l "non-root user to create dir under striped dir with stale layout"
25032
25033 test_300m() {
25034         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25035         [ $MDSCOUNT -ge 2 ] && skip_env "Only for single MDT"
25036         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25037                 skip "Need MDS version at least 2.7.55"
25038
25039         mkdir -p $DIR/$tdir/striped_dir
25040         $LFS setdirstripe -D -c 1 $DIR/$tdir/striped_dir ||
25041                 error "set default stripes dir error"
25042
25043         mkdir $DIR/$tdir/striped_dir/a || error "mkdir a fails"
25044
25045         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/a)
25046         [ $stripe_count -eq 0 ] ||
25047                         error "expect 0 get $stripe_count for a"
25048
25049         $LFS setdirstripe -D -c 2 $DIR/$tdir/striped_dir ||
25050                 error "set default stripes dir error"
25051
25052         mkdir $DIR/$tdir/striped_dir/b || error "mkdir b fails"
25053
25054         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/b)
25055         [ $stripe_count -eq 0 ] ||
25056                         error "expect 0 get $stripe_count for b"
25057
25058         $LFS setdirstripe -D -c1 -i2 $DIR/$tdir/striped_dir ||
25059                 error "set default stripes dir error"
25060
25061         mkdir $DIR/$tdir/striped_dir/c &&
25062                 error "default stripe_index is invalid, mkdir c should fails"
25063
25064         rm -rf $DIR/$tdir || error "rmdir fails"
25065 }
25066 run_test 300m "setstriped directory on single MDT FS"
25067
25068 cleanup_300n() {
25069         local list=$(comma_list $(mdts_nodes))
25070
25071         trap 0
25072         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
25073 }
25074
25075 test_300n() {
25076         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25077         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25078         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25079                 skip "Need MDS version at least 2.7.55"
25080         remote_mds_nodsh && skip "remote MDS with nodsh"
25081
25082         local stripe_index
25083         local list=$(comma_list $(mdts_nodes))
25084
25085         trap cleanup_300n RETURN EXIT
25086         mkdir -p $DIR/$tdir
25087         chmod 777 $DIR/$tdir
25088         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT \
25089                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
25090                 error "create striped dir succeeds with gid=0"
25091
25092         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
25093         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
25094                 error "create striped dir fails with gid=-1"
25095
25096         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
25097         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D \
25098                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
25099                 error "set default striped dir succeeds with gid=0"
25100
25101
25102         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
25103         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D $DIR/$tdir/striped_dir ||
25104                 error "set default striped dir fails with gid=-1"
25105
25106
25107         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
25108         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir ||
25109                                         error "create test_dir fails"
25110         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir1 ||
25111                                         error "create test_dir1 fails"
25112         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir2 ||
25113                                         error "create test_dir2 fails"
25114         cleanup_300n
25115 }
25116 run_test 300n "non-root user to create dir under striped dir with default EA"
25117
25118 test_300o() {
25119         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25120         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25121         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25122                 skip "Need MDS version at least 2.7.55"
25123
25124         local numfree1
25125         local numfree2
25126
25127         mkdir -p $DIR/$tdir
25128
25129         numfree1=$(lctl get_param -n mdc.*MDT0000*.filesfree)
25130         numfree2=$(lctl get_param -n mdc.*MDT0001*.filesfree)
25131         if [ $numfree1 -lt 66000 ] || [ $numfree2 -lt 66000 ]; then
25132                 skip "not enough free inodes $numfree1 $numfree2"
25133         fi
25134
25135         numfree1=$(lctl get_param -n mdc.*MDT0000-mdc-*.kbytesfree)
25136         numfree2=$(lctl get_param -n mdc.*MDT0001-mdc-*.kbytesfree)
25137         if [ $numfree1 -lt 300000 ] || [ $numfree2 -lt 300000 ]; then
25138                 skip "not enough free space $numfree1 $numfree2"
25139         fi
25140
25141         $LFS setdirstripe -c2 $DIR/$tdir/striped_dir ||
25142                 error "setdirstripe fails"
25143
25144         createmany -d $DIR/$tdir/striped_dir/d 131000 ||
25145                 error "create dirs fails"
25146
25147         $LCTL set_param ldlm.namespaces.*mdc-*.lru_size=0
25148         ls $DIR/$tdir/striped_dir > /dev/null ||
25149                 error "ls striped dir fails"
25150         unlinkmany -d $DIR/$tdir/striped_dir/d 131000 ||
25151                 error "unlink big striped dir fails"
25152 }
25153 run_test 300o "unlink big sub stripe(> 65000 subdirs)"
25154
25155 test_300p() {
25156         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25157         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25158         remote_mds_nodsh && skip "remote MDS with nodsh"
25159
25160         mkdir_on_mdt0 $DIR/$tdir
25161
25162         #define OBD_FAIL_OUT_ENOSPC     0x1704
25163         do_facet mds2 lctl set_param fail_loc=0x80001704
25164         $LFS setdirstripe -i 0 -c2 $DIR/$tdir/bad_striped_dir > /dev/null 2>&1 \
25165                  && error "create striped directory should fail"
25166
25167         [ -e $DIR/$tdir/bad_striped_dir ] && error "striped dir exists"
25168
25169         $LFS setdirstripe -c2 $DIR/$tdir/bad_striped_dir
25170         true
25171 }
25172 run_test 300p "create striped directory without space"
25173
25174 test_300q() {
25175         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25176         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25177
25178         local fd=$(free_fd)
25179         local cmd="exec $fd<$tdir"
25180         cd $DIR
25181         $LFS mkdir -c $MDSCOUNT $tdir || error "create $tdir fails"
25182         eval $cmd
25183         cmd="exec $fd<&-"
25184         trap "eval $cmd" EXIT
25185         cd $tdir || error "cd $tdir fails"
25186         rmdir  ../$tdir || error "rmdir $tdir fails"
25187         mkdir local_dir && error "create dir succeeds"
25188         $LFS setdirstripe -i1 remote_dir && error "create remote dir succeeds"
25189         eval $cmd
25190         return 0
25191 }
25192 run_test 300q "create remote directory under orphan directory"
25193
25194 test_300r() {
25195         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25196                 skip "Need MDS version at least 2.7.55" && return
25197         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
25198
25199         mkdir $DIR/$tdir
25200
25201         $LFS setdirstripe -i 0 -c -1 $DIR/$tdir/striped_dir ||
25202                 error "set striped dir error"
25203
25204         $LFS getdirstripe $DIR/$tdir/striped_dir ||
25205                 error "getstripeddir fails"
25206
25207         local stripe_count
25208         stripe_count=$($LFS getdirstripe $DIR/$tdir/striped_dir |
25209                       awk '/lmv_stripe_count:/ { print $2 }')
25210
25211         [ $MDSCOUNT -ne $stripe_count ] &&
25212                 error "wrong stripe count $stripe_count expected $MDSCOUNT"
25213
25214         rm -rf $DIR/$tdir/striped_dir ||
25215                 error "unlink striped dir fails"
25216 }
25217 run_test 300r "test -1 striped directory"
25218
25219 test_300s_helper() {
25220         local count=$1
25221
25222         local stripe_dir=$DIR/$tdir/striped_dir.$count
25223
25224         $LFS mkdir -c $count $stripe_dir ||
25225                 error "lfs mkdir -c error"
25226
25227         $LFS getdirstripe $stripe_dir ||
25228                 error "lfs getdirstripe fails"
25229
25230         local stripe_count
25231         stripe_count=$($LFS getdirstripe $stripe_dir |
25232                       awk '/lmv_stripe_count:/ { print $2 }')
25233
25234         [ $count -ne $stripe_count ] &&
25235                 error_noexit "bad stripe count $stripe_count expected $count"
25236
25237         local dupe_stripes
25238         dupe_stripes=$($LFS getdirstripe $stripe_dir |
25239                 awk '/0x/ {count[$1] += 1}; END {
25240                         for (idx in count) {
25241                                 if (count[idx]>1) {
25242                                         print "index " idx " count " count[idx]
25243                                 }
25244                         }
25245                 }')
25246
25247         if [[ -n "$dupe_stripes" ]] ; then
25248                 lfs getdirstripe $stripe_dir
25249                 error_noexit "Dupe MDT above: $dupe_stripes "
25250         fi
25251
25252         rm -rf $stripe_dir ||
25253                 error_noexit "unlink $stripe_dir fails"
25254 }
25255
25256 test_300s() {
25257         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25258                 skip "Need MDS version at least 2.7.55" && return
25259         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
25260
25261         mkdir $DIR/$tdir
25262         for count in $(seq 2 $MDSCOUNT); do
25263                 test_300s_helper $count
25264         done
25265 }
25266 run_test 300s "test lfs mkdir -c without -i"
25267
25268 test_300t() {
25269         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
25270                 skip "need MDS 2.14.55 or later"
25271         (( $MDSCOUNT >= 2 )) || skip "needs at least 2 MDTs"
25272
25273         local testdir="$DIR/$tdir/striped_dir"
25274         local dir1=$testdir/dir1
25275         local dir2=$testdir/dir2
25276
25277         mkdir -p $testdir
25278
25279         $LFS setdirstripe -D -c -1 --max-inherit=3 $testdir ||
25280                 error "failed to set default stripe count for $testdir"
25281
25282         mkdir $dir1
25283         local stripe_count=$($LFS getdirstripe -c $dir1)
25284
25285         (( $stripe_count == $MDSCOUNT )) || error "wrong stripe count"
25286
25287         local max_count=$((MDSCOUNT - 1))
25288         local mdts=$(comma_list $(mdts_nodes))
25289
25290         do_nodes $mdts $LCTL set_param lod.*.max_mdt_stripecount=$max_count
25291         stack_trap "do_nodes $mdts $LCTL set_param lod.*.max_mdt_stripecount=0"
25292
25293         mkdir $dir2
25294         stripe_count=$($LFS getdirstripe -c $dir2)
25295
25296         (( $stripe_count == $max_count )) || error "wrong stripe count"
25297 }
25298 run_test 300t "test max_mdt_stripecount"
25299
25300 prepare_remote_file() {
25301         mkdir $DIR/$tdir/src_dir ||
25302                 error "create remote source failed"
25303
25304         cp /etc/hosts $DIR/$tdir/src_dir/a ||
25305                  error "cp to remote source failed"
25306         touch $DIR/$tdir/src_dir/a
25307
25308         $LFS mkdir -i 1 $DIR/$tdir/tgt_dir ||
25309                 error "create remote target dir failed"
25310
25311         touch $DIR/$tdir/tgt_dir/b
25312
25313         mrename $DIR/$tdir/src_dir/a $DIR/$tdir/tgt_dir/b ||
25314                 error "rename dir cross MDT failed!"
25315
25316         $CHECKSTAT -t file $DIR/$tdir/src_dir/a &&
25317                 error "src_child still exists after rename"
25318
25319         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/b ||
25320                 error "missing file(a) after rename"
25321
25322         diff /etc/hosts $DIR/$tdir/tgt_dir/b ||
25323                 error "diff after rename"
25324 }
25325
25326 test_310a() {
25327         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
25328         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25329
25330         local remote_file=$DIR/$tdir/tgt_dir/b
25331
25332         mkdir -p $DIR/$tdir
25333
25334         prepare_remote_file || error "prepare remote file failed"
25335
25336         #open-unlink file
25337         $OPENUNLINK $remote_file $remote_file ||
25338                 error "openunlink $remote_file failed"
25339         $CHECKSTAT -a $remote_file || error "$remote_file exists"
25340 }
25341 run_test 310a "open unlink remote file"
25342
25343 test_310b() {
25344         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
25345         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25346
25347         local remote_file=$DIR/$tdir/tgt_dir/b
25348
25349         mkdir -p $DIR/$tdir
25350
25351         prepare_remote_file || error "prepare remote file failed"
25352
25353         ln $remote_file $DIR/$tfile || error "link failed for remote file"
25354         $MULTIOP $DIR/$tfile Ouc || error "mulitop failed"
25355         $CHECKSTAT -t file $remote_file || error "check file failed"
25356 }
25357 run_test 310b "unlink remote file with multiple links while open"
25358
25359 test_310c() {
25360         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25361         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
25362
25363         local remote_file=$DIR/$tdir/tgt_dir/b
25364
25365         mkdir -p $DIR/$tdir
25366
25367         prepare_remote_file || error "prepare remote file failed"
25368
25369         ln $remote_file $DIR/$tfile || error "link failed for remote file"
25370         multiop_bg_pause $remote_file O_uc ||
25371                         error "mulitop failed for remote file"
25372         MULTIPID=$!
25373         $MULTIOP $DIR/$tfile Ouc
25374         kill -USR1 $MULTIPID
25375         wait $MULTIPID
25376 }
25377 run_test 310c "open-unlink remote file with multiple links"
25378
25379 #LU-4825
25380 test_311() {
25381         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25382         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
25383         [ $MDS1_VERSION -lt $(version_code 2.8.54) ] &&
25384                 skip "lustre < 2.8.54 does not contain LU-4825 fix"
25385         remote_mds_nodsh && skip "remote MDS with nodsh"
25386
25387         local old_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
25388         local mdts=$(comma_list $(mdts_nodes))
25389
25390         mkdir -p $DIR/$tdir
25391         $LFS setstripe -i 0 -c 1 $DIR/$tdir
25392         createmany -o $DIR/$tdir/$tfile. 1000
25393
25394         # statfs data is not real time, let's just calculate it
25395         old_iused=$((old_iused + 1000))
25396
25397         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
25398                         osp.*OST0000*MDT0000.create_count")
25399         local max_count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
25400                                 osp.*OST0000*MDT0000.max_create_count")
25401         do_nodes $mdts "$LCTL set_param -n osp.*OST0000*.max_create_count=0"
25402
25403         $LFS setstripe -i 0 $DIR/$tdir/$tfile || error "setstripe failed"
25404         local index=$($LFS getstripe -i $DIR/$tdir/$tfile)
25405         [ $index -ne 0 ] || error "$tfile stripe index is 0"
25406
25407         unlinkmany $DIR/$tdir/$tfile. 1000
25408
25409         do_nodes $mdts "$LCTL set_param -n \
25410                         osp.*OST0000*.max_create_count=$max_count"
25411         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
25412                 do_nodes $mdts "$LCTL set_param -n \
25413                                 osp.*OST0000*.create_count=$count"
25414         do_nodes $mdts "$LCTL get_param osp.*OST0000*.create_count" |
25415                         grep "=0" && error "create_count is zero"
25416
25417         local new_iused
25418         for i in $(seq 120); do
25419                 new_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
25420                 # system may be too busy to destroy all objs in time, use
25421                 # a somewhat small value to not fail autotest
25422                 [ $((old_iused - new_iused)) -gt 400 ] && break
25423                 sleep 1
25424         done
25425
25426         echo "waited $i sec, old Iused $old_iused, new Iused $new_iused"
25427         [ $((old_iused - new_iused)) -gt 400 ] ||
25428                 error "objs not destroyed after unlink"
25429 }
25430 run_test 311 "disable OSP precreate, and unlink should destroy objs"
25431
25432 zfs_get_objid()
25433 {
25434         local ost=$1
25435         local tf=$2
25436         local fid=($($LFS getstripe $tf | grep 0x))
25437         local seq=${fid[3]#0x}
25438         local objid=${fid[1]}
25439
25440         local vdevdir=$(dirname $(facet_vdevice $ost))
25441         local cmd="$ZDB -e -p $vdevdir -ddddd $(facet_device $ost)"
25442         local zfs_zapid=$(do_facet $ost $cmd |
25443                           grep -w "/O/$seq/d$((objid%32))" -C 5 |
25444                           awk '/Object/{getline; print $1}')
25445         local zfs_objid=$(do_facet $ost $cmd $zfs_zapid |
25446                           awk "/$objid = /"'{printf $3}')
25447
25448         echo $zfs_objid
25449 }
25450
25451 zfs_object_blksz() {
25452         local ost=$1
25453         local objid=$2
25454
25455         local vdevdir=$(dirname $(facet_vdevice $ost))
25456         local cmd="$ZDB -e -p $vdevdir -dddd $(facet_device $ost)"
25457         local blksz=$(do_facet $ost $cmd $objid |
25458                       awk '/dblk/{getline; printf $4}')
25459
25460         case "${blksz: -1}" in
25461                 k|K) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024)) ;;
25462                 m|M) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024*1024)) ;;
25463                 *) ;;
25464         esac
25465
25466         echo $blksz
25467 }
25468
25469 test_312() { # LU-4856
25470         remote_ost_nodsh && skip "remote OST with nodsh"
25471         [[ "$ost1_FSTYPE" == "zfs" ]] || skip "the test only applies to zfs"
25472
25473         local max_blksz=$(do_facet ost1 \
25474                           $ZFS get -p recordsize $(facet_device ost1) |
25475                           awk '!/VALUE/{print $3}')
25476         local tf=$DIR/$tfile
25477
25478         $LFS setstripe -c1 $tf
25479         local facet="ost$(($($LFS getstripe -i $tf) + 1))"
25480
25481         # Get ZFS object id
25482         local zfs_objid=$(zfs_get_objid $facet $tf)
25483         # block size change by sequential overwrite
25484         local bs
25485
25486         for ((bs=$PAGE_SIZE; bs <= max_blksz; bs *= 4)) ; do
25487                 dd if=/dev/zero of=$tf bs=$bs count=1 oflag=sync conv=notrunc
25488
25489                 local blksz=$(zfs_object_blksz $facet $zfs_objid)
25490                 [[ $blksz -eq $bs ]] || error "blksz error: $blksz, expected: $bs"
25491         done
25492         rm -f $tf
25493
25494         $LFS setstripe -c1 $tf
25495         facet="ost$(($($LFS getstripe -i $tf) + 1))"
25496
25497         # block size change by sequential append write
25498         dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=1 oflag=sync conv=notrunc
25499         zfs_objid=$(zfs_get_objid $facet $tf)
25500         local count
25501
25502         for ((count = 1; count < $((max_blksz / PAGE_SIZE)); count *= 2)); do
25503                 dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=$count seek=$count \
25504                         oflag=sync conv=notrunc
25505
25506                 blksz=$(zfs_object_blksz $facet $zfs_objid)
25507                 (( $blksz == 2 * count * PAGE_SIZE )) ||
25508                         error "blksz error, actual $blksz, " \
25509                                 "expected: 2 * $count * $PAGE_SIZE"
25510         done
25511         rm -f $tf
25512
25513         # random write
25514         $LFS setstripe -c1 $tf
25515         facet="ost$(($($LFS getstripe -i $tf) + 1))"
25516         zfs_objid=$(zfs_get_objid $facet $tf)
25517
25518         dd if=/dev/zero of=$tf bs=1K count=1 oflag=sync conv=notrunc
25519         blksz=$(zfs_object_blksz $facet $zfs_objid)
25520         (( blksz == PAGE_SIZE )) ||
25521                 error "blksz error: $blksz, expected: $PAGE_SIZE"
25522
25523         dd if=/dev/zero of=$tf bs=64K count=1 oflag=sync conv=notrunc seek=128
25524         blksz=$(zfs_object_blksz $facet $zfs_objid)
25525         (( blksz == 65536 )) || error "blksz error: $blksz, expected: 64k"
25526
25527         dd if=/dev/zero of=$tf bs=1M count=1 oflag=sync conv=notrunc
25528         blksz=$(zfs_object_blksz $facet $zfs_objid)
25529         (( blksz == 65536 )) || error "rewrite error: $blksz, expected: 64k"
25530 }
25531 run_test 312 "make sure ZFS adjusts its block size by write pattern"
25532
25533 test_313() {
25534         remote_ost_nodsh && skip "remote OST with nodsh"
25535
25536         local file=$DIR/$tfile
25537
25538         rm -f $file
25539         $LFS setstripe -c 1 -i 0 $file || error "setstripe failed"
25540
25541         # define OBD_FAIL_TGT_RCVD_EIO           0x720
25542         do_facet ost1 "$LCTL set_param fail_loc=0x720"
25543         dd if=/dev/zero of=$file bs=$PAGE_SIZE oflag=direct count=1 &&
25544                 error "write should failed"
25545         do_facet ost1 "$LCTL set_param fail_loc=0"
25546         rm -f $file
25547 }
25548 run_test 313 "io should fail after last_rcvd update fail"
25549
25550 test_314() {
25551         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
25552
25553         $LFS setstripe -c 2 -i 0 $DIR/$tfile || error "setstripe failed"
25554         do_facet ost1 "$LCTL set_param fail_loc=0x720"
25555         rm -f $DIR/$tfile
25556         wait_delete_completed
25557         do_facet ost1 "$LCTL set_param fail_loc=0"
25558 }
25559 run_test 314 "OSP shouldn't fail after last_rcvd update failure"
25560
25561 test_315() { # LU-618
25562         [ -f /proc/$$/io ] || skip_env "no IO accounting in kernel"
25563
25564         local file=$DIR/$tfile
25565         rm -f $file
25566
25567         $MULTIOP $file oO_CREAT:O_DIRECT:O_RDWR:w4063232c ||
25568                 error "multiop file write failed"
25569         $MULTIOP $file oO_RDONLY:r4063232_c &
25570         PID=$!
25571
25572         sleep 2
25573
25574         local rbytes=$(awk '/read_bytes/ { print $2 }' /proc/$PID/io)
25575         kill -USR1 $PID
25576
25577         [ $rbytes -gt 4000000 ] || error "read is not accounted ($rbytes)"
25578         rm -f $file
25579 }
25580 run_test 315 "read should be accounted"
25581
25582 test_316() {
25583         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
25584         large_xattr_enabled || skip "ea_inode feature disabled"
25585
25586         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
25587         mkdir $DIR/$tdir/d || error "mkdir $tdir/d failed"
25588         chown nobody $DIR/$tdir/d || error "chown $tdir/d failed"
25589         touch $DIR/$tdir/d/$tfile || error "touch $tdir/d/$tfile failed"
25590
25591         $LFS migrate -m1 $DIR/$tdir/d || error "lfs migrate -m1 failed"
25592 }
25593 run_test 316 "lfs migrate of file with large_xattr enabled"
25594
25595 test_317() {
25596         [ $MDS1_VERSION -lt $(version_code 2.11.53) ] &&
25597                 skip "Need MDS version at least 2.11.53"
25598         if [ "$ost1_FSTYPE" == "zfs" ]; then
25599                 skip "LU-10370: no implementation for ZFS"
25600         fi
25601
25602         local trunc_sz
25603         local grant_blk_size
25604
25605         grant_blk_size=$($LCTL get_param osc.$FSNAME*.import |
25606                         awk '/grant_block_size:/ { print $2; exit; }')
25607         #
25608         # Create File of size 5M. Truncate it to below size's and verify
25609         # blocks count.
25610         #
25611         dd if=/dev/zero of=$DIR/$tfile bs=5M count=1 conv=fsync ||
25612                 error "Create file $DIR/$tfile failed"
25613         stack_trap "rm -f $DIR/$tfile" EXIT
25614
25615         for trunc_sz in 2097152 4097 4000 509 0; do
25616                 $TRUNCATE $DIR/$tfile $trunc_sz ||
25617                         error "truncate $tfile to $trunc_sz failed"
25618                 local sz=$(stat --format=%s $DIR/$tfile)
25619                 local blk=$(stat --format=%b $DIR/$tfile)
25620                 local trunc_blk=$((((trunc_sz + (grant_blk_size - 1) ) /
25621                                      grant_blk_size) * 8))
25622
25623                 if [[ $blk -ne $trunc_blk ]]; then
25624                         $(which stat) $DIR/$tfile
25625                         error "Expected Block $trunc_blk got $blk for $tfile"
25626                 fi
25627
25628                 $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
25629                         error "Expected Size $trunc_sz got $sz for $tfile"
25630         done
25631
25632         #
25633         # sparse file test
25634         # Create file with a hole and write actual 65536 bytes which aligned
25635         # with 4K and 64K PAGE_SIZE. Block count must be 128.
25636         #
25637         local bs=65536
25638         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 seek=5 conv=fsync ||
25639                 error "Create file : $DIR/$tfile"
25640
25641         #
25642         # Truncate to size $trunc_sz bytes. Strip tail blocks and leave only 8
25643         # blocks. The block count must drop to 8.
25644         #
25645         trunc_sz=$(($(stat --format=%s $DIR/$tfile) -
25646                 ((bs - grant_blk_size) + 1)))
25647         $TRUNCATE $DIR/$tfile $trunc_sz ||
25648                 error "truncate $tfile to $trunc_sz failed"
25649
25650         local trunc_bsz=$((grant_blk_size / $(stat --format=%B $DIR/$tfile)))
25651         sz=$(stat --format=%s $DIR/$tfile)
25652         blk=$(stat --format=%b $DIR/$tfile)
25653
25654         if [[ $blk -ne $trunc_bsz ]]; then
25655                 $(which stat) $DIR/$tfile
25656                 error "Expected Block $trunc_bsz got $blk for $tfile"
25657         fi
25658
25659         $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
25660                 error "Expected Size $trunc_sz got $sz for $tfile"
25661 }
25662 run_test 317 "Verify blocks get correctly update after truncate"
25663
25664 test_318() {
25665         local llite_name="llite.$($LFS getname $MOUNT | awk '{print $1}')"
25666         local old_max_active=$($LCTL get_param -n \
25667                             ${llite_name}.max_read_ahead_async_active \
25668                             2>/dev/null)
25669
25670         $LCTL set_param llite.*.max_read_ahead_async_active=256
25671         local max_active=$($LCTL get_param -n \
25672                            ${llite_name}.max_read_ahead_async_active \
25673                            2>/dev/null)
25674         [ $max_active -ne 256 ] && error "expected 256 but got $max_active"
25675
25676         $LCTL set_param llite.*.max_read_ahead_async_active=0 ||
25677                 error "set max_read_ahead_async_active should succeed"
25678
25679         $LCTL set_param llite.*.max_read_ahead_async_active=512
25680         max_active=$($LCTL get_param -n \
25681                      ${llite_name}.max_read_ahead_async_active 2>/dev/null)
25682         [ $max_active -eq 512 ] || error "expected 512 but got $max_active"
25683
25684         # restore @max_active
25685         [ $old_max_active -ne 0 ] && $LCTL set_param \
25686                 llite.*.max_read_ahead_async_active=$old_max_active
25687
25688         local old_threshold=$($LCTL get_param -n \
25689                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
25690         local max_per_file_mb=$($LCTL get_param -n \
25691                 ${llite_name}.max_read_ahead_per_file_mb 2>/dev/null)
25692
25693         local invalid=$(($max_per_file_mb + 1))
25694         $LCTL set_param \
25695                 llite.*.read_ahead_async_file_threshold_mb=$invalid\
25696                         && error "set $invalid should fail"
25697
25698         local valid=$(($invalid - 1))
25699         $LCTL set_param \
25700                 llite.*.read_ahead_async_file_threshold_mb=$valid ||
25701                         error "set $valid should succeed"
25702         local threshold=$($LCTL get_param -n \
25703                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
25704         [ $threshold -eq $valid ] || error \
25705                 "expect threshold $valid got $threshold"
25706         $LCTL set_param \
25707                 llite.*.read_ahead_async_file_threshold_mb=$old_threshold
25708 }
25709 run_test 318 "Verify async readahead tunables"
25710
25711 test_319() {
25712         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
25713
25714         local before=$(date +%s)
25715         local evict
25716         local mdir=$DIR/$tdir
25717         local file=$mdir/xxx
25718
25719         $LFS mkdir -i0 $mdir || error "mkdir $mdir fails"
25720         touch $file
25721
25722 #define OBD_FAIL_LDLM_LOCAL_CANCEL_PAUSE 0x32c
25723         $LCTL set_param fail_val=5 fail_loc=0x8000032c
25724         $LFS migrate -m1 $mdir &
25725
25726         sleep 1
25727         dd if=$file of=/dev/null
25728         wait
25729         evict=$($LCTL get_param mdc.$FSNAME-MDT*.state |
25730           awk -F"[ [,]" '/EVICTED ]$/ { if (mx<$5) {mx=$5;} } END { print mx }')
25731
25732         [ -z "$evict" ] || [[ $evict -le $before ]] || error "eviction happened"
25733 }
25734 run_test 319 "lost lease lock on migrate error"
25735
25736 test_398a() { # LU-4198
25737         local ost1_imp=$(get_osc_import_name client ost1)
25738         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
25739                          cut -d'.' -f2)
25740
25741         $LFS setstripe -c 1 -i 0 $DIR/$tfile
25742         stack_trap "rm -f $DIR/$tfile"
25743         $LCTL set_param ldlm.namespaces.*.lru_size=clear
25744
25745         # request a new lock on client
25746         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
25747
25748         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
25749         local lock_count=$($LCTL get_param -n \
25750                            ldlm.namespaces.$imp_name.lru_size)
25751         [[ $lock_count -eq 0 ]] || error "lock should be cancelled by direct IO"
25752
25753         $LCTL set_param ldlm.namespaces.*-OST0000-osc-ffff*.lru_size=clear
25754
25755         # no lock cached, should use lockless DIO and not enqueue new lock
25756         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
25757         lock_count=$($LCTL get_param -n \
25758                      ldlm.namespaces.$imp_name.lru_size)
25759         [[ $lock_count -eq 0 ]] || error "no lock should be held by direct IO"
25760
25761         $LCTL set_param ldlm.namespaces.*-OST0000-osc-ffff*.lru_size=clear
25762
25763         # no lock cached, should use locked DIO append
25764         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct oflag=append \
25765                 conv=notrunc || error "DIO append failed"
25766         lock_count=$($LCTL get_param -n \
25767                      ldlm.namespaces.*-OST0000-osc-ffff*.lru_size)
25768         [[ $lock_count -ne 0 ]] || error "lock still must be held by DIO append"
25769 }
25770 run_test 398a "direct IO should cancel lock otherwise lockless"
25771
25772 test_398b() { # LU-4198
25773         local before=$(date +%s)
25774         local njobs=4
25775         local size=48
25776
25777         which fio || skip_env "no fio installed"
25778         $LFS setstripe -c -1 -S 1M $DIR/$tfile
25779         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size
25780
25781         # Single page, multiple pages, stripe size, 4*stripe size
25782         for bsize in $(( $PAGE_SIZE )) $(( 4*$PAGE_SIZE )) 1048576 4194304; do
25783                 echo "mix direct rw ${bsize} by fio with $njobs jobs..."
25784                 fio --name=rand-rw --rw=randrw --bs=$bsize --direct=1 \
25785                         --numjobs=$njobs --fallocate=none \
25786                         --iodepth=16 --allow_file_create=0 \
25787                         --size=$((size/njobs))M \
25788                         --filename=$DIR/$tfile &
25789                 bg_pid=$!
25790
25791                 echo "mix buffer rw ${bsize} by fio with $njobs jobs..."
25792                 fio --name=rand-rw --rw=randrw --bs=$bsize \
25793                         --numjobs=$njobs --fallocate=none \
25794                         --iodepth=16 --allow_file_create=0 \
25795                         --size=$((size/njobs))M \
25796                         --filename=$DIR/$tfile || true
25797                 wait $bg_pid
25798         done
25799
25800         evict=$(do_facet client $LCTL get_param \
25801                 osc.$FSNAME-OST*-osc-*/state |
25802             awk -F"[ [,]" '/EVICTED ]$/ { if (t<$5) {t=$5;} } END { print t }')
25803
25804         [ -z "$evict" ] || [[ $evict -le $before ]] ||
25805                 (do_facet client $LCTL get_param \
25806                         osc.$FSNAME-OST*-osc-*/state;
25807                     error "eviction happened: $evict before:$before")
25808
25809         rm -f $DIR/$tfile
25810 }
25811 run_test 398b "DIO and buffer IO race"
25812
25813 test_398c() { # LU-4198
25814         local ost1_imp=$(get_osc_import_name client ost1)
25815         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
25816                          cut -d'.' -f2)
25817
25818         which fio || skip_env "no fio installed"
25819
25820         saved_debug=$($LCTL get_param -n debug)
25821         $LCTL set_param debug=0
25822
25823         local size=$(lctl get_param -n osc.$FSNAME-OST0000*.kbytesavail | head -1)
25824         ((size /= 1024)) # by megabytes
25825         ((size /= 2)) # write half of the OST at most
25826         [ $size -gt 40 ] && size=40 #reduce test time anyway
25827
25828         $LFS setstripe -c 1 $DIR/$tfile
25829
25830         # it seems like ldiskfs reserves more space than necessary if the
25831         # writing blocks are not mapped, so it extends the file firstly
25832         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size && sync
25833         cancel_lru_locks osc
25834
25835         # clear and verify rpc_stats later
25836         $LCTL set_param osc.${FSNAME}-OST0000-osc-ffff*.rpc_stats=clear
25837
25838         local njobs=4
25839         echo "writing ${size}M to OST0 by fio with $njobs jobs..."
25840         fio --name=rand-write --rw=randwrite --bs=$PAGE_SIZE --direct=1 \
25841                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
25842                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
25843                 --filename=$DIR/$tfile
25844         [ $? -eq 0 ] || error "fio write error"
25845
25846         [ $($LCTL get_param -n ldlm.namespaces.$imp_name.lock_count) -eq 0 ] ||
25847                 error "Locks were requested while doing AIO"
25848
25849         # get the percentage of 1-page I/O
25850         pct=$($LCTL get_param osc.${imp_name}.rpc_stats |
25851                 grep -A 1 'pages per rpc' | grep -v 'pages per rpc' |
25852                 awk '{print $7}')
25853         [ $pct -le 50 ] || error "$pct% of I/O are 1-page"
25854
25855         echo "mix rw ${size}M to OST0 by fio with $njobs jobs..."
25856         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
25857                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
25858                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
25859                 --filename=$DIR/$tfile
25860         [ $? -eq 0 ] || error "fio mixed read write error"
25861
25862         echo "AIO with large block size ${size}M"
25863         fio --name=rand-rw --rw=randrw --bs=${size}M --direct=1 \
25864                 --numjobs=1 --fallocate=none --ioengine=libaio \
25865                 --iodepth=16 --allow_file_create=0 --size=${size}M \
25866                 --filename=$DIR/$tfile
25867         [ $? -eq 0 ] || error "fio large block size failed"
25868
25869         rm -f $DIR/$tfile
25870         $LCTL set_param debug="$saved_debug"
25871 }
25872 run_test 398c "run fio to test AIO"
25873
25874 test_398d() { #  LU-13846
25875         which aiocp || skip_env "no aiocp installed"
25876         local aio_file=$DIR/$tfile.aio
25877
25878         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
25879
25880         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=64
25881         aiocp -a $PAGE_SIZE -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file
25882         stack_trap "rm -f $DIR/$tfile $aio_file"
25883
25884         diff $DIR/$tfile $aio_file || error "file diff after aiocp"
25885
25886         # make sure we don't crash and fail properly
25887         aiocp -a 512 -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
25888                 error "aio not aligned with PAGE SIZE should fail"
25889
25890         rm -f $DIR/$tfile $aio_file
25891 }
25892 run_test 398d "run aiocp to verify block size > stripe size"
25893
25894 test_398e() {
25895         dd if=/dev/zero of=$DIR/$tfile bs=1234 count=1
25896         touch $DIR/$tfile.new
25897         dd if=$DIR/$tfile of=$DIR/$tfile.new bs=1M count=1 oflag=direct
25898 }
25899 run_test 398e "O_Direct open cleared by fcntl doesn't cause hang"
25900
25901 test_398f() { #  LU-14687
25902         which aiocp || skip_env "no aiocp installed"
25903         local aio_file=$DIR/$tfile.aio
25904
25905         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
25906
25907         dd if=/dev/zero of=$DIR/$tfile bs=1M count=64
25908         stack_trap "rm -f $DIR/$tfile $aio_file"
25909
25910         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
25911         $LCTL set_param fail_loc=0x1418
25912         # make sure we don't crash and fail properly
25913         aiocp -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
25914                 error "aio with page allocation failure succeeded"
25915         $LCTL set_param fail_loc=0
25916         diff $DIR/$tfile $aio_file
25917         [[ $? != 0 ]] || error "no diff after failed aiocp"
25918 }
25919 run_test 398f "verify aio handles ll_direct_rw_pages errors correctly"
25920
25921 # NB: To get the parallel DIO behavior in LU-13798, there must be > 1
25922 # stripe and i/o size must be > stripe size
25923 # Old style synchronous DIO waits after submitting each chunk, resulting in a
25924 # single RPC in flight.  This test shows async DIO submission is working by
25925 # showing multiple RPCs in flight.
25926 test_398g() { #  LU-13798
25927         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
25928
25929         # We need to do some i/o first to acquire enough grant to put our RPCs
25930         # in flight; otherwise a new connection may not have enough grant
25931         # available
25932         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
25933                 error "parallel dio failed"
25934         stack_trap "rm -f $DIR/$tfile"
25935
25936         # Reduce RPC size to 1M to avoid combination in to larger RPCs
25937         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
25938         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
25939         stack_trap "$LCTL set_param -n $pages_per_rpc"
25940
25941         # Recreate file so it's empty
25942         rm -f $DIR/$tfile
25943         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
25944         #Pause rpc completion to guarantee we see multiple rpcs in flight
25945         #define OBD_FAIL_OST_BRW_PAUSE_BULK
25946         do_facet ost1 $LCTL set_param fail_loc=0x214 fail_val=2
25947         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
25948
25949         # Clear rpc stats
25950         $LCTL set_param osc.*.rpc_stats=c
25951
25952         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
25953                 error "parallel dio failed"
25954         stack_trap "rm -f $DIR/$tfile"
25955
25956         $LCTL get_param osc.*-OST0000-*.rpc_stats
25957         pct=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
25958                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
25959                 grep "8:" | awk '{print $8}')
25960         # We look at the "8 rpcs in flight" field, and verify A) it is present
25961         # and B) it includes all RPCs.  This proves we had 8 RPCs in flight,
25962         # as expected for an 8M DIO to a file with 1M stripes.
25963         [ $pct -eq 100 ] || error "we should see 8 RPCs in flight"
25964
25965         # Verify turning off parallel dio works as expected
25966         # Clear rpc stats
25967         $LCTL set_param osc.*.rpc_stats=c
25968         $LCTL set_param llite.*.parallel_dio=0
25969         stack_trap '$LCTL set_param llite.*.parallel_dio=1'
25970
25971         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
25972                 error "dio with parallel dio disabled failed"
25973
25974         # Ideally, we would see only one RPC in flight here, but there is an
25975         # unavoidable race between i/o completion and RPC in flight counting,
25976         # so while only 1 i/o is in flight at a time, the RPC in flight counter
25977         # will sometimes exceed 1 (3 or 4 is not rare on VM testing).
25978         # So instead we just verify it's always < 8.
25979         $LCTL get_param osc.*-OST0000-*.rpc_stats
25980         ret=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
25981                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
25982                 grep '^$' -B1 | grep . | awk '{print $1}')
25983         [ $ret != "8:" ] ||
25984                 error "we should see fewer than 8 RPCs in flight (saw $ret)"
25985 }
25986 run_test 398g "verify parallel dio async RPC submission"
25987
25988 test_398h() { #  LU-13798
25989         local dio_file=$DIR/$tfile.dio
25990
25991         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
25992
25993         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
25994         stack_trap "rm -f $DIR/$tfile $dio_file"
25995
25996         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct ||
25997                 error "parallel dio failed"
25998         diff $DIR/$tfile $dio_file
25999         [[ $? == 0 ]] || error "file diff after aiocp"
26000 }
26001 run_test 398h "verify correctness of read & write with i/o size >> stripe size"
26002
26003 test_398i() { #  LU-13798
26004         local dio_file=$DIR/$tfile.dio
26005
26006         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
26007
26008         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
26009         stack_trap "rm -f $DIR/$tfile $dio_file"
26010
26011         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
26012         $LCTL set_param fail_loc=0x1418
26013         # make sure we don't crash and fail properly
26014         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct &&
26015                 error "parallel dio page allocation failure succeeded"
26016         diff $DIR/$tfile $dio_file
26017         [[ $? != 0 ]] || error "no diff after failed aiocp"
26018 }
26019 run_test 398i "verify parallel dio handles ll_direct_rw_pages errors correctly"
26020
26021 test_398j() { #  LU-13798
26022         # Stripe size > RPC size but less than i/o size tests split across
26023         # stripes and RPCs for individual i/o op
26024         $LFS setstripe -o 0,0 -S 4M $DIR/$tfile $DIR/$tfile.2
26025
26026         # Reduce RPC size to 1M to guarantee split to multiple RPCs per stripe
26027         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
26028         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
26029         stack_trap "$LCTL set_param -n $pages_per_rpc"
26030
26031         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
26032                 error "parallel dio write failed"
26033         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.2"
26034
26035         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct ||
26036                 error "parallel dio read failed"
26037         diff $DIR/$tfile $DIR/$tfile.2
26038         [[ $? == 0 ]] || error "file diff after parallel dio read"
26039 }
26040 run_test 398j "test parallel dio where stripe size > rpc_size"
26041
26042 test_398k() { #  LU-13798
26043         wait_delete_completed
26044         wait_mds_ost_sync
26045
26046         # 4 stripe file; we will cause out of space on OST0
26047         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
26048
26049         # Fill OST0 (if it's not too large)
26050         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
26051                    head -n1)
26052         if [[ $ORIGFREE -gt $MAXFREE ]]; then
26053                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
26054         fi
26055         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
26056         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
26057                 error "dd should fill OST0"
26058         stack_trap "rm -f $DIR/$tfile.1"
26059
26060         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
26061         err=$?
26062
26063         ls -la $DIR/$tfile
26064         $CHECKSTAT -t file -s 0 $DIR/$tfile ||
26065                 error "file is not 0 bytes in size"
26066
26067         # dd above should not succeed, but don't error until here so we can
26068         # get debug info above
26069         [[ $err != 0 ]] ||
26070                 error "parallel dio write with enospc succeeded"
26071         stack_trap "rm -f $DIR/$tfile"
26072 }
26073 run_test 398k "test enospc on first stripe"
26074
26075 test_398l() { #  LU-13798
26076         wait_delete_completed
26077         wait_mds_ost_sync
26078
26079         # 4 stripe file; we will cause out of space on OST0
26080         # Note the 1M stripe size and the > 1M i/o size mean this ENOSPC
26081         # happens on the second i/o chunk we issue
26082         $LFS setstripe -o 1,0,1,0 -S 1M $DIR/$tfile $DIR/$tfile.2
26083
26084         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=2 oflag=direct
26085         stack_trap "rm -f $DIR/$tfile"
26086
26087         # Fill OST0 (if it's not too large)
26088         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
26089                    head -n1)
26090         if [[ $ORIGFREE -gt $MAXFREE ]]; then
26091                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
26092         fi
26093         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
26094         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
26095                 error "dd should fill OST0"
26096         stack_trap "rm -f $DIR/$tfile.1"
26097
26098         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 oflag=direct
26099         err=$?
26100         stack_trap "rm -f $DIR/$tfile.2"
26101
26102         # Check that short write completed as expected
26103         ls -la $DIR/$tfile.2
26104         $CHECKSTAT -t file -s 1048576 $DIR/$tfile.2 ||
26105                 error "file is not 1M in size"
26106
26107         # dd above should not succeed, but don't error until here so we can
26108         # get debug info above
26109         [[ $err != 0 ]] ||
26110                 error "parallel dio write with enospc succeeded"
26111
26112         # Truncate source file to same length as output file and diff them
26113         $TRUNCATE $DIR/$tfile 1048576
26114         diff $DIR/$tfile $DIR/$tfile.2
26115         [[ $? == 0 ]] || error "data incorrect after short write"
26116 }
26117 run_test 398l "test enospc on intermediate stripe/RPC"
26118
26119 test_398m() { #  LU-13798
26120         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
26121
26122         # Set up failure on OST0, the first stripe:
26123         #define OBD_FAIL_OST_BRW_WRITE_BULK     0x20e
26124         #NB: Fail val is ost # + 1, because we cannot use cfs_fail_val = 0
26125         # OST0 is on ost1, OST1 is on ost2.
26126         # So this fail_val specifies OST0
26127         do_facet ost1 $LCTL set_param fail_loc=0x20e fail_val=1
26128         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
26129
26130         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
26131                 error "parallel dio write with failure on first stripe succeeded"
26132         stack_trap "rm -f $DIR/$tfile"
26133         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
26134
26135         # Place data in file for read
26136         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
26137                 error "parallel dio write failed"
26138
26139         # Fail read on OST0, first stripe
26140         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
26141         do_facet ost1 $LCTL set_param fail_loc=0x20f fail_val=1
26142         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
26143                 error "parallel dio read with error on first stripe succeeded"
26144         rm -f $DIR/$tfile.2
26145         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
26146
26147         # Switch to testing on OST1, second stripe
26148         # Clear file contents, maintain striping
26149         echo > $DIR/$tfile
26150         # Set up failure on OST1, second stripe:
26151         do_facet ost2 $LCTL set_param fail_loc=0x20e fail_val=2
26152         stack_trap "do_facet ost2 $LCTL set_param fail_loc=0"
26153
26154         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
26155                 error "parallel dio write with failure on second stripe succeeded"
26156         stack_trap "rm -f $DIR/$tfile"
26157         do_facet ost2 $LCTL set_param fail_loc=0 fail_val=0
26158
26159         # Place data in file for read
26160         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
26161                 error "parallel dio write failed"
26162
26163         # Fail read on OST1, second stripe
26164         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
26165         do_facet ost2 $LCTL set_param fail_loc=0x20f fail_val=2
26166         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
26167                 error "parallel dio read with error on second stripe succeeded"
26168         rm -f $DIR/$tfile.2
26169         do_facet ost2 $LCTL set_param fail_loc=0 fail_val=0
26170 }
26171 run_test 398m "test RPC failures with parallel dio"
26172
26173 # Parallel submission of DIO should not cause problems for append, but it's
26174 # important to verify.
26175 test_398n() { #  LU-13798
26176         $LFS setstripe -C 2 -S 1M $DIR/$tfile
26177
26178         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 ||
26179                 error "dd to create source file failed"
26180         stack_trap "rm -f $DIR/$tfile"
26181
26182         dd if=$DIR/$tfile of=$DIR/$tfile.1 bs=8M count=8 oflag=direct oflag=append ||
26183                 error "parallel dio write with failure on second stripe succeeded"
26184         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.1"
26185         diff $DIR/$tfile $DIR/$tfile.1
26186         [[ $? == 0 ]] || error "data incorrect after append"
26187
26188 }
26189 run_test 398n "test append with parallel DIO"
26190
26191 test_398o() {
26192         directio rdwr $DIR/$tfile 0 1 1 || error "bad KMS"
26193 }
26194 run_test 398o "right kms with DIO"
26195
26196 test_398p()
26197 {
26198         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
26199         which aiocp || skip_env "no aiocp installed"
26200
26201         local stripe_size=$((1024 * 1024)) #1 MiB
26202         # Max i/o below is ~ 4 * stripe_size, so this gives ~5 i/os
26203         local file_size=$((25 * stripe_size))
26204
26205         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
26206         stack_trap "rm -f $DIR/$tfile*"
26207         # Just a bit bigger than the largest size in the test set below
26208         dd if=/dev/urandom bs=$file_size count=1 of=$DIR/$tfile.1 ||
26209                 error "buffered i/o to create file failed"
26210
26211         for bs in $PAGE_SIZE $((PAGE_SIZE * 4)) $stripe_size \
26212                 $((stripe_size * 4)); do
26213
26214                 $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.2
26215
26216                 echo "bs: $bs, file_size $file_size"
26217                 aiocp -a $PAGE_SIZE -b $bs -s $file_size -f O_DIRECT \
26218                         $DIR/$tfile.1 $DIR/$tfile.2 &
26219                 pid_dio1=$!
26220                 # Buffered I/O with similar but not the same block size
26221                 dd if=$DIR/$tfile.1 bs=$((bs * 2)) of=$DIR/$tfile.2 \
26222                         conv=notrunc &
26223                 pid_bio2=$!
26224                 wait $pid_dio1
26225                 rc1=$?
26226                 wait $pid_bio2
26227                 rc2=$?
26228                 if (( rc1 != 0 )); then
26229                         error "aio copy 1 w/bsize $bs failed: $rc1"
26230                 fi
26231                 if (( rc2 != 0 )); then
26232                         error "buffered copy 2 w/bsize $bs failed: $rc2"
26233                 fi
26234
26235                 $CHECKSTAT -t file -s $file_size $DIR/$tfile.2 ||
26236                         error "size incorrect"
26237                 cmp --verbose $DIR/$tfile.1 $DIR/$tfile.2 ||
26238                         error "files differ, bsize $bs"
26239                 rm -f $DIR/$tfile.2
26240         done
26241 }
26242 run_test 398p "race aio with buffered i/o"
26243
26244 test_fake_rw() {
26245         local read_write=$1
26246         if [ "$read_write" = "write" ]; then
26247                 local dd_cmd="dd if=/dev/zero of=$DIR/$tfile"
26248         elif [ "$read_write" = "read" ]; then
26249                 local dd_cmd="dd of=/dev/null if=$DIR/$tfile"
26250         else
26251                 error "argument error"
26252         fi
26253
26254         # turn off debug for performance testing
26255         local saved_debug=$($LCTL get_param -n debug)
26256         $LCTL set_param debug=0
26257
26258         $LFS setstripe -c 1 -i 0 $DIR/$tfile
26259
26260         # get ost1 size - $FSNAME-OST0000
26261         local ost1_avail_size=$($LFS df $DIR | awk /${ost1_svc}/'{ print $4 }')
26262         local blocks=$((ost1_avail_size/2/1024)) # half avail space by megabytes
26263         [ $blocks -gt 1000 ] && blocks=1000 # 1G in maximum
26264
26265         if [ "$read_write" = "read" ]; then
26266                 $TRUNCATE $DIR/$tfile $(expr 1048576 \* $blocks)
26267         fi
26268
26269         local start_time=$(date +%s.%N)
26270         $dd_cmd bs=1M count=$blocks oflag=sync ||
26271                 error "real dd $read_write error"
26272         local duration=$(bc <<< "$(date +%s.%N) - $start_time")
26273
26274         if [ "$read_write" = "write" ]; then
26275                 rm -f $DIR/$tfile
26276         fi
26277
26278         # define OBD_FAIL_OST_FAKE_RW           0x238
26279         do_facet ost1 $LCTL set_param fail_loc=0x238
26280
26281         local start_time=$(date +%s.%N)
26282         $dd_cmd bs=1M count=$blocks oflag=sync ||
26283                 error "fake dd $read_write error"
26284         local duration_fake=$(bc <<< "$(date +%s.%N) - $start_time")
26285
26286         if [ "$read_write" = "write" ]; then
26287                 # verify file size
26288                 cancel_lru_locks osc
26289                 $CHECKSTAT -t file -s $((blocks * 1024 * 1024)) $DIR/$tfile ||
26290                         error "$tfile size not $blocks MB"
26291         fi
26292         do_facet ost1 $LCTL set_param fail_loc=0
26293
26294         echo "fake $read_write $duration_fake vs. normal $read_write" \
26295                 "$duration in seconds"
26296         [ $(bc <<< "$duration_fake < $duration") -eq 1 ] ||
26297                 error_not_in_vm "fake write is slower"
26298
26299         $LCTL set_param -n debug="$saved_debug"
26300         rm -f $DIR/$tfile
26301 }
26302 test_399a() { # LU-7655 for OST fake write
26303         remote_ost_nodsh && skip "remote OST with nodsh"
26304
26305         test_fake_rw write
26306 }
26307 run_test 399a "fake write should not be slower than normal write"
26308
26309 test_399b() { # LU-8726 for OST fake read
26310         remote_ost_nodsh && skip "remote OST with nodsh"
26311         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
26312                 skip_env "ldiskfs only test"
26313         fi
26314
26315         test_fake_rw read
26316 }
26317 run_test 399b "fake read should not be slower than normal read"
26318
26319 test_400a() { # LU-1606, was conf-sanity test_74
26320         if ! which $CC > /dev/null 2>&1; then
26321                 skip_env "$CC is not installed"
26322         fi
26323
26324         local extra_flags=''
26325         local out=$TMP/$tfile
26326         local prefix=/usr/include/lustre
26327         local prog
26328
26329         # Oleg removes .c files in his test rig so test if any c files exist
26330         [[ -n "$(ls -A $LUSTRE_TESTS_API_DIR)" ]] ||
26331                 skip_env "Needed .c test files are missing"
26332
26333         if ! [[ -d $prefix ]]; then
26334                 # Assume we're running in tree and fixup the include path.
26335                 extra_flags+=" -I$LUSTRE/../lnet/include/uapi"
26336                 extra_flags+=" -I$LUSTRE/include/uapi -I$LUSTRE/include"
26337                 extra_flags+=" -L$LUSTRE/utils/.libs"
26338         fi
26339
26340         for prog in $LUSTRE_TESTS_API_DIR/*.c; do
26341                 $CC -Wall -Werror $extra_flags -o $out $prog -llustreapi ||
26342                         error "client api broken"
26343         done
26344         rm -f $out
26345 }
26346 run_test 400a "Lustre client api program can compile and link"
26347
26348 test_400b() { # LU-1606, LU-5011
26349         local header
26350         local out=$TMP/$tfile
26351         local prefix=/usr/include/linux/lustre
26352
26353         # We use a hard coded prefix so that this test will not fail
26354         # when run in tree. There are headers in lustre/include/lustre/
26355         # that are not packaged (like lustre_idl.h) and have more
26356         # complicated include dependencies (like config.h and lnet/types.h).
26357         # Since this test about correct packaging we just skip them when
26358         # they don't exist (see below) rather than try to fixup cppflags.
26359
26360         if ! which $CC > /dev/null 2>&1; then
26361                 skip_env "$CC is not installed"
26362         fi
26363
26364         for header in $prefix/*.h; do
26365                 if ! [[ -f "$header" ]]; then
26366                         continue
26367                 fi
26368
26369                 if [[ "$(basename $header)" == lustre_ioctl.h ]]; then
26370                         continue # lustre_ioctl.h is internal header
26371                 fi
26372
26373                 $CC -Wall -Werror -include $header -c -x c /dev/null -o $out ||
26374                         error "cannot compile '$header'"
26375         done
26376         rm -f $out
26377 }
26378 run_test 400b "packaged headers can be compiled"
26379
26380 test_401a() { #LU-7437
26381         local printf_arg=$(find -printf 2>&1 | grep "unrecognized:")
26382         [ -n "$printf_arg" ] && skip_env "find does not support -printf"
26383
26384         #count the number of parameters by "list_param -R"
26385         local params=$($LCTL list_param -R '*' 2>/dev/null | wc -l)
26386         #count the number of parameters by listing proc files
26387         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
26388         echo "proc_dirs='$proc_dirs'"
26389         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
26390         local procs=$(find -L $proc_dirs -mindepth 1 -printf '%P\n' 2>/dev/null|
26391                       sort -u | wc -l)
26392
26393         [ $params -eq $procs ] ||
26394                 error "found $params parameters vs. $procs proc files"
26395
26396         # test the list_param -D option only returns directories
26397         params=$($LCTL list_param -R -D '*' 2>/dev/null | wc -l)
26398         #count the number of parameters by listing proc directories
26399         procs=$(find -L $proc_dirs -mindepth 1 -type d -printf '%P\n' 2>/dev/null |
26400                 sort -u | wc -l)
26401
26402         [ $params -eq $procs ] ||
26403                 error "found $params parameters vs. $procs proc files"
26404 }
26405 run_test 401a "Verify if 'lctl list_param -R' can list parameters recursively"
26406
26407 test_401b() {
26408         # jobid_var may not allow arbitrary values, so use jobid_name
26409         # if available
26410         if $LCTL list_param jobid_name > /dev/null 2>&1; then
26411                 local testname=jobid_name tmp='testing%p'
26412         else
26413                 local testname=jobid_var tmp=testing
26414         fi
26415
26416         local save=$($LCTL get_param -n $testname)
26417
26418         $LCTL set_param foo=bar $testname=$tmp bar=baz &&
26419                 error "no error returned when setting bad parameters"
26420
26421         local jobid_new=$($LCTL get_param -n foe $testname baz)
26422         [[ "$jobid_new" == "$tmp" ]] || error "jobid tmp $jobid_new != $tmp"
26423
26424         $LCTL set_param -n fog=bam $testname=$save bat=fog
26425         local jobid_old=$($LCTL get_param -n foe $testname bag)
26426         [[ "$jobid_old" == "$save" ]] || error "jobid new $jobid_old != $save"
26427 }
26428 run_test 401b "Verify 'lctl {get,set}_param' continue after error"
26429
26430 test_401c() {
26431         # jobid_var may not allow arbitrary values, so use jobid_name
26432         # if available
26433         if $LCTL list_param jobid_name > /dev/null 2>&1; then
26434                 local testname=jobid_name
26435         else
26436                 local testname=jobid_var
26437         fi
26438
26439         local jobid_var_old=$($LCTL get_param -n $testname)
26440         local jobid_var_new
26441
26442         $LCTL set_param $testname= &&
26443                 error "no error returned for 'set_param a='"
26444
26445         jobid_var_new=$($LCTL get_param -n $testname)
26446         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
26447                 error "$testname was changed by setting without value"
26448
26449         $LCTL set_param $testname &&
26450                 error "no error returned for 'set_param a'"
26451
26452         jobid_var_new=$($LCTL get_param -n $testname)
26453         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
26454                 error "$testname was changed by setting without value"
26455 }
26456 run_test 401c "Verify 'lctl set_param' without value fails in either format."
26457
26458 test_401d() {
26459         # jobid_var may not allow arbitrary values, so use jobid_name
26460         # if available
26461         if $LCTL list_param jobid_name > /dev/null 2>&1; then
26462                 local testname=jobid_name new_value='foo=bar%p'
26463         else
26464                 local testname=jobid_var new_valuie=foo=bar
26465         fi
26466
26467         local jobid_var_old=$($LCTL get_param -n $testname)
26468         local jobid_var_new
26469
26470         $LCTL set_param $testname=$new_value ||
26471                 error "'set_param a=b' did not accept a value containing '='"
26472
26473         jobid_var_new=$($LCTL get_param -n $testname)
26474         [[ "$jobid_var_new" == "$new_value" ]] ||
26475                 error "'set_param a=b' failed on a value containing '='"
26476
26477         # Reset the $testname to test the other format
26478         $LCTL set_param $testname=$jobid_var_old
26479         jobid_var_new=$($LCTL get_param -n $testname)
26480         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
26481                 error "failed to reset $testname"
26482
26483         $LCTL set_param $testname $new_value ||
26484                 error "'set_param a b' did not accept a value containing '='"
26485
26486         jobid_var_new=$($LCTL get_param -n $testname)
26487         [[ "$jobid_var_new" == "$new_value" ]] ||
26488                 error "'set_param a b' failed on a value containing '='"
26489
26490         $LCTL set_param $testname $jobid_var_old
26491         jobid_var_new=$($LCTL get_param -n $testname)
26492         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
26493                 error "failed to reset $testname"
26494 }
26495 run_test 401d "Verify 'lctl set_param' accepts values containing '='"
26496
26497 test_401e() { # LU-14779
26498         $LCTL list_param -R "ldlm.namespaces.MGC*" ||
26499                 error "lctl list_param MGC* failed"
26500         $LCTL get_param "ldlm.namespaces.MGC*" || error "lctl get_param failed"
26501         $LCTL get_param "ldlm.namespaces.MGC*.lru_size" ||
26502                 error "lctl get_param lru_size failed"
26503 }
26504 run_test 401e "verify 'lctl get_param' works with NID in parameter"
26505
26506 test_402() {
26507         [[ $MDS1_VERSION -ge $(version_code 2.7.66) ]] ||
26508         [[ $MDS1_VERSION -ge $(version_code 2.7.18.4) &&
26509                 $MDS1_VERSION -lt $(version_code 2.7.50) ]] ||
26510         [[ $MDS1_VERSION -ge $(version_code 2.7.2) &&
26511                 $MDS1_VERSION -lt $(version_code 2.7.11) ]] ||
26512                 skip "Need MDS version 2.7.2+ or 2.7.18.4+ or 2.7.66+"
26513         remote_mds_nodsh && skip "remote MDS with nodsh"
26514
26515         $LFS setdirstripe -i 0 $DIR/$tdir || error "setdirstripe -i 0 failed"
26516 #define OBD_FAIL_MDS_FLD_LOOKUP 0x15c
26517         do_facet mds1 "lctl set_param fail_loc=0x8000015c"
26518         touch $DIR/$tdir/$tfile && error "touch should fail with ENOENT" ||
26519                 echo "Touch failed - OK"
26520 }
26521 run_test 402 "Return ENOENT to lod_generate_and_set_lovea"
26522
26523 test_403() {
26524         local file1=$DIR/$tfile.1
26525         local file2=$DIR/$tfile.2
26526         local tfile=$TMP/$tfile
26527
26528         rm -f $file1 $file2 $tfile
26529
26530         touch $file1
26531         ln $file1 $file2
26532
26533         # 30 sec OBD_TIMEOUT in ll_getattr()
26534         # right before populating st_nlink
26535         $LCTL set_param fail_loc=0x80001409
26536         stat -c %h $file1 > $tfile &
26537
26538         # create an alias, drop all locks and reclaim the dentry
26539         < $file2
26540         cancel_lru_locks mdc
26541         cancel_lru_locks osc
26542         sysctl -w vm.drop_caches=2
26543
26544         wait
26545
26546         [ $(cat $tfile) -gt 0 ] || error "wrong nlink count: $(cat $tfile)"
26547
26548         rm -f $tfile $file1 $file2
26549 }
26550 run_test 403 "i_nlink should not drop to zero due to aliasing"
26551
26552 test_404() { # LU-6601
26553         [[ $MDS1_VERSION -ge $(version_code 2.8.53) ]] ||
26554                 skip "Need server version newer than 2.8.52"
26555         remote_mds_nodsh && skip "remote MDS with nodsh"
26556
26557         local mosps=$(do_facet $SINGLEMDS $LCTL dl |
26558                 awk '/osp .*-osc-MDT/ { print $4}')
26559
26560         local osp
26561         for osp in $mosps; do
26562                 echo "Deactivate: " $osp
26563                 do_facet $SINGLEMDS $LCTL --device %$osp deactivate
26564                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
26565                         awk -vp=$osp '$4 == p { print $2 }')
26566                 [ $stat = IN ] || {
26567                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
26568                         error "deactivate error"
26569                 }
26570                 echo "Activate: " $osp
26571                 do_facet $SINGLEMDS $LCTL --device %$osp activate
26572                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
26573                         awk -vp=$osp '$4 == p { print $2 }')
26574                 [ $stat = UP ] || {
26575                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
26576                         error "activate error"
26577                 }
26578         done
26579 }
26580 run_test 404 "validate manual {de}activated works properly for OSPs"
26581
26582 test_405() {
26583         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
26584         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] ||
26585                 [ $CLIENT_VERSION -lt $(version_code 2.6.99) ] &&
26586                         skip "Layout swap lock is not supported"
26587
26588         check_swap_layouts_support
26589         check_swap_layout_no_dom $DIR
26590
26591         test_mkdir $DIR/$tdir
26592         swap_lock_test -d $DIR/$tdir ||
26593                 error "One layout swap locked test failed"
26594 }
26595 run_test 405 "Various layout swap lock tests"
26596
26597 test_406() {
26598         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26599         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
26600         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
26601         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26602         [ $MDS1_VERSION -lt $(version_code 2.8.50) ] &&
26603                 skip "Need MDS version at least 2.8.50"
26604
26605         local def_stripe_size=$($LFS getstripe -S $MOUNT)
26606         local test_pool=$TESTNAME
26607
26608         pool_add $test_pool || error "pool_add failed"
26609         pool_add_targets $test_pool 0 $(($OSTCOUNT - 1)) 1 ||
26610                 error "pool_add_targets failed"
26611
26612         save_layout_restore_at_exit $MOUNT
26613
26614         # parent set default stripe count only, child will stripe from both
26615         # parent and fs default
26616         $LFS setstripe -c 1 -i 1 -S $((def_stripe_size * 2)) -p $test_pool $MOUNT ||
26617                 error "setstripe $MOUNT failed"
26618         $LFS mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
26619         $LFS setstripe -c $OSTCOUNT $DIR/$tdir || error "setstripe $tdir failed"
26620         for i in $(seq 10); do
26621                 local f=$DIR/$tdir/$tfile.$i
26622                 touch $f || error "touch failed"
26623                 local count=$($LFS getstripe -c $f)
26624                 [ $count -eq $OSTCOUNT ] ||
26625                         error "$f stripe count $count != $OSTCOUNT"
26626                 local offset=$($LFS getstripe -i $f)
26627                 [ $offset -eq 1 ] || error "$f stripe offset $offset != 1"
26628                 local size=$($LFS getstripe -S $f)
26629                 [ $size -eq $((def_stripe_size * 2)) ] ||
26630                         error "$f stripe size $size != $((def_stripe_size * 2))"
26631                 local pool=$($LFS getstripe -p $f)
26632                 [ $pool == $test_pool ] || error "$f pool $pool != $test_pool"
26633         done
26634
26635         # change fs default striping, delete parent default striping, now child
26636         # will stripe from new fs default striping only
26637         $LFS setstripe -c 1 -S $def_stripe_size -i 0 $MOUNT ||
26638                 error "change $MOUNT default stripe failed"
26639         $LFS setstripe -c 0 $DIR/$tdir ||
26640                 error "delete $tdir default stripe failed"
26641         for i in $(seq 11 20); do
26642                 local f=$DIR/$tdir/$tfile.$i
26643                 touch $f || error "touch $f failed"
26644                 local count=$($LFS getstripe -c $f)
26645                 [ $count -eq 1 ] || error "$f stripe count $count != 1"
26646                 local offset=$($LFS getstripe -i $f)
26647                 [ $offset -eq 0 ] || error "$f stripe offset $offset != 0"
26648                 local size=$($LFS getstripe -S $f)
26649                 [ $size -eq $def_stripe_size ] ||
26650                         error "$f stripe size $size != $def_stripe_size"
26651                 local pool=$($LFS getstripe -p $f)
26652                 [ $pool == $test_pool ] || error "$f pool $pool isn't set"
26653         done
26654
26655         unlinkmany $DIR/$tdir/$tfile. 1 20
26656
26657         local f=$DIR/$tdir/$tfile
26658         pool_remove_all_targets $test_pool $f
26659         pool_remove $test_pool $f
26660 }
26661 run_test 406 "DNE support fs default striping"
26662
26663 test_407() {
26664         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26665         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
26666                 skip "Need MDS version at least 2.8.55"
26667         remote_mds_nodsh && skip "remote MDS with nodsh"
26668
26669         $LFS mkdir -i 0 -c 1 $DIR/$tdir.0 ||
26670                 error "$LFS mkdir -i 0 -c 1 $tdir.0 failed"
26671         $LFS mkdir -i 1 -c 1 $DIR/$tdir.1 ||
26672                 error "$LFS mkdir -i 1 -c 1 $tdir.1 failed"
26673         touch $DIR/$tdir.0/$tfile.0 || error "touch $tdir.0/$tfile.0 failed"
26674
26675         #define OBD_FAIL_DT_TXN_STOP    0x2019
26676         for idx in $(seq $MDSCOUNT); do
26677                 do_facet mds$idx "lctl set_param fail_loc=0x2019"
26678         done
26679         $LFS mkdir -c 2 $DIR/$tdir && error "$LFS mkdir -c 2 $tdir should fail"
26680         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1/$tfile.1 &&
26681                 error "mv $tdir.0/$tfile.0 $tdir.1/$tfile.1 should fail"
26682         true
26683 }
26684 run_test 407 "transaction fail should cause operation fail"
26685
26686 test_408() {
26687         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
26688
26689         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
26690         lctl set_param fail_loc=0x8000040a
26691         # let ll_prepare_partial_page() fail
26692         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 conv=notrunc || true
26693
26694         rm -f $DIR/$tfile
26695
26696         # create at least 100 unused inodes so that
26697         # shrink_icache_memory(0) should not return 0
26698         touch $DIR/$tfile-{0..100}
26699         rm -f $DIR/$tfile-{0..100}
26700         sync
26701
26702         echo 2 > /proc/sys/vm/drop_caches
26703 }
26704 run_test 408 "drop_caches should not hang due to page leaks"
26705
26706 test_409()
26707 {
26708         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
26709
26710         mkdir -p $DIR/$tdir || error "(0) Fail to mkdir"
26711         $LFS mkdir -i 1 -c 2 $DIR/$tdir/foo || error "(1) Fail to mkdir"
26712         touch $DIR/$tdir/guard || error "(2) Fail to create"
26713
26714         local PREFIX=$(str_repeat 'A' 128)
26715         echo "Create 1K hard links start at $(date)"
26716         createmany -l $DIR/$tdir/guard $DIR/$tdir/foo/${PREFIX}_ 1000 ||
26717                 error "(3) Fail to hard link"
26718
26719         echo "Links count should be right although linkEA overflow"
26720         stat $DIR/$tdir/guard || error "(4) Fail to stat"
26721         local linkcount=$(stat --format=%h $DIR/$tdir/guard)
26722         [ $linkcount -eq 1001 ] ||
26723                 error "(5) Unexpected hard links count: $linkcount"
26724
26725         echo "List all links start at $(date)"
26726         ls -l $DIR/$tdir/foo > /dev/null ||
26727                 error "(6) Fail to list $DIR/$tdir/foo"
26728
26729         echo "Unlink hard links start at $(date)"
26730         unlinkmany $DIR/$tdir/foo/${PREFIX}_ 1000 ||
26731                 error "(7) Fail to unlink"
26732         echo "Unlink hard links finished at $(date)"
26733 }
26734 run_test 409 "Large amount of cross-MDTs hard links on the same file"
26735
26736 test_410()
26737 {
26738         [[ $CLIENT_VERSION -lt $(version_code 2.9.59) ]] &&
26739                 skip "Need client version at least 2.9.59"
26740         [ -f $LUSTRE/tests/kernel/kinode.ko ] ||
26741                 skip "Need MODULES build"
26742
26743         # Create a file, and stat it from the kernel
26744         local testfile=$DIR/$tfile
26745         touch $testfile
26746
26747         local run_id=$RANDOM
26748         local my_ino=$(stat --format "%i" $testfile)
26749
26750         # Try to insert the module. This will always fail as the
26751         # module is designed to not be inserted.
26752         insmod $LUSTRE/tests/kernel/kinode.ko run_id=$run_id fname=$testfile \
26753             &> /dev/null
26754
26755         # Anything but success is a test failure
26756         dmesg | grep -q \
26757             "lustre_kinode_$run_id: inode numbers are identical: $my_ino" ||
26758             error "no inode match"
26759 }
26760 run_test 410 "Test inode number returned from kernel thread"
26761
26762 cleanup_test411_cgroup() {
26763         trap 0
26764         rmdir "$1"
26765 }
26766
26767 test_411() {
26768         local cg_basedir=/sys/fs/cgroup/memory
26769         # LU-9966
26770         test -f "$cg_basedir/memory.kmem.limit_in_bytes" ||
26771                 skip "no setup for cgroup"
26772
26773         dd if=/dev/zero of=$DIR/$tfile bs=1M count=100 conv=fsync ||
26774                 error "test file creation failed"
26775         cancel_lru_locks osc
26776
26777         # Create a very small memory cgroup to force a slab allocation error
26778         local cgdir=$cg_basedir/osc_slab_alloc
26779         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
26780         trap "cleanup_test411_cgroup $cgdir" EXIT
26781         echo 2M > $cgdir/memory.kmem.limit_in_bytes
26782         echo 1M > $cgdir/memory.limit_in_bytes
26783
26784         # Should not LBUG, just be killed by oom-killer
26785         # dd will return 0 even allocation failure in some environment.
26786         # So don't check return value
26787         bash -c "echo \$$ > $cgdir/tasks && dd if=$DIR/$tfile of=/dev/null"
26788         cleanup_test411_cgroup $cgdir
26789
26790         return 0
26791 }
26792 run_test 411 "Slab allocation error with cgroup does not LBUG"
26793
26794 test_412() {
26795         (( $MDSCOUNT > 1 )) || skip_env "needs >= 2 MDTs"
26796         (( $MDS1_VERSION >= $(version_code 2.10.55) )) ||
26797                 skip "Need server version at least 2.10.55"
26798
26799         $LFS mkdir -i $((MDSCOUNT - 1)),$((MDSCOUNT - 2)) $DIR/$tdir ||
26800                 error "mkdir failed"
26801         $LFS getdirstripe $DIR/$tdir
26802         local stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
26803         [ $stripe_index -eq $((MDSCOUNT - 1)) ] ||
26804                 error "expect $((MDSCOUT - 1)) get $stripe_index"
26805         local stripe_count=$($LFS getdirstripe -T $DIR/$tdir)
26806         [ $stripe_count -eq 2 ] ||
26807                 error "expect 2 get $stripe_count"
26808
26809         (( $MDS1_VERSION >= $(version_code 2.14.55) )) || return 0
26810
26811         local index
26812         local index2
26813
26814         # subdirs should be on the same MDT as parent
26815         for i in $(seq 0 $((MDSCOUNT - 1))); do
26816                 $LFS mkdir -i $i $DIR/$tdir/mdt$i || error "mkdir mdt$i failed"
26817                 mkdir $DIR/$tdir/mdt$i/sub || error "mkdir sub failed"
26818                 index=$($LFS getstripe -m $DIR/$tdir/mdt$i/sub)
26819                 (( index == i )) || error "mdt$i/sub on MDT$index"
26820         done
26821
26822         # stripe offset -1, ditto
26823         for i in {1..10}; do
26824                 $LFS mkdir -i -1 $DIR/$tdir/qos$i || error "mkdir qos$i failed"
26825                 index=$($LFS getstripe -m $DIR/$tdir/qos$i)
26826                 mkdir $DIR/$tdir/qos$i/sub || error "mkdir sub failed"
26827                 index2=$($LFS getstripe -m $DIR/$tdir/qos$i/sub)
26828                 (( index == index2 )) ||
26829                         error "qos$i on MDT$index, sub on MDT$index2"
26830         done
26831
26832         local testdir=$DIR/$tdir/inherit
26833
26834         $LFS mkdir -i 1 --max-inherit=3 $testdir || error "mkdir inherit failed"
26835         # inherit 2 levels
26836         for i in 1 2; do
26837                 testdir=$testdir/s$i
26838                 mkdir $testdir || error "mkdir $testdir failed"
26839                 index=$($LFS getstripe -m $testdir)
26840                 (( index == 1 )) ||
26841                         error "$testdir on MDT$index"
26842         done
26843
26844         # not inherit any more
26845         testdir=$testdir/s3
26846         mkdir $testdir || error "mkdir $testdir failed"
26847         getfattr -d -m dmv $testdir | grep dmv &&
26848                 error "default LMV set on $testdir" || true
26849 }
26850 run_test 412 "mkdir on specific MDTs"
26851
26852 TEST413_COUNT=${TEST413_COUNT:-200}
26853
26854 #
26855 # set_maxage() is used by test_413 only.
26856 # This is a helper function to set maxage. Does not return any value.
26857 # Input: maxage to set
26858 #
26859 set_maxage() {
26860         local lmv_qos_maxage
26861         local lod_qos_maxage
26862         local new_maxage=$1
26863
26864         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
26865         $LCTL set_param lmv.*.qos_maxage=$new_maxage
26866         stack_trap "$LCTL set_param \
26867                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null"
26868         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
26869                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
26870         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
26871                 lod.*.mdt_qos_maxage=$new_maxage
26872         stack_trap "do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
26873                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null"
26874 }
26875
26876 generate_uneven_mdts() {
26877         local threshold=$1
26878         local ffree
26879         local bavail
26880         local max
26881         local min
26882         local max_index
26883         local min_index
26884         local tmp
26885         local i
26886
26887         echo
26888         echo "Check for uneven MDTs: "
26889
26890         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
26891         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
26892         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
26893
26894         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
26895         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
26896         max_index=0
26897         min_index=0
26898         for ((i = 1; i < ${#ffree[@]}; i++)); do
26899                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
26900                 if [ $tmp -gt $max ]; then
26901                         max=$tmp
26902                         max_index=$i
26903                 fi
26904                 if [ $tmp -lt $min ]; then
26905                         min=$tmp
26906                         min_index=$i
26907                 fi
26908         done
26909
26910         (( min > 0 )) || skip "low space on MDT$min_index"
26911         (( ${ffree[min_index]} > 0 )) ||
26912                 skip "no free files on MDT$min_index"
26913         (( ${ffree[min_index]} < 10000000 )) ||
26914                 skip "too many free files on MDT$min_index"
26915
26916         # Check if we need to generate uneven MDTs
26917         local diff=$(((max - min) * 100 / min))
26918         local testdirp=$DIR/$tdir-fillmdt # parent fill folder
26919         local testdir # individual folder within $testdirp
26920         local start
26921         local cmd
26922
26923         # fallocate is faster to consume space on MDT, if available
26924         if check_fallocate_supported mds$((min_index + 1)); then
26925                 cmd="fallocate -l 128K "
26926         else
26927                 cmd="dd if=/dev/zero bs=128K count=1 of="
26928         fi
26929
26930         echo "using cmd $cmd"
26931         for (( i = 0; diff < threshold; i++ )); do
26932                 testdir=${testdirp}/$i
26933                 [ -d $testdir ] && continue
26934
26935                 (( i % 10 > 0 )) || { $LFS df; $LFS df -i; }
26936
26937                 mkdir -p $testdirp
26938                 # generate uneven MDTs, create till $threshold% diff
26939                 echo -n "weight diff=$diff% must be > $threshold% ..."
26940                 echo "Fill MDT$min_index with $TEST413_COUNT files: loop $i"
26941                 $LFS mkdir -i $min_index $testdir ||
26942                         error "mkdir $testdir failed"
26943                 $LFS setstripe -E 1M -L mdt $testdir ||
26944                         error "setstripe $testdir failed"
26945                 start=$SECONDS
26946                 for (( f = 0; f < TEST413_COUNT; f++ )); do
26947                         $cmd$testdir/f.$f &> /dev/null || error "$cmd $f failed"
26948                 done
26949                 sync; sleep 1; sync
26950
26951                 # wait for QOS to update
26952                 (( SECONDS < start + 2 )) && sleep $((start + 2 - SECONDS))
26953
26954                 ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-*.filesfree))
26955                 bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-*.kbytesavail))
26956                 max=$(((${ffree[max_index]} >> 8) *
26957                         (${bavail[max_index]} * bsize >> 16)))
26958                 min=$(((${ffree[min_index]} >> 8) *
26959                         (${bavail[min_index]} * bsize >> 16)))
26960                 (( min > 0 )) || skip "low space on MDT$min_index"
26961                 diff=$(((max - min) * 100 / min))
26962         done
26963
26964         echo "MDT filesfree available: ${ffree[*]}"
26965         echo "MDT blocks available: ${bavail[*]}"
26966         echo "weight diff=$diff%"
26967 }
26968
26969 test_qos_mkdir() {
26970         local mkdir_cmd=$1
26971         local stripe_count=$2
26972         local mdts=$(comma_list $(mdts_nodes))
26973
26974         local testdir
26975         local lmv_qos_prio_free
26976         local lmv_qos_threshold_rr
26977         local lod_qos_prio_free
26978         local lod_qos_threshold_rr
26979         local total
26980         local count
26981         local i
26982
26983         # @total is total directories created if it's testing plain
26984         # directories, otherwise it's total stripe object count for
26985         # striped directories test.
26986         # remote/striped directory unlinking is slow on zfs and may
26987         # timeout, test with fewer directories
26988         [ "$mds1_FSTYPE" = "zfs" ] && total=120 || total=240
26989
26990         lmv_qos_prio_free=$($LCTL get_param -n lmv.*.qos_prio_free | head -n1)
26991         lmv_qos_prio_free=${lmv_qos_prio_free%%%}
26992         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
26993                 head -n1)
26994         lmv_qos_threshold_rr=${lmv_qos_threshold_rr%%%}
26995         stack_trap "$LCTL set_param \
26996                 lmv.*.qos_prio_free=$lmv_qos_prio_free > /dev/null"
26997         stack_trap "$LCTL set_param \
26998                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null"
26999
27000         lod_qos_prio_free=$(do_facet mds1 $LCTL get_param -n \
27001                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_prio_free | head -n1)
27002         lod_qos_prio_free=${lod_qos_prio_free%%%}
27003         lod_qos_threshold_rr=$(do_facet mds1 $LCTL get_param -n \
27004                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_threshold_rr | head -n1)
27005         lod_qos_threshold_rr=${lod_qos_threshold_rr%%%}
27006         stack_trap "do_nodes $mdts $LCTL set_param \
27007                 lod.*.mdt_qos_prio_free=$lod_qos_prio_free > /dev/null"
27008         stack_trap "do_nodes $mdts $LCTL set_param \
27009                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null"
27010
27011         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
27012         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=100 > /dev/null
27013
27014         testdir=$DIR/$tdir-s$stripe_count/rr
27015
27016         local stripe_index=$($LFS getstripe -m $testdir)
27017         local test_mkdir_rr=true
27018
27019         getfattr -d -m dmv -e hex $testdir | grep dmv
27020         if (( $? == 0 && $MDS1_VERSION >= $(version_code 2.14.51) )); then
27021                 echo "defstripe: '$($LFS getdirstripe -D $testdir)'"
27022                 (( $($LFS getdirstripe -D --max-inherit-rr $testdir) == 0 )) &&
27023                         test_mkdir_rr=false
27024         fi
27025
27026         echo
27027         $test_mkdir_rr &&
27028                 echo "Mkdir (stripe_count $stripe_count) roundrobin:" ||
27029                 echo "Mkdir (stripe_count $stripe_count) on stripe $stripe_index"
27030
27031         stack_trap "unlinkmany -d $testdir/subdir $((total / stripe_count))"
27032         for (( i = 0; i < total / stripe_count; i++ )); do
27033                 eval $mkdir_cmd $testdir/subdir$i ||
27034                         error "$mkdir_cmd subdir$i failed"
27035         done
27036
27037         for (( i = 0; i < $MDSCOUNT; i++ )); do
27038                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
27039                 echo "$count directories created on MDT$i"
27040                 if $test_mkdir_rr; then
27041                         (( count == total / stripe_count / MDSCOUNT )) ||
27042                                 error "subdirs are not evenly distributed"
27043                 elif (( i == stripe_index )); then
27044                         (( count == total / stripe_count )) ||
27045                                 error "$count subdirs created on MDT$i"
27046                 else
27047                         (( count == 0 )) ||
27048                                 error "$count subdirs created on MDT$i"
27049                 fi
27050
27051                 if $test_mkdir_rr && [ $stripe_count -gt 1 ]; then
27052                         count=$($LFS getdirstripe $testdir/* |
27053                                 grep -c -P "^\s+$i\t")
27054                         echo "$count stripes created on MDT$i"
27055                         # deviation should < 5% of average
27056                         delta=$((count - total / MDSCOUNT))
27057                         (( ${delta#-} <= total / MDSCOUNT / 20 )) ||
27058                                 error "stripes are not evenly distributed"
27059                 fi
27060         done
27061
27062         echo
27063         echo "Check for uneven MDTs: "
27064
27065         local ffree
27066         local bavail
27067         local max
27068         local min
27069         local max_index
27070         local min_index
27071         local tmp
27072
27073         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
27074         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
27075         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
27076
27077         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
27078         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
27079         max_index=0
27080         min_index=0
27081         for ((i = 1; i < ${#ffree[@]}; i++)); do
27082                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
27083                 if [ $tmp -gt $max ]; then
27084                         max=$tmp
27085                         max_index=$i
27086                 fi
27087                 if [ $tmp -lt $min ]; then
27088                         min=$tmp
27089                         min_index=$i
27090                 fi
27091         done
27092         echo "stripe_count=$stripe_count min_idx=$min_index max_idx=$max_index"
27093
27094         (( min > 0 )) || skip "low space on MDT$min_index"
27095         (( ${ffree[min_index]} < 10000000 )) ||
27096                 skip "too many free files on MDT$min_index"
27097
27098         generate_uneven_mdts 120
27099
27100         echo "MDT filesfree available: ${ffree[*]}"
27101         echo "MDT blocks available: ${bavail[*]}"
27102         echo "weight diff=$(((max - min) * 100 / min))%"
27103         echo
27104         echo "Mkdir (stripe_count $stripe_count) with balanced space usage:"
27105
27106         $LCTL set_param lmv.*.qos_threshold_rr=0 > /dev/null
27107         $LCTL set_param lmv.*.qos_prio_free=100 > /dev/null
27108         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=0 > /dev/null
27109         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_prio_free=100 > /dev/null
27110         # decrease statfs age, so that it can be updated in time
27111         $LCTL set_param lmv.*.qos_maxage=1 > /dev/null
27112         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_maxage=1 > /dev/null
27113
27114         sleep 1
27115
27116         testdir=$DIR/$tdir-s$stripe_count/qos
27117
27118         stack_trap "unlinkmany -d $testdir/subdir $((total / stripe_count))"
27119         for (( i = 0; i < total / stripe_count; i++ )); do
27120                 eval $mkdir_cmd $testdir/subdir$i ||
27121                         error "$mkdir_cmd subdir$i failed"
27122         done
27123
27124         max=0
27125         for (( i = 0; i < $MDSCOUNT; i++ )); do
27126                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
27127                 (( count > max )) && max=$count
27128                 echo "$count directories created on MDT$i : curmax=$max"
27129         done
27130
27131         min=$($LFS getdirstripe -i $testdir/* | grep -c "^$min_index$")
27132
27133         # D-value should > 10% of average
27134         (( max - min > total / stripe_count / MDSCOUNT / 10 )) ||
27135                 error "subdirs shouldn't be evenly distributed: $max - $min <= $((total / stripe_count / MDSCOUNT / 10))"
27136
27137         # ditto for stripes
27138         if (( stripe_count > 1 )); then
27139                 max=0
27140                 for (( i = 0; i < $MDSCOUNT; i++ )); do
27141                         count=$($LFS getdirstripe $testdir/* |
27142                                 grep -c -P "^\s+$i\t")
27143                         (( count > max )) && max=$count
27144                         echo "$count stripes created on MDT$i"
27145                 done
27146
27147                 min=$($LFS getdirstripe $testdir/* |
27148                         grep -c -P "^\s+$min_index\t")
27149                 (( max - min > total / MDSCOUNT / 10 )) ||
27150                         error "stripes shouldn't be evenly distributed: $max - $min <= $((total / MDSCOUNT / 10))"
27151         fi
27152 }
27153
27154 most_full_mdt() {
27155         local ffree
27156         local bavail
27157         local bsize
27158         local min
27159         local min_index
27160         local tmp
27161
27162         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
27163         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
27164         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
27165
27166         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
27167         min_index=0
27168         for ((i = 1; i < ${#ffree[@]}; i++)); do
27169                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
27170                 (( tmp < min )) && min=$tmp && min_index=$i
27171         done
27172
27173         echo -n $min_index
27174 }
27175
27176 test_413a() {
27177         [ $MDSCOUNT -lt 2 ] &&
27178                 skip "We need at least 2 MDTs for this test"
27179
27180         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
27181                 skip "Need server version at least 2.12.52"
27182
27183         local stripe_max=$((MDSCOUNT - 1))
27184         local stripe_count
27185
27186         # let caller set maxage for latest result
27187         set_maxage 1
27188
27189         # fill MDT unevenly
27190         generate_uneven_mdts 120
27191
27192         # test 4-stripe directory at most, otherwise it's too slow
27193         # We are being very defensive. Although Autotest uses 4 MDTs.
27194         # We make sure stripe_max does not go over 4.
27195         (( stripe_max > 4 )) && stripe_max=4
27196         # unlinking striped directory is slow on zfs, and may timeout, only test
27197         # plain directory
27198         [ "$mds1_FSTYPE" == "zfs" ] && stripe_max=1
27199         for stripe_count in $(seq 1 $stripe_max); do
27200                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
27201                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
27202                 $LFS mkdir -i $(most_full_mdt) $DIR/$tdir-s$stripe_count/qos ||
27203                         error "mkdir failed"
27204                 test_qos_mkdir "$LFS mkdir -i -1 -c $stripe_count" $stripe_count
27205         done
27206 }
27207 run_test 413a "QoS mkdir with 'lfs mkdir -i -1'"
27208
27209 test_413b() {
27210         [ $MDSCOUNT -lt 2 ] &&
27211                 skip "We need at least 2 MDTs for this test"
27212
27213         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
27214                 skip "Need server version at least 2.12.52"
27215
27216         local stripe_max=$((MDSCOUNT - 1))
27217         local testdir
27218         local stripe_count
27219
27220         # let caller set maxage for latest result
27221         set_maxage 1
27222
27223         # fill MDT unevenly
27224         generate_uneven_mdts 120
27225
27226         # test 4-stripe directory at most, otherwise it's too slow
27227         # We are being very defensive. Although Autotest uses 4 MDTs.
27228         # We make sure stripe_max does not go over 4.
27229         (( stripe_max > 4 )) && stripe_max=4
27230         [ "$mds1_FSTYPE" == "zfs" ] && stripe_max=1
27231         for stripe_count in $(seq 1 $stripe_max); do
27232                 testdir=$DIR/$tdir-s$stripe_count
27233                 mkdir $testdir || error "mkdir $testdir failed"
27234                 mkdir $testdir/rr || error "mkdir rr failed"
27235                 $LFS mkdir -i $(most_full_mdt) $testdir/qos ||
27236                         error "mkdir qos failed"
27237                 $LFS setdirstripe -D -c $stripe_count --max-inherit-rr 2 \
27238                         $testdir/rr || error "setdirstripe rr failed"
27239                 $LFS setdirstripe -D -c $stripe_count $testdir/qos ||
27240                         error "setdirstripe failed"
27241                 test_qos_mkdir "mkdir" $stripe_count
27242         done
27243 }
27244 run_test 413b "QoS mkdir under dir whose default LMV starting MDT offset is -1"
27245
27246 test_413c() {
27247         (( $MDSCOUNT >= 2 )) ||
27248                 skip "We need at least 2 MDTs for this test"
27249
27250         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
27251                 skip "Need server version at least 2.14.51"
27252
27253         local testdir
27254         local inherit
27255         local inherit_rr
27256         local lmv_qos_maxage
27257         local lod_qos_maxage
27258
27259         # let caller set maxage for latest result
27260         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
27261         $LCTL set_param lmv.*.qos_maxage=1
27262         stack_trap "$LCTL set_param \
27263                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null" RETURN
27264         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
27265                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
27266         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
27267                 lod.*.mdt_qos_maxage=1
27268         stack_trap "do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
27269                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null" RETURN
27270
27271         # fill MDT unevenly
27272         generate_uneven_mdts 120
27273
27274         testdir=$DIR/${tdir}-s1
27275         mkdir $testdir || error "mkdir $testdir failed"
27276         mkdir $testdir/rr || error "mkdir rr failed"
27277         $LFS mkdir -i $(most_full_mdt) $testdir/qos || error "mkdir qos failed"
27278         # default max_inherit is -1, default max_inherit_rr is 0
27279         $LFS setdirstripe -D -c 1 $testdir/rr ||
27280                 error "setdirstripe rr failed"
27281         $LFS setdirstripe -D -c 1 -i -1 -X 2 --max-inherit-rr 1 $testdir/qos ||
27282                 error "setdirstripe qos failed"
27283         test_qos_mkdir "mkdir" 1
27284
27285         mkdir $testdir/rr/level1 || error "mkdir rr/level1 failed"
27286         inherit=$($LFS getdirstripe -D -X $testdir/rr/level1)
27287         (( $inherit == -1 )) || error "rr/level1 inherit $inherit != -1"
27288         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/rr/level1)
27289         (( $inherit_rr == 0 )) || error "rr/level1 inherit-rr $inherit_rr != 0"
27290
27291         mkdir $testdir/qos/level1 || error "mkdir qos/level1 failed"
27292         inherit=$($LFS getdirstripe -D -X $testdir/qos/level1)
27293         (( $inherit == 1 )) || error "qos/level1 inherit $inherit != 1"
27294         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/qos/level1)
27295         (( $inherit_rr == 0 )) || error "qos/level1 inherit-rr $inherit_rr != 0"
27296         mkdir $testdir/qos/level1/level2 || error "mkdir level2 failed"
27297         getfattr -d -m dmv -e hex $testdir/qos/level1/level2 | grep dmv &&
27298                 error "level2 shouldn't have default LMV" || true
27299 }
27300 run_test 413c "mkdir with default LMV max inherit rr"
27301
27302 test_413d() {
27303         (( MDSCOUNT >= 2 )) ||
27304                 skip "We need at least 2 MDTs for this test"
27305
27306         (( MDS1_VERSION >= $(version_code 2.14.51) )) ||
27307                 skip "Need server version at least 2.14.51"
27308
27309         local lmv_qos_threshold_rr
27310
27311         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
27312                 head -n1)
27313         stack_trap "$LCTL set_param \
27314                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null" EXIT
27315
27316         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
27317         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
27318         getfattr -d -m dmv -e hex $DIR/$tdir | grep dmv &&
27319                 error "$tdir shouldn't have default LMV"
27320         createmany -d $DIR/$tdir/sub $((100 * MDSCOUNT)) ||
27321                 error "mkdir sub failed"
27322
27323         local count=$($LFS getstripe -m $DIR/$tdir/* | grep -c ^0)
27324
27325         (( count == 100 )) || error "$count subdirs on MDT0"
27326 }
27327 run_test 413d "inherit ROOT default LMV"
27328
27329 test_413e() {
27330         (( MDSCOUNT >= 2 )) ||
27331                 skip "We need at least 2 MDTs for this test"
27332         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
27333                 skip "Need server version at least 2.14.55"
27334
27335         local testdir=$DIR/$tdir
27336         local tmpfile=$TMP/temp.setdirstripe.stderr.$$
27337         local max_inherit
27338         local sub_max_inherit
27339
27340         mkdir -p $testdir || error "failed to create $testdir"
27341
27342         # set default max-inherit to -1 if stripe count is 0 or 1
27343         $LFS setdirstripe -D -c 1 $testdir ||
27344                 error "failed to set default LMV"
27345         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
27346         (( max_inherit == -1 )) ||
27347                 error "wrong max_inherit value $max_inherit"
27348
27349         # set default max_inherit to a fixed value if stripe count is not 0 or 1
27350         $LFS setdirstripe -D -c -1 $testdir ||
27351                 error "failed to set default LMV"
27352         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
27353         (( max_inherit > 0 )) ||
27354                 error "wrong max_inherit value $max_inherit"
27355
27356         # and the subdir will decrease the max_inherit by 1
27357         mkdir -p $testdir/subdir-1 || error "failed to make subdir"
27358         sub_max_inherit=$($LFS getdirstripe -D --max-inherit $testdir/subdir-1)
27359         (( sub_max_inherit == max_inherit - 1)) ||
27360                 error "wrong max-inherit of subdir $sub_max_inherit"
27361
27362         # check specified --max-inherit and warning message
27363         stack_trap "rm -f $tmpfile"
27364         $LFS setdirstripe -D -c 2 --max-inherit=-1 $testdir 2> $tmpfile ||
27365                 error "failed to set default LMV"
27366         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
27367         (( max_inherit == -1 )) ||
27368                 error "wrong max_inherit value $max_inherit"
27369
27370         # check the warning messages
27371         if ! [[ $(cat $tmpfile) =~ "max-inherit=" ]]; then
27372                 error "failed to detect warning string"
27373         fi
27374 }
27375 run_test 413e "check default max-inherit value"
27376
27377 test_fs_dmv_inherit()
27378 {
27379         local testdir=$DIR/$tdir
27380
27381         local count
27382         local inherit
27383         local inherit_rr
27384
27385         for i in 1 2; do
27386                 mkdir $testdir || error "mkdir $testdir failed"
27387                 count=$($LFS getdirstripe -D -c $testdir)
27388                 (( count == 1 )) ||
27389                         error "$testdir default LMV count mismatch $count != 1"
27390                 inherit=$($LFS getdirstripe -D -X $testdir)
27391                 (( inherit == 3 - i )) ||
27392                         error "$testdir default LMV max-inherit $inherit != $((3 - i))"
27393                 inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir)
27394                 (( inherit_rr == 3 - i )) ||
27395                         error "$testdir default LMV max-inherit-rr $inherit_rr != $((3 - i))"
27396                 testdir=$testdir/sub
27397         done
27398
27399         mkdir $testdir || error "mkdir $testdir failed"
27400         count=$($LFS getdirstripe -D -c $testdir)
27401         (( count == 0 )) ||
27402                 error "$testdir default LMV count not zero: $count"
27403 }
27404
27405 test_413f() {
27406         (( MDSCOUNT >= 2 )) || skip "We need at least 2 MDTs for this test"
27407
27408         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
27409                 skip "Need server version at least 2.14.55"
27410
27411         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
27412                 error "dump $DIR default LMV failed"
27413         stack_trap "setfattr --restore=$TMP/dmv.ea"
27414
27415         $LFS setdirstripe -D -i -1 -c 1 -X 3 --max-inherit-rr 3 $DIR ||
27416                 error "set $DIR default LMV failed"
27417
27418         test_fs_dmv_inherit
27419 }
27420 run_test 413f "lfs getdirstripe -D list ROOT default LMV if it's not set on dir"
27421
27422 test_413g() {
27423         (( MDSCOUNT >= 2 )) || skip "We need at least 2 MDTs for this test"
27424
27425         mkdir -p $DIR/$tdir/l2/l3/l4 || error "mkdir $tdir/l1/l2/l3 failed"
27426         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
27427                 error "dump $DIR default LMV failed"
27428         stack_trap "setfattr --restore=$TMP/dmv.ea"
27429
27430         $LFS setdirstripe -D -i -1 -c 1 -X 3 --max-inherit-rr 3 $DIR ||
27431                 error "set $DIR default LMV failed"
27432
27433         FILESET="$FILESET/$tdir/l2/l3/l4" mount_client $MOUNT2 ||
27434                 error "mount $MOUNT2 failed"
27435         stack_trap "umount_client $MOUNT2"
27436
27437         local saved_DIR=$DIR
27438
27439         export DIR=$MOUNT2
27440
27441         stack_trap "export DIR=$saved_DIR"
27442
27443         # first check filesystem-wide default LMV inheritance
27444         test_fs_dmv_inherit || error "incorrect fs default LMV inheritance"
27445
27446         # then check subdirs are spread to all MDTs
27447         createmany -d $DIR/s $((MDSCOUNT * 100)) || error "createmany failed"
27448
27449         local count=$($LFS getstripe -m $DIR/s* | sort -u | wc -l)
27450
27451         (( $count == $MDSCOUNT )) || error "dirs are spread to $count MDTs"
27452 }
27453 run_test 413g "enforce ROOT default LMV on subdir mount"
27454
27455 test_413h() {
27456         (( MDSCOUNT >= 2 )) ||
27457                 skip "We need at least 2 MDTs for this test"
27458
27459         (( MDS1_VERSION >= $(version_code 2.15.50.6) )) ||
27460                 skip "Need server version at least 2.15.50.6"
27461
27462         local lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
27463
27464         stack_trap "$LCTL set_param \
27465                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null"
27466         $LCTL set_param lmv.*.qos_maxage=1
27467
27468         local depth=5
27469         local rr_depth=4
27470         local dir=$DIR/$tdir/l1/l2/l3/l4/l5
27471         local count=$((MDSCOUNT * 20))
27472
27473         generate_uneven_mdts 50
27474
27475         mkdir -p $dir || error "mkdir $dir failed"
27476         stack_trap "rm -rf $dir"
27477         $LFS setdirstripe -D -c 1 -i -1 --max-inherit=$depth \
27478                 --max-inherit-rr=$rr_depth $dir
27479
27480         for ((d=0; d < depth + 2; d++)); do
27481                 log "dir=$dir:"
27482                 for ((sub=0; sub < count; sub++)); do
27483                         mkdir $dir/d$sub
27484                 done
27485                 $LFS getdirstripe -i $dir/d* | sort | uniq -c | sort -nr
27486                 local num=($($LFS getdirstripe -i $dir/d* | sort | uniq -c))
27487                 # subdirs within $rr_depth should be created round-robin
27488                 if (( d < rr_depth )); then
27489                         (( ${num[0]} != count )) ||
27490                                 error "all objects created on MDT ${num[1]}"
27491                 fi
27492
27493                 dir=$dir/d0
27494         done
27495 }
27496 run_test 413h "don't stick to parent for round-robin dirs"
27497
27498 test_413i() {
27499         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
27500
27501         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
27502                 skip "Need server version at least 2.14.55"
27503
27504         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
27505                 error "dump $DIR default LMV failed"
27506         stack_trap "setfattr --restore=$TMP/dmv.ea"
27507
27508         local testdir=$DIR/$tdir
27509         local def_max_rr=1
27510         local def_max=3
27511         local count
27512
27513         $LFS setdirstripe -D -i-1 -c1 --max-inherit=$def_max \
27514                 --max-inherit-rr=$def_max_rr $DIR ||
27515                 error "set $DIR default LMV failed"
27516
27517         for i in $(seq 2 3); do
27518                 def_max=$((def_max - 1))
27519                 (( def_max_rr == 0 )) || def_max_rr=$((def_max_rr - 1))
27520
27521                 mkdir $testdir
27522                 # RR is decremented and keeps zeroed once exhausted
27523                 count=$($LFS getdirstripe -D --max-inherit-rr $testdir)
27524                 (( count == def_max_rr )) ||
27525                         error_noexit "$testdir: max-inherit-rr $count != $def_max_rr"
27526
27527                 # max-inherit is decremented
27528                 count=$($LFS getdirstripe -D --max-inherit $testdir)
27529                 (( count == def_max )) ||
27530                         error_noexit "$testdir: max-inherit $count != $def_max"
27531
27532                 testdir=$testdir/d$i
27533         done
27534
27535         # d3 is the last inherited from ROOT, no inheritance anymore
27536         # i.e. no the default layout anymore
27537         mkdir -p $testdir/d4/d5
27538         count=$($LFS getdirstripe -D --max-inherit $testdir)
27539         (( count == -1 )) ||
27540                 error_noexit "$testdir: max-inherit $count != -1"
27541
27542         local p_count=$($LFS getdirstripe -i $testdir)
27543
27544         for i in $(seq 4 5); do
27545                 testdir=$testdir/d$i
27546
27547                 # the root default layout is not applied once exhausted
27548                 count=$($LFS getdirstripe -i $testdir)
27549                 (( count == p_count )) ||
27550                         error_noexit "$testdir: stripe-offset $count != parent offset $p_count"
27551         done
27552
27553         $LFS setdirstripe -i 0 $DIR/d2
27554         count=$($LFS getdirstripe -D --max-inherit $DIR/d2)
27555         (( count == -1 )) ||
27556                 error_noexit "$DIR/d2: max-inherit non-striped default $count != -1"
27557 }
27558 run_test 413i "check default layout inheritance"
27559
27560 test_413z() {
27561         local pids=""
27562         local subdir
27563         local pid
27564
27565         for subdir in $(\ls -1 -d $DIR/d413*-fillmdt/*); do
27566                 unlinkmany $subdir/f. $TEST413_COUNT &
27567                 pids="$pids $!"
27568         done
27569
27570         for pid in $pids; do
27571                 wait $pid
27572         done
27573
27574         true
27575 }
27576 run_test 413z "413 test cleanup"
27577
27578 test_414() {
27579 #define OBD_FAIL_PTLRPC_BULK_ATTACH      0x521
27580         $LCTL set_param fail_loc=0x80000521
27581         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
27582         rm -f $DIR/$tfile
27583 }
27584 run_test 414 "simulate ENOMEM in ptlrpc_register_bulk()"
27585
27586 test_415() {
27587         [[ $PARALLEL == "yes" ]] && skip "skip parallel run"
27588         (( $MDS1_VERSION >= $(version_code 2.11.52) )) ||
27589                 skip "Need server version at least 2.11.52"
27590
27591         # LU-11102
27592         local total=500
27593         local max=120
27594
27595         # this test may be slow on ZFS
27596         [[ "$mds1_FSTYPE" == "zfs" ]] && total=50
27597
27598         # though this test is designed for striped directory, let's test normal
27599         # directory too since lock is always saved as CoS lock.
27600         test_mkdir $DIR/$tdir || error "mkdir $tdir"
27601         createmany -o $DIR/$tdir/$tfile. $total || error "createmany"
27602         stack_trap "unlinkmany $DIR/$tdir/$tfile. $total || true"
27603         # if looping with ONLY_REPEAT, wait for previous deletions to finish
27604         wait_delete_completed_mds
27605
27606         # run a loop without concurrent touch to measure rename duration.
27607         # only for test debug/robustness, NOT part of COS functional test.
27608         local start_time=$SECONDS
27609         for ((i = 0; i < total; i++)); do
27610                 mrename $DIR/$tdir/$tfile.$i $DIR/$tdir/$tfile-new.$i \
27611                         > /dev/null
27612         done
27613         local baseline=$((SECONDS - start_time))
27614         echo "rename $total files without 'touch' took $baseline sec"
27615
27616         (
27617                 while true; do
27618                         touch $DIR/$tdir
27619                 done
27620         ) &
27621         local setattr_pid=$!
27622
27623         # rename files back to original name so unlinkmany works
27624         start_time=$SECONDS
27625         for ((i = 0; i < total; i++)); do
27626                 mrename $DIR/$tdir/$tfile-new.$i $DIR/$tdir/$tfile.$i\
27627                         > /dev/null
27628         done
27629         local duration=$((SECONDS - start_time))
27630
27631         kill -9 $setattr_pid
27632
27633         echo "rename $total files with 'touch' took $duration sec"
27634         (( max > 2 * baseline )) || max=$((2 * baseline + 5))
27635         (( duration <= max )) ||
27636                 error_not_in_vm "rename took $duration > $max sec"
27637 }
27638 run_test 415 "lock revoke is not missing"
27639
27640 test_416() {
27641         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
27642                 skip "Need server version at least 2.11.55"
27643
27644         # define OBD_FAIL_OSD_TXN_START    0x19a
27645         do_facet mds1 lctl set_param fail_loc=0x19a
27646
27647         lfs mkdir -c $MDSCOUNT $DIR/$tdir
27648
27649         true
27650 }
27651 run_test 416 "transaction start failure won't cause system hung"
27652
27653 cleanup_417() {
27654         trap 0
27655         do_nodes $(comma_list $(mdts_nodes)) \
27656                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=1"
27657         do_nodes $(comma_list $(mdts_nodes)) \
27658                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=1"
27659         do_nodes $(comma_list $(mdts_nodes)) \
27660                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=1"
27661 }
27662
27663 test_417() {
27664         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
27665         [[ $MDS1_VERSION -lt $(version_code 2.11.56) ]] &&
27666                 skip "Need MDS version at least 2.11.56"
27667
27668         trap cleanup_417 RETURN EXIT
27669
27670         $LFS mkdir -i 1 $DIR/$tdir.1 || error "create remote dir $tdir.1 failed"
27671         do_nodes $(comma_list $(mdts_nodes)) \
27672                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=0"
27673         $LFS migrate -m 0 $DIR/$tdir.1 &&
27674                 error "migrate dir $tdir.1 should fail"
27675
27676         do_nodes $(comma_list $(mdts_nodes)) \
27677                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=0"
27678         $LFS mkdir -i 1 $DIR/$tdir.2 &&
27679                 error "create remote dir $tdir.2 should fail"
27680
27681         do_nodes $(comma_list $(mdts_nodes)) \
27682                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=0"
27683         $LFS mkdir -c 2 $DIR/$tdir.3 &&
27684                 error "create striped dir $tdir.3 should fail"
27685         true
27686 }
27687 run_test 417 "disable remote dir, striped dir and dir migration"
27688
27689 # Checks that the outputs of df [-i] and lfs df [-i] match
27690 #
27691 # usage: check_lfs_df <blocks | inodes> <mountpoint>
27692 check_lfs_df() {
27693         local dir=$2
27694         local inodes
27695         local df_out
27696         local lfs_df_out
27697         local count
27698         local passed=false
27699
27700         # blocks or inodes
27701         [ "$1" == "blocks" ] && inodes= || inodes="-i"
27702
27703         for count in {1..100}; do
27704                 do_nodes "$CLIENTS" \
27705                         $LCTL set_param ldlm.namespaces.*.lru_size=clear
27706                 sync; sleep 0.2
27707
27708                 # read the lines of interest
27709                 df_out=($(df -P $inodes $dir | tail -n +2)) ||
27710                         error "df $inodes $dir | tail -n +2 failed"
27711                 lfs_df_out=($($LFS df $inodes $dir | grep summary:)) ||
27712                         error "lfs df $inodes $dir | grep summary: failed"
27713
27714                 # skip first substrings of each output as they are different
27715                 # "<NID>:/<fsname>" for df, "filesystem_summary:" for lfs df
27716                 # compare the two outputs
27717                 passed=true
27718                 #  skip "available" on MDT until LU-13997 is fixed.
27719                 #for i in {1..5}; do
27720                 for i in 1 2 4 5; do
27721                         [ "${df_out[i]}" != "${lfs_df_out[i]}" ] && passed=false
27722                 done
27723                 $passed && break
27724         done
27725
27726         if ! $passed; then
27727                 df -P $inodes $dir
27728                 echo
27729                 lfs df $inodes $dir
27730                 error "df and lfs df $1 output mismatch: "      \
27731                       "df ${inodes}: ${df_out[*]}, "            \
27732                       "lfs df ${inodes}: ${lfs_df_out[*]}"
27733         fi
27734 }
27735
27736 test_418() {
27737         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27738
27739         local dir=$DIR/$tdir
27740         local numfiles=$((RANDOM % 4096 + 2))
27741         local numblocks=$((RANDOM % 256 + 1))
27742
27743         wait_delete_completed
27744         test_mkdir $dir
27745
27746         # check block output
27747         check_lfs_df blocks $dir
27748         # check inode output
27749         check_lfs_df inodes $dir
27750
27751         # create a single file and retest
27752         echo "Creating a single file and testing"
27753         createmany -o $dir/$tfile- 1 &>/dev/null ||
27754                 error "creating 1 file in $dir failed"
27755         check_lfs_df blocks $dir
27756         check_lfs_df inodes $dir
27757
27758         # create a random number of files
27759         echo "Creating $((numfiles - 1)) files and testing"
27760         createmany -o $dir/$tfile- 1 $((numfiles - 1)) &>/dev/null ||
27761                 error "creating $((numfiles - 1)) files in $dir failed"
27762
27763         # write a random number of blocks to the first test file
27764         echo "Writing $numblocks 4K blocks and testing"
27765         dd if=/dev/urandom of=$dir/${tfile}-0 bs=4K conv=fsync \
27766                 count=$numblocks &>/dev/null ||
27767                 error "dd to $dir/${tfile}-0 failed"
27768
27769         # retest
27770         check_lfs_df blocks $dir
27771         check_lfs_df inodes $dir
27772
27773         unlinkmany $dir/$tfile- $numfiles &>/dev/null ||
27774                 error "unlinking $numfiles files in $dir failed"
27775 }
27776 run_test 418 "df and lfs df outputs match"
27777
27778 test_419()
27779 {
27780         local dir=$DIR/$tdir
27781
27782         mkdir -p $dir
27783         touch $dir/file
27784
27785         cancel_lru_locks mdc
27786
27787         #OBD_FAIL_LLITE_OPEN_BY_NAME    0x1410
27788         $LCTL set_param fail_loc=0x1410
27789         cat $dir/file
27790         $LCTL set_param fail_loc=0
27791         rm -rf $dir
27792 }
27793 run_test 419 "Verify open file by name doesn't crash kernel"
27794
27795 test_420()
27796 {
27797         [[ $MDS1_VERSION -ge $(version_code 2.12.53) ]] ||
27798                 skip "Need MDS version at least 2.12.53"
27799
27800         local SAVE_UMASK=$(umask)
27801         local dir=$DIR/$tdir
27802         local uname=$(getent passwd $RUNAS_ID | cut -d: -f1)
27803
27804         mkdir -p $dir
27805         umask 0000
27806         mkdir -m03777 $dir/testdir
27807         ls -dn $dir/testdir
27808         # Need to remove trailing '.' when SELinux is enabled
27809         local dirperms=$(ls -dn $dir/testdir |
27810                          awk '{ sub(/\.$/, "", $1); print $1}')
27811         [ $dirperms == "drwxrwsrwt" ] ||
27812                 error "incorrect perms on $dir/testdir"
27813
27814         su - $uname -c "PATH=$LUSTRE/tests:\$PATH; \
27815                 openfile -f O_RDONLY:O_CREAT -m 02755 $dir/testdir/testfile"
27816         ls -n $dir/testdir/testfile
27817         local fileperms=$(ls -n $dir/testdir/testfile |
27818                           awk '{ sub(/\.$/, "", $1); print $1}')
27819         [ $fileperms == "-rwxr-xr-x" ] ||
27820                 error "incorrect perms on $dir/testdir/testfile"
27821
27822         umask $SAVE_UMASK
27823 }
27824 run_test 420 "clear SGID bit on non-directories for non-members"
27825
27826 test_421a() {
27827         local cnt
27828         local fid1
27829         local fid2
27830
27831         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
27832                 skip "Need MDS version at least 2.12.54"
27833
27834         test_mkdir $DIR/$tdir
27835         createmany -o $DIR/$tdir/f 3
27836         cnt=$(ls -1 $DIR/$tdir | wc -l)
27837         [ $cnt != 3 ] && error "unexpected #files: $cnt"
27838
27839         fid1=$(lfs path2fid $DIR/$tdir/f1)
27840         fid2=$(lfs path2fid $DIR/$tdir/f2)
27841         $LFS rmfid $DIR $fid1 $fid2 || error "rmfid failed"
27842
27843         stat $DIR/$tdir/f1 && error "f1 still visible on the client"
27844         stat $DIR/$tdir/f2 && error "f2 still visible on the client"
27845
27846         cnt=$(ls -1 $DIR/$tdir | wc -l)
27847         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
27848
27849         rm -f $DIR/$tdir/f3 || error "can't remove f3"
27850         createmany -o $DIR/$tdir/f 3
27851         cnt=$(ls -1 $DIR/$tdir | wc -l)
27852         [ $cnt != 3 ] && error "unexpected #files: $cnt"
27853
27854         fid1=$(lfs path2fid $DIR/$tdir/f1)
27855         fid2=$(lfs path2fid $DIR/$tdir/f2)
27856         echo "remove using fsname $FSNAME"
27857         $LFS rmfid $FSNAME $fid1 $fid2 || error "rmfid with fsname failed"
27858
27859         cnt=$(ls -1 $DIR/$tdir | wc -l)
27860         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
27861 }
27862 run_test 421a "simple rm by fid"
27863
27864 test_421b() {
27865         local cnt
27866         local FID1
27867         local FID2
27868
27869         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
27870                 skip "Need MDS version at least 2.12.54"
27871
27872         test_mkdir $DIR/$tdir
27873         createmany -o $DIR/$tdir/f 3
27874         multiop_bg_pause $DIR/$tdir/f1 o_c || error "multiop failed to start"
27875         MULTIPID=$!
27876
27877         FID1=$(lfs path2fid $DIR/$tdir/f1)
27878         FID2=$(lfs path2fid $DIR/$tdir/f2)
27879         $LFS rmfid $DIR $FID1 $FID2 && error "rmfid didn't fail"
27880
27881         kill -USR1 $MULTIPID
27882         wait
27883
27884         cnt=$(ls $DIR/$tdir | wc -l)
27885         [ $cnt == 2 ] || error "unexpected #files after: $cnt"
27886 }
27887 run_test 421b "rm by fid on open file"
27888
27889 test_421c() {
27890         local cnt
27891         local FIDS
27892
27893         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
27894                 skip "Need MDS version at least 2.12.54"
27895
27896         test_mkdir $DIR/$tdir
27897         createmany -o $DIR/$tdir/f 3
27898         touch $DIR/$tdir/$tfile
27899         createmany -l$DIR/$tdir/$tfile $DIR/$tdir/h 180
27900         cnt=$(ls -1 $DIR/$tdir | wc -l)
27901         [ $cnt != 184 ] && error "unexpected #files: $cnt"
27902
27903         FID1=$(lfs path2fid $DIR/$tdir/$tfile)
27904         $LFS rmfid $DIR $FID1 || error "rmfid failed"
27905
27906         cnt=$(ls $DIR/$tdir | wc -l)
27907         [ $cnt == 3 ] || error "unexpected #files after: $cnt"
27908 }
27909 run_test 421c "rm by fid against hardlinked files"
27910
27911 test_421d() {
27912         local cnt
27913         local FIDS
27914
27915         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
27916                 skip "Need MDS version at least 2.12.54"
27917
27918         test_mkdir $DIR/$tdir
27919         createmany -o $DIR/$tdir/f 4097
27920         cnt=$(ls -1 $DIR/$tdir | wc -l)
27921         [ $cnt != 4097 ] && error "unexpected #files: $cnt"
27922
27923         FIDS=$(lfs path2fid $DIR/$tdir/f* | sed "s/[/][^:]*://g")
27924         $LFS rmfid $DIR $FIDS || error "rmfid failed"
27925
27926         cnt=$(ls $DIR/$tdir | wc -l)
27927         rm -rf $DIR/$tdir
27928         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
27929 }
27930 run_test 421d "rmfid en masse"
27931
27932 test_421e() {
27933         local cnt
27934         local FID
27935
27936         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
27937         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
27938                 skip "Need MDS version at least 2.12.54"
27939
27940         mkdir -p $DIR/$tdir
27941         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
27942         createmany -o $DIR/$tdir/striped_dir/f 512
27943         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
27944         [ $cnt != 512 ] && error "unexpected #files: $cnt"
27945
27946         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
27947                 sed "s/[/][^:]*://g")
27948         $LFS rmfid $DIR $FIDS || error "rmfid failed"
27949
27950         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
27951         rm -rf $DIR/$tdir
27952         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
27953 }
27954 run_test 421e "rmfid in DNE"
27955
27956 test_421f() {
27957         local cnt
27958         local FID
27959
27960         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
27961                 skip "Need MDS version at least 2.12.54"
27962
27963         test_mkdir $DIR/$tdir
27964         touch $DIR/$tdir/f
27965         cnt=$(ls -1 $DIR/$tdir | wc -l)
27966         [ $cnt != 1 ] && error "unexpected #files: $cnt"
27967
27968         FID=$(lfs path2fid $DIR/$tdir/f)
27969         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (1)"
27970         # rmfid should fail
27971         cnt=$(ls -1 $DIR/$tdir | wc -l)
27972         [ $cnt != 1 ] && error "unexpected #files after (2): $cnt"
27973
27974         chmod a+rw $DIR/$tdir
27975         ls -la $DIR/$tdir
27976         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (2)"
27977         # rmfid should fail
27978         cnt=$(ls -1 $DIR/$tdir | wc -l)
27979         [ $cnt != 1 ] && error "unexpected #files after (3): $cnt"
27980
27981         rm -f $DIR/$tdir/f
27982         $RUNAS touch $DIR/$tdir/f
27983         FID=$(lfs path2fid $DIR/$tdir/f)
27984         echo "rmfid as root"
27985         $LFS rmfid $DIR $FID || error "rmfid as root failed"
27986         cnt=$(ls -1 $DIR/$tdir | wc -l)
27987         [ $cnt == 0 ] || error "unexpected #files after (4): $cnt"
27988
27989         rm -f $DIR/$tdir/f
27990         $RUNAS touch $DIR/$tdir/f
27991         cnt=$(ls -1 $DIR/$tdir | wc -l)
27992         [ $cnt != 1 ] && error "unexpected #files (4): $cnt"
27993         FID=$(lfs path2fid $DIR/$tdir/f)
27994         # rmfid w/o user_fid2path mount option should fail
27995         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail(3)"
27996         cnt=$(ls -1 $DIR/$tdir | wc -l)
27997         [ $cnt == 1 ] || error "unexpected #files after (5): $cnt"
27998
27999         tmpdir=$(mktemp -d /tmp/lustre-XXXXXX)
28000         stack_trap "rmdir $tmpdir"
28001         mount_client $tmpdir "$MOUNT_OPTS,user_fid2path" ||
28002                 error "failed to mount client'"
28003         stack_trap "umount_client $tmpdir"
28004
28005         $RUNAS $LFS rmfid $tmpdir $FID || error "rmfid failed"
28006         # rmfid should succeed
28007         cnt=$(ls -1 $tmpdir/$tdir | wc -l)
28008         [ $cnt == 0 ] || error "unexpected #files after (6): $cnt"
28009
28010         # rmfid shouldn't allow to remove files due to dir's permission
28011         chmod a+rwx $tmpdir/$tdir
28012         touch $tmpdir/$tdir/f
28013         ls -la $tmpdir/$tdir
28014         FID=$(lfs path2fid $tmpdir/$tdir/f)
28015         $RUNAS $LFS rmfid $tmpdir $FID && error "rmfid didn't fail"
28016         return 0
28017 }
28018 run_test 421f "rmfid checks permissions"
28019
28020 test_421g() {
28021         local cnt
28022         local FIDS
28023
28024         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
28025         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
28026                 skip "Need MDS version at least 2.12.54"
28027
28028         mkdir -p $DIR/$tdir
28029         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
28030         createmany -o $DIR/$tdir/striped_dir/f 512
28031         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
28032         [ $cnt != 512 ] && error "unexpected #files: $cnt"
28033
28034         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
28035                 sed "s/[/][^:]*://g")
28036
28037         rm -f $DIR/$tdir/striped_dir/f1*
28038         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
28039         removed=$((512 - cnt))
28040
28041         # few files have been just removed, so we expect
28042         # rmfid to fail on their fids
28043         errors=$($LFS rmfid $DIR $FIDS 2>&1 | wc -l)
28044         [ $removed != $errors ] && error "$errors != $removed"
28045
28046         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
28047         rm -rf $DIR/$tdir
28048         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
28049 }
28050 run_test 421g "rmfid to return errors properly"
28051
28052 test_421h() {
28053         local mount_other
28054         local mount_ret
28055         local rmfid_ret
28056         local old_fid
28057         local fidA
28058         local fidB
28059         local fidC
28060         local fidD
28061
28062         (( MDS1_VERSION >= $(version_code 2.15.53) )) ||
28063                 skip "Need MDS version at least 2.15.53"
28064
28065         test_mkdir $DIR/$tdir
28066         test_mkdir $DIR/$tdir/subdir
28067         touch $DIR/$tdir/subdir/file0
28068         old_fid=$(lfs path2fid $DIR/$tdir/subdir/file0 | sed "s/[/][^:]*://g")
28069         echo File $DIR/$tdir/subdir/file0 FID $old_fid
28070         rm -f $DIR/$tdir/subdir/file0
28071         touch $DIR/$tdir/subdir/fileA
28072         fidA=$(lfs path2fid $DIR/$tdir/subdir/fileA | sed "s/[/][^:]*://g")
28073         echo File $DIR/$tdir/subdir/fileA FID $fidA
28074         touch $DIR/$tdir/subdir/fileB
28075         fidB=$(lfs path2fid $DIR/$tdir/subdir/fileB | sed "s/[/][^:]*://g")
28076         echo File $DIR/$tdir/subdir/fileB FID $fidB
28077         ln $DIR/$tdir/subdir/fileB $DIR/$tdir/subdir/fileB_hl
28078         touch $DIR/$tdir/subdir/fileC
28079         fidC=$(lfs path2fid $DIR/$tdir/subdir/fileC | sed "s/[/][^:]*://g")
28080         echo File $DIR/$tdir/subdir/fileC FID $fidC
28081         ln $DIR/$tdir/subdir/fileC $DIR/$tdir/fileC
28082         touch $DIR/$tdir/fileD
28083         fidD=$(lfs path2fid $DIR/$tdir/fileD | sed "s/[/][^:]*://g")
28084         echo File $DIR/$tdir/fileD FID $fidD
28085
28086         # mount another client mount point with subdirectory mount
28087         export FILESET=/$tdir/subdir
28088         mount_other=${MOUNT}_other
28089         mount_client $mount_other ${MOUNT_OPTS}
28090         mount_ret=$?
28091         export FILESET=""
28092         (( mount_ret == 0 )) || error "mount $mount_other failed"
28093
28094         echo Removing FIDs:
28095         echo $LFS rmfid $mount_other $old_fid $fidA $fidD $fidB $fidC
28096         $LFS rmfid $mount_other $old_fid $fidA $fidD $fidB $fidC
28097         rmfid_ret=$?
28098
28099         umount_client $mount_other || error "umount $mount_other failed"
28100
28101         (( rmfid_ret != 0 )) || error "rmfid should have failed"
28102
28103         # fileA should have been deleted
28104         stat $DIR/$tdir/subdir/fileA && error "fileA not deleted"
28105
28106         # fileB should have been deleted
28107         stat $DIR/$tdir/subdir/fileB && error "fileB not deleted"
28108
28109         # fileC should not have been deleted, fid also exists outside of fileset
28110         stat $DIR/$tdir/subdir/fileC || error "fileC deleted"
28111
28112         # fileD should not have been deleted, it exists outside of fileset
28113         stat $DIR/$tdir/fileD || error "fileD deleted"
28114 }
28115 run_test 421h "rmfid with fileset mount"
28116
28117 test_422() {
28118         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d1
28119         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d2
28120         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d3
28121         dd if=/dev/zero of=$DIR/$tdir/d1/file1 bs=1k count=1
28122         dd if=/dev/zero of=$DIR/$tdir/d2/file1 bs=1k count=1
28123
28124         local amc=$(at_max_get client)
28125         local amo=$(at_max_get mds1)
28126         local timeout=`lctl get_param -n timeout`
28127
28128         at_max_set 0 client
28129         at_max_set 0 mds1
28130
28131 #define OBD_FAIL_PTLRPC_PAUSE_REQ        0x50a
28132         do_facet mds1 $LCTL set_param fail_loc=0x8000050a \
28133                         fail_val=$(((2*timeout + 10)*1000))
28134         touch $DIR/$tdir/d3/file &
28135         sleep 2
28136 #define OBD_FAIL_TGT_REPLY_DATA_RACE     0x722
28137         do_facet mds1 $LCTL set_param fail_loc=0x80000722 \
28138                         fail_val=$((2*timeout + 5))
28139         mv $DIR/$tdir/d1/file1 $DIR/$tdir/d1/file2 &
28140         local pid=$!
28141         sleep 1
28142         kill -9 $pid
28143         sleep $((2 * timeout))
28144         echo kill $pid
28145         kill -9 $pid
28146         lctl mark touch
28147         touch $DIR/$tdir/d2/file3
28148         touch $DIR/$tdir/d2/file4
28149         touch $DIR/$tdir/d2/file5
28150
28151         wait
28152         at_max_set $amc client
28153         at_max_set $amo mds1
28154
28155         # LU-12838 - verify the ptlrpc thread watchdog is not always throttled
28156         do_facet mds1 "dmesg | grep 'Dumping the stack trace for debugging'" ||
28157                 error "Watchdog is always throttled"
28158 }
28159 run_test 422 "kill a process with RPC in progress"
28160
28161 stat_test() {
28162     df -h $MOUNT &
28163     df -h $MOUNT &
28164     df -h $MOUNT &
28165     df -h $MOUNT &
28166     df -h $MOUNT &
28167     df -h $MOUNT &
28168 }
28169
28170 test_423() {
28171     local _stats
28172     # ensure statfs cache is expired
28173     sleep 2;
28174
28175     _stats=$(stat_test | grep $MOUNT | sort -u | wc -l)
28176     [[ ${_stats} -ne 1 ]] && error "statfs wrong"
28177
28178     return 0
28179 }
28180 run_test 423 "statfs should return a right data"
28181
28182 test_424() {
28183 #define OBD_FAIL_PTLRPC_BULK_REPLY_ATTACH      0x522 | CFS_FAIL_ONCE
28184         $LCTL set_param fail_loc=0x80000522
28185         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
28186         rm -f $DIR/$tfile
28187 }
28188 run_test 424 "simulate ENOMEM in ptl_send_rpc bulk reply ME attach"
28189
28190 test_425() {
28191         test_mkdir -c -1 $DIR/$tdir
28192         $LFS setstripe -c -1 $DIR/$tdir
28193
28194         lru_resize_disable "" 100
28195         stack_trap "lru_resize_enable" EXIT
28196
28197         sleep 5
28198
28199         for i in $(seq $((MDSCOUNT * 125))); do
28200                 local t=$DIR/$tdir/$tfile_$i
28201
28202                 dd if=/dev/zero of=$t bs=4K count=1 > /dev/null 2>&1 ||
28203                         error_noexit "Create file $t"
28204         done
28205         stack_trap "rm -rf $DIR/$tdir" EXIT
28206
28207         for oscparam in $($LCTL list_param ldlm.namespaces.*osc-[-0-9a-f]*); do
28208                 local lru_size=$($LCTL get_param -n $oscparam.lru_size)
28209                 local lock_count=$($LCTL get_param -n $oscparam.lock_count)
28210
28211                 [ $lock_count -le $lru_size ] ||
28212                         error "osc lock count $lock_count > lru size $lru_size"
28213         done
28214
28215         for mdcparam in $($LCTL list_param ldlm.namespaces.*mdc-*); do
28216                 local lru_size=$($LCTL get_param -n $mdcparam.lru_size)
28217                 local lock_count=$($LCTL get_param -n $mdcparam.lock_count)
28218
28219                 [ $lock_count -le $lru_size ] ||
28220                         error "mdc lock count $lock_count > lru size $lru_size"
28221         done
28222 }
28223 run_test 425 "lock count should not exceed lru size"
28224
28225 test_426() {
28226         splice-test -r $DIR/$tfile
28227         splice-test -rd $DIR/$tfile
28228         splice-test $DIR/$tfile
28229         splice-test -d $DIR/$tfile
28230 }
28231 run_test 426 "splice test on Lustre"
28232
28233 test_427() {
28234         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
28235         (( $MDS1_VERSION >= $(version_code 2.12.4) )) ||
28236                 skip "Need MDS version at least 2.12.4"
28237         local log
28238
28239         mkdir $DIR/$tdir
28240         mkdir $DIR/$tdir/1
28241         mkdir $DIR/$tdir/2
28242         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/1/dir
28243         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/2/dir2
28244
28245         $LFS getdirstripe $DIR/$tdir/1/dir
28246
28247         #first setfattr for creating updatelog
28248         setfattr -n user.attr0 -v "some text" $DIR/$tdir/1/dir
28249
28250 #define OBD_FAIL_OUT_OBJECT_MISS        0x1708
28251         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param fail_loc=0x80001708
28252         setfattr -n user.attr1 -v "some text" $DIR/$tdir/1/dir &
28253         setfattr -n user.attr2 -v "another attr"  $DIR/$tdir/2/dir2 &
28254
28255         sleep 2
28256         fail mds2
28257         wait_recovery_complete mds2 $((2*TIMEOUT))
28258
28259         log=$(do_facet mds1 dmesg | tac | sed "/${TESTNAME//_/ }/,$ d")
28260         echo $log | grep "get update log failed" &&
28261                 error "update log corruption is detected" || true
28262 }
28263 run_test 427 "Failed DNE2 update request shouldn't corrupt updatelog"
28264
28265 test_428() {
28266         [ $PARALLEL == "yes" ] && skip "skip parallel run"
28267         local cache_limit=$CACHE_MAX
28268
28269         stack_trap "$LCTL set_param -n llite.*.max_cached_mb=$cache_limit"
28270         $LCTL set_param -n llite.*.max_cached_mb=64
28271
28272         mkdir $DIR/$tdir
28273         $LFS setstripe -c 1 $DIR/$tdir
28274         eval touch $DIR/$tdir/$tfile.{1..$OSTCOUNT}
28275         stack_trap "rm -f $DIR/$tdir/$tfile.*"
28276         #test write
28277         for f in $(seq 4); do
28278                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$f bs=128M count=1 &
28279         done
28280         wait
28281
28282         cancel_lru_locks osc
28283         # Test read
28284         for f in $(seq 4); do
28285                 dd if=$DIR/$tdir/$tfile.$f of=/dev/null bs=128M count=1 &
28286         done
28287         wait
28288 }
28289 run_test 428 "large block size IO should not hang"
28290
28291 test_429() { # LU-7915 / LU-10948
28292         local ll_opencache_threshold_count="llite.*.opencache_threshold_count"
28293         local testfile=$DIR/$tfile
28294         local mdc_rpcstats="mdc.$FSNAME-MDT0000-*.stats"
28295         local new_flag=1
28296         local first_rpc
28297         local second_rpc
28298         local third_rpc
28299
28300         $LCTL get_param $ll_opencache_threshold_count ||
28301                 skip "client does not have opencache parameter"
28302
28303         set_opencache $new_flag
28304         stack_trap "restore_opencache"
28305         [ $($LCTL get_param -n $ll_opencache_threshold_count) == $new_flag ] ||
28306                 error "enable opencache failed"
28307         touch $testfile
28308         # drop MDC DLM locks
28309         cancel_lru_locks mdc
28310         # clear MDC RPC stats counters
28311         $LCTL set_param $mdc_rpcstats=clear
28312
28313         # According to the current implementation, we need to run 3 times
28314         # open & close file to verify if opencache is enabled correctly.
28315         # 1st, RPCs are sent for lookup/open and open handle is released on
28316         #      close finally.
28317         # 2nd, RPC is sent for open, MDS_OPEN_LOCK is fetched automatically,
28318         #      so open handle won't be released thereafter.
28319         # 3rd, No RPC is sent out.
28320         $MULTIOP $testfile oc || error "multiop failed"
28321         first_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
28322         echo "1st: $first_rpc RPCs in flight"
28323
28324         $MULTIOP $testfile oc || error "multiop failed"
28325         second_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
28326         echo "2nd: $second_rpc RPCs in flight"
28327
28328         $MULTIOP $testfile oc || error "multiop failed"
28329         third_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
28330         echo "3rd: $third_rpc RPCs in flight"
28331
28332         #verify no MDC RPC is sent
28333         [[ $second_rpc == $third_rpc ]] || error "MDC RPC is still sent"
28334 }
28335 run_test 429 "verify if opencache flag on client side does work"
28336
28337 lseek_test_430() {
28338         local offset
28339         local file=$1
28340
28341         # data at [200K, 400K)
28342         dd if=/dev/urandom of=$file bs=256K count=1 seek=1 ||
28343                 error "256K->512K dd fails"
28344         # data at [2M, 3M)
28345         dd if=/dev/urandom of=$file bs=1M count=1 seek=2 ||
28346                 error "2M->3M dd fails"
28347         # data at [4M, 5M)
28348         dd if=/dev/urandom of=$file bs=1M count=1 seek=4 ||
28349                 error "4M->5M dd fails"
28350         echo "Data at 256K...512K, 2M...3M and 4M...5M"
28351         # start at first component hole #1
28352         printf "Seeking hole from 1000 ... "
28353         offset=$(lseek_test -l 1000 $file)
28354         echo $offset
28355         [[ $offset == 1000 ]] || error "offset $offset != 1000"
28356         printf "Seeking data from 1000 ... "
28357         offset=$(lseek_test -d 1000 $file)
28358         echo $offset
28359         [[ $offset == 262144 ]] || error "offset $offset != 262144"
28360
28361         # start at first component data block
28362         printf "Seeking hole from 300000 ... "
28363         offset=$(lseek_test -l 300000 $file)
28364         echo $offset
28365         [[ $offset == 524288 ]] || error "offset $offset != 524288"
28366         printf "Seeking data from 300000 ... "
28367         offset=$(lseek_test -d 300000 $file)
28368         echo $offset
28369         [[ $offset == 300000 ]] || error "offset $offset != 300000"
28370
28371         # start at the first component but beyond end of object size
28372         printf "Seeking hole from 1000000 ... "
28373         offset=$(lseek_test -l 1000000 $file)
28374         echo $offset
28375         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
28376         printf "Seeking data from 1000000 ... "
28377         offset=$(lseek_test -d 1000000 $file)
28378         echo $offset
28379         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
28380
28381         # start at second component stripe 2 (empty file)
28382         printf "Seeking hole from 1500000 ... "
28383         offset=$(lseek_test -l 1500000 $file)
28384         echo $offset
28385         [[ $offset == 1500000 ]] || error "offset $offset != 1500000"
28386         printf "Seeking data from 1500000 ... "
28387         offset=$(lseek_test -d 1500000 $file)
28388         echo $offset
28389         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
28390
28391         # start at second component stripe 1 (all data)
28392         printf "Seeking hole from 3000000 ... "
28393         offset=$(lseek_test -l 3000000 $file)
28394         echo $offset
28395         [[ $offset == 3145728 ]] || error "offset $offset != 3145728"
28396         printf "Seeking data from 3000000 ... "
28397         offset=$(lseek_test -d 3000000 $file)
28398         echo $offset
28399         [[ $offset == 3000000 ]] || error "offset $offset != 3000000"
28400
28401         dd if=/dev/urandom of=$file bs=640K count=1 seek=1 ||
28402                 error "2nd dd fails"
28403         echo "Add data block at 640K...1280K"
28404
28405         # start at before new data block, in hole
28406         printf "Seeking hole from 600000 ... "
28407         offset=$(lseek_test -l 600000 $file)
28408         echo $offset
28409         [[ $offset == 600000 ]] || error "offset $offset != 600000"
28410         printf "Seeking data from 600000 ... "
28411         offset=$(lseek_test -d 600000 $file)
28412         echo $offset
28413         [[ $offset == 655360 ]] || error "offset $offset != 655360"
28414
28415         # start at the first component new data block
28416         printf "Seeking hole from 1000000 ... "
28417         offset=$(lseek_test -l 1000000 $file)
28418         echo $offset
28419         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
28420         printf "Seeking data from 1000000 ... "
28421         offset=$(lseek_test -d 1000000 $file)
28422         echo $offset
28423         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
28424
28425         # start at second component stripe 2, new data
28426         printf "Seeking hole from 1200000 ... "
28427         offset=$(lseek_test -l 1200000 $file)
28428         echo $offset
28429         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
28430         printf "Seeking data from 1200000 ... "
28431         offset=$(lseek_test -d 1200000 $file)
28432         echo $offset
28433         [[ $offset == 1200000 ]] || error "offset $offset != 1200000"
28434
28435         # start beyond file end
28436         printf "Using offset > filesize ... "
28437         lseek_test -l 4000000 $file && error "lseek should fail"
28438         printf "Using offset > filesize ... "
28439         lseek_test -d 4000000 $file && error "lseek should fail"
28440
28441         printf "Done\n\n"
28442 }
28443
28444 test_430a() {
28445         $LCTL get_param mdc.*.import | grep -q 'connect_flags:.*seek' ||
28446                 skip "MDT does not support SEEK_HOLE"
28447
28448         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
28449                 skip "OST does not support SEEK_HOLE"
28450
28451         local file=$DIR/$tdir/$tfile
28452
28453         mkdir -p $DIR/$tdir
28454
28455         $LFS setstripe -E 1M -L mdt -E eof -c2 $file
28456         # OST stripe #1 will have continuous data at [1M, 3M)
28457         # OST stripe #2 is empty
28458         echo "Component #1: 1M DoM, component #2: EOF, 2 stripes 1M"
28459         lseek_test_430 $file
28460         rm $file
28461         $LFS setstripe -E 1M -c2 -S 64K -E 10M -c2 -S 1M $file
28462         echo "Component #1: 1M, 2 stripes 64K, component #2: EOF, 2 stripes 1M"
28463         lseek_test_430 $file
28464         rm $file
28465         $LFS setstripe -c2 -S 512K $file
28466         echo "Two stripes, stripe size 512K"
28467         lseek_test_430 $file
28468         rm $file
28469         # FLR with stale mirror
28470         $LFS setstripe -N -E 512K -c1 -S 64K -E eof -c2 -S 512K \
28471                        -N -c2 -S 1M $file
28472         echo "Mirrored file:"
28473         echo "Component #1: 512K, stripe 64K, component #2: EOF, 2 stripes 512K"
28474         echo "Plain 2 stripes 1M"
28475         lseek_test_430 $file
28476         rm $file
28477 }
28478 run_test 430a "lseek: SEEK_DATA/SEEK_HOLE basic functionality"
28479
28480 test_430b() {
28481         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
28482                 skip "OST does not support SEEK_HOLE"
28483
28484         local offset
28485         local file=$DIR/$tdir/$tfile
28486
28487         mkdir -p $DIR/$tdir
28488         # Empty layout lseek should fail
28489         $MCREATE $file
28490         # seek from 0
28491         printf "Seeking hole from 0 ... "
28492         lseek_test -l 0 $file && error "lseek should fail"
28493         printf "Seeking data from 0 ... "
28494         lseek_test -d 0 $file && error "lseek should fail"
28495         rm $file
28496
28497         # 1M-hole file
28498         $LFS setstripe -E 1M -c2 -E eof $file
28499         $TRUNCATE $file 1048576
28500         printf "Seeking hole from 1000000 ... "
28501         offset=$(lseek_test -l 1000000 $file)
28502         echo $offset
28503         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
28504         printf "Seeking data from 1000000 ... "
28505         lseek_test -d 1000000 $file && error "lseek should fail"
28506         rm $file
28507
28508         # full component followed by non-inited one
28509         $LFS setstripe -E 1M -c2 -E eof $file
28510         dd if=/dev/urandom of=$file bs=1M count=1
28511         printf "Seeking hole from 1000000 ... "
28512         offset=$(lseek_test -l 1000000 $file)
28513         echo $offset
28514         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
28515         printf "Seeking hole from 1048576 ... "
28516         lseek_test -l 1048576 $file && error "lseek should fail"
28517         # init second component and truncate back
28518         echo "123" >> $file
28519         $TRUNCATE $file 1048576
28520         printf "Seeking hole from 1000000 ... "
28521         offset=$(lseek_test -l 1000000 $file)
28522         echo $offset
28523         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
28524         printf "Seeking hole from 1048576 ... "
28525         lseek_test -l 1048576 $file && error "lseek should fail"
28526         # boundary checks for big values
28527         dd if=/dev/urandom of=$file.10g bs=1 count=1 seek=10G
28528         offset=$(lseek_test -d 0 $file.10g)
28529         [[ $offset == 10737418240 ]] || error "offset $offset != 10737418240"
28530         dd if=/dev/urandom of=$file.100g bs=1 count=1 seek=100G
28531         offset=$(lseek_test -d 0 $file.100g)
28532         [[ $offset == 107374182400 ]] || error "offset $offset != 107374182400"
28533         return 0
28534 }
28535 run_test 430b "lseek: SEEK_DATA/SEEK_HOLE special cases"
28536
28537 test_430c() {
28538         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
28539                 skip "OST does not support SEEK_HOLE"
28540
28541         local file=$DIR/$tdir/$tfile
28542         local start
28543
28544         mkdir -p $DIR/$tdir
28545         stack_trap "rm -f $file $file.tmp"
28546         dd if=/dev/urandom of=$file bs=1k count=1 seek=5M || error "dd failed"
28547
28548         # cp version 8.33+ prefers lseek over fiemap
28549         local ver=$(cp --version | awk '{ print $4; exit; }')
28550
28551         echo "cp $ver installed"
28552         if (( $(version_code $ver) >= $(version_code 8.33) )); then
28553                 start=$SECONDS
28554                 time cp -v $file $file.tmp || error "cp $file failed"
28555                 (( SECONDS - start < 5 )) || {
28556                         strace cp $file $file.tmp |&
28557                                 grep -E "open|read|seek|FIEMAP" |
28558                                 grep -A 100 $file
28559                         error "cp: too long runtime $((SECONDS - start))"
28560                 }
28561         else
28562                 echo "cp test skipped due to $ver < 8.33"
28563         fi
28564
28565         # tar version 1.29+ supports SEEK_HOLE/DATA
28566         ver=$(tar --version | awk '{ print $4; exit; }')
28567         echo "tar $ver installed"
28568         if (( $(version_code $ver) >= $(version_code 1.29) )); then
28569                 start=$SECONDS
28570                 time tar cvf $file.tmp --sparse $file || error "tar $file error"
28571                 (( SECONDS - start < 5 )) || {
28572                         strace tar cf $file.tmp --sparse $file |&
28573                                 grep -E "open|read|seek|FIEMAP" |
28574                                 grep -A 100 $file
28575                         error "tar: too long runtime $((SECONDS - start))"
28576                 }
28577         else
28578                 echo "tar test skipped due to $ver < 1.29"
28579         fi
28580 }
28581 run_test 430c "lseek: external tools check"
28582
28583 test_431() { # LU-14187
28584         local file=$DIR/$tdir/$tfile
28585
28586         mkdir -p $DIR/$tdir
28587         $LFS setstripe -c 1 -i 0 $file || error "lfs setstripe failed"
28588         dd if=/dev/urandom of=$file bs=4k count=1
28589         dd if=/dev/urandom of=$file bs=4k count=1 seek=10 conv=notrunc
28590         dd if=/dev/urandom of=$file bs=4k count=1 seek=12 conv=notrunc
28591         #define OBD_FAIL_OST_RESTART_IO 0x251
28592         do_facet ost1 "$LCTL set_param fail_loc=0x251"
28593         $LFS setstripe -c 1 -i 0 $file.0 || error "lfs setstripe failed"
28594         cp $file $file.0
28595         cancel_lru_locks
28596         sync_all_data
28597         echo 3 > /proc/sys/vm/drop_caches
28598         diff  $file $file.0 || error "data diff"
28599 }
28600 run_test 431 "Restart transaction for IO"
28601
28602 cleanup_test_432() {
28603         do_facet mgs $LCTL nodemap_activate 0
28604         wait_nm_sync active
28605 }
28606
28607 test_432() {
28608         local tmpdir=$TMP/dir432
28609
28610         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
28611                 skip "Need MDS version at least 2.14.52"
28612
28613         stack_trap cleanup_test_432 EXIT
28614         mkdir $DIR/$tdir
28615         mkdir $tmpdir
28616
28617         do_facet mgs $LCTL nodemap_activate 1
28618         wait_nm_sync active
28619         do_facet mgs $LCTL nodemap_modify --name default \
28620                 --property admin --value 1
28621         do_facet mgs $LCTL nodemap_modify --name default \
28622                 --property trusted --value 1
28623         cancel_lru_locks mdc
28624         wait_nm_sync default admin_nodemap
28625         wait_nm_sync default trusted_nodemap
28626
28627         if [ $(mv $tmpdir $DIR/$tdir/ 2>&1 |
28628                grep -ci "Operation not permitted") -ne 0 ]; then
28629                 error "mv $tmpdir $DIR/$tdir/ hits 'Operation not permitted'"
28630         fi
28631 }
28632 run_test 432 "mv dir from outside Lustre"
28633
28634 test_433() {
28635         [ $PARALLEL == "yes" ] && skip "skip parallel run"
28636
28637         [[ -n "$($LCTL list_param llite.*.inode_cache 2>/dev/null)" ]] ||
28638                 skip "inode cache not supported"
28639
28640         $LCTL set_param llite.*.inode_cache=0
28641         stack_trap "$LCTL set_param llite.*.inode_cache=1"
28642
28643         local count=256
28644         local before
28645         local after
28646
28647         cancel_lru_locks mdc
28648         test_mkdir $DIR/$tdir || error "mkdir $tdir"
28649         createmany -m $DIR/$tdir/f $count
28650         createmany -d $DIR/$tdir/d $count
28651         ls -l $DIR/$tdir > /dev/null
28652         stack_trap "rm -rf $DIR/$tdir"
28653
28654         before=$(num_objects)
28655         cancel_lru_locks mdc
28656         after=$(num_objects)
28657
28658         # sometimes even @before is less than 2 * count
28659         while (( before - after < count )); do
28660                 sleep 1
28661                 after=$(num_objects)
28662                 wait=$((wait + 1))
28663                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
28664                 if (( wait > 60 )); then
28665                         error "inode slab grew from $before to $after"
28666                 fi
28667         done
28668
28669         echo "lustre_inode_cache $before objs before lock cancel, $after after"
28670 }
28671 run_test 433 "ldlm lock cancel releases dentries and inodes"
28672
28673 test_434() {
28674         local file
28675         local getxattr_count
28676         local mdc_stat_param="mdc.$FSNAME-MDT0000*.md_stats"
28677         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
28678
28679         [[ $(getenforce) == "Disabled" ]] ||
28680                 skip "lsm selinux module have to be disabled for this test"
28681
28682         test_mkdir -i 0 -c1 $DIR/$tdir/ ||
28683                 error "fail to create $DIR/$tdir/ on MDT0000"
28684
28685         touch $DIR/$tdir/$tfile-{001..100}
28686
28687         # disable the xattr cache
28688         save_lustre_params client "llite.*.xattr_cache" > $p
28689         lctl set_param llite.*.xattr_cache=0
28690         stack_trap "restore_lustre_params < $p; rm -f $p" EXIT
28691
28692         # clear clients mdc stats
28693         clear_stats $mdc_stat_param ||
28694                 error "fail to clear stats on mdc MDT0000"
28695
28696         for file in $DIR/$tdir/$tfile-{001..100}; do
28697                 getfattr -n security.selinux $file |&
28698                         grep -q "Operation not supported" ||
28699                         error "getxattr on security.selinux should return EOPNOTSUPP"
28700         done
28701
28702         getxattr_count=$(calc_stats $mdc_stat_param "getxattr")
28703         (( getxattr_count < 100 )) ||
28704                 error "client sent $getxattr_count getxattr RPCs to the MDS"
28705 }
28706 run_test 434 "Client should not send RPCs for security.selinux with SElinux disabled"
28707
28708 test_440() {
28709         if [[ -f $LUSTRE/scripts/bash-completion/lustre ]]; then
28710                 source $LUSTRE/scripts/bash-completion/lustre
28711         elif [[ -f /usr/share/bash-completion/completions/lustre ]]; then
28712                 source /usr/share/bash-completion/completions/lustre
28713         else
28714                 skip "bash completion scripts not found"
28715         fi
28716
28717         local lctl_completions
28718         local lfs_completions
28719
28720         lctl_completions=$(_lustre_cmds lctl)
28721         if [[ ! $lctl_completions =~ "get_param" ]]; then
28722                 error "lctl bash completion failed"
28723         fi
28724
28725         lfs_completions=$(_lustre_cmds lfs)
28726         if [[ ! $lfs_completions =~ "setstripe" ]]; then
28727                 error "lfs bash completion failed"
28728         fi
28729 }
28730 run_test 440 "bash completion for lfs, lctl"
28731
28732 prep_801() {
28733         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
28734         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
28735                 skip "Need server version at least 2.9.55"
28736
28737         start_full_debug_logging
28738 }
28739
28740 post_801() {
28741         stop_full_debug_logging
28742 }
28743
28744 barrier_stat() {
28745         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
28746                 local st=$(do_facet mgs $LCTL barrier_stat $FSNAME |
28747                            awk '/The barrier for/ { print $7 }')
28748                 echo $st
28749         else
28750                 local st=$(do_facet mgs $LCTL barrier_stat -s $FSNAME)
28751                 echo \'$st\'
28752         fi
28753 }
28754
28755 barrier_expired() {
28756         local expired
28757
28758         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
28759                 expired=$(do_facet mgs $LCTL barrier_stat $FSNAME |
28760                           awk '/will be expired/ { print $7 }')
28761         else
28762                 expired=$(do_facet mgs $LCTL barrier_stat -t $FSNAME)
28763         fi
28764
28765         echo $expired
28766 }
28767
28768 test_801a() {
28769         prep_801
28770
28771         echo "Start barrier_freeze at: $(date)"
28772         #define OBD_FAIL_BARRIER_DELAY          0x2202
28773         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
28774         # Do not reduce barrier time - See LU-11873
28775         do_facet mgs $LCTL barrier_freeze $FSNAME 20 &
28776
28777         sleep 2
28778         local b_status=$(barrier_stat)
28779         echo "Got barrier status at: $(date)"
28780         [ "$b_status" = "'freezing_p1'" ] ||
28781                 error "(1) unexpected barrier status $b_status"
28782
28783         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
28784         wait
28785         b_status=$(barrier_stat)
28786         [ "$b_status" = "'frozen'" ] ||
28787                 error "(2) unexpected barrier status $b_status"
28788
28789         local expired=$(barrier_expired)
28790         echo "sleep $((expired + 3)) seconds, then the barrier will be expired"
28791         sleep $((expired + 3))
28792
28793         b_status=$(barrier_stat)
28794         [ "$b_status" = "'expired'" ] ||
28795                 error "(3) unexpected barrier status $b_status"
28796
28797         # Do not reduce barrier time - See LU-11873
28798         do_facet mgs $LCTL barrier_freeze $FSNAME 20 ||
28799                 error "(4) fail to freeze barrier"
28800
28801         b_status=$(barrier_stat)
28802         [ "$b_status" = "'frozen'" ] ||
28803                 error "(5) unexpected barrier status $b_status"
28804
28805         echo "Start barrier_thaw at: $(date)"
28806         #define OBD_FAIL_BARRIER_DELAY          0x2202
28807         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
28808         do_facet mgs $LCTL barrier_thaw $FSNAME &
28809
28810         sleep 2
28811         b_status=$(barrier_stat)
28812         echo "Got barrier status at: $(date)"
28813         [ "$b_status" = "'thawing'" ] ||
28814                 error "(6) unexpected barrier status $b_status"
28815
28816         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
28817         wait
28818         b_status=$(barrier_stat)
28819         [ "$b_status" = "'thawed'" ] ||
28820                 error "(7) unexpected barrier status $b_status"
28821
28822         #define OBD_FAIL_BARRIER_FAILURE        0x2203
28823         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2203
28824         do_facet mgs $LCTL barrier_freeze $FSNAME
28825
28826         b_status=$(barrier_stat)
28827         [ "$b_status" = "'failed'" ] ||
28828                 error "(8) unexpected barrier status $b_status"
28829
28830         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
28831         do_facet mgs $LCTL barrier_thaw $FSNAME
28832
28833         post_801
28834 }
28835 run_test 801a "write barrier user interfaces and stat machine"
28836
28837 test_801b() {
28838         prep_801
28839
28840         mkdir $DIR/$tdir || error "(1) fail to mkdir"
28841         createmany -d $DIR/$tdir/d 6 || error "(2) fail to mkdir"
28842         touch $DIR/$tdir/d2/f10 || error "(3) fail to touch"
28843         touch $DIR/$tdir/d3/f11 || error "(4) fail to touch"
28844         touch $DIR/$tdir/d4/f12 || error "(5) fail to touch"
28845
28846         cancel_lru_locks mdc
28847
28848         # 180 seconds should be long enough
28849         do_facet mgs $LCTL barrier_freeze $FSNAME 180
28850
28851         local b_status=$(barrier_stat)
28852         [ "$b_status" = "'frozen'" ] ||
28853                 error "(6) unexpected barrier status $b_status"
28854
28855         mkdir $DIR/$tdir/d0/d10 &
28856         mkdir_pid=$!
28857
28858         touch $DIR/$tdir/d1/f13 &
28859         touch_pid=$!
28860
28861         ln $DIR/$tdir/d2/f10 $DIR/$tdir/d2/f14 &
28862         ln_pid=$!
28863
28864         mv $DIR/$tdir/d3/f11 $DIR/$tdir/d3/f15 &
28865         mv_pid=$!
28866
28867         rm -f $DIR/$tdir/d4/f12 &
28868         rm_pid=$!
28869
28870         stat $DIR/$tdir/d5 || error "(7) stat should succeed"
28871
28872         # To guarantee taht the 'stat' is not blocked
28873         b_status=$(barrier_stat)
28874         [ "$b_status" = "'frozen'" ] ||
28875                 error "(8) unexpected barrier status $b_status"
28876
28877         # let above commands to run at background
28878         sleep 5
28879
28880         ps -p $mkdir_pid || error "(9) mkdir should be blocked"
28881         ps -p $touch_pid || error "(10) touch should be blocked"
28882         ps -p $ln_pid || error "(11) link should be blocked"
28883         ps -p $mv_pid || error "(12) rename should be blocked"
28884         ps -p $rm_pid || error "(13) unlink should be blocked"
28885
28886         b_status=$(barrier_stat)
28887         [ "$b_status" = "'frozen'" ] ||
28888                 error "(14) unexpected barrier status $b_status"
28889
28890         do_facet mgs $LCTL barrier_thaw $FSNAME
28891         b_status=$(barrier_stat)
28892         [ "$b_status" = "'thawed'" ] ||
28893                 error "(15) unexpected barrier status $b_status"
28894
28895         wait $mkdir_pid || error "(16) mkdir should succeed"
28896         wait $touch_pid || error "(17) touch should succeed"
28897         wait $ln_pid || error "(18) link should succeed"
28898         wait $mv_pid || error "(19) rename should succeed"
28899         wait $rm_pid || error "(20) unlink should succeed"
28900
28901         post_801
28902 }
28903 run_test 801b "modification will be blocked by write barrier"
28904
28905 test_801c() {
28906         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
28907
28908         prep_801
28909
28910         stop mds2 || error "(1) Fail to stop mds2"
28911
28912         do_facet mgs $LCTL barrier_freeze $FSNAME 30
28913
28914         local b_status=$(barrier_stat)
28915         [ "$b_status" = "'expired'" ] || [ "$b_status" = "'failed'" ] || {
28916                 do_facet mgs $LCTL barrier_thaw $FSNAME
28917                 error "(2) unexpected barrier status $b_status"
28918         }
28919
28920         do_facet mgs $LCTL barrier_rescan $FSNAME ||
28921                 error "(3) Fail to rescan barrier bitmap"
28922
28923         # Do not reduce barrier time - See LU-11873
28924         do_facet mgs $LCTL barrier_freeze $FSNAME 20
28925
28926         b_status=$(barrier_stat)
28927         [ "$b_status" = "'frozen'" ] ||
28928                 error "(4) unexpected barrier status $b_status"
28929
28930         do_facet mgs $LCTL barrier_thaw $FSNAME
28931         b_status=$(barrier_stat)
28932         [ "$b_status" = "'thawed'" ] ||
28933                 error "(5) unexpected barrier status $b_status"
28934
28935         local devname=$(mdsdevname 2)
28936
28937         start mds2 $devname $MDS_MOUNT_OPTS || error "(6) Fail to start mds2"
28938
28939         do_facet mgs $LCTL barrier_rescan $FSNAME ||
28940                 error "(7) Fail to rescan barrier bitmap"
28941
28942         post_801
28943 }
28944 run_test 801c "rescan barrier bitmap"
28945
28946 test_802b() {
28947         [ $PARALLEL == "yes" ] && skip "skip parallel run"
28948         remote_mds_nodsh && skip "remote MDS with nodsh"
28949
28950         do_facet $SINGLEMDS $LCTL get_param mdt.*.readonly ||
28951                 skip "readonly option not available"
28952
28953         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "(1) fail to mkdir"
28954
28955         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
28956                 error "(2) Fail to copy"
28957
28958         # write back all cached data before setting MDT to readonly
28959         cancel_lru_locks
28960         sync_all_data
28961
28962         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=1
28963         stack_trap "do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0" EXIT
28964
28965         echo "Modify should be refused"
28966         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
28967
28968         echo "Read should be allowed"
28969         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
28970                 error "(7) Read should succeed under ro mode"
28971
28972         # disable readonly
28973         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0
28974 }
28975 run_test 802b "be able to set MDTs to readonly"
28976
28977 test_803a() {
28978         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
28979         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
28980                 skip "MDS needs to be newer than 2.10.54"
28981
28982         mkdir_on_mdt0 $DIR/$tdir
28983         # Create some objects on all MDTs to trigger related logs objects
28984         for idx in $(seq $MDSCOUNT); do
28985                 $LFS mkdir -c $MDSCOUNT -i $((idx % $MDSCOUNT)) \
28986                         $DIR/$tdir/dir${idx} ||
28987                         error "Fail to create $DIR/$tdir/dir${idx}"
28988         done
28989
28990         wait_delete_completed # ensure old test cleanups are finished
28991         sleep 3
28992         echo "before create:"
28993         $LFS df -i $MOUNT
28994         local before_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
28995
28996         for i in {1..10}; do
28997                 $LFS mkdir -c 1 -i 1 $DIR/$tdir/foo$i ||
28998                         error "Fail to create $DIR/$tdir/foo$i"
28999         done
29000
29001         # sync ZFS-on-MDS to refresh statfs data
29002         wait_zfs_commit mds1
29003         sleep 3
29004         echo "after create:"
29005         $LFS df -i $MOUNT
29006         local after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
29007
29008         # allow for an llog to be cleaned up during the test
29009         [ $after_used -ge $((before_used + 10 - 1)) ] ||
29010                 error "before ($before_used) + 10 > after ($after_used)"
29011
29012         for i in {1..10}; do
29013                 rm -rf $DIR/$tdir/foo$i ||
29014                         error "Fail to remove $DIR/$tdir/foo$i"
29015         done
29016
29017         # sync ZFS-on-MDS to refresh statfs data
29018         wait_zfs_commit mds1
29019         wait_delete_completed
29020         sleep 3 # avoid MDT return cached statfs
29021         echo "after unlink:"
29022         $LFS df -i $MOUNT
29023         after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
29024
29025         # allow for an llog to be created during the test
29026         [ $after_used -le $((before_used + 1)) ] ||
29027                 error "after ($after_used) > before ($before_used) + 1"
29028 }
29029 run_test 803a "verify agent object for remote object"
29030
29031 test_803b() {
29032         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
29033         [ $MDS1_VERSION -lt $(version_code 2.13.56) ] &&
29034                 skip "MDS needs to be newer than 2.13.56"
29035         [ $PARALLEL == "yes" ] && skip "skip parallel run"
29036
29037         for i in $(seq 0 $((MDSCOUNT - 1))); do
29038                 $LFS mkdir -i $i $DIR/$tdir.$i || error "mkdir $tdir.$i"
29039         done
29040
29041         local before=0
29042         local after=0
29043
29044         local tmp
29045
29046         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
29047         for i in $(seq 0 $((MDSCOUNT - 1))); do
29048                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
29049                         awk '/getattr/ { print $2 }')
29050                 before=$((before + tmp))
29051         done
29052         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
29053         for i in $(seq 0 $((MDSCOUNT - 1))); do
29054                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
29055                         awk '/getattr/ { print $2 }')
29056                 after=$((after + tmp))
29057         done
29058
29059         [ $before -eq $after ] || error "getattr count $before != $after"
29060 }
29061 run_test 803b "remote object can getattr from cache"
29062
29063 test_804() {
29064         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
29065         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
29066                 skip "MDS needs to be newer than 2.10.54"
29067         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
29068
29069         mkdir -p $DIR/$tdir
29070         $LFS mkdir -c 1 -i 1 $DIR/$tdir/dir0 ||
29071                 error "Fail to create $DIR/$tdir/dir0"
29072
29073         local fid=$($LFS path2fid $DIR/$tdir/dir0)
29074         local dev=$(mdsdevname 2)
29075
29076         do_facet mds2 "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
29077                 grep ${fid} || error "NOT found agent entry for dir0"
29078
29079         $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir/dir1 ||
29080                 error "Fail to create $DIR/$tdir/dir1"
29081
29082         touch $DIR/$tdir/dir1/foo0 ||
29083                 error "Fail to create $DIR/$tdir/dir1/foo0"
29084         fid=$($LFS path2fid $DIR/$tdir/dir1/foo0)
29085         local rc=0
29086
29087         for idx in $(seq $MDSCOUNT); do
29088                 dev=$(mdsdevname $idx)
29089                 do_facet mds${idx} \
29090                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
29091                         grep ${fid} && rc=$idx
29092         done
29093
29094         mv $DIR/$tdir/dir1/foo0 $DIR/$tdir/dir1/foo1 ||
29095                 error "Fail to rename foo0 to foo1"
29096         if [ $rc -eq 0 ]; then
29097                 for idx in $(seq $MDSCOUNT); do
29098                         dev=$(mdsdevname $idx)
29099                         do_facet mds${idx} \
29100                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
29101                         grep ${fid} && rc=$idx
29102                 done
29103         fi
29104
29105         mv $DIR/$tdir/dir1/foo1 $DIR/$tdir/dir1/foo2 ||
29106                 error "Fail to rename foo1 to foo2"
29107         if [ $rc -eq 0 ]; then
29108                 for idx in $(seq $MDSCOUNT); do
29109                         dev=$(mdsdevname $idx)
29110                         do_facet mds${idx} \
29111                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
29112                         grep ${fid} && rc=$idx
29113                 done
29114         fi
29115
29116         [ $rc -ne 0 ] || error "NOT found agent entry for foo"
29117
29118         ln $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir0/guard ||
29119                 error "Fail to link to $DIR/$tdir/dir1/foo2"
29120         mv $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir1/foo0 ||
29121                 error "Fail to rename foo2 to foo0"
29122         unlink $DIR/$tdir/dir1/foo0 ||
29123                 error "Fail to unlink $DIR/$tdir/dir1/foo0"
29124         rm -rf $DIR/$tdir/dir0 ||
29125                 error "Fail to rm $DIR/$tdir/dir0"
29126
29127         for idx in $(seq $MDSCOUNT); do
29128                 rc=0
29129
29130                 stop mds${idx}
29131                 dev=$(mdsdevname $idx)
29132                 run_e2fsck $(facet_active_host mds$idx) $dev -n ||
29133                         rc=$?
29134                 start mds${idx} $dev $MDS_MOUNT_OPTS ||
29135                         error "mount mds$idx failed"
29136                 df $MOUNT > /dev/null 2>&1
29137
29138                 # e2fsck should not return error
29139                 [ $rc -eq 0 ] ||
29140                         error "e2fsck detected error on MDT${idx}: rc=$rc"
29141         done
29142 }
29143 run_test 804 "verify agent entry for remote entry"
29144
29145 cleanup_805() {
29146         do_facet $SINGLEMDS zfs set quota=$old $fsset
29147         unlinkmany $DIR/$tdir/f- 1000000
29148         trap 0
29149 }
29150
29151 test_805() {
29152         local zfs_version=$(do_facet mds1 cat /sys/module/zfs/version)
29153         [ "$mds1_FSTYPE" != "zfs" ] && skip "ZFS specific test"
29154         [ $(version_code $zfs_version) -lt $(version_code 0.7.2) ] &&
29155                 skip "netfree not implemented before 0.7"
29156         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
29157                 skip "Need MDS version at least 2.10.57"
29158
29159         local fsset
29160         local freekb
29161         local usedkb
29162         local old
29163         local quota
29164         local pref="osd-zfs.$FSNAME-MDT0000."
29165
29166         # limit available space on MDS dataset to meet nospace issue
29167         # quickly. then ZFS 0.7.2 can use reserved space if asked
29168         # properly (using netfree flag in osd_declare_destroy()
29169         fsset=$(do_facet $SINGLEMDS lctl get_param -n $pref.mntdev)
29170         old=$(do_facet $SINGLEMDS zfs get -H quota $fsset | \
29171                 gawk '{print $3}')
29172         freekb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytesfree)
29173         usedkb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytestotal)
29174         let "usedkb=usedkb-freekb"
29175         let "freekb=freekb/2"
29176         if let "freekb > 5000"; then
29177                 let "freekb=5000"
29178         fi
29179         do_facet $SINGLEMDS zfs set quota=$(((usedkb+freekb)*1024)) $fsset
29180         trap cleanup_805 EXIT
29181         mkdir_on_mdt0 $DIR/$tdir
29182         $LFS setstripe -E 1M -c2 -E 4M -c2 -E -1 -c2 $DIR/$tdir ||
29183                 error "Can't set PFL layout"
29184         createmany -m $DIR/$tdir/f- 1000000 && error "ENOSPC wasn't met"
29185         rm -rf $DIR/$tdir || error "not able to remove"
29186         do_facet $SINGLEMDS zfs set quota=$old $fsset
29187         trap 0
29188 }
29189 run_test 805 "ZFS can remove from full fs"
29190
29191 # Size-on-MDS test
29192 check_lsom_data()
29193 {
29194         local file=$1
29195         local expect=$(stat -c %s $file)
29196
29197         check_lsom_size $1 $expect
29198
29199         local blocks=$($LFS getsom -b $file)
29200         expect=$(stat -c %b $file)
29201         [[ $blocks == $expect ]] ||
29202                 error "$file expected blocks: $expect, got: $blocks"
29203 }
29204
29205 check_lsom_size()
29206 {
29207         local size
29208         local expect=$2
29209
29210         cancel_lru_locks mdc
29211
29212         size=$($LFS getsom -s $1)
29213         [[ $size == $expect ]] ||
29214                 error "$file expected size: $expect, got: $size"
29215 }
29216
29217 test_806() {
29218         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
29219                 skip "Need MDS version at least 2.11.52"
29220
29221         local bs=1048576
29222
29223         $LFS setstripe -c-1 $DIR/$tfile || error "setstripe $tfile failed"
29224
29225         disable_opencache
29226         stack_trap "restore_opencache"
29227
29228         # single-threaded write
29229         echo "Test SOM for single-threaded write"
29230         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 ||
29231                 error "write $tfile failed"
29232         check_lsom_size $DIR/$tfile $bs
29233
29234         local num=32
29235         local size=$(($num * $bs))
29236         local offset=0
29237         local i
29238
29239         echo "Test SOM for single client multi-threaded($num) write"
29240         $TRUNCATE $DIR/$tfile 0
29241         for ((i = 0; i < $num; i++)); do
29242                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
29243                 local pids[$i]=$!
29244                 offset=$((offset + $bs))
29245         done
29246         for (( i=0; i < $num; i++ )); do
29247                 wait ${pids[$i]}
29248         done
29249         check_lsom_size $DIR/$tfile $size
29250
29251         $TRUNCATE $DIR/$tfile 0
29252         for ((i = 0; i < $num; i++)); do
29253                 offset=$((offset - $bs))
29254                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
29255                 local pids[$i]=$!
29256         done
29257         for (( i=0; i < $num; i++ )); do
29258                 wait ${pids[$i]}
29259         done
29260         check_lsom_size $DIR/$tfile $size
29261
29262         # multi-client writes
29263         num=$(get_node_count ${CLIENTS//,/ })
29264         size=$(($num * $bs))
29265         offset=0
29266         i=0
29267
29268         echo "Test SOM for multi-client ($num) writes"
29269         $TRUNCATE $DIR/$tfile 0
29270         for client in ${CLIENTS//,/ }; do
29271                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
29272                 local pids[$i]=$!
29273                 i=$((i + 1))
29274                 offset=$((offset + $bs))
29275         done
29276         for (( i=0; i < $num; i++ )); do
29277                 wait ${pids[$i]}
29278         done
29279         check_lsom_size $DIR/$tfile $offset
29280
29281         i=0
29282         $TRUNCATE $DIR/$tfile 0
29283         for client in ${CLIENTS//,/ }; do
29284                 offset=$((offset - $bs))
29285                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
29286                 local pids[$i]=$!
29287                 i=$((i + 1))
29288         done
29289         for (( i=0; i < $num; i++ )); do
29290                 wait ${pids[$i]}
29291         done
29292         check_lsom_size $DIR/$tfile $size
29293
29294         # verify SOM blocks count
29295         echo "Verify SOM block count"
29296         $TRUNCATE $DIR/$tfile 0
29297         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w$((bs))YSc ||
29298                 error "failed to write file $tfile with fdatasync and fstat"
29299         check_lsom_data $DIR/$tfile
29300
29301         $TRUNCATE $DIR/$tfile 0
29302         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w$((bs * 2))Yc ||
29303                 error "failed to write file $tfile with fdatasync"
29304         check_lsom_data $DIR/$tfile
29305
29306         $TRUNCATE $DIR/$tfile 0
29307         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:O_SYNC:w$((bs * 3))c ||
29308                 error "failed to write file $tfile with sync IO"
29309         check_lsom_data $DIR/$tfile
29310
29311         # verify truncate
29312         echo "Test SOM for truncate"
29313         # use ftruncate to sync blocks on close request
29314         $MULTIOP $DIR/$tfile oO_WRONLY:T16384c
29315         check_lsom_size $DIR/$tfile 16384
29316         check_lsom_data $DIR/$tfile
29317
29318         $TRUNCATE $DIR/$tfile 1234
29319         check_lsom_size $DIR/$tfile 1234
29320         # sync blocks on the MDT
29321         $MULTIOP $DIR/$tfile oc
29322         check_lsom_data $DIR/$tfile
29323 }
29324 run_test 806 "Verify Lazy Size on MDS"
29325
29326 test_807() {
29327         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
29328         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
29329                 skip "Need MDS version at least 2.11.52"
29330
29331         # Registration step
29332         changelog_register || error "changelog_register failed"
29333         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
29334         changelog_users $SINGLEMDS | grep -q $cl_user ||
29335                 error "User $cl_user not found in changelog_users"
29336
29337         rm -rf $DIR/$tdir || error "rm $tdir failed"
29338         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
29339         touch $DIR/$tdir/trunc || error "touch $tdir/trunc failed"
29340         $TRUNCATE $DIR/$tdir/trunc 1024 || error "truncate $tdir/trunc failed"
29341         $TRUNCATE $DIR/$tdir/trunc 1048576 ||
29342                 error "truncate $tdir/trunc failed"
29343
29344         local bs=1048576
29345         echo "Test SOM for single-threaded write with fsync"
29346         dd if=/dev/zero of=$DIR/$tdir/single_dd bs=$bs count=1 ||
29347                 error "write $tfile failed"
29348         sync;sync;sync
29349
29350         # multi-client wirtes
29351         local num=$(get_node_count ${CLIENTS//,/ })
29352         local offset=0
29353         local i=0
29354
29355         echo "Test SOM for multi-client ($num) writes"
29356         touch $DIR/$tfile || error "touch $tfile failed"
29357         $TRUNCATE $DIR/$tfile 0
29358         for client in ${CLIENTS//,/ }; do
29359                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
29360                 local pids[$i]=$!
29361                 i=$((i + 1))
29362                 offset=$((offset + $bs))
29363         done
29364         for (( i=0; i < $num; i++ )); do
29365                 wait ${pids[$i]}
29366         done
29367
29368         do_rpc_nodes "$CLIENTS" cancel_lru_locks osc
29369         do_nodes "$CLIENTS" "sync ; sleep 5 ; sync"
29370         $LSOM_SYNC -u $cl_user -m $FSNAME-MDT0000 $MOUNT
29371         check_lsom_data $DIR/$tdir/trunc
29372         check_lsom_data $DIR/$tdir/single_dd
29373         check_lsom_data $DIR/$tfile
29374
29375         rm -rf $DIR/$tdir
29376         # Deregistration step
29377         changelog_deregister || error "changelog_deregister failed"
29378 }
29379 run_test 807 "verify LSOM syncing tool"
29380
29381 check_som_nologged()
29382 {
29383         local lines=$($LFS changelog $FSNAME-MDT0000 |
29384                 grep 'x=trusted.som' | wc -l)
29385         [ $lines -ne 0 ] && error "trusted.som xattr is logged in Changelogs"
29386 }
29387
29388 test_808() {
29389         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
29390                 skip "Need MDS version at least 2.11.55"
29391
29392         # Registration step
29393         changelog_register || error "changelog_register failed"
29394
29395         touch $DIR/$tfile || error "touch $tfile failed"
29396         check_som_nologged
29397
29398         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=1 ||
29399                 error "write $tfile failed"
29400         check_som_nologged
29401
29402         $TRUNCATE $DIR/$tfile 1234
29403         check_som_nologged
29404
29405         $TRUNCATE $DIR/$tfile 1048576
29406         check_som_nologged
29407
29408         # Deregistration step
29409         changelog_deregister || error "changelog_deregister failed"
29410 }
29411 run_test 808 "Check trusted.som xattr not logged in Changelogs"
29412
29413 check_som_nodata()
29414 {
29415         $LFS getsom $1
29416         [[ $? -eq 61 ]] || error "DoM-only file $1 has SOM xattr"
29417 }
29418
29419 test_809() {
29420         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
29421                 skip "Need MDS version at least 2.11.56"
29422
29423         $LFS setstripe -E 1M -L mdt $DIR/$tfile ||
29424                 error "failed to create DoM-only file $DIR/$tfile"
29425         touch $DIR/$tfile || error "touch $tfile failed"
29426         check_som_nodata $DIR/$tfile
29427
29428         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 ||
29429                 error "write $tfile failed"
29430         check_som_nodata $DIR/$tfile
29431
29432         $TRUNCATE $DIR/$tfile 1234
29433         check_som_nodata $DIR/$tfile
29434
29435         $TRUNCATE $DIR/$tfile 4097
29436         check_som_nodata $DIR/$file
29437 }
29438 run_test 809 "Verify no SOM xattr store for DoM-only files"
29439
29440 test_810() {
29441         [ $PARALLEL == "yes" ] && skip "skip parallel run"
29442         $GSS && skip_env "could not run with gss"
29443         [[ $OST1_VERSION -gt $(version_code 2.12.58) ]] ||
29444                 skip "OST < 2.12.58 doesn't align checksum"
29445
29446         set_checksums 1
29447         stack_trap "set_checksums $ORIG_CSUM" EXIT
29448         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
29449
29450         local csum
29451         local before
29452         local after
29453         for csum in $CKSUM_TYPES; do
29454                 #define OBD_FAIL_OSC_NO_GRANT   0x411
29455                 $LCTL set_param osc.*.checksum_type=$csum fail_loc=0x411
29456                 for i in "10240 0" "10000 0" "4000 1" "500 1"; do
29457                         eval set -- $i
29458                         dd if=/dev/urandom of=$DIR/$tfile bs=$1 count=2 seek=$2
29459                         before=$(md5sum $DIR/$tfile)
29460                         $LCTL set_param ldlm.namespaces.*osc*.lru_size=clear
29461                         after=$(md5sum $DIR/$tfile)
29462                         [ "$before" == "$after" ] ||
29463                                 error "$csum: $before != $after bs=$1 seek=$2"
29464                 done
29465         done
29466 }
29467 run_test 810 "partial page writes on ZFS (LU-11663)"
29468
29469 test_812a() {
29470         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
29471                 skip "OST < 2.12.51 doesn't support this fail_loc"
29472
29473         $LFS setstripe -c 1 -i 0 $DIR/$tfile
29474         # ensure ost1 is connected
29475         stat $DIR/$tfile >/dev/null || error "can't stat"
29476         wait_osc_import_state client ost1 FULL
29477         # no locks, no reqs to let the connection idle
29478         cancel_lru_locks osc
29479
29480         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
29481 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
29482         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
29483         wait_osc_import_state client ost1 CONNECTING
29484         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
29485
29486         stat $DIR/$tfile >/dev/null || error "can't stat file"
29487 }
29488 run_test 812a "do not drop reqs generated when imp is going to idle (LU-11951)"
29489
29490 test_812b() { # LU-12378
29491         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
29492                 skip "OST < 2.12.51 doesn't support this fail_loc"
29493
29494         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "setstripe failed"
29495         # ensure ost1 is connected
29496         stat $DIR/$tfile >/dev/null || error "can't stat"
29497         wait_osc_import_state client ost1 FULL
29498         # no locks, no reqs to let the connection idle
29499         cancel_lru_locks osc
29500
29501         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
29502 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
29503         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
29504         wait_osc_import_state client ost1 CONNECTING
29505         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
29506
29507         $LFS quota -u 0 $DIR/ || error "lfs quota should succeed"
29508         wait_osc_import_state client ost1 IDLE
29509 }
29510 run_test 812b "do not drop no resend request for idle connect"
29511
29512 test_812c() {
29513         local old
29514
29515         old=$($LCTL get_param -n osc.*.idle_timeout | head -n 1)
29516
29517         $LFS setstripe -c 1 -o 0 $DIR/$tfile
29518         $LFS getstripe $DIR/$tfile
29519         $LCTL set_param osc.*.idle_timeout=10
29520         stack_trap "$LCTL set_param osc.*.idle_timeout=$old" EXIT
29521         # ensure ost1 is connected
29522         stat $DIR/$tfile >/dev/null || error "can't stat"
29523         wait_osc_import_state client ost1 FULL
29524         # no locks, no reqs to let the connection idle
29525         cancel_lru_locks osc
29526
29527 #define OBD_FAIL_PTLRPC_IDLE_RACE        0x533
29528         $LCTL set_param fail_loc=0x80000533
29529         sleep 15
29530         dd if=/dev/zero of=$DIR/$tfile count=1 conv=sync || error "dd failed"
29531 }
29532 run_test 812c "idle import vs lock enqueue race"
29533
29534 test_813() {
29535         local file_heat_sav=$($LCTL get_param -n llite.*.file_heat 2>/dev/null)
29536         [ -z "$file_heat_sav" ] && skip "no file heat support"
29537
29538         local readsample
29539         local writesample
29540         local readbyte
29541         local writebyte
29542         local readsample1
29543         local writesample1
29544         local readbyte1
29545         local writebyte1
29546
29547         local period_second=$($LCTL get_param -n llite.*.heat_period_second)
29548         local decay_pct=$($LCTL get_param -n llite.*.heat_decay_percentage)
29549
29550         $LCTL set_param -n llite.*.file_heat=1
29551         echo "Turn on file heat"
29552         echo "Period second: $period_second, Decay percentage: $decay_pct"
29553
29554         echo "QQQQ" > $DIR/$tfile
29555         echo "QQQQ" > $DIR/$tfile
29556         echo "QQQQ" > $DIR/$tfile
29557         cat $DIR/$tfile > /dev/null
29558         cat $DIR/$tfile > /dev/null
29559         cat $DIR/$tfile > /dev/null
29560         cat $DIR/$tfile > /dev/null
29561
29562         local out=$($LFS heat_get $DIR/$tfile)
29563
29564         $LFS heat_get $DIR/$tfile
29565         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
29566         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
29567         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
29568         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
29569
29570         [ $readsample -le 4 ] || error "read sample ($readsample) is wrong"
29571         [ $writesample -le 3 ] || error "write sample ($writesample) is wrong"
29572         [ $readbyte -le 20 ] || error "read bytes ($readbyte) is wrong"
29573         [ $writebyte -le 15 ] || error "write bytes ($writebyte) is wrong"
29574
29575         sleep $((period_second + 3))
29576         echo "Sleep $((period_second + 3)) seconds..."
29577         # The recursion formula to calculate the heat of the file f is as
29578         # follow:
29579         # Hi+1(f) = (1-P)*Hi(f)+ P*Ci
29580         # Where Hi is the heat value in the period between time points i*I and
29581         # (i+1)*I; Ci is the access count in the period; the symbol P refers
29582         # to the weight of Ci.
29583         out=$($LFS heat_get $DIR/$tfile)
29584         $LFS heat_get $DIR/$tfile
29585         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
29586         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
29587         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
29588         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
29589
29590         [ $(bc <<< "$readsample <= 4 * $decay_pct / 100") -eq 1 ] ||
29591                 error "read sample ($readsample) is wrong"
29592         [ $(bc <<< "$writesample <= 3 * $decay_pct / 100") -eq 1 ] ||
29593                 error "write sample ($writesample) is wrong"
29594         [ $(bc <<< "$readbyte <= 20 * $decay_pct / 100") -eq 1 ] ||
29595                 error "read bytes ($readbyte) is wrong"
29596         [ $(bc <<< "$writebyte <= 15 * $decay_pct / 100") -eq 1 ] ||
29597                 error "write bytes ($writebyte) is wrong"
29598
29599         echo "QQQQ" > $DIR/$tfile
29600         echo "QQQQ" > $DIR/$tfile
29601         echo "QQQQ" > $DIR/$tfile
29602         cat $DIR/$tfile > /dev/null
29603         cat $DIR/$tfile > /dev/null
29604         cat $DIR/$tfile > /dev/null
29605         cat $DIR/$tfile > /dev/null
29606
29607         sleep $((period_second + 3))
29608         echo "Sleep $((period_second + 3)) seconds..."
29609
29610         out=$($LFS heat_get $DIR/$tfile)
29611         $LFS heat_get $DIR/$tfile
29612         readsample1=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
29613         writesample1=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
29614         readbyte1=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
29615         writebyte1=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
29616
29617         [ $(bc <<< "$readsample1 <= ($readsample * (100 - $decay_pct) + \
29618                 4 * $decay_pct) / 100") -eq 1 ] ||
29619                 error "read sample ($readsample1) is wrong"
29620         [ $(bc <<< "$writesample1 <= ($writesample * (100 - $decay_pct) + \
29621                 3 * $decay_pct) / 100") -eq 1 ] ||
29622                 error "write sample ($writesample1) is wrong"
29623         [ $(bc <<< "$readbyte1 <= ($readbyte * (100 - $decay_pct) + \
29624                 20 * $decay_pct) / 100") -eq 1 ] ||
29625                 error "read bytes ($readbyte1) is wrong"
29626         [ $(bc <<< "$writebyte1 <= ($writebyte * (100 - $decay_pct) + \
29627                 15 * $decay_pct) / 100") -eq 1 ] ||
29628                 error "write bytes ($writebyte1) is wrong"
29629
29630         echo "Turn off file heat for the file $DIR/$tfile"
29631         $LFS heat_set -o $DIR/$tfile
29632
29633         echo "QQQQ" > $DIR/$tfile
29634         echo "QQQQ" > $DIR/$tfile
29635         echo "QQQQ" > $DIR/$tfile
29636         cat $DIR/$tfile > /dev/null
29637         cat $DIR/$tfile > /dev/null
29638         cat $DIR/$tfile > /dev/null
29639         cat $DIR/$tfile > /dev/null
29640
29641         out=$($LFS heat_get $DIR/$tfile)
29642         $LFS heat_get $DIR/$tfile
29643         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
29644         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
29645         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
29646         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
29647
29648         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
29649         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
29650         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
29651         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
29652
29653         echo "Trun on file heat for the file $DIR/$tfile"
29654         $LFS heat_set -O $DIR/$tfile
29655
29656         echo "QQQQ" > $DIR/$tfile
29657         echo "QQQQ" > $DIR/$tfile
29658         echo "QQQQ" > $DIR/$tfile
29659         cat $DIR/$tfile > /dev/null
29660         cat $DIR/$tfile > /dev/null
29661         cat $DIR/$tfile > /dev/null
29662         cat $DIR/$tfile > /dev/null
29663
29664         out=$($LFS heat_get $DIR/$tfile)
29665         $LFS heat_get $DIR/$tfile
29666         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
29667         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
29668         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
29669         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
29670
29671         [ $readsample -gt 0 ] || error "read sample ($readsample) is wrong"
29672         [ $writesample -gt 0 ] || error "write sample ($writesample) is wrong"
29673         [ $readbyte -gt 0 ] || error "read bytes ($readbyte) is wrong"
29674         [ $writebyte -gt 0 ] || error "write bytes ($writebyte) is wrong"
29675
29676         $LFS heat_set -c $DIR/$tfile
29677         $LCTL set_param -n llite.*.file_heat=0
29678         echo "Turn off file heat support for the Lustre filesystem"
29679
29680         echo "QQQQ" > $DIR/$tfile
29681         echo "QQQQ" > $DIR/$tfile
29682         echo "QQQQ" > $DIR/$tfile
29683         cat $DIR/$tfile > /dev/null
29684         cat $DIR/$tfile > /dev/null
29685         cat $DIR/$tfile > /dev/null
29686         cat $DIR/$tfile > /dev/null
29687
29688         out=$($LFS heat_get $DIR/$tfile)
29689         $LFS heat_get $DIR/$tfile
29690         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
29691         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
29692         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
29693         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
29694
29695         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
29696         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
29697         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
29698         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
29699
29700         $LCTL set_param -n llite.*.file_heat=$file_heat_sav
29701         rm -f $DIR/$tfile
29702 }
29703 run_test 813 "File heat verfication"
29704
29705 test_814()
29706 {
29707         dd of=$DIR/$tfile seek=128 bs=1k < /dev/null
29708         echo -n y >> $DIR/$tfile
29709         cp --sparse=always $DIR/$tfile $DIR/${tfile}.cp || error "copy failed"
29710         diff $DIR/$tfile $DIR/${tfile}.cp || error "files should be same"
29711 }
29712 run_test 814 "sparse cp works as expected (LU-12361)"
29713
29714 test_815()
29715 {
29716         writeme -b 100 $DIR/$tfile || error "write 100 bytes failed"
29717         writeme -b 0 $DIR/$tfile || error "write 0 byte failed"
29718 }
29719 run_test 815 "zero byte tiny write doesn't hang (LU-12382)"
29720
29721 test_816() {
29722         local ost1_imp=$(get_osc_import_name client ost1)
29723         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
29724                          cut -d'.' -f2)
29725
29726         $LFS setstripe -c 1 -i 0 $DIR/$tfile
29727         # ensure ost1 is connected
29728
29729         stat $DIR/$tfile >/dev/null || error "can't stat"
29730         wait_osc_import_state client ost1 FULL
29731         # no locks, no reqs to let the connection idle
29732         cancel_lru_locks osc
29733         lru_resize_disable osc
29734         local before
29735         local now
29736         before=$($LCTL get_param -n \
29737                  ldlm.namespaces.$imp_name.lru_size)
29738
29739         wait_osc_import_state client ost1 IDLE
29740         dd if=/dev/null of=$DIR/$tfile bs=1k count=1 conv=sync
29741         now=$($LCTL get_param -n \
29742               ldlm.namespaces.$imp_name.lru_size)
29743         [ $before == $now ] || error "lru_size changed $before != $now"
29744 }
29745 run_test 816 "do not reset lru_resize on idle reconnect"
29746
29747 cleanup_817() {
29748         umount $tmpdir
29749         exportfs -u localhost:$DIR/nfsexp
29750         rm -rf $DIR/nfsexp
29751 }
29752
29753 test_817() {
29754         systemctl restart nfs-server.service || skip "failed to restart nfsd"
29755
29756         mkdir -p $DIR/nfsexp
29757         exportfs -orw,no_root_squash localhost:$DIR/nfsexp ||
29758                 error "failed to export nfs"
29759
29760         tmpdir=$(mktemp -d /tmp/nfs-XXXXXX)
29761         stack_trap cleanup_817 EXIT
29762
29763         mount -t nfs -orw localhost:$DIR/nfsexp $tmpdir ||
29764                 error "failed to mount nfs to $tmpdir"
29765
29766         cp /bin/true $tmpdir
29767         $DIR/nfsexp/true || error "failed to execute 'true' command"
29768 }
29769 run_test 817 "nfsd won't cache write lock for exec file"
29770
29771 test_818() {
29772         test_mkdir -i0 -c1 $DIR/$tdir
29773         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
29774         $LFS setstripe -c1 -i1 $DIR/$tdir/$tfile
29775         stop $SINGLEMDS
29776
29777         # restore osp-syn threads
29778         stack_trap "fail $SINGLEMDS"
29779
29780         #define OBD_FAIL_OSP_CANT_PROCESS_LLOG          0x2105
29781         do_facet $SINGLEMDS lctl set_param fail_loc=0x80002105
29782         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
29783                 error "start $SINGLEMDS failed"
29784         rm -rf $DIR/$tdir
29785
29786         local testid=$(echo $TESTNAME | tr '_' ' ')
29787
29788         do_facet mds1 dmesg | tac | sed "/$testid/,$ d" |
29789                 grep "run LFSCK" || error "run LFSCK is not suggested"
29790 }
29791 run_test 818 "unlink with failed llog"
29792
29793 test_819a() {
29794         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
29795         cancel_lru_locks osc
29796         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
29797         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
29798         dd if=$DIR/$tfile of=/dev/null bs=1M count=1
29799         rm -f $TDIR/$tfile
29800 }
29801 run_test 819a "too big niobuf in read"
29802
29803 test_819b() {
29804         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
29805         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
29806         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
29807         cancel_lru_locks osc
29808         sleep 1
29809         rm -f $TDIR/$tfile
29810 }
29811 run_test 819b "too big niobuf in write"
29812
29813
29814 function test_820_start_ost() {
29815         sleep 5
29816
29817         for num in $(seq $OSTCOUNT); do
29818                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS
29819         done
29820 }
29821
29822 test_820() {
29823         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
29824
29825         mkdir $DIR/$tdir
29826         umount_client $MOUNT || error "umount failed"
29827         for num in $(seq $OSTCOUNT); do
29828                 stop ost$num
29829         done
29830
29831         # mount client with no active OSTs
29832         # so that the client can't initialize max LOV EA size
29833         # from OSC notifications
29834         mount_client $MOUNT || error "mount failed"
29835         # delay OST starting to keep this 0 max EA size for a while
29836         test_820_start_ost &
29837
29838         # create a directory on MDS2
29839         test_mkdir -i 1 -c1 $DIR/$tdir/mds2 ||
29840                 error "Failed to create directory"
29841         # open intent should update default EA size
29842         # see mdc_update_max_ea_from_body()
29843         # notice this is the very first RPC to MDS2
29844         out=$(cp /etc/services $DIR/$tdir/mds2 2>&1)
29845         ret=$?
29846         echo $out
29847         # With SSK, this situation can lead to -EPERM being returned.
29848         # In that case, simply retry.
29849         if [ $ret -ne 0 ] && $SHARED_KEY; then
29850                 if echo "$out" | grep -q "not permitted"; then
29851                         cp /etc/services $DIR/$tdir/mds2
29852                         ret=$?
29853                 fi
29854         fi
29855         [ $ret -eq 0 ] || error "Failed to copy files to mds$n"
29856 }
29857 run_test 820 "update max EA from open intent"
29858
29859 test_823() {
29860         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
29861         local OST_MAX_PRECREATE=20000
29862
29863         (( $MDS1_VERSION >= $(version_code 2.14.56) )) ||
29864                 skip "Need MDS version at least 2.14.56"
29865
29866         save_lustre_params mds1 \
29867                 "osp.$FSNAME-OST*-osc-MDT0000.max_create_count" > $p
29868         do_facet $SINGLEMDS "$LCTL set_param -n \
29869                 osp.$FSNAME-OST*MDT0000.max_create_count=0"
29870         do_facet $SINGLEMDS "$LCTL set_param -n \
29871                 osp.$FSNAME-OST0000*MDT0000.max_create_count=$OST_MAX_PRECREATE"
29872
29873         stack_trap "restore_lustre_params < $p; rm $p"
29874
29875         do_facet $SINGLEMDS "$LCTL set_param -n \
29876                 osp.$FSNAME-OST*-osc-MDT*.create_count=100200"
29877
29878         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
29879                       osp.$FSNAME-OST0000*MDT0000.create_count")
29880         local max=$(do_facet $SINGLEMDS "$LCTL get_param -n \
29881                     osp.$FSNAME-OST0000*MDT0000.max_create_count")
29882         local expect_count=$(((($max/2)/256) * 256))
29883
29884         log "setting create_count to 100200:"
29885         log " -result- count: $count with max: $max, expecting: $expect_count"
29886
29887         [[ $count -eq expect_count ]] ||
29888                 error "Create count not set to max precreate."
29889 }
29890 run_test 823 "Setting create_count > OST_MAX_PRECREATE is lowered to maximum"
29891
29892 test_831() {
29893         [[ $MDS1_VERSION -lt $(version_code 2.14.56) ]] &&
29894                 skip "Need MDS version 2.14.56"
29895
29896         local sync_changes=$(do_facet $SINGLEMDS \
29897                 $LCTL get_param -n osp.$FSNAME-OST0000-osc-MDT0000.sync_changes)
29898
29899         [ "$sync_changes" -gt 100 ] &&
29900                 skip "Sync changes $sync_changes > 100 already"
29901
29902         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
29903
29904         $LFS mkdir -i 0 $DIR/$tdir
29905         $LFS setstripe -c 1 -i 0 $DIR/$tdir
29906
29907         save_lustre_params mds1 \
29908                 "osp.$FSNAME-OST*-osc-MDT0000.max_sync_changes" > $p
29909         save_lustre_params mds1 \
29910                 "osp.$FSNAME-OST*-osc-MDT0000.max_rpcs_in_progress" >> $p
29911
29912         do_facet mds1 "$LCTL set_param -n \
29913                 osp.$FSNAME-OST*-osc-MDT0000.max_sync_changes=100 \
29914                 osp.$FSNAME-OST*-osc-MDT0000.max_rpcs_in_progress=128"
29915         stack_trap "restore_lustre_params < $p" EXIT
29916
29917         createmany -o $DIR/$tdir/f- 1000
29918         unlinkmany $DIR/$tdir/f- 1000 &
29919         local UNLINK_PID=$!
29920
29921         while sleep 1; do
29922                 sync_changes=$(do_facet mds1 \
29923                 $LCTL get_param -n osp.$FSNAME-OST0000-osc-MDT0000.sync_changes)
29924                 # the check in the code is racy, fail the test
29925                 # if the value above the limit by 10.
29926                 [ $sync_changes -gt 110 ] && {
29927                         kill -2 $UNLINK_PID
29928                         wait
29929                         error "osp changes throttling failed, $sync_changes>110"
29930                 }
29931                 kill -0 $UNLINK_PID 2> /dev/null || break
29932         done
29933         wait
29934 }
29935 run_test 831 "throttling unlink/setattr queuing on OSP"
29936
29937 test_832() {
29938         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
29939         (( $MDS1_VERSION >= $(version_code 2.15.52) )) ||
29940                 skip "Need MDS version 2.15.52+"
29941         is_rmentry_supported || skip "rm_entry not supported"
29942
29943         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
29944         mkdir $DIR/$tdir/local_dir || error "mkdir local_dir failed"
29945         mkdir_on_mdt -i 1 $DIR/$tdir/remote_dir ||
29946                 error "mkdir remote_dir failed"
29947         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/striped_dir ||
29948                 error "mkdir striped_dir failed"
29949         touch $DIR/$tdir/file || error "touch file failed"
29950         $LFS rm_entry $DIR/$tdir/* || error "lfs rm_entry $tdir/* failed"
29951         [ -z "$(ls -A $DIR/$tdir)" ] || error "$tdir not empty"
29952 }
29953 run_test 832 "lfs rm_entry"
29954
29955 #
29956 # tests that do cleanup/setup should be run at the end
29957 #
29958
29959 test_900() {
29960         [ $PARALLEL == "yes" ] && skip "skip parallel run"
29961         local ls
29962
29963         #define OBD_FAIL_MGC_PAUSE_PROCESS_LOG   0x903
29964         $LCTL set_param fail_loc=0x903
29965
29966         cancel_lru_locks MGC
29967
29968         FAIL_ON_ERROR=true cleanup
29969         FAIL_ON_ERROR=true setup
29970 }
29971 run_test 900 "umount should not race with any mgc requeue thread"
29972
29973 # LUS-6253/LU-11185
29974 test_901() {
29975         local old
29976         local count
29977         local oldc
29978         local newc
29979         local olds
29980         local news
29981         [ $PARALLEL == "yes" ] && skip "skip parallel run"
29982
29983         # some get_param have a bug to handle dot in param name
29984         cancel_lru_locks MGC
29985         old=$(mount -t lustre | wc -l)
29986         # 1 config+sptlrpc
29987         # 2 params
29988         # 3 nodemap
29989         # 4 IR
29990         old=$((old * 4))
29991         oldc=0
29992         count=0
29993         while [ $old -ne $oldc ]; do
29994                 oldc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
29995                 sleep 1
29996                 ((count++))
29997                 if [ $count -ge $TIMEOUT ]; then
29998                         error "too large timeout"
29999                 fi
30000         done
30001         umount_client $MOUNT || error "umount failed"
30002         mount_client $MOUNT || error "mount failed"
30003         cancel_lru_locks MGC
30004         newc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
30005
30006         [ $oldc -lt $newc ] && error "mgc lock leak ($oldc != $newc)"
30007
30008         return 0
30009 }
30010 run_test 901 "don't leak a mgc lock on client umount"
30011
30012 # LU-13377
30013 test_902() {
30014         [ $CLIENT_VERSION -lt $(version_code 2.13.52) ] &&
30015                 skip "client does not have LU-13377 fix"
30016         #define OBD_FAIL_LLITE_SHORT_COMMIT 0x1415
30017         $LCTL set_param fail_loc=0x1415
30018         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
30019         cancel_lru_locks osc
30020         rm -f $DIR/$tfile
30021 }
30022 run_test 902 "test short write doesn't hang lustre"
30023
30024 # LU-14711
30025 test_903() {
30026         $LFS setstripe -i 0 -c 1 $DIR/$tfile $DIR/${tfile}-2
30027         echo "blah" > $DIR/${tfile}-2
30028         dd if=/dev/zero of=$DIR/$tfile bs=1M count=6 conv=fsync
30029         #define OBD_FAIL_OSC_SLOW_PAGE_EVICT 0x417
30030         $LCTL set_param fail_loc=0x417 fail_val=20
30031
30032         mv $DIR/${tfile}-2 $DIR/$tfile # Destroys the big object
30033         sleep 1 # To start the destroy
30034         wait_destroy_complete 150 || error "Destroy taking too long"
30035         cat $DIR/$tfile > /dev/null || error "Evicted"
30036 }
30037 run_test 903 "Test long page discard does not cause evictions"
30038
30039 test_904() {
30040         [ "$mds1_FSTYPE" == "ldiskfs" ] || skip "ldiskfs only test"
30041         do_facet mds1 $DEBUGFS -R features $(mdsdevname 1) |
30042                 grep -q project || skip "skip project quota not supported"
30043
30044         local testfile="$DIR/$tdir/$tfile"
30045         local xattr="trusted.projid"
30046         local projid
30047         local mdts=$(comma_list $(mdts_nodes))
30048         local saved=$(do_facet mds1 $LCTL get_param -n \
30049                 osd-ldiskfs.*MDT0000.enable_projid_xattr)
30050
30051         do_nodes $mdts $LCTL set_param osd-ldiskfs.*MDT*.enable_projid_xattr=0
30052         stack_trap "do_nodes $mdts $LCTL set_param \
30053                 osd-ldiskfs.*MDT*.enable_projid_xattr=$saved"
30054
30055         mkdir -p $DIR/$tdir
30056         touch $testfile
30057         #hide projid xattr on server
30058         $LFS project -p 1 $testfile ||
30059                 error "set $testfile project id failed"
30060         getfattr -m - $testfile | grep $xattr &&
30061                 error "do not show trusted.projid when disabled on server"
30062         do_nodes $mdts $LCTL set_param osd-ldiskfs.*MDT*.enable_projid_xattr=1
30063         #should be hidden when projid is 0
30064         $LFS project -p 0 $testfile ||
30065                 error "set $testfile project id failed"
30066         getfattr -m - $testfile | grep $xattr &&
30067                 error "do not show trusted.projid with project ID 0"
30068
30069         #still can getxattr explicitly
30070         projid=$(getfattr -n $xattr $testfile |
30071                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
30072         [ $projid == "0" ] ||
30073                 error "projid expected 0 not $projid"
30074
30075         #set the projid via setxattr
30076         setfattr -n $xattr -v "1000" $testfile ||
30077                 error "setattr failed with $?"
30078         projid=($($LFS project $testfile))
30079         [ ${projid[0]} == "1000" ] ||
30080                 error "projid expected 1000 not $projid"
30081
30082         #check the new projid via getxattr
30083         $LFS project -p 1001 $testfile ||
30084                 error "set $testfile project id failed"
30085         getfattr -m - $testfile | grep $xattr ||
30086                 error "should show trusted.projid when project ID != 0"
30087         projid=$(getfattr -n $xattr $testfile |
30088                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
30089         [ $projid == "1001" ] ||
30090                 error "projid expected 1001 not $projid"
30091
30092         #try to set invalid projid
30093         setfattr -n $xattr -v "4294967295" $testfile &&
30094                 error "set invalid projid should fail"
30095
30096         #remove the xattr means setting projid to 0
30097         setfattr -x $xattr $testfile ||
30098                 error "setfattr failed with $?"
30099         projid=($($LFS project $testfile))
30100         [ ${projid[0]} == "0" ] ||
30101                 error "projid expected 0 not $projid"
30102
30103         #should be hidden when parent has inherit flag and same projid
30104         $LFS project -srp 1002 $DIR/$tdir ||
30105                 error "set $tdir project id failed"
30106         getfattr -m - $testfile | grep $xattr &&
30107                 error "do not show trusted.projid with inherit flag"
30108
30109         #still can getxattr explicitly
30110         projid=$(getfattr -n $xattr $testfile |
30111                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
30112         [ $projid == "1002" ] ||
30113                 error "projid expected 1002 not $projid"
30114 }
30115 run_test 904 "virtual project ID xattr"
30116
30117 # LU-8582
30118 test_905() {
30119         (( $OST1_VERSION >= $(version_code 2.8.54) )) ||
30120                 skip "lustre < 2.8.54 does not support ladvise"
30121
30122         remote_ost_nodsh && skip "remote OST with nodsh"
30123         $LFS setstripe -c -1 -i 0 $DIR/$tfile || error "setstripe failed"
30124
30125         $LFS ladvise -a willread $DIR/$tfile || error "ladvise does not work"
30126
30127         #define OBD_FAIL_OST_OPCODE 0x253
30128         # OST_LADVISE = 21
30129         do_facet ost1 "$LCTL set_param fail_val=21 fail_loc=0x0253"
30130         $LFS ladvise -a willread $DIR/$tfile &&
30131                 error "unexpected success of ladvise with fault injection"
30132         $LFS ladvise -a willread $DIR/$tfile |&
30133                 grep -q "Operation not supported"
30134         (( $? == 0 )) || error "unexpected stderr of ladvise with fault injection"
30135 }
30136 run_test 905 "bad or new opcode should not stuck client"
30137
30138 test_906() {
30139         grep -q io_uring_setup /proc/kallsyms ||
30140                 skip "Client OS does not support io_uring I/O engine"
30141         io_uring_probe || skip "kernel does not support io_uring fully"
30142         which fio || skip_env "no fio installed"
30143         fio --enghelp | grep -q io_uring ||
30144                 skip_env "fio does not support io_uring I/O engine"
30145
30146         local file=$DIR/$tfile
30147         local ioengine="io_uring"
30148         local numjobs=2
30149         local size=50M
30150
30151         fio --name=seqwrite --ioengine=$ioengine        \
30152                 --bs=$PAGE_SIZE --direct=1 --numjobs=$numjobs   \
30153                 --iodepth=64 --size=$size --filename=$file --rw=write ||
30154                 error "fio seqwrite $file failed"
30155
30156         fio --name=seqread --ioengine=$ioengine \
30157                 --bs=$PAGE_SIZE --direct=1 --numjobs=$numjobs   \
30158                 --iodepth=64 --size=$size --filename=$file --rw=read ||
30159                 error "fio seqread $file failed"
30160
30161         rm -f $file || error "rm -f $file failed"
30162 }
30163 run_test 906 "Simple test for io_uring I/O engine via fio"
30164
30165 complete $SECONDS
30166 [ -f $EXT2_DEV ] && rm $EXT2_DEV || true
30167 check_and_cleanup_lustre
30168 if [ "$I_MOUNTED" != "yes" ]; then
30169         lctl set_param debug="$OLDDEBUG" 2> /dev/null || true
30170 fi
30171 exit_status