Whamcloud - gitweb
LU-16828 sanity: wrong argument for find in test_133g
[fs/lustre-release.git] / lustre / tests / sanity.sh
1 #!/bin/bash
2 #
3 # Run select tests by setting ONLY, or as arguments to the script.
4 # Skip specific tests by setting EXCEPT.
5 #
6 # e.g. ONLY="22 23" or ONLY="`seq 32 39`" or EXCEPT="31"
7 set -e
8
9 ONLY=${ONLY:-"$*"}
10
11 # Check Grants after these tests
12 GRANT_CHECK_LIST="$GRANT_CHECK_LIST 42a 42b 42c 42d 42e 63a 63b 64a 64b 64c 64d"
13
14 OSC=${OSC:-"osc"}
15
16 CC=${CC:-cc}
17 CREATETEST=${CREATETEST:-createtest}
18 LVERIFY=${LVERIFY:-ll_dirstripe_verify}
19 OPENFILE=${OPENFILE:-openfile}
20 OPENUNLINK=${OPENUNLINK:-openunlink}
21 READS=${READS:-"reads"}
22 MUNLINK=${MUNLINK:-munlink}
23 SOCKETSERVER=${SOCKETSERVER:-socketserver}
24 SOCKETCLIENT=${SOCKETCLIENT:-socketclient}
25 MEMHOG=${MEMHOG:-memhog}
26 DIRECTIO=${DIRECTIO:-directio}
27 ACCEPTOR_PORT=${ACCEPTOR_PORT:-988}
28 DEF_STRIPE_COUNT=-1
29 CHECK_GRANT=${CHECK_GRANT:-"yes"}
30 GRANT_CHECK_LIST=${GRANT_CHECK_LIST:-""}
31
32 TRACE=${TRACE:-""}
33 LUSTRE=${LUSTRE:-$(dirname $0)/..}
34 LUSTRE_TESTS_API_DIR=${LUSTRE_TESTS_API_DIR:-${LUSTRE}/tests/clientapi}
35 . $LUSTRE/tests/test-framework.sh
36 init_test_env "$@"
37
38 init_logging
39
40 ALWAYS_EXCEPT="$SANITY_EXCEPT "
41 always_except LU-9693  42a 42c
42 always_except LU-6493  42b
43 always_except LU-16515 118c 118d
44 always_except LU-8411  407
45
46 if $SHARED_KEY; then
47         always_except LU-14181 64e 64f
48 fi
49
50 # skip the grant tests for ARM until they are fixed
51 if [[ $(uname -m) = aarch64 ]]; then
52         always_except LU-11671 45
53 fi
54
55 # skip nfs tests on kernels >= 4.12.0 until they are fixed
56 if [ $LINUX_VERSION_CODE -ge $(version_code 4.12.0) ]; then
57         always_except LU-12661 817
58 fi
59 # skip cgroup tests on RHEL8.1 kernels until they are fixed
60 if (( $LINUX_VERSION_CODE >= $(version_code 4.18.0) &&
61       $LINUX_VERSION_CODE <  $(version_code 5.4.0) )); then
62         always_except LU-13063 411
63 fi
64
65 # skip basic ops on file with foreign LOV tests on 5.16.0+ kernels
66 # until the filemap_read() issue is fixed
67 if (( $LINUX_VERSION_CODE >= $(version_code 5.16.0) )); then
68         always_except LU-16101 27J
69 fi
70
71 #                                  5              12     8   12  15   (min)"
72 [[ "$SLOW" = "no" ]] && EXCEPT_SLOW="27m 60i 64b 68 71 135 136 230d 300o"
73
74 if [[ "$mds1_FSTYPE" == "zfs" ]]; then
75         #                                               13    (min)"
76         [[ "$SLOW" == "no" ]] && EXCEPT_SLOW="$EXCEPT_SLOW 51b"
77 fi
78
79 if [[ "$ost1_FSTYPE" = "zfs" ]]; then
80         always_except LU-1941 130b 130c 130d 130e 130f 130g
81         always_except LU-9054 312
82 fi
83
84 proc_regexp="/{proc,sys}/{fs,sys,kernel/debug}/{lustre,lnet}/"
85
86 # Get the SLES distro version
87 #
88 # Returns a version string that should only be used in comparing
89 # strings returned by version_code()
90 sles_version_code()
91 {
92         local version=$(grep VERSION_ID /etc/os-release | cut -d'"' -f2)
93
94         # All SuSE Linux versions have one decimal. version_code expects two
95         local sles_version=$version.0
96         version_code $sles_version
97 }
98
99 # Check if we are running on Ubuntu or SLES so we can make decisions on
100 # what tests to run
101 if [ -r /etc/SuSE-release ] || [ -r /etc/SUSE-brand ]; then
102         sles_version=$(sles_version_code)
103         [ $sles_version -lt $(version_code 11.4.0) ] &&
104                 always_except LU-4341 170
105
106         [ $sles_version -lt $(version_code 12.0.0) ] &&
107                 always_except LU-3703 234
108
109         [ $sles_version -ge $(version_code 15.4.0) ] &&
110                 always_except LU-16101 27J
111 elif [ -r /etc/os-release ]; then
112         if grep -qi ubuntu /etc/os-release; then
113                 ubuntu_version=$(version_code $(sed -n -e 's/"//g' \
114                                                 -e 's/^VERSION=//p' \
115                                                 /etc/os-release |
116                                                 awk '{ print $1 }'))
117
118                 if [[ $ubuntu_version -gt $(version_code 16.0.0) ]]; then
119                         always_except LU-10366 410
120                 fi
121         fi
122 fi
123
124 build_test_filter
125 FAIL_ON_ERROR=false
126
127 cleanup() {
128         echo -n "cln.."
129         pgrep ll_sa > /dev/null && { echo "There are ll_sa thread not exit!"; exit 20; }
130         cleanupall ${FORCE} $* || { echo "FAILed to clean up"; exit 20; }
131 }
132 setup() {
133         echo -n "mnt.."
134         load_modules
135         setupall || exit 10
136         echo "done"
137 }
138
139 check_swap_layouts_support()
140 {
141         $LCTL get_param -n llite.*.sbi_flags | grep -q layout ||
142                 skip "Does not support layout lock."
143 }
144
145 check_swap_layout_no_dom()
146 {
147         local FOLDER=$1
148         local SUPP=$(lfs getstripe $FOLDER | grep "pattern:       mdt" | wc -l)
149         [ $SUPP -eq 0 ] || skip "layout swap does not support DOM files so far"
150 }
151
152 check_and_setup_lustre
153 DIR=${DIR:-$MOUNT}
154 assert_DIR
155
156 MAXFREE=${MAXFREE:-$((300000 * $OSTCOUNT))}
157
158 [ -f $DIR/d52a/foo ] && chattr -a $DIR/d52a/foo
159 [ -f $DIR/d52b/foo ] && chattr -i $DIR/d52b/foo
160 rm -rf $DIR/[Rdfs][0-9]*
161
162 # $RUNAS_ID may get set incorrectly somewhere else
163 [ $UID -eq 0 -a $RUNAS_ID -eq 0 ] &&
164         error "\$RUNAS_ID set to 0, but \$UID is also 0!"
165
166 check_runas_id $RUNAS_ID $RUNAS_GID $RUNAS
167
168 if [ "${ONLY}" = "MOUNT" ] ; then
169         echo "Lustre is up, please go on"
170         exit
171 fi
172
173 echo "preparing for tests involving mounts"
174 EXT2_DEV=${EXT2_DEV:-$TMP/SANITY.LOOP}
175 touch $EXT2_DEV
176 mke2fs -j -F $EXT2_DEV 8000 > /dev/null
177 echo # add a newline after mke2fs.
178
179 umask 077
180
181 OLDDEBUG=$(lctl get_param -n debug 2> /dev/null)
182
183 # ensure all internal functions know we want full debug
184 export PTLDEBUG=all
185 lctl set_param debug=$PTLDEBUG 2> /dev/null || true
186
187 test_0a() {
188         touch $DIR/$tfile
189         $CHECKSTAT -t file $DIR/$tfile || error "$tfile is not a file"
190         rm $DIR/$tfile
191         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
192 }
193 run_test 0a "touch; rm ====================="
194
195 test_0b() {
196         chmod 0755 $DIR || error "chmod 0755 $DIR failed"
197         $CHECKSTAT -p 0755 $DIR || error "$DIR permission is not 0755"
198 }
199 run_test 0b "chmod 0755 $DIR ============================="
200
201 test_0c() {
202         $LCTL get_param mdc.*.import | grep "state: FULL" ||
203                 error "import not FULL"
204         $LCTL get_param mdc.*.import | grep "target: $FSNAME-MDT" ||
205                 error "bad target"
206 }
207 run_test 0c "check import proc"
208
209 test_0d() { # LU-3397
210         [ $MGS_VERSION -lt $(version_code 2.10.57) ] &&
211                 skip "proc exports not supported before 2.10.57"
212
213         local mgs_exp="mgs.MGS.exports"
214         local client_uuid=$($LCTL get_param -n mgc.*.uuid)
215         local exp_client_nid
216         local exp_client_version
217         local exp_val
218         local imp_val
219         local temp_imp=$DIR/$tfile.import
220         local temp_exp=$DIR/$tfile.export
221
222         # save mgc import file to $temp_imp
223         $LCTL get_param mgc.*.import | tee $temp_imp
224         # Check if client uuid is found in MGS export
225         for exp_client_nid in $(do_facet mgs $LCTL get_param -N $mgs_exp.*); do
226                 [ $(do_facet mgs $LCTL get_param -n $exp_client_nid.uuid) == \
227                         $client_uuid ] &&
228                         break;
229         done
230         # save mgs export file to $temp_exp
231         do_facet mgs $LCTL get_param $exp_client_nid.export | tee $temp_exp
232
233         # Compare the value of field "connect_flags"
234         imp_val=$(grep "connect_flags" $temp_imp)
235         exp_val=$(grep "connect_flags" $temp_exp)
236         [ "$exp_val" == "$imp_val" ] ||
237                 error "export flags '$exp_val' != import flags '$imp_val'"
238
239         # Compare client versions.  Only compare top-3 fields for compatibility
240         exp_client_version=$(awk '/target_version:/ { print $2 }' $temp_exp)
241         exp_val=$(version_code $(cut -d. -f1,2,3 <<<$exp_client_version))
242         imp_val=$(version_code $(lustre_build_version client | cut -d. -f1,2,3))
243         [ "$exp_val" == "$imp_val" ] ||
244                 error "exp version '$exp_client_version'($exp_val) != " \
245                         "'$(lustre_build_version client)'($imp_val)"
246 }
247 run_test 0d "check export proc ============================="
248
249 test_0e() { # LU-13417
250         (( $MDSCOUNT > 1 )) ||
251                 skip "We need at least 2 MDTs for this test"
252
253         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
254                 skip "Need server version at least 2.14.51"
255
256         local default_lmv_count=$($LFS getdirstripe -D -c $MOUNT)
257         local default_lmv_index=$($LFS getdirstripe -D -i $MOUNT)
258
259         [ $default_lmv_count -eq 1 ] ||
260                 error "$MOUNT default stripe count $default_lmv_count"
261
262         [ $default_lmv_index -eq -1 ] ||
263                 error "$MOUNT default stripe index $default_lmv_index"
264
265         mkdir $MOUNT/$tdir.1 || error "mkdir $MOUNT/$tdir.1 failed"
266         mkdir $MOUNT/$tdir.2 || error "mkdir $MOUNT/$tdir.2 failed"
267
268         local mdt_index1=$($LFS getdirstripe -i $MOUNT/$tdir.1)
269         local mdt_index2=$($LFS getdirstripe -i $MOUNT/$tdir.2)
270
271         [ $mdt_index1 -eq $mdt_index2 ] &&
272                 error "directories are on the same MDT $mdt_index1=$mdt_index2"
273
274         rmdir $MOUNT/$tdir.1 $MOUNT/$tdir.2
275 }
276 run_test 0e "Enable DNE MDT balancing for mkdir in the ROOT"
277
278 test_1() {
279         test_mkdir $DIR/$tdir
280         test_mkdir $DIR/$tdir/d2
281         mkdir $DIR/$tdir/d2 && error "we expect EEXIST, but not returned"
282         $CHECKSTAT -t dir $DIR/$tdir/d2 || error "$tdir/d2 is not a dir"
283         rmdir $DIR/$tdir/d2
284         rmdir $DIR/$tdir
285         $CHECKSTAT -a $DIR/$tdir || error "$tdir was not removed"
286 }
287 run_test 1 "mkdir; remkdir; rmdir"
288
289 test_2() {
290         test_mkdir $DIR/$tdir
291         touch $DIR/$tdir/$tfile || error "touch $tdir/$tfile failed"
292         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "$tdir/$tfile not a file"
293         rm -r $DIR/$tdir
294         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$file is not removed"
295 }
296 run_test 2 "mkdir; touch; rmdir; check file"
297
298 test_3() {
299         test_mkdir $DIR/$tdir
300         $CHECKSTAT -t dir $DIR/$tdir || error "$tdir is not a directory"
301         touch $DIR/$tdir/$tfile
302         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "$tdir/$tfile not a file"
303         rm -r $DIR/$tdir
304         $CHECKSTAT -a $DIR/$tdir || error "$tdir is not removed"
305 }
306 run_test 3 "mkdir; touch; rmdir; check dir"
307
308 # LU-4471 - failed rmdir on remote directories still removes directory on MDT0
309 test_4() {
310         test_mkdir -i 1 $DIR/$tdir
311
312         touch $DIR/$tdir/$tfile ||
313                 error "Create file under remote directory failed"
314
315         rmdir $DIR/$tdir &&
316                 error "Expect error removing in-use dir $DIR/$tdir"
317
318         test -d $DIR/$tdir || error "Remote directory disappeared"
319
320         rm -rf $DIR/$tdir || error "remove remote dir error"
321 }
322 run_test 4 "mkdir; touch dir/file; rmdir; checkdir (expect error)"
323
324 test_5() {
325         test_mkdir $DIR/$tdir
326         test_mkdir $DIR/$tdir/d2
327         chmod 0707 $DIR/$tdir/d2 || error "chmod 0707 $tdir/d2 failed"
328         $CHECKSTAT -t dir -p 0707 $DIR/$tdir/d2 || error "$tdir/d2 not mode 707"
329         $CHECKSTAT -t dir $DIR/$tdir/d2 || error "$tdir/d2 is not a directory"
330 }
331 run_test 5 "mkdir .../d5 .../d5/d2; chmod .../d5/d2"
332
333 test_6a() {
334         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
335         chmod 0666 $DIR/$tfile || error "chmod 0666 $tfile failed"
336         $CHECKSTAT -t file -p 0666 -u \#$UID $DIR/$tfile ||
337                 error "$tfile does not have perm 0666 or UID $UID"
338         $RUNAS chmod 0444 $DIR/$tfile && error "chmod $tfile worked on UID $UID"
339         $CHECKSTAT -t file -p 0666 -u \#$UID $DIR/$tfile ||
340                 error "$tfile should be 0666 and owned by UID $UID"
341 }
342 run_test 6a "touch f6a; chmod f6a; $RUNAS chmod f6a (should return error) =="
343
344 test_6c() {
345         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
346
347         touch $DIR/$tfile
348         chown $RUNAS_ID $DIR/$tfile || error "chown $RUNAS_ID $file failed"
349         $CHECKSTAT -t file -u \#$RUNAS_ID $DIR/$tfile ||
350                 error "$tfile should be owned by UID $RUNAS_ID"
351         $RUNAS chown $UID $DIR/$tfile && error "chown $UID $file succeeded"
352         $CHECKSTAT -t file -u \#$RUNAS_ID $DIR/$tfile ||
353                 error "$tfile should be owned by UID $RUNAS_ID"
354 }
355 run_test 6c "touch f6c; chown f6c; $RUNAS chown f6c (should return error) =="
356
357 test_6e() {
358         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
359
360         touch $DIR/$tfile
361         chgrp $RUNAS_ID $DIR/$tfile || error "chgrp $RUNAS_ID $file failed"
362         $CHECKSTAT -t file -u \#$UID -g \#$RUNAS_ID $DIR/$tfile ||
363                 error "$tfile should be owned by GID $UID"
364         $RUNAS chgrp $UID $DIR/$tfile && error "chgrp $UID $file succeeded"
365         $CHECKSTAT -t file -u \#$UID -g \#$RUNAS_ID $DIR/$tfile ||
366                 error "$tfile should be owned by UID $UID and GID $RUNAS_ID"
367 }
368 run_test 6e "touch+chgrp $tfile; $RUNAS chgrp $tfile (should return error)"
369
370 test_6g() {
371         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
372
373         test_mkdir $DIR/$tdir
374         chmod 777 $DIR/$tdir || error "chmod 0777 $tdir failed"
375         $RUNAS mkdir $DIR/$tdir/d || error "mkdir $tdir/d failed"
376         chmod g+s $DIR/$tdir/d || error "chmod g+s $tdir/d failed"
377         test_mkdir $DIR/$tdir/d/subdir
378         $CHECKSTAT -g \#$RUNAS_GID $DIR/$tdir/d/subdir ||
379                 error "$tdir/d/subdir should be GID $RUNAS_GID"
380         if [[ $MDSCOUNT -gt 1 ]]; then
381                 # check remote dir sgid inherite
382                 $LFS mkdir -i 0 $DIR/$tdir.local ||
383                         error "mkdir $tdir.local failed"
384                 chmod g+s $DIR/$tdir.local ||
385                         error "chmod $tdir.local failed"
386                 chgrp $RUNAS_GID $DIR/$tdir.local ||
387                         error "chgrp $tdir.local failed"
388                 $LFS mkdir -i 1 $DIR/$tdir.local/$tdir.remote ||
389                         error "mkdir $tdir.remote failed"
390                 $CHECKSTAT -g \#$RUNAS_GID $DIR/$tdir.local/$tdir.remote ||
391                         error "$tdir.remote should be owned by $UID.$RUNAS_ID"
392                 $CHECKSTAT -p 02755 $DIR/$tdir.local/$tdir.remote ||
393                         error "$tdir.remote should be mode 02755"
394         fi
395 }
396 run_test 6g "verify new dir in sgid dir inherits group"
397
398 test_6h() { # bug 7331
399         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
400
401         touch $DIR/$tfile || error "touch failed"
402         chown $RUNAS_ID:$RUNAS_GID $DIR/$tfile || error "initial chown failed"
403         $RUNAS -G$RUNAS_GID chown $RUNAS_ID:0 $DIR/$tfile &&
404                 error "chown $RUNAS_ID:0 $tfile worked as GID $RUNAS_GID"
405         $CHECKSTAT -t file -u \#$RUNAS_ID -g \#$RUNAS_GID $DIR/$tfile ||
406                 error "$tdir/$tfile should be UID $RUNAS_UID GID $RUNAS_GID"
407 }
408 run_test 6h "$RUNAS chown RUNAS_ID.0 .../$tfile (should return error)"
409
410 test_7a() {
411         test_mkdir $DIR/$tdir
412         $MCREATE $DIR/$tdir/$tfile
413         chmod 0666 $DIR/$tdir/$tfile
414         $CHECKSTAT -t file -p 0666 $DIR/$tdir/$tfile ||
415                 error "$tdir/$tfile should be mode 0666"
416 }
417 run_test 7a "mkdir .../d7; mcreate .../d7/f; chmod .../d7/f ===="
418
419 test_7b() {
420         if [ ! -d $DIR/$tdir ]; then
421                 test_mkdir $DIR/$tdir
422         fi
423         $MCREATE $DIR/$tdir/$tfile
424         echo -n foo > $DIR/$tdir/$tfile
425         [ "$(cat $DIR/$tdir/$tfile)" = "foo" ] || error "$tdir/$tfile not 'foo'"
426         $CHECKSTAT -t file -s 3 $DIR/$tdir/$tfile || error "$tfile size not 3"
427 }
428 run_test 7b "mkdir .../d7; mcreate d7/f2; echo foo > d7/f2 ====="
429
430 test_8() {
431         test_mkdir $DIR/$tdir
432         touch $DIR/$tdir/$tfile
433         chmod 0666 $DIR/$tdir/$tfile
434         $CHECKSTAT -t file -p 0666 $DIR/$tdir/$tfile ||
435                 error "$tfile mode not 0666"
436 }
437 run_test 8 "mkdir .../d8; touch .../d8/f; chmod .../d8/f ======="
438
439 test_9() {
440         test_mkdir $DIR/$tdir
441         test_mkdir $DIR/$tdir/d2
442         test_mkdir $DIR/$tdir/d2/d3
443         $CHECKSTAT -t dir $DIR/$tdir/d2/d3 || error "$tdir/d2/d3 not a dir"
444 }
445 run_test 9 "mkdir .../d9 .../d9/d2 .../d9/d2/d3 ================"
446
447 test_10() {
448         test_mkdir $DIR/$tdir
449         test_mkdir $DIR/$tdir/d2
450         touch $DIR/$tdir/d2/$tfile
451         $CHECKSTAT -t file $DIR/$tdir/d2/$tfile ||
452                 error "$tdir/d2/$tfile not a file"
453 }
454 run_test 10 "mkdir .../d10 .../d10/d2; touch .../d10/d2/f ======"
455
456 test_11() {
457         test_mkdir $DIR/$tdir
458         test_mkdir $DIR/$tdir/d2
459         chmod 0666 $DIR/$tdir/d2
460         chmod 0705 $DIR/$tdir/d2
461         $CHECKSTAT -t dir -p 0705 $DIR/$tdir/d2 ||
462                 error "$tdir/d2 mode not 0705"
463 }
464 run_test 11 "mkdir .../d11 d11/d2; chmod .../d11/d2 ============"
465
466 test_12() {
467         test_mkdir $DIR/$tdir
468         touch $DIR/$tdir/$tfile
469         chmod 0666 $DIR/$tdir/$tfile
470         chmod 0654 $DIR/$tdir/$tfile
471         $CHECKSTAT -t file -p 0654 $DIR/$tdir/$tfile ||
472                 error "$tdir/d2 mode not 0654"
473 }
474 run_test 12 "touch .../d12/f; chmod .../d12/f .../d12/f ========"
475
476 test_13() {
477         test_mkdir $DIR/$tdir
478         dd if=/dev/zero of=$DIR/$tdir/$tfile count=10
479         >  $DIR/$tdir/$tfile
480         $CHECKSTAT -t file -s 0 $DIR/$tdir/$tfile ||
481                 error "$tdir/$tfile size not 0 after truncate"
482 }
483 run_test 13 "creat .../d13/f; dd .../d13/f; > .../d13/f ========"
484
485 test_14() {
486         test_mkdir $DIR/$tdir
487         touch $DIR/$tdir/$tfile
488         rm $DIR/$tdir/$tfile
489         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$tfile not removed"
490 }
491 run_test 14 "touch .../d14/f; rm .../d14/f; rm .../d14/f ======="
492
493 test_15() {
494         test_mkdir $DIR/$tdir
495         touch $DIR/$tdir/$tfile
496         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}_2
497         $CHECKSTAT -t file $DIR/$tdir/${tfile}_2 ||
498                 error "$tdir/${tfile_2} not a file after rename"
499         rm $DIR/$tdir/${tfile}_2 || error "unlink failed after rename"
500 }
501 run_test 15 "touch .../d15/f; mv .../d15/f .../d15/f2 =========="
502
503 test_16() {
504         test_mkdir $DIR/$tdir
505         touch $DIR/$tdir/$tfile
506         rm -rf $DIR/$tdir/$tfile
507         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$tfile not removed"
508 }
509 run_test 16 "touch .../d16/f; rm -rf .../d16/f"
510
511 test_17a() {
512         test_mkdir $DIR/$tdir
513         touch $DIR/$tdir/$tfile
514         ln -s $DIR/$tdir/$tfile $DIR/$tdir/l-exist
515         ls -l $DIR/$tdir
516         $CHECKSTAT -l $DIR/$tdir/$tfile $DIR/$tdir/l-exist ||
517                 error "$tdir/l-exist not a symlink"
518         $CHECKSTAT -f -t f $DIR/$tdir/l-exist ||
519                 error "$tdir/l-exist not referencing a file"
520         rm -f $DIR/$tdir/l-exist
521         $CHECKSTAT -a $DIR/$tdir/l-exist || error "$tdir/l-exist not removed"
522 }
523 run_test 17a "symlinks: create, remove (real)"
524
525 test_17b() {
526         test_mkdir $DIR/$tdir
527         ln -s no-such-file $DIR/$tdir/l-dangle
528         ls -l $DIR/$tdir
529         $CHECKSTAT -l no-such-file $DIR/$tdir/l-dangle ||
530                 error "$tdir/l-dangle not referencing no-such-file"
531         $CHECKSTAT -fa $DIR/$tdir/l-dangle ||
532                 error "$tdir/l-dangle not referencing non-existent file"
533         rm -f $DIR/$tdir/l-dangle
534         $CHECKSTAT -a $DIR/$tdir/l-dangle || error "$tdir/l-dangle not removed"
535 }
536 run_test 17b "symlinks: create, remove (dangling)"
537
538 test_17c() { # bug 3440 - don't save failed open RPC for replay
539         test_mkdir $DIR/$tdir
540         ln -s foo $DIR/$tdir/$tfile
541         cat $DIR/$tdir/$tfile && error "opened non-existent symlink" || true
542 }
543 run_test 17c "symlinks: open dangling (should return error)"
544
545 test_17d() {
546         test_mkdir $DIR/$tdir
547         ln -s foo $DIR/$tdir/$tfile
548         touch $DIR/$tdir/$tfile || error "creating to new symlink"
549 }
550 run_test 17d "symlinks: create dangling"
551
552 test_17e() {
553         test_mkdir $DIR/$tdir
554         local foo=$DIR/$tdir/$tfile
555         ln -s $foo $foo || error "create symlink failed"
556         ls -l $foo || error "ls -l failed"
557         ls $foo && error "ls not failed" || true
558 }
559 run_test 17e "symlinks: create recursive symlink (should return error)"
560
561 test_17f() {
562         test_mkdir $DIR/$tdir
563         ln -s 1234567890/2234567890/3234567890/4234567890 $DIR/$tdir/111
564         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890 $DIR/$tdir/222
565         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890 $DIR/$tdir/333
566         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890 $DIR/$tdir/444
567         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890/c234567890/d234567890/f234567890 $DIR/$tdir/555
568         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890/c234567890/d234567890/f234567890/aaaaaaaaaa/bbbbbbbbbb/cccccccccc/dddddddddd/eeeeeeeeee/ffffffffff/ $DIR/$tdir/666
569         ls -l  $DIR/$tdir
570 }
571 run_test 17f "symlinks: long and very long symlink name"
572
573 # str_repeat(S, N) generate a string that is string S repeated N times
574 str_repeat() {
575         local s=$1
576         local n=$2
577         local ret=''
578         while [ $((n -= 1)) -ge 0 ]; do
579                 ret=$ret$s
580         done
581         echo $ret
582 }
583
584 # Long symlinks and LU-2241
585 test_17g() {
586         test_mkdir $DIR/$tdir
587         local TESTS="59 60 61 4094 4095"
588
589         # Fix for inode size boundary in 2.1.4
590         [ $MDS1_VERSION -lt $(version_code 2.1.4) ] &&
591                 TESTS="4094 4095"
592
593         # Patch not applied to 2.2 or 2.3 branches
594         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
595         [ $MDS1_VERSION -le $(version_code 2.3.55) ] &&
596                 TESTS="4094 4095"
597
598         for i in $TESTS; do
599                 local SYMNAME=$(str_repeat 'x' $i)
600                 ln -s $SYMNAME $DIR/$tdir/f$i || error "failed $i-char symlink"
601                 readlink $DIR/$tdir/f$i || error "failed $i-char readlink"
602         done
603 }
604 run_test 17g "symlinks: really long symlink name and inode boundaries"
605
606 test_17h() { #bug 17378
607         [ $PARALLEL == "yes" ] && skip "skip parallel run"
608         remote_mds_nodsh && skip "remote MDS with nodsh"
609
610         local mdt_idx
611
612         test_mkdir $DIR/$tdir
613         mdt_idx=$($LFS getdirstripe -i $DIR/$tdir)
614         $LFS setstripe -c -1 $DIR/$tdir
615         #define OBD_FAIL_MDS_LOV_PREP_CREATE 0x141
616         do_facet mds$((mdt_idx + 1)) lctl set_param fail_loc=0x80000141
617         touch $DIR/$tdir/$tfile || true
618 }
619 run_test 17h "create objects: lov_free_memmd() doesn't lbug"
620
621 test_17i() { #bug 20018
622         [ $PARALLEL == "yes" ] && skip "skip parallel run"
623         remote_mds_nodsh && skip "remote MDS with nodsh"
624
625         local foo=$DIR/$tdir/$tfile
626         local mdt_idx
627
628         test_mkdir -c1 $DIR/$tdir
629         mdt_idx=$($LFS getdirstripe -i $DIR/$tdir)
630         ln -s $foo $foo || error "create symlink failed"
631 #define OBD_FAIL_MDS_READLINK_EPROTO     0x143
632         do_facet mds$((mdt_idx + 1)) lctl set_param fail_loc=0x80000143
633         ls -l $foo && error "error not detected"
634         return 0
635 }
636 run_test 17i "don't panic on short symlink (should return error)"
637
638 test_17k() { #bug 22301
639         [ $PARALLEL == "yes" ] && skip "skip parallel run"
640         [[ -z "$(which rsync 2>/dev/null)" ]] &&
641                 skip "no rsync command"
642         rsync --help | grep -q xattr ||
643                 skip_env "$(rsync --version | head -n1) does not support xattrs"
644         test_mkdir $DIR/$tdir
645         test_mkdir $DIR/$tdir.new
646         touch $DIR/$tdir/$tfile
647         ln -s $DIR/$tdir/$tfile $DIR/$tdir/$tfile.lnk
648         rsync -av -X $DIR/$tdir/ $DIR/$tdir.new ||
649                 error "rsync failed with xattrs enabled"
650 }
651 run_test 17k "symlinks: rsync with xattrs enabled"
652
653 test_17l() { # LU-279
654         [[ -z "$(which getfattr 2>/dev/null)" ]] &&
655                 skip "no getfattr command"
656
657         test_mkdir $DIR/$tdir
658         touch $DIR/$tdir/$tfile
659         ln -s $DIR/$tdir/$tfile $DIR/$tdir/$tfile.lnk
660         for path in "$DIR/$tdir" "$DIR/$tdir/$tfile" "$DIR/$tdir/$tfile.lnk"; do
661                 # -h to not follow symlinks. -m '' to list all the xattrs.
662                 # grep to remove first line: '# file: $path'.
663                 for xattr in `getfattr -hm '' $path 2>/dev/null | grep -v '^#'`;
664                 do
665                         lgetxattr_size_check $path $xattr ||
666                                 error "lgetxattr_size_check $path $xattr failed"
667                 done
668         done
669 }
670 run_test 17l "Ensure lgetxattr's returned xattr size is consistent"
671
672 # LU-1540
673 test_17m() {
674         [ $PARALLEL == "yes" ] && skip "skip parallel run"
675         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
676         remote_mds_nodsh && skip "remote MDS with nodsh"
677         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
678         [ $MDS1_VERSION -le $(version_code 2.2.93) ] &&
679                 skip "MDS 2.2.0-2.2.93 do not NUL-terminate symlinks"
680
681         local short_sym="0123456789"
682         local wdir=$DIR/$tdir
683         local i
684
685         test_mkdir $wdir
686         long_sym=$short_sym
687         # create a long symlink file
688         for ((i = 0; i < 4; ++i)); do
689                 long_sym=${long_sym}${long_sym}
690         done
691
692         echo "create 512 short and long symlink files under $wdir"
693         for ((i = 0; i < 256; ++i)); do
694                 ln -sf ${long_sym}"a5a5" $wdir/long-$i
695                 ln -sf ${short_sym}"a5a5" $wdir/short-$i
696         done
697
698         echo "erase them"
699         rm -f $wdir/*
700         sync
701         wait_delete_completed
702
703         echo "recreate the 512 symlink files with a shorter string"
704         for ((i = 0; i < 512; ++i)); do
705                 # rewrite the symlink file with a shorter string
706                 ln -sf ${long_sym} $wdir/long-$i || error "long_sym failed"
707                 ln -sf ${short_sym} $wdir/short-$i || error "short_sym failed"
708         done
709
710         local mds_index=$(($($LFS getstripe -m $wdir) + 1))
711
712         echo "stop and checking mds${mds_index}:"
713         # e2fsck should not return error
714         stop mds${mds_index}
715         local devname=$(mdsdevname $mds_index)
716         run_e2fsck $(facet_active_host mds${mds_index}) $devname -n
717         rc=$?
718
719         start mds${mds_index} $devname $MDS_MOUNT_OPTS ||
720                 error "start mds${mds_index} failed"
721         df $MOUNT > /dev/null 2>&1
722         [ $rc -eq 0 ] ||
723                 error "e2fsck detected error for short/long symlink: rc=$rc"
724         rm -f $wdir/*
725 }
726 run_test 17m "run e2fsck against MDT which contains short/long symlink"
727
728 check_fs_consistency_17n() {
729         local mdt_index
730         local rc=0
731
732         # create/unlink in 17n only change 2 MDTs(MDT1/MDT2),
733         # so it only check MDT1/MDT2 instead of all of MDTs.
734         for mdt_index in 1 2; do
735                 # e2fsck should not return error
736                 stop mds${mdt_index}
737                 local devname=$(mdsdevname $mdt_index)
738                 run_e2fsck $(facet_active_host mds$mdt_index) $devname -n ||
739                         rc=$((rc + $?))
740
741                 start mds${mdt_index} $devname $MDS_MOUNT_OPTS ||
742                         error "mount mds$mdt_index failed"
743                 df $MOUNT > /dev/null 2>&1
744         done
745         return $rc
746 }
747
748 test_17n() {
749         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
750         [ $PARALLEL == "yes" ] && skip "skip parallel run"
751         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
752         remote_mds_nodsh && skip "remote MDS with nodsh"
753         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
754         [ $MDS1_VERSION -le $(version_code 2.2.93) ] &&
755                 skip "MDS 2.2.0-2.2.93 do not NUL-terminate symlinks"
756
757         local i
758
759         test_mkdir $DIR/$tdir
760         for ((i=0; i<10; i++)); do
761                 $LFS mkdir -i1 -c2 $DIR/$tdir/remote_dir_${i} ||
762                         error "create remote dir error $i"
763                 createmany -o $DIR/$tdir/remote_dir_${i}/f 10 ||
764                         error "create files under remote dir failed $i"
765         done
766
767         check_fs_consistency_17n ||
768                 error "e2fsck report error after create files under remote dir"
769
770         for ((i = 0; i < 10; i++)); do
771                 rm -rf $DIR/$tdir/remote_dir_${i} ||
772                         error "destroy remote dir error $i"
773         done
774
775         check_fs_consistency_17n ||
776                 error "e2fsck report error after unlink files under remote dir"
777
778         [ $MDS1_VERSION -lt $(version_code 2.4.50) ] &&
779                 skip "lustre < 2.4.50 does not support migrate mv"
780
781         for ((i = 0; i < 10; i++)); do
782                 mkdir -p $DIR/$tdir/remote_dir_${i}
783                 createmany -o $DIR/$tdir/remote_dir_${i}/f 10 ||
784                         error "create files under remote dir failed $i"
785                 $LFS migrate --mdt-index 1 $DIR/$tdir/remote_dir_${i} ||
786                         error "migrate remote dir error $i"
787         done
788         check_fs_consistency_17n || error "e2fsck report error after migration"
789
790         for ((i = 0; i < 10; i++)); do
791                 rm -rf $DIR/$tdir/remote_dir_${i} ||
792                         error "destroy remote dir error $i"
793         done
794
795         check_fs_consistency_17n || error "e2fsck report error after unlink"
796 }
797 run_test 17n "run e2fsck against master/slave MDT which contains remote dir"
798
799 test_17o() {
800         remote_mds_nodsh && skip "remote MDS with nodsh"
801         [ $MDS1_VERSION -lt $(version_code 2.3.64) ] &&
802                 skip "Need MDS version at least 2.3.64"
803
804         local wdir=$DIR/${tdir}o
805         local mdt_index
806         local rc=0
807
808         test_mkdir $wdir
809         touch $wdir/$tfile
810         mdt_index=$($LFS getstripe -m $wdir/$tfile)
811         mdt_index=$((mdt_index + 1))
812
813         cancel_lru_locks mdc
814         #fail mds will wait the failover finish then set
815         #following fail_loc to avoid interfer the recovery process.
816         fail mds${mdt_index}
817
818         #define OBD_FAIL_OSD_LMA_INCOMPAT 0x194
819         do_facet mds${mdt_index} lctl set_param fail_loc=0x194
820         ls -l $wdir/$tfile && rc=1
821         do_facet mds${mdt_index} lctl set_param fail_loc=0
822         [[ $rc -eq 0 ]] || error "stat file should fail"
823 }
824 run_test 17o "stat file with incompat LMA feature"
825
826 test_18() {
827         touch $DIR/$tfile || error "Failed to touch $DIR/$tfile: $?"
828         ls $DIR || error "Failed to ls $DIR: $?"
829 }
830 run_test 18 "touch .../f ; ls ... =============================="
831
832 test_19a() {
833         touch $DIR/$tfile
834         ls -l $DIR
835         rm $DIR/$tfile
836         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
837 }
838 run_test 19a "touch .../f19 ; ls -l ... ; rm .../f19 ==========="
839
840 test_19b() {
841         ls -l $DIR/$tfile && error "ls -l $tfile failed"|| true
842 }
843 run_test 19b "ls -l .../f19 (should return error) =============="
844
845 test_19c() {
846         [ $RUNAS_ID -eq $UID ] &&
847                 skip_env "RUNAS_ID = UID = $UID -- skipping"
848
849         $RUNAS touch $DIR/$tfile && error "create non-root file failed" || true
850 }
851 run_test 19c "$RUNAS touch .../f19 (should return error) =="
852
853 test_19d() {
854         cat $DIR/f19 && error || true
855 }
856 run_test 19d "cat .../f19 (should return error) =============="
857
858 test_20() {
859         touch $DIR/$tfile
860         rm $DIR/$tfile
861         touch $DIR/$tfile
862         rm $DIR/$tfile
863         touch $DIR/$tfile
864         rm $DIR/$tfile
865         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
866 }
867 run_test 20 "touch .../f ; ls -l ..."
868
869 test_21() {
870         test_mkdir $DIR/$tdir
871         [ -f $DIR/$tdir/dangle ] && rm -f $DIR/$tdir/dangle
872         ln -s dangle $DIR/$tdir/link
873         echo foo >> $DIR/$tdir/link
874         cat $DIR/$tdir/dangle
875         $CHECKSTAT -t link $DIR/$tdir/link || error "$tdir/link not a link"
876         $CHECKSTAT -f -t file $DIR/$tdir/link ||
877                 error "$tdir/link not linked to a file"
878 }
879 run_test 21 "write to dangling link"
880
881 test_22() {
882         local wdir=$DIR/$tdir
883         test_mkdir $wdir
884         chown $RUNAS_ID:$RUNAS_GID $wdir
885         (cd $wdir || error "cd $wdir failed";
886                 $RUNAS tar cf - /etc/hosts /etc/sysconfig/network |
887                 $RUNAS tar xf -)
888         ls -lR $wdir/etc || error "ls -lR $wdir/etc failed"
889         $CHECKSTAT -t dir $wdir/etc || error "checkstat -t dir failed"
890         $CHECKSTAT -u \#$RUNAS_ID -g \#$RUNAS_GID $wdir/etc ||
891                 error "checkstat -u failed"
892 }
893 run_test 22 "unpack tar archive as non-root user"
894
895 # was test_23
896 test_23a() {
897         test_mkdir $DIR/$tdir
898         local file=$DIR/$tdir/$tfile
899
900         openfile -f O_CREAT:O_EXCL $file || error "$file create failed"
901         openfile -f O_CREAT:O_EXCL $file &&
902                 error "$file recreate succeeded" || true
903 }
904 run_test 23a "O_CREAT|O_EXCL in subdir"
905
906 test_23b() { # bug 18988
907         test_mkdir $DIR/$tdir
908         local file=$DIR/$tdir/$tfile
909
910         rm -f $file
911         echo foo > $file || error "write filed"
912         echo bar >> $file || error "append filed"
913         $CHECKSTAT -s 8 $file || error "wrong size"
914         rm $file
915 }
916 run_test 23b "O_APPEND check"
917
918 # LU-9409, size with O_APPEND and tiny writes
919 test_23c() {
920         local file=$DIR/$tfile
921
922         # single dd
923         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800
924         $CHECKSTAT -s 6400 $file || error "wrong size, expected 6400"
925         rm -f $file
926
927         # racing tiny writes
928         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800 &
929         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800 &
930         wait
931         $CHECKSTAT -s 12800 $file || error "wrong size, expected 12800"
932         rm -f $file
933
934         #racing tiny & normal writes
935         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=4096 count=4 &
936         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=100 &
937         wait
938         $CHECKSTAT -s 17184 $file || error "wrong size, expected 17184"
939         rm -f $file
940
941         #racing tiny & normal writes 2, ugly numbers
942         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=4099 count=11 &
943         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=17 count=173 &
944         wait
945         $CHECKSTAT -s 48030 $file || error "wrong size, expected 48030"
946         rm -f $file
947 }
948 run_test 23c "O_APPEND size checks for tiny writes"
949
950 # LU-11069 file offset is correct after appending writes
951 test_23d() {
952         local file=$DIR/$tfile
953         local offset
954
955         echo CentaurHauls > $file
956         offset=$($MULTIOP $file oO_WRONLY:O_APPEND:w13Zp)
957         if ((offset != 26)); then
958                 error "wrong offset, expected 26, got '$offset'"
959         fi
960 }
961 run_test 23d "file offset is correct after appending writes"
962
963 # rename sanity
964 test_24a() {
965         echo '-- same directory rename'
966         test_mkdir $DIR/$tdir
967         touch $DIR/$tdir/$tfile.1
968         mv $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
969         $CHECKSTAT -t file $DIR/$tdir/$tfile.2 || error "$tfile.2 not a file"
970 }
971 run_test 24a "rename file to non-existent target"
972
973 test_24b() {
974         test_mkdir $DIR/$tdir
975         touch $DIR/$tdir/$tfile.{1,2}
976         mv $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
977         $CHECKSTAT -a $DIR/$tdir/$tfile.1 || error "$tfile.1 exists"
978         $CHECKSTAT -t file $DIR/$tdir/$tfile.2 || error "$tfile.2 not a file"
979 }
980 run_test 24b "rename file to existing target"
981
982 test_24c() {
983         test_mkdir $DIR/$tdir
984         test_mkdir $DIR/$tdir/d$testnum.1
985         mv $DIR/$tdir/d$testnum.1 $DIR/$tdir/d$testnum.2
986         $CHECKSTAT -a $DIR/$tdir/d$testnum.1 || error "d$testnum.1 exists"
987         $CHECKSTAT -t dir $DIR/$tdir/d$testnum.2 || error "d$testnum.2 not dir"
988 }
989 run_test 24c "rename directory to non-existent target"
990
991 test_24d() {
992         test_mkdir -c1 $DIR/$tdir
993         test_mkdir -c1 $DIR/$tdir/d$testnum.1
994         test_mkdir -c1 $DIR/$tdir/d$testnum.2
995         mrename $DIR/$tdir/d$testnum.1 $DIR/$tdir/d$testnum.2
996         $CHECKSTAT -a $DIR/$tdir/d$testnum.1 || error "d$testnum.1 exists"
997         $CHECKSTAT -t dir $DIR/$tdir/d$testnum.2 || error "d$testnum.2 not dir"
998 }
999 run_test 24d "rename directory to existing target"
1000
1001 test_24e() {
1002         echo '-- cross directory renames --'
1003         test_mkdir $DIR/R5a
1004         test_mkdir $DIR/R5b
1005         touch $DIR/R5a/f
1006         mv $DIR/R5a/f $DIR/R5b/g
1007         $CHECKSTAT -a $DIR/R5a/f || error "$DIR/R5a/f exists"
1008         $CHECKSTAT -t file $DIR/R5b/g || error "$DIR/R5b/g not file type"
1009 }
1010 run_test 24e "touch .../R5a/f; rename .../R5a/f .../R5b/g ======"
1011
1012 test_24f() {
1013         test_mkdir $DIR/R6a
1014         test_mkdir $DIR/R6b
1015         touch $DIR/R6a/f $DIR/R6b/g
1016         mv $DIR/R6a/f $DIR/R6b/g
1017         $CHECKSTAT -a $DIR/R6a/f || error "$DIR/R6a/f exists"
1018         $CHECKSTAT -t file $DIR/R6b/g || error "$DIR/R6b/g not file type"
1019 }
1020 run_test 24f "touch .../R6a/f R6b/g; mv .../R6a/f .../R6b/g ===="
1021
1022 test_24g() {
1023         test_mkdir $DIR/R7a
1024         test_mkdir $DIR/R7b
1025         test_mkdir $DIR/R7a/d
1026         mv $DIR/R7a/d $DIR/R7b/e
1027         $CHECKSTAT -a $DIR/R7a/d || error "$DIR/R7a/d exists"
1028         $CHECKSTAT -t dir $DIR/R7b/e || error "$DIR/R7b/e not dir type"
1029 }
1030 run_test 24g "mkdir .../R7{a,b}/d; mv .../R7a/d .../R7b/e ======"
1031
1032 test_24h() {
1033         test_mkdir -c1 $DIR/R8a
1034         test_mkdir -c1 $DIR/R8b
1035         test_mkdir -c1 $DIR/R8a/d
1036         test_mkdir -c1 $DIR/R8b/e
1037         mrename $DIR/R8a/d $DIR/R8b/e
1038         $CHECKSTAT -a $DIR/R8a/d || error "$DIR/R8a/d exists"
1039         $CHECKSTAT -t dir $DIR/R8b/e || error "$DIR/R8b/e not dir type"
1040 }
1041 run_test 24h "mkdir .../R8{a,b}/{d,e}; rename .../R8a/d .../R8b/e"
1042
1043 test_24i() {
1044         echo "-- rename error cases"
1045         test_mkdir $DIR/R9
1046         test_mkdir $DIR/R9/a
1047         touch $DIR/R9/f
1048         mrename $DIR/R9/f $DIR/R9/a
1049         $CHECKSTAT -t file $DIR/R9/f || error "$DIR/R9/f not file type"
1050         $CHECKSTAT -t dir  $DIR/R9/a || error "$DIR/R9/a not dir type"
1051         $CHECKSTAT -a $DIR/R9/a/f || error "$DIR/R9/a/f exists"
1052 }
1053 run_test 24i "rename file to dir error: touch f ; mkdir a ; rename f a"
1054
1055 test_24j() {
1056         test_mkdir $DIR/R10
1057         mrename $DIR/R10/f $DIR/R10/g
1058         $CHECKSTAT -t dir $DIR/R10 || error "$DIR/R10 not dir type"
1059         $CHECKSTAT -a $DIR/R10/f || error "$DIR/R10/f exists"
1060         $CHECKSTAT -a $DIR/R10/g || error "$DIR/R10/g exists"
1061 }
1062 run_test 24j "source does not exist ============================"
1063
1064 test_24k() {
1065         test_mkdir $DIR/R11a
1066         test_mkdir $DIR/R11a/d
1067         touch $DIR/R11a/f
1068         mv $DIR/R11a/f $DIR/R11a/d
1069         $CHECKSTAT -a $DIR/R11a/f || error "$DIR/R11a/f exists"
1070         $CHECKSTAT -t file $DIR/R11a/d/f || error "$DIR/R11a/d/f not file type"
1071 }
1072 run_test 24k "touch .../R11a/f; mv .../R11a/f .../R11a/d ======="
1073
1074 # bug 2429 - rename foo foo foo creates invalid file
1075 test_24l() {
1076         f="$DIR/f24l"
1077         $MULTIOP $f OcNs || error "rename of ${f} to itself failed"
1078 }
1079 run_test 24l "Renaming a file to itself ========================"
1080
1081 test_24m() {
1082         f="$DIR/f24m"
1083         $MULTIOP $f OcLN ${f}2 ${f}2 || error "link ${f}2 ${f}2 failed"
1084         # on ext3 this does not remove either the source or target files
1085         # though the "expected" operation would be to remove the source
1086         $CHECKSTAT -t file ${f} || error "${f} missing"
1087         $CHECKSTAT -t file ${f}2 || error "${f}2 missing"
1088 }
1089 run_test 24m "Renaming a file to a hard link to itself ========="
1090
1091 test_24n() {
1092     f="$DIR/f24n"
1093     # this stats the old file after it was renamed, so it should fail
1094     touch ${f}
1095     $CHECKSTAT ${f} || error "${f} missing"
1096     mv ${f} ${f}.rename
1097     $CHECKSTAT ${f}.rename || error "${f}.rename missing"
1098     $CHECKSTAT -a ${f} || error "${f} exists"
1099 }
1100 run_test 24n "Statting the old file after renaming (Posix rename 2)"
1101
1102 test_24o() {
1103         test_mkdir $DIR/$tdir
1104         rename_many -s random -v -n 10 $DIR/$tdir
1105 }
1106 run_test 24o "rename of files during htree split"
1107
1108 test_24p() {
1109         test_mkdir $DIR/R12a
1110         test_mkdir $DIR/R12b
1111         DIRINO=`ls -lid $DIR/R12a | awk '{ print $1 }'`
1112         mrename $DIR/R12a $DIR/R12b
1113         $CHECKSTAT -a $DIR/R12a || error "$DIR/R12a exists"
1114         $CHECKSTAT -t dir $DIR/R12b || error "$DIR/R12b not dir type"
1115         DIRINO2=`ls -lid $DIR/R12b | awk '{ print $1 }'`
1116         [ "$DIRINO" = "$DIRINO2" ] || error "R12a $DIRINO != R12b $DIRINO2"
1117 }
1118 run_test 24p "mkdir .../R12{a,b}; rename .../R12a .../R12b"
1119
1120 cleanup_multiop_pause() {
1121         trap 0
1122         kill -USR1 $MULTIPID
1123 }
1124
1125 test_24q() {
1126         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1127
1128         test_mkdir $DIR/R13a
1129         test_mkdir $DIR/R13b
1130         local DIRINO=$(ls -lid $DIR/R13a | awk '{ print $1 }')
1131         multiop_bg_pause $DIR/R13b D_c || error "multiop failed to start"
1132         MULTIPID=$!
1133
1134         trap cleanup_multiop_pause EXIT
1135         mrename $DIR/R13a $DIR/R13b
1136         $CHECKSTAT -a $DIR/R13a || error "R13a still exists"
1137         $CHECKSTAT -t dir $DIR/R13b || error "R13b does not exist"
1138         local DIRINO2=$(ls -lid $DIR/R13b | awk '{ print $1 }')
1139         [ "$DIRINO" = "$DIRINO2" ] || error "R13a $DIRINO != R13b $DIRINO2"
1140         cleanup_multiop_pause
1141         wait $MULTIPID || error "multiop close failed"
1142 }
1143 run_test 24q "mkdir .../R13{a,b}; open R13b rename R13a R13b ==="
1144
1145 test_24r() { #bug 3789
1146         test_mkdir $DIR/R14a
1147         test_mkdir $DIR/R14a/b
1148         mrename $DIR/R14a $DIR/R14a/b && error "rename to subdir worked!"
1149         $CHECKSTAT -t dir $DIR/R14a || error "$DIR/R14a missing"
1150         $CHECKSTAT -t dir $DIR/R14a/b || error "$DIR/R14a/b missing"
1151 }
1152 run_test 24r "mkdir .../R14a/b; rename .../R14a .../R14a/b ====="
1153
1154 test_24s() {
1155         test_mkdir $DIR/R15a
1156         test_mkdir $DIR/R15a/b
1157         test_mkdir $DIR/R15a/b/c
1158         mrename $DIR/R15a $DIR/R15a/b/c && error "rename to sub-subdir worked!"
1159         $CHECKSTAT -t dir $DIR/R15a || error "$DIR/R15a missing"
1160         $CHECKSTAT -t dir $DIR/R15a/b/c || error "$DIR/R15a/b/c missing"
1161 }
1162 run_test 24s "mkdir .../R15a/b/c; rename .../R15a .../R15a/b/c ="
1163
1164 test_24t() {
1165         test_mkdir $DIR/R16a
1166         test_mkdir $DIR/R16a/b
1167         test_mkdir $DIR/R16a/b/c
1168         mrename $DIR/R16a/b/c $DIR/R16a && error "rename to sub-subdir worked!"
1169         $CHECKSTAT -t dir $DIR/R16a || error "$DIR/R16a missing"
1170         $CHECKSTAT -t dir $DIR/R16a/b/c || error "$DIR/R16a/b/c missing"
1171 }
1172 run_test 24t "mkdir .../R16a/b/c; rename .../R16a/b/c .../R16a ="
1173
1174 test_24u() { # bug12192
1175         $MULTIOP $DIR/$tfile C2w$((2048 * 1024))c || error "multiop failed"
1176         $CHECKSTAT -s $((2048 * 1024)) $DIR/$tfile || error "wrong file size"
1177 }
1178 run_test 24u "create stripe file"
1179
1180 simple_cleanup_common() {
1181         local createmany=$1
1182         local rc=0
1183
1184         [[ -z "$DIR" || -z "$tdir" || ! -d "$DIR/$tdir" ]] && return 0
1185
1186         local start=$SECONDS
1187
1188         [[ -n "$createmany" ]] && unlinkmany $DIR/$tdir/$tfile $createmany
1189         rm -rf $DIR/$tdir || error "cleanup $DIR/$tdir failed"
1190         rc=$?
1191         wait_delete_completed
1192         echo "cleanup time $((SECONDS - start))"
1193         return $rc
1194 }
1195
1196 max_pages_per_rpc() {
1197         local mdtname="$(printf "MDT%04x" ${1:-0})"
1198         $LCTL get_param -n mdc.*$mdtname*.max_pages_per_rpc
1199 }
1200
1201 test_24v() {
1202         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1203
1204         local nrfiles=${COUNT:-100000}
1205         local fname="$DIR/$tdir/$tfile"
1206
1207         # Performance issue on ZFS see LU-4072 (c.f. LU-2887)
1208         [ "$mds1_FSTYPE" = "zfs" ] && nrfiles=${COUNT:-10000}
1209
1210         test_mkdir "$(dirname $fname)"
1211         # assume MDT0000 has the fewest inodes
1212         local stripes=$($LFS getdirstripe -c $(dirname $fname))
1213         local free_inodes=$(($(mdt_free_inodes 0) * ${stripes/#0/1}))
1214         [[ $free_inodes -lt $nrfiles ]] && nrfiles=$free_inodes
1215
1216         stack_trap "simple_cleanup_common $nrfiles"
1217
1218         createmany -m "$fname" $nrfiles
1219
1220         cancel_lru_locks mdc
1221         lctl set_param mdc.*.stats clear
1222
1223         # was previously test_24D: LU-6101
1224         # readdir() returns correct number of entries after cursor reload
1225         local num_ls=$(ls $DIR/$tdir | wc -l)
1226         local num_uniq=$(ls $DIR/$tdir | sort -u | wc -l)
1227         local num_all=$(ls -a $DIR/$tdir | wc -l)
1228         if [ $num_ls -ne $nrfiles ] || [ $num_uniq -ne $nrfiles ] ||
1229                 [ $num_all -ne $((nrfiles + 2)) ]; then
1230                         error "Expected $nrfiles files, got $num_ls " \
1231                                 "($num_uniq unique $num_all .&..)"
1232         fi
1233         # LU-5 large readdir
1234         # dirent_size = 32 bytes for sizeof(struct lu_dirent) +
1235         #               N bytes for name (len($nrfiles) rounded to 8 bytes) +
1236         #               8 bytes for luda_type (4 bytes rounded to 8 bytes)
1237         # take into account of overhead in lu_dirpage header and end mark in
1238         # each page, plus one in rpc_num calculation.
1239         local dirent_size=$((32 + (${#tfile} | 7) + 1 + 8))
1240         local page_entries=$(((PAGE_SIZE - 24) / dirent_size))
1241         local mdt_idx=$($LFS getdirstripe -i $(dirname $fname))
1242         local rpc_pages=$(max_pages_per_rpc $mdt_idx)
1243         local rpc_max=$((nrfiles / (page_entries * rpc_pages) + stripes))
1244         local mds_readpage=$(calc_stats mdc.*.stats mds_readpage)
1245         echo "readpages: $mds_readpage rpc_max: $rpc_max-2/+1"
1246         (( $mds_readpage >= $rpc_max - 2 && $mds_readpage <= $rpc_max + 1)) ||
1247                 error "large readdir doesn't take effect: " \
1248                       "$mds_readpage should be about $rpc_max"
1249 }
1250 run_test 24v "list large directory (test hash collision, b=17560)"
1251
1252 test_24w() { # bug21506
1253         SZ1=234852
1254         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=4096 || return 1
1255         dd if=/dev/zero bs=$SZ1 count=1 >> $DIR/$tfile || return 2
1256         dd if=$DIR/$tfile of=$DIR/${tfile}_left bs=1M skip=4097 || return 3
1257         SZ2=`ls -l $DIR/${tfile}_left | awk '{print $5}'`
1258         [[ "$SZ1" -eq "$SZ2" ]] ||
1259                 error "Error reading at the end of the file $tfile"
1260 }
1261 run_test 24w "Reading a file larger than 4Gb"
1262
1263 test_24x() {
1264         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1265         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1266         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1267                 skip "Need MDS version at least 2.7.56"
1268
1269         local MDTIDX=1
1270         local remote_dir=$DIR/$tdir/remote_dir
1271
1272         test_mkdir $DIR/$tdir
1273         $LFS mkdir -i $MDTIDX $remote_dir ||
1274                 error "create remote directory failed"
1275
1276         test_mkdir $DIR/$tdir/src_dir
1277         touch $DIR/$tdir/src_file
1278         test_mkdir $remote_dir/tgt_dir
1279         touch $remote_dir/tgt_file
1280
1281         mrename $DIR/$tdir/src_dir $remote_dir/tgt_dir ||
1282                 error "rename dir cross MDT failed!"
1283
1284         mrename $DIR/$tdir/src_file $remote_dir/tgt_file ||
1285                 error "rename file cross MDT failed!"
1286
1287         touch $DIR/$tdir/ln_file
1288         ln $DIR/$tdir/ln_file $remote_dir/ln_name ||
1289                 error "ln file cross MDT failed"
1290
1291         rm -rf $DIR/$tdir || error "Can not delete directories"
1292 }
1293 run_test 24x "cross MDT rename/link"
1294
1295 test_24y() {
1296         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1297         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1298
1299         local remote_dir=$DIR/$tdir/remote_dir
1300         local mdtidx=1
1301
1302         test_mkdir $DIR/$tdir
1303         $LFS mkdir -i $mdtidx $remote_dir ||
1304                 error "create remote directory failed"
1305
1306         test_mkdir $remote_dir/src_dir
1307         touch $remote_dir/src_file
1308         test_mkdir $remote_dir/tgt_dir
1309         touch $remote_dir/tgt_file
1310
1311         mrename $remote_dir/src_dir $remote_dir/tgt_dir ||
1312                 error "rename subdir in the same remote dir failed!"
1313
1314         mrename $remote_dir/src_file $remote_dir/tgt_file ||
1315                 error "rename files in the same remote dir failed!"
1316
1317         ln $remote_dir/tgt_file $remote_dir/tgt_file1 ||
1318                 error "link files in the same remote dir failed!"
1319
1320         rm -rf $DIR/$tdir || error "Can not delete directories"
1321 }
1322 run_test 24y "rename/link on the same dir should succeed"
1323
1324 test_24z() {
1325         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1326         [[ $MDS1_VERSION -lt $(version_code 2.12.51) ]] &&
1327                 skip "Need MDS version at least 2.12.51"
1328
1329         local index
1330
1331         for index in 0 1; do
1332                 $LFS mkdir -i $index $DIR/$tdir.$index || error "mkdir failed"
1333                 touch $DIR/$tdir.0/$tfile.$index || error "touch failed"
1334         done
1335
1336         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1 || error "mv $tfile.0 failed"
1337
1338         index=$($LFS getstripe -m $DIR/$tdir.1/$tfile.0)
1339         [ $index -eq 0 ] || error "$tfile.0 is on MDT$index"
1340
1341         local mdts=$(comma_list $(mdts_nodes))
1342
1343         do_nodes $mdts $LCTL set_param mdt.*.enable_remote_rename=0
1344         stack_trap "do_nodes $mdts $LCTL \
1345                 set_param mdt.*.enable_remote_rename=1" EXIT
1346
1347         mv $DIR/$tdir.0/$tfile.1 $DIR/$tdir.1 || error "mv $tfile.1 failed"
1348
1349         index=$($LFS getstripe -m $DIR/$tdir.1/$tfile.1)
1350         [ $index -eq 1 ] || error "$tfile.1 is on MDT$index"
1351 }
1352 run_test 24z "cross-MDT rename is done as cp"
1353
1354 test_24A() { # LU-3182
1355         local NFILES=5000
1356
1357         test_mkdir $DIR/$tdir
1358         stack_trap "simple_cleanup_common $NFILES"
1359         createmany -m $DIR/$tdir/$tfile $NFILES
1360         local t=$(ls $DIR/$tdir | wc -l)
1361         local u=$(ls $DIR/$tdir | sort -u | wc -l)
1362         local v=$(ls -ai $DIR/$tdir | sort -u | wc -l)
1363
1364         (( $t == $NFILES && $u == $NFILES && $v == NFILES + 2 )) ||
1365                 error "Expected $NFILES files, got $t ($u unique $v .&..)"
1366 }
1367 run_test 24A "readdir() returns correct number of entries."
1368
1369 test_24B() { # LU-4805
1370         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1371
1372         local count
1373
1374         test_mkdir $DIR/$tdir
1375         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir/ ||
1376                 error "create striped dir failed"
1377
1378         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1379         [ $count -eq 2 ] || error "Expected 2, got $count"
1380
1381         touch $DIR/$tdir/striped_dir/a
1382
1383         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1384         [ $count -eq 3 ] || error "Expected 3, got $count"
1385
1386         touch $DIR/$tdir/striped_dir/.f
1387
1388         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1389         [ $count -eq 4 ] || error "Expected 4, got $count"
1390
1391         rm -rf $DIR/$tdir || error "Can not delete directories"
1392 }
1393 run_test 24B "readdir for striped dir return correct number of entries"
1394
1395 test_24C() {
1396         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1397
1398         mkdir $DIR/$tdir
1399         mkdir $DIR/$tdir/d0
1400         mkdir $DIR/$tdir/d1
1401
1402         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/d0/striped_dir ||
1403                 error "create striped dir failed"
1404
1405         cd $DIR/$tdir/d0/striped_dir
1406
1407         local d0_ino=$(ls -i -l -a $DIR/$tdir | grep "d0" | awk '{print $1}')
1408         local d1_ino=$(ls -i -l -a $DIR/$tdir | grep "d1" | awk '{print $1}')
1409         local parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1410
1411         [ "$d0_ino" = "$parent_ino" ] ||
1412                 error ".. wrong, expect $d0_ino, get $parent_ino"
1413
1414         mv $DIR/$tdir/d0/striped_dir $DIR/$tdir/d1/ ||
1415                 error "mv striped dir failed"
1416
1417         parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1418
1419         [ "$d1_ino" = "$parent_ino" ] ||
1420                 error ".. wrong after mv, expect $d1_ino, get $parent_ino"
1421 }
1422 run_test 24C "check .. in striped dir"
1423
1424 test_24E() {
1425         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
1426         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1427
1428         mkdir -p $DIR/$tdir
1429         mkdir $DIR/$tdir/src_dir
1430         $LFS mkdir -i 1 $DIR/$tdir/src_dir/src_child ||
1431                 error "create remote source failed"
1432
1433         touch $DIR/$tdir/src_dir/src_child/a
1434
1435         $LFS mkdir -i 2 $DIR/$tdir/tgt_dir ||
1436                 error "create remote target dir failed"
1437
1438         $LFS mkdir -i 3 $DIR/$tdir/tgt_dir/tgt_child ||
1439                 error "create remote target child failed"
1440
1441         mrename $DIR/$tdir/src_dir/src_child $DIR/$tdir/tgt_dir/tgt_child ||
1442                 error "rename dir cross MDT failed!"
1443
1444         find $DIR/$tdir
1445
1446         $CHECKSTAT -t dir $DIR/$tdir/src_dir/src_child &&
1447                 error "src_child still exists after rename"
1448
1449         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/tgt_child/a ||
1450                 error "missing file(a) after rename"
1451
1452         rm -rf $DIR/$tdir || error "Can not delete directories"
1453 }
1454 run_test 24E "cross MDT rename/link"
1455
1456 test_24F () {
1457         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
1458
1459         local repeats=1000
1460         [ "$SLOW" = "no" ] && repeats=100
1461
1462         mkdir -p $DIR/$tdir
1463
1464         echo "$repeats repeats"
1465         for ((i = 0; i < repeats; i++)); do
1466                 $LFS mkdir -i0 -c2 $DIR/$tdir/test || error "mkdir fails"
1467                 touch $DIR/$tdir/test/a || error "touch fails"
1468                 mkdir $DIR/$tdir/test/b || error "mkdir fails"
1469                 rm -rf $DIR/$tdir/test || error "rmdir fails"
1470         done
1471
1472         true
1473 }
1474 run_test 24F "hash order vs readdir (LU-11330)"
1475
1476 test_24G () {
1477         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
1478
1479         local ino1
1480         local ino2
1481
1482         $LFS mkdir -i 0 $DIR/$tdir-0 || error "mkdir $tdir-0"
1483         $LFS mkdir -i 1 $DIR/$tdir-1 || error "mkdir $tdir-1"
1484         touch $DIR/$tdir-0/f1 || error "touch f1"
1485         ln -s $DIR/$tdir-0/f1 $DIR/$tdir-0/s1 || error "ln s1"
1486         ino1=$(stat -c%i $DIR/$tdir-0/s1)
1487         mv $DIR/$tdir-0/s1 $DIR/$tdir-1 || error "mv s1"
1488         ino2=$(stat -c%i $DIR/$tdir-1/s1)
1489         [ $ino1 -ne $ino2 ] || error "s1 should be migrated"
1490 }
1491 run_test 24G "migrate symlink in rename"
1492
1493 test_24H() {
1494         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
1495         [[ $(hostname) != $(facet_active_host mds2) ]] ||
1496                 skip "MDT1 should be on another node"
1497
1498         test_mkdir -i 1 -c 1 $DIR/$tdir
1499 #define OBD_FAIL_FLD_QUERY_REQ           0x1103
1500         do_facet mds2 $LCTL set_param fail_loc=0x80001103
1501         touch $DIR/$tdir/$tfile || error "touch failed"
1502 }
1503 run_test 24H "repeat FLD_QUERY rpc"
1504
1505 test_25a() {
1506         echo '== symlink sanity ============================================='
1507
1508         test_mkdir $DIR/d25
1509         ln -s d25 $DIR/s25
1510         touch $DIR/s25/foo ||
1511                 error "File creation in symlinked directory failed"
1512 }
1513 run_test 25a "create file in symlinked directory ==============="
1514
1515 test_25b() {
1516         [ ! -d $DIR/d25 ] && test_25a
1517         $CHECKSTAT -t file $DIR/s25/foo || error "$DIR/s25/foo not file type"
1518 }
1519 run_test 25b "lookup file in symlinked directory ==============="
1520
1521 test_26a() {
1522         test_mkdir $DIR/d26
1523         test_mkdir $DIR/d26/d26-2
1524         ln -s d26/d26-2 $DIR/s26
1525         touch $DIR/s26/foo || error "File creation failed"
1526 }
1527 run_test 26a "multiple component symlink ======================="
1528
1529 test_26b() {
1530         test_mkdir -p $DIR/$tdir/d26-2
1531         ln -s $tdir/d26-2/foo $DIR/s26-2
1532         touch $DIR/s26-2 || error "File creation failed"
1533 }
1534 run_test 26b "multiple component symlink at end of lookup ======"
1535
1536 test_26c() {
1537         test_mkdir $DIR/d26.2
1538         touch $DIR/d26.2/foo
1539         ln -s d26.2 $DIR/s26.2-1
1540         ln -s s26.2-1 $DIR/s26.2-2
1541         ln -s s26.2-2 $DIR/s26.2-3
1542         chmod 0666 $DIR/s26.2-3/foo
1543 }
1544 run_test 26c "chain of symlinks"
1545
1546 # recursive symlinks (bug 439)
1547 test_26d() {
1548         ln -s d26-3/foo $DIR/d26-3
1549 }
1550 run_test 26d "create multiple component recursive symlink"
1551
1552 test_26e() {
1553         [ ! -h $DIR/d26-3 ] && test_26d
1554         rm $DIR/d26-3
1555 }
1556 run_test 26e "unlink multiple component recursive symlink"
1557
1558 # recursive symlinks (bug 7022)
1559 test_26f() {
1560         test_mkdir $DIR/$tdir
1561         test_mkdir $DIR/$tdir/$tfile
1562         cd $DIR/$tdir/$tfile           || error "cd $DIR/$tdir/$tfile failed"
1563         test_mkdir -p lndir/bar1
1564         test_mkdir $DIR/$tdir/$tfile/$tfile
1565         cd $tfile                || error "cd $tfile failed"
1566         ln -s .. dotdot          || error "ln dotdot failed"
1567         ln -s dotdot/lndir lndir || error "ln lndir failed"
1568         cd $DIR/$tdir                 || error "cd $DIR/$tdir failed"
1569         output=`ls $tfile/$tfile/lndir/bar1`
1570         [ "$output" = bar1 ] && error "unexpected output"
1571         rm -r $tfile             || error "rm $tfile failed"
1572         $CHECKSTAT -a $DIR/$tfile || error "$tfile not gone"
1573 }
1574 run_test 26f "rm -r of a directory which has recursive symlink"
1575
1576 test_27a() {
1577         test_mkdir $DIR/$tdir
1578         $LFS getstripe $DIR/$tdir
1579         $LFS setstripe -c 1 $DIR/$tdir/$tfile || error "setstripe failed"
1580         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1581         cp /etc/hosts $DIR/$tdir/$tfile || error "Can't copy to one stripe file"
1582 }
1583 run_test 27a "one stripe file"
1584
1585 test_27b() {
1586         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1587
1588         test_mkdir $DIR/$tdir
1589         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1590         $LFS getstripe -c $DIR/$tdir/$tfile
1591         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
1592                 error "two-stripe file doesn't have two stripes"
1593
1594         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1595 }
1596 run_test 27b "create and write to two stripe file"
1597
1598 # 27c family tests specific striping, setstripe -o
1599 test_27ca() {
1600         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1601         test_mkdir -p $DIR/$tdir
1602         local osts="1"
1603
1604         $LFS setstripe -o $osts $DIR/$tdir/$tfile  || error "setstripe failed"
1605         $LFS getstripe -i $DIR/$tdir/$tfile
1606         [ $($LFS getstripe -i $DIR/$tdir/$tfile ) -eq $osts ] ||
1607                 error "stripe not on specified OST"
1608
1609         dd if=/dev/zero of=$DIR/$tdir/$tfile  bs=1M count=4 || error "dd failed"
1610 }
1611 run_test 27ca "one stripe on specified OST"
1612
1613 test_27cb() {
1614         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1615         test_mkdir -p $DIR/$tdir
1616         local osts="1,0"
1617         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1618         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1619         echo "$getstripe"
1620
1621         # Strip getstripe output to a space separated list of OSTs
1622         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1623                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1624         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1625                 error "stripes not on specified OSTs"
1626
1627         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1628 }
1629 run_test 27cb "two stripes on specified OSTs"
1630
1631 test_27cc() {
1632         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1633         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1634                 skip "server does not support overstriping"
1635
1636         test_mkdir -p $DIR/$tdir
1637         local osts="0,0"
1638         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1639         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1640         echo "$getstripe"
1641
1642         # Strip getstripe output to a space separated list of OSTs
1643         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1644                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1645         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1646                 error "stripes not on specified OSTs"
1647
1648         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1649 }
1650 run_test 27cc "two stripes on the same OST"
1651
1652 test_27cd() {
1653         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1654         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1655                 skip "server does not support overstriping"
1656         test_mkdir -p $DIR/$tdir
1657         local osts="0,1,1,0"
1658         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1659         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1660         echo "$getstripe"
1661
1662         # Strip getstripe output to a space separated list of OSTs
1663         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1664                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1665         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1666                 error "stripes not on specified OSTs"
1667
1668         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1669 }
1670 run_test 27cd "four stripes on two OSTs"
1671
1672 test_27ce() {
1673         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
1674                 skip_env "too many osts, skipping"
1675         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1676                 skip "server does not support overstriping"
1677         # We do one more stripe than we have OSTs
1678         [ $OSTCOUNT -lt 159 ] || large_xattr_enabled ||
1679                 skip_env "ea_inode feature disabled"
1680
1681         test_mkdir -p $DIR/$tdir
1682         local osts=""
1683         for i in $(seq 0 $OSTCOUNT);
1684         do
1685                 osts=$osts"0"
1686                 if [ $i -ne $OSTCOUNT ]; then
1687                         osts=$osts","
1688                 fi
1689         done
1690         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1691         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1692         echo "$getstripe"
1693
1694         # Strip getstripe output to a space separated list of OSTs
1695         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1696                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1697         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1698                 error "stripes not on specified OSTs"
1699
1700         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1701 }
1702 run_test 27ce "more stripes than OSTs with -o"
1703
1704 test_27cf() {
1705         local osp_proc="osp.$FSNAME-OST0000-osc-MDT000*.active"
1706         local pid=0
1707
1708         test_mkdir -p $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
1709         do_facet $SINGLEMDS "$LCTL set_param -n $osp_proc=0"
1710         stack_trap "do_facet $SINGLEMDS $LCTL set_param -n $osp_proc=1" EXIT
1711         wait_update_facet $SINGLEMDS "$LCTL get_param -n $osp_proc | grep 1" ||
1712                 error "failed to set $osp_proc=0"
1713
1714         $LFS setstripe -o 0 $DIR/$tdir/$tfile &
1715         pid=$!
1716         sleep 1
1717         do_facet $SINGLEMDS "$LCTL set_param -n $osp_proc=1"
1718         wait_update_facet $SINGLEMDS "$LCTL get_param -n $osp_proc | grep 0" ||
1719                 error "failed to set $osp_proc=1"
1720         wait $pid
1721         [[ $pid -ne 0 ]] ||
1722                 error "should return error due to $osp_proc=0"
1723 }
1724 run_test 27cf "'setstripe -o' on inactive OSTs should return error"
1725
1726 test_27cg() {
1727         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1728                 skip "server does not support overstriping"
1729         [[ $mds1_FSTYPE != "ldiskfs" ]] && skip_env "ldiskfs only test"
1730         large_xattr_enabled || skip_env "ea_inode feature disabled"
1731
1732         local osts="0"
1733
1734         for ((i=1;i<1000;i++)); do
1735                 osts+=",$((i % OSTCOUNT))"
1736         done
1737
1738         local mdts=$(comma_list $(mdts_nodes))
1739         local before=$(do_nodes $mdts \
1740                 "$LCTL get_param -n osd-ldiskfs.*MDT*.stats" |
1741                 awk '/many credits/{print $3}' |
1742                 calc_sum)
1743
1744         $LFS setstripe -o $osts $DIR/$tfile || error "setstripe failed"
1745         $LFS getstripe $DIR/$tfile | grep stripe
1746
1747         rm -f $DIR/$tfile || error "can't unlink"
1748
1749         after=$(do_nodes $mdts \
1750                 "$LCTL get_param -n osd-ldiskfs.*MDT*.stats" |
1751                 awk '/many credits/{print $3}' |
1752                 calc_sum)
1753
1754         (( before == after )) ||
1755                 error "too many credits happened: $after > $before"
1756 }
1757 run_test 27cg "1000 shouldn't cause too many credits"
1758
1759 test_27d() {
1760         test_mkdir $DIR/$tdir
1761         $LFS setstripe -c 0 -i -1 -S 0 $DIR/$tdir/$tfile ||
1762                 error "setstripe failed"
1763         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1764         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1765 }
1766 run_test 27d "create file with default settings"
1767
1768 test_27e() {
1769         # LU-5839 adds check for existed layout before setting it
1770         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1771                 skip "Need MDS version at least 2.7.56"
1772
1773         test_mkdir $DIR/$tdir
1774         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1775         $LFS setstripe -c 2 $DIR/$tdir/$tfile && error "setstripe worked twice"
1776         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1777 }
1778 run_test 27e "setstripe existing file (should return error)"
1779
1780 test_27f() {
1781         test_mkdir $DIR/$tdir
1782         $LFS setstripe -S 100 -i 0 -c 1 $DIR/$tdir/$tfile &&
1783                 error "$LFS setstripe $DIR/$tdir/$tfile failed"
1784         $CHECKSTAT -t file $DIR/$tdir/$tfile &&
1785                 error "$CHECKSTAT -t file $DIR/$tdir/$tfile should fail"
1786         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1787         $LFS getstripe $DIR/$tdir/$tfile || error "$LFS getstripe failed"
1788 }
1789 run_test 27f "setstripe with bad stripe size (should return error)"
1790
1791 test_27g() {
1792         test_mkdir $DIR/$tdir
1793         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1794         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "no stripe info" ||
1795                 error "$DIR/$tdir/$tfile has object"
1796 }
1797 run_test 27g "$LFS getstripe with no objects"
1798
1799 test_27ga() {
1800         test_mkdir $DIR/$tdir
1801         touch $DIR/$tdir/$tfile || error "touch failed"
1802         ln -s bogus $DIR/$tdir/$tfile.2 || error "ln failed"
1803         $LFS getstripe -m $DIR/$tdir/$tfile $DIR/$tdir/$tfile.2
1804         local rc=$?
1805         (( rc == 2 )) || error "getstripe did not return ENOENT"
1806 }
1807 run_test 27ga "$LFS getstripe with missing file (should return error)"
1808
1809 test_27i() {
1810         test_mkdir $DIR/$tdir
1811         touch $DIR/$tdir/$tfile || error "touch failed"
1812         [[ $($LFS getstripe -c $DIR/$tdir/$tfile) -gt 0 ]] ||
1813                 error "missing objects"
1814 }
1815 run_test 27i "$LFS getstripe with some objects"
1816
1817 test_27j() {
1818         test_mkdir $DIR/$tdir
1819         $LFS setstripe -i $OSTCOUNT $DIR/$tdir/$tfile &&
1820                 error "setstripe failed" || true
1821 }
1822 run_test 27j "setstripe with bad stripe offset (should return error)"
1823
1824 test_27k() { # bug 2844
1825         test_mkdir $DIR/$tdir
1826         local file=$DIR/$tdir/$tfile
1827         local ll_max_blksize=$((4 * 1024 * 1024))
1828         $LFS setstripe -S 67108864 $file || error "setstripe failed"
1829         local blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1830         [ $blksize -le $ll_max_blksize ] || error "1:$blksize > $ll_max_blksize"
1831         dd if=/dev/zero of=$file bs=4k count=1
1832         blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1833         [ $blksize -le $ll_max_blksize ] || error "2:$blksize > $ll_max_blksize"
1834 }
1835 run_test 27k "limit i_blksize for broken user apps"
1836
1837 test_27l() {
1838         mcreate $DIR/$tfile || error "creating file"
1839         $RUNAS $LFS setstripe -c 1 $DIR/$tfile &&
1840                 error "setstripe should have failed" || true
1841 }
1842 run_test 27l "check setstripe permissions (should return error)"
1843
1844 test_27m() {
1845         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1846
1847         [ -n "$RCLIENTS" -o -n "$MOUNT_2" ] &&
1848                 skip_env "multiple clients -- skipping"
1849
1850         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
1851                    head -n1)
1852         if [[ $ORIGFREE -gt $MAXFREE ]]; then
1853                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
1854         fi
1855         stack_trap simple_cleanup_common
1856         test_mkdir $DIR/$tdir
1857         $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.1
1858         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1024 count=$MAXFREE &&
1859                 error "dd should fill OST0"
1860         i=2
1861         while $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.$i; do
1862                 i=$((i + 1))
1863                 [ $i -gt 256 ] && break
1864         done
1865         i=$((i + 1))
1866         touch $DIR/$tdir/$tfile.$i
1867         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1868             awk '{print $1}'| grep -w "0") ] &&
1869                 error "OST0 was full but new created file still use it"
1870         i=$((i + 1))
1871         touch $DIR/$tdir/$tfile.$i
1872         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1873             awk '{print $1}'| grep -w "0") ] &&
1874                 error "OST0 was full but new created file still use it" || true
1875 }
1876 run_test 27m "create file while OST0 was full"
1877
1878 # OSCs keep a NOSPC flag that will be reset after ~5s (qos_maxage)
1879 # if the OST isn't full anymore.
1880 reset_enospc() {
1881         local ostidx=${1:-""}
1882         local delay
1883         local ready
1884         local get_prealloc
1885
1886         local list=$(comma_list $(osts_nodes))
1887         [ "$ostidx" ] && list=$(facet_host ost$((ostidx + 1)))
1888
1889         do_nodes $list lctl set_param fail_loc=0
1890         wait_delete_completed   # initiate all OST_DESTROYs from MDS to OST
1891         delay=$(do_facet $SINGLEMDS lctl get_param -n lov.*.qos_maxage |
1892                 awk '{print $1 * 2;exit;}')
1893         get_prealloc="$LCTL get_param -n osc.*MDT*.prealloc_status |
1894                         grep -v \"^0$\""
1895         wait_update_facet $SINGLEMDS "$get_prealloc" "" $delay
1896 }
1897
1898 test_27n() {
1899         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1900         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1901         remote_mds_nodsh && skip "remote MDS with nodsh"
1902         remote_ost_nodsh && skip "remote OST with nodsh"
1903
1904         reset_enospc
1905         rm -f $DIR/$tdir/$tfile
1906         exhaust_precreations 0 0x80000215
1907         $LFS setstripe -c -1 $DIR/$tdir || error "setstripe failed"
1908         touch $DIR/$tdir/$tfile || error "touch failed"
1909         $LFS getstripe $DIR/$tdir/$tfile
1910         reset_enospc
1911 }
1912 run_test 27n "create file with some full OSTs"
1913
1914 test_27o() {
1915         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1916         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1917         remote_mds_nodsh && skip "remote MDS with nodsh"
1918         remote_ost_nodsh && skip "remote OST with nodsh"
1919
1920         reset_enospc
1921         rm -f $DIR/$tdir/$tfile
1922         exhaust_all_precreations 0x215
1923
1924         touch $DIR/$tdir/$tfile && error "able to create $DIR/$tdir/$tfile"
1925
1926         reset_enospc
1927         rm -rf $DIR/$tdir/*
1928 }
1929 run_test 27o "create file with all full OSTs (should error)"
1930
1931 function create_and_checktime() {
1932         local fname=$1
1933         local loops=$2
1934         local i
1935
1936         for ((i=0; i < $loops; i++)); do
1937                 local start=$SECONDS
1938                 multiop $fname-$i Oc
1939                 ((SECONDS-start < TIMEOUT)) ||
1940                         error "creation took " $((SECONDS-$start)) && return 1
1941         done
1942 }
1943
1944 test_27oo() {
1945         local mdts=$(comma_list $(mdts_nodes))
1946
1947         [ $MDS1_VERSION -lt $(version_code 2.13.57) ] &&
1948                 skip "Need MDS version at least 2.13.57"
1949
1950         local f0=$DIR/${tfile}-0
1951         local f1=$DIR/${tfile}-1
1952
1953         wait_delete_completed
1954
1955         # refill precreated objects
1956         $LFS setstripe -i0 -c1 $f0
1957
1958         saved=$(do_facet mds1 $LCTL get_param -n lov.*0000*.qos_threshold_rr)
1959         # force QoS allocation policy
1960         do_nodes $mdts $LCTL set_param lov.*.qos_threshold_rr=0%
1961         stack_trap "do_nodes $mdts $LCTL set_param \
1962                 lov.*.qos_threshold_rr=$saved" EXIT
1963         sleep_maxage
1964
1965         # one OST is unavailable, but still have few objects preallocated
1966         stop ost1
1967         stack_trap "start ost1 $(ostdevname 1) $OST_MOUNT_OPTS; \
1968                 rm -rf $f1 $DIR/$tdir*" EXIT
1969
1970         for ((i=0; i < 7; i++)); do
1971                 mkdir $DIR/$tdir$i || error "can't create dir"
1972                 $LFS setstripe -c$((OSTCOUNT-1)) $DIR/$tdir$i ||
1973                         error "can't set striping"
1974         done
1975         for ((i=0; i < 7; i++)); do
1976                 create_and_checktime $DIR/$tdir$i/$tfile 100 &
1977         done
1978         wait
1979 }
1980 run_test 27oo "don't let few threads to reserve too many objects"
1981
1982 test_27p() {
1983         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1984         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1985         remote_mds_nodsh && skip "remote MDS with nodsh"
1986         remote_ost_nodsh && skip "remote OST with nodsh"
1987
1988         reset_enospc
1989         rm -f $DIR/$tdir/$tfile
1990         test_mkdir $DIR/$tdir
1991
1992         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1993         $TRUNCATE $DIR/$tdir/$tfile 80000000 || error "truncate failed"
1994         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
1995
1996         exhaust_precreations 0 0x80000215
1997         echo foo >> $DIR/$tdir/$tfile || error "append failed"
1998         $CHECKSTAT -s 80000004 $DIR/$tdir/$tfile || error "checkstat failed"
1999         $LFS getstripe $DIR/$tdir/$tfile
2000
2001         reset_enospc
2002 }
2003 run_test 27p "append to a truncated file with some full OSTs"
2004
2005 test_27q() {
2006         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2007         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2008         remote_mds_nodsh && skip "remote MDS with nodsh"
2009         remote_ost_nodsh && skip "remote OST with nodsh"
2010
2011         reset_enospc
2012         rm -f $DIR/$tdir/$tfile
2013
2014         mkdir_on_mdt0 $DIR/$tdir
2015         $MCREATE $DIR/$tdir/$tfile || error "mcreate $DIR/$tdir/$tfile failed"
2016         $TRUNCATE $DIR/$tdir/$tfile 80000000 ||
2017                 error "truncate $DIR/$tdir/$tfile failed"
2018         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
2019
2020         exhaust_all_precreations 0x215
2021
2022         echo foo >> $DIR/$tdir/$tfile && error "append succeeded"
2023         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat 2 failed"
2024
2025         reset_enospc
2026 }
2027 run_test 27q "append to truncated file with all OSTs full (should error)"
2028
2029 test_27r() {
2030         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2031         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2032         remote_mds_nodsh && skip "remote MDS with nodsh"
2033         remote_ost_nodsh && skip "remote OST with nodsh"
2034
2035         reset_enospc
2036         rm -f $DIR/$tdir/$tfile
2037         exhaust_precreations 0 0x80000215
2038
2039         $LFS setstripe -i 0 -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
2040
2041         reset_enospc
2042 }
2043 run_test 27r "stripe file with some full OSTs (shouldn't LBUG) ="
2044
2045 test_27s() { # bug 10725
2046         test_mkdir $DIR/$tdir
2047         local stripe_size=$((4096 * 1024 * 1024))       # 2^32
2048         local stripe_count=0
2049         [ $OSTCOUNT -eq 1 ] || stripe_count=2
2050         $LFS setstripe -S $stripe_size -c $stripe_count $DIR/$tdir &&
2051                 error "stripe width >= 2^32 succeeded" || true
2052
2053 }
2054 run_test 27s "lsm_xfersize overflow (should error) (bug 10725)"
2055
2056 test_27t() { # bug 10864
2057         WDIR=$(pwd)
2058         WLFS=$(which lfs)
2059         cd $DIR
2060         touch $tfile
2061         $WLFS getstripe $tfile
2062         cd $WDIR
2063 }
2064 run_test 27t "check that utils parse path correctly"
2065
2066 test_27u() { # bug 4900
2067         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2068         remote_mds_nodsh && skip "remote MDS with nodsh"
2069
2070         local index
2071         local list=$(comma_list $(mdts_nodes))
2072
2073 #define OBD_FAIL_MDS_OSC_PRECREATE      0x139
2074         do_nodes $list $LCTL set_param fail_loc=0x139
2075         test_mkdir -p $DIR/$tdir
2076         stack_trap "simple_cleanup_common 1000"
2077         createmany -o $DIR/$tdir/$tfile 1000
2078         do_nodes $list $LCTL set_param fail_loc=0
2079
2080         TLOG=$TMP/$tfile.getstripe
2081         $LFS getstripe $DIR/$tdir > $TLOG
2082         OBJS=$(awk -vobj=0 '($1 == 0) { obj += 1 } END { print obj; }' $TLOG)
2083         [[ $OBJS -gt 0 ]] &&
2084                 error "$OBJS objects created on OST-0. See $TLOG" ||
2085                 rm -f $TLOG
2086 }
2087 run_test 27u "skip object creation on OSC w/o objects"
2088
2089 test_27v() { # bug 4900
2090         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2091         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2092         remote_mds_nodsh && skip "remote MDS with nodsh"
2093         remote_ost_nodsh && skip "remote OST with nodsh"
2094
2095         exhaust_all_precreations 0x215
2096         reset_enospc
2097
2098         $LFS setstripe -c 1 $DIR/$tdir         # 1 stripe / file
2099
2100         touch $DIR/$tdir/$tfile
2101         #define OBD_FAIL_TGT_DELAY_PRECREATE     0x705
2102         # all except ost1
2103         for (( i=1; i < OSTCOUNT; i++ )); do
2104                 do_facet ost$i lctl set_param fail_loc=0x705
2105         done
2106         local START=`date +%s`
2107         createmany -o $DIR/$tdir/$tfile 32
2108
2109         local FINISH=`date +%s`
2110         local TIMEOUT=`lctl get_param -n timeout`
2111         local PROCESS=$((FINISH - START))
2112         [ $PROCESS -ge $((TIMEOUT / 2)) ] && \
2113                error "$FINISH - $START >= $TIMEOUT / 2"
2114         sleep $((TIMEOUT / 2 - PROCESS))
2115         reset_enospc
2116 }
2117 run_test 27v "skip object creation on slow OST"
2118
2119 test_27w() { # bug 10997
2120         test_mkdir $DIR/$tdir
2121         $LFS setstripe -S 65536 $DIR/$tdir/f0 || error "setstripe failed"
2122         [ $($LFS getstripe -S $DIR/$tdir/f0) -ne 65536 ] &&
2123                 error "stripe size $size != 65536" || true
2124         [ $($LFS getstripe -d $DIR/$tdir | grep -c "stripe_count") -eq 0 ] &&
2125                 error "$LFS getstripe -d $DIR/$tdir no 'stripe_count'" || true
2126 }
2127 run_test 27w "check $LFS setstripe -S and getstrip -d options"
2128
2129 test_27wa() {
2130         [[ $OSTCOUNT -lt 2 ]] &&
2131                 skip_env "skipping multiple stripe count/offset test"
2132
2133         test_mkdir $DIR/$tdir
2134         for i in $(seq 1 $OSTCOUNT); do
2135                 offset=$((i - 1))
2136                 $LFS setstripe -c $i -i $offset $DIR/$tdir/f$i ||
2137                         error "setstripe -c $i -i $offset failed"
2138                 count=$($LFS getstripe -c $DIR/$tdir/f$i)
2139                 index=$($LFS getstripe -i $DIR/$tdir/f$i)
2140                 [ $count -ne $i ] && error "stripe count $count != $i" || true
2141                 [ $index -ne $offset ] &&
2142                         error "stripe offset $index != $offset" || true
2143         done
2144 }
2145 run_test 27wa "check $LFS setstripe -c -i options"
2146
2147 test_27x() {
2148         remote_ost_nodsh && skip "remote OST with nodsh"
2149         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2150         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2151
2152         OFFSET=$(($OSTCOUNT - 1))
2153         OSTIDX=0
2154         local OST=$(ostname_from_index $OSTIDX)
2155
2156         test_mkdir $DIR/$tdir
2157         $LFS setstripe -c 1 $DIR/$tdir  # 1 stripe per file
2158         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 1
2159         sleep_maxage
2160         createmany -o $DIR/$tdir/$tfile $OSTCOUNT
2161         for i in $(seq 0 $OFFSET); do
2162                 [ $($LFS getstripe $DIR/$tdir/$tfile$i | grep -A 10 obdidx |
2163                         awk '{print $1}' | grep -w "$OSTIDX") ] &&
2164                 error "OST0 was degraded but new created file still use it"
2165         done
2166         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 0
2167 }
2168 run_test 27x "create files while OST0 is degraded"
2169
2170 test_27y() {
2171         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2172         remote_mds_nodsh && skip "remote MDS with nodsh"
2173         remote_ost_nodsh && skip "remote OST with nodsh"
2174         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2175
2176         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS $FSNAME-OST0000)
2177         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
2178                 osp.$mdtosc.prealloc_last_id)
2179         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
2180                 osp.$mdtosc.prealloc_next_id)
2181         local fcount=$((last_id - next_id))
2182         [[ $fcount -eq 0 ]] && skip "not enough space on OST0"
2183         [[ $fcount -gt $OSTCOUNT ]] && fcount=$OSTCOUNT
2184
2185         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
2186                          awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
2187         local OST_DEACTIVE_IDX=-1
2188         local OSC
2189         local OSTIDX
2190         local OST
2191
2192         for OSC in $MDS_OSCS; do
2193                 OST=$(osc_to_ost $OSC)
2194                 OSTIDX=$(index_from_ostuuid $OST)
2195                 if [ $OST_DEACTIVE_IDX == -1 ]; then
2196                         OST_DEACTIVE_IDX=$OSTIDX
2197                 fi
2198                 if [ $OSTIDX != $OST_DEACTIVE_IDX ]; then
2199                         echo $OSC "is Deactivated:"
2200                         do_facet $SINGLEMDS lctl --device  %$OSC deactivate
2201                 fi
2202         done
2203
2204         OSTIDX=$(index_from_ostuuid $OST)
2205         test_mkdir $DIR/$tdir
2206         $LFS setstripe -c 1 $DIR/$tdir      # 1 stripe / file
2207
2208         for OSC in $MDS_OSCS; do
2209                 OST=$(osc_to_ost $OSC)
2210                 OSTIDX=$(index_from_ostuuid $OST)
2211                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2212                         echo $OST "is degraded:"
2213                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2214                                                 obdfilter.$OST.degraded=1
2215                 fi
2216         done
2217
2218         sleep_maxage
2219         createmany -o $DIR/$tdir/$tfile $fcount
2220
2221         for OSC in $MDS_OSCS; do
2222                 OST=$(osc_to_ost $OSC)
2223                 OSTIDX=$(index_from_ostuuid $OST)
2224                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2225                         echo $OST "is recovered from degraded:"
2226                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2227                                                 obdfilter.$OST.degraded=0
2228                 else
2229                         do_facet $SINGLEMDS lctl --device %$OSC activate
2230                 fi
2231         done
2232
2233         # all osp devices get activated, hence -1 stripe count restored
2234         local stripe_count=0
2235
2236         # sleep 2*lod_qos_maxage seconds waiting for lod qos to notice osp
2237         # devices get activated.
2238         sleep_maxage
2239         $LFS setstripe -c -1 $DIR/$tfile
2240         stripe_count=$($LFS getstripe -c $DIR/$tfile)
2241         rm -f $DIR/$tfile
2242         [ $stripe_count -ne $OSTCOUNT ] &&
2243                 error "Of $OSTCOUNT OSTs, only $stripe_count is available"
2244         return 0
2245 }
2246 run_test 27y "create files while OST0 is degraded and the rest inactive"
2247
2248 check_seq_oid()
2249 {
2250         log "check file $1"
2251
2252         lmm_count=$($LFS getstripe -c $1)
2253         lmm_seq=$($LFS getstripe -v $1 | awk '/lmm_seq/ { print $2 }')
2254         lmm_oid=$($LFS getstripe -v $1 | awk '/lmm_object_id/ { print $2 }')
2255
2256         local old_ifs="$IFS"
2257         IFS=$'[:]'
2258         fid=($($LFS path2fid $1))
2259         IFS="$old_ifs"
2260
2261         log "FID seq ${fid[1]}, oid ${fid[2]} ver ${fid[3]}"
2262         log "LOV seq $lmm_seq, oid $lmm_oid, count: $lmm_count"
2263
2264         # compare lmm_seq and lu_fid->f_seq
2265         [ $lmm_seq = ${fid[1]} ] || { error "SEQ mismatch"; return 1; }
2266         # compare lmm_object_id and lu_fid->oid
2267         [ $lmm_oid = ${fid[2]} ] || { error "OID mismatch"; return 2; }
2268
2269         # check the trusted.fid attribute of the OST objects of the file
2270         local have_obdidx=false
2271         local stripe_nr=0
2272         $LFS getstripe $1 | while read obdidx oid hex seq; do
2273                 # skip lines up to and including "obdidx"
2274                 [ -z "$obdidx" ] && break
2275                 [ "$obdidx" = "obdidx" ] && have_obdidx=true && continue
2276                 $have_obdidx || continue
2277
2278                 local ost=$((obdidx + 1))
2279                 local dev=$(ostdevname $ost)
2280                 local oid_hex
2281
2282                 log "want: stripe:$stripe_nr ost:$obdidx oid:$oid/$hex seq:$seq"
2283
2284                 seq=$(echo $seq | sed -e "s/^0x//g")
2285                 if [ $seq == 0 ] || [ $(facet_fstype ost$ost) == zfs ]; then
2286                         oid_hex=$(echo $oid)
2287                 else
2288                         oid_hex=$(echo $hex | sed -e "s/^0x//g")
2289                 fi
2290                 local obj_file="O/$seq/d$((oid %32))/$oid_hex"
2291
2292                 local ff=""
2293                 #
2294                 # Don't unmount/remount the OSTs if we don't need to do that.
2295                 # LU-2577 changes filter_fid to be smaller, so debugfs needs
2296                 # update too, until that use mount/ll_decode_filter_fid/mount.
2297                 # Re-enable when debugfs will understand new filter_fid.
2298                 #
2299                 if [ $(facet_fstype ost$ost) == ldiskfs ]; then
2300                         ff=$(do_facet ost$ost "$DEBUGFS -c -R 'stat $obj_file' \
2301                                 $dev 2>/dev/null" | grep "parent=")
2302                 fi
2303                 if [ -z "$ff" ]; then
2304                         stop ost$ost
2305                         mount_fstype ost$ost
2306                         ff=$(do_facet ost$ost $LL_DECODE_FILTER_FID \
2307                                 $(facet_mntpt ost$ost)/$obj_file)
2308                         unmount_fstype ost$ost
2309                         start ost$ost $dev $OST_MOUNT_OPTS
2310                         clients_up
2311                 fi
2312
2313                 [ -z "$ff" ] && error "$obj_file: no filter_fid info"
2314
2315                 echo "$ff" | sed -e 's#.*objid=#got: objid=#'
2316
2317                 # /mnt/O/0/d23/23: objid=23 seq=0 parent=[0x200000400:0x1e:0x1]
2318                 # fid: objid=23 seq=0 parent=[0x200000400:0x1e:0x0] stripe=1
2319                 #
2320                 # fid: parent=[0x200000400:0x1e:0x0] stripe=1 stripe_count=2 \
2321                 #       stripe_size=1048576 component_id=1 component_start=0 \
2322                 #       component_end=33554432
2323                 local ff_parent=$(sed -e 's/.*parent=.//' <<<$ff)
2324                 local ff_pseq=$(cut -d: -f1 <<<$ff_parent)
2325                 local ff_poid=$(cut -d: -f2 <<<$ff_parent)
2326                 local ff_pstripe
2327                 if grep -q 'stripe=' <<<$ff; then
2328                         ff_pstripe=$(sed -e 's/.*stripe=//' -e 's/ .*//' <<<$ff)
2329                 else
2330                         # $LL_DECODE_FILTER_FID does not print "stripe="; look
2331                         # into f_ver in this case.  See comment on ff_parent.
2332                         ff_pstripe=$(cut -d: -f3 <<<$ff_parent | sed -e 's/]//')
2333                 fi
2334
2335                 # compare lmm_seq and filter_fid->ff_parent.f_seq
2336                 [ $ff_pseq = $lmm_seq ] ||
2337                         error "FF parent SEQ $ff_pseq != $lmm_seq"
2338                 # compare lmm_object_id and filter_fid->ff_parent.f_oid
2339                 [ $ff_poid = $lmm_oid ] ||
2340                         error "FF parent OID $ff_poid != $lmm_oid"
2341                 (($ff_pstripe == $stripe_nr)) ||
2342                         error "FF stripe $ff_pstripe != $stripe_nr"
2343
2344                 stripe_nr=$((stripe_nr + 1))
2345                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2346                         continue
2347                 if grep -q 'stripe_count=' <<<$ff; then
2348                         local ff_scnt=$(sed -e 's/.*stripe_count=//' \
2349                                             -e 's/ .*//' <<<$ff)
2350                         [ $lmm_count = $ff_scnt ] ||
2351                                 error "FF stripe count $lmm_count != $ff_scnt"
2352                 fi
2353         done
2354 }
2355
2356 test_27z() {
2357         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2358         remote_ost_nodsh && skip "remote OST with nodsh"
2359
2360         test_mkdir $DIR/$tdir
2361         $LFS setstripe -c 1 -i 0 -S 64k $DIR/$tdir/$tfile-1 ||
2362                 { error "setstripe -c -1 failed"; return 1; }
2363         # We need to send a write to every object to get parent FID info set.
2364         # This _should_ also work for setattr, but does not currently.
2365         # touch $DIR/$tdir/$tfile-1 ||
2366         dd if=/dev/zero of=$DIR/$tdir/$tfile-1 bs=1M count=1 ||
2367                 { error "dd $tfile-1 failed"; return 2; }
2368         $LFS setstripe -c -1 -i $((OSTCOUNT - 1)) -S 1M $DIR/$tdir/$tfile-2 ||
2369                 { error "setstripe -c -1 failed"; return 3; }
2370         dd if=/dev/zero of=$DIR/$tdir/$tfile-2 bs=1M count=$OSTCOUNT ||
2371                 { error "dd $tfile-2 failed"; return 4; }
2372
2373         # make sure write RPCs have been sent to OSTs
2374         sync; sleep 5; sync
2375
2376         check_seq_oid $DIR/$tdir/$tfile-1 || return 5
2377         check_seq_oid $DIR/$tdir/$tfile-2 || return 6
2378 }
2379 run_test 27z "check SEQ/OID on the MDT and OST filesystems"
2380
2381 test_27A() { # b=19102
2382         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2383
2384         save_layout_restore_at_exit $MOUNT
2385         $LFS setstripe -c 0 -i -1 -S 0 $MOUNT
2386         wait_update $HOSTNAME "$LFS getstripe -c $MOUNT | sed 's/  *//g'" "1" 20 ||
2387                 error "stripe count $($LFS getstripe -c $MOUNT) != 1"
2388         local default_size=$($LFS getstripe -S $MOUNT)
2389         local default_offset=$($LFS getstripe -i $MOUNT)
2390         local dsize=$(do_facet $SINGLEMDS \
2391                 "$LCTL get_param -n lod.$(facet_svc $SINGLEMDS)*.stripesize")
2392         [ $default_size -eq $dsize ] ||
2393                 error "stripe size $default_size != $dsize"
2394         [ $default_offset -eq -1 ] ||
2395                 error "stripe offset $default_offset != -1"
2396 }
2397 run_test 27A "check filesystem-wide default LOV EA values"
2398
2399 test_27B() { # LU-2523
2400         test_mkdir $DIR/$tdir
2401         rm -f $DIR/$tdir/f0 $DIR/$tdir/f1
2402         touch $DIR/$tdir/f0
2403         # open f1 with O_LOV_DELAY_CREATE
2404         # rename f0 onto f1
2405         # call setstripe ioctl on open file descriptor for f1
2406         # close
2407         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:nB1c \
2408                 $DIR/$tdir/f0
2409
2410         rm -f $DIR/$tdir/f1
2411         # open f1 with O_LOV_DELAY_CREATE
2412         # unlink f1
2413         # call setstripe ioctl on open file descriptor for f1
2414         # close
2415         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:uB1c
2416
2417         # Allow multiop to fail in imitation of NFS's busted semantics.
2418         true
2419 }
2420 run_test 27B "call setstripe on open unlinked file/rename victim"
2421
2422 # 27C family tests full striping and overstriping
2423 test_27Ca() { #LU-2871
2424         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2425
2426         declare -a ost_idx
2427         local index
2428         local found
2429         local i
2430         local j
2431
2432         test_mkdir $DIR/$tdir
2433         cd $DIR/$tdir
2434         for i in $(seq 0 $((OSTCOUNT - 1))); do
2435                 # set stripe across all OSTs starting from OST$i
2436                 $LFS setstripe -i $i -c -1 $tfile$i
2437                 # get striping information
2438                 ost_idx=($($LFS getstripe $tfile$i |
2439                          tail -n $((OSTCOUNT + 1)) | awk '{print $1}'))
2440                 echo "OST Index: ${ost_idx[*]}"
2441
2442                 # check the layout
2443                 [ ${#ost_idx[@]} -eq $OSTCOUNT ] ||
2444                         error "${#ost_idx[@]} != $OSTCOUNT"
2445
2446                 for index in $(seq 0 $((OSTCOUNT - 1))); do
2447                         found=0
2448                         for j in "${ost_idx[@]}"; do
2449                                 if [ $index -eq $j ]; then
2450                                         found=1
2451                                         break
2452                                 fi
2453                         done
2454                         [ $found = 1 ] ||
2455                                 error "Can not find $index in ${ost_idx[*]}"
2456                 done
2457         done
2458 }
2459 run_test 27Ca "check full striping across all OSTs"
2460
2461 test_27Cb() {
2462         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2463                 skip "server does not support overstriping"
2464         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2465                 skip_env "too many osts, skipping"
2466
2467         test_mkdir -p $DIR/$tdir
2468         local setcount=$(($OSTCOUNT * 2))
2469         [ $setcount -lt 160 ] || large_xattr_enabled ||
2470                 skip_env "ea_inode feature disabled"
2471
2472         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2473                 error "setstripe failed"
2474
2475         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2476         [ $count -eq $setcount ] ||
2477                 error "stripe count $count, should be $setcount"
2478
2479         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2480                 error "overstriped should be set in pattern"
2481
2482         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2483                 error "dd failed"
2484 }
2485 run_test 27Cb "more stripes than OSTs with -C"
2486
2487 test_27Cc() {
2488         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2489                 skip "server does not support overstriping"
2490         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2491
2492         test_mkdir -p $DIR/$tdir
2493         local setcount=$(($OSTCOUNT - 1))
2494
2495         [ $setcount -lt 160 ] || large_xattr_enabled ||
2496                 skip_env "ea_inode feature disabled"
2497
2498         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2499                 error "setstripe failed"
2500
2501         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2502         [ $count -eq $setcount ] ||
2503                 error "stripe count $count, should be $setcount"
2504
2505         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" &&
2506                 error "overstriped should not be set in pattern"
2507
2508         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2509                 error "dd failed"
2510 }
2511 run_test 27Cc "fewer stripes than OSTs does not set overstriping"
2512
2513 test_27Cd() {
2514         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2515                 skip "server does not support overstriping"
2516         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2517         large_xattr_enabled || skip_env "ea_inode feature disabled"
2518
2519         force_new_seq_all
2520
2521         test_mkdir -p $DIR/$tdir
2522         local setcount=$LOV_MAX_STRIPE_COUNT
2523
2524         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2525                 error "setstripe failed"
2526
2527         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2528         [ $count -eq $setcount ] ||
2529                 error "stripe count $count, should be $setcount"
2530
2531         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2532                 error "overstriped should be set in pattern"
2533
2534         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2535                 error "dd failed"
2536
2537         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2538 }
2539 run_test 27Cd "test maximum stripe count"
2540
2541 test_27Ce() {
2542         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2543                 skip "server does not support overstriping"
2544         test_mkdir -p $DIR/$tdir
2545
2546         pool_add $TESTNAME || error "Pool creation failed"
2547         pool_add_targets $TESTNAME 0 || error "pool_add_targets failed"
2548
2549         local setcount=8
2550
2551         $LFS setstripe  -C $setcount -p "$TESTNAME" $DIR/$tdir/$tfile ||
2552                 error "setstripe failed"
2553
2554         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2555         [ $count -eq $setcount ] ||
2556                 error "stripe count $count, should be $setcount"
2557
2558         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2559                 error "overstriped should be set in pattern"
2560
2561         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2562                 error "dd failed"
2563
2564         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2565 }
2566 run_test 27Ce "test pool with overstriping"
2567
2568 test_27Cf() {
2569         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2570                 skip "server does not support overstriping"
2571         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2572                 skip_env "too many osts, skipping"
2573
2574         test_mkdir -p $DIR/$tdir
2575
2576         local setcount=$(($OSTCOUNT * 2))
2577         [ $setcount -lt 160 ] || large_xattr_enabled ||
2578                 skip_env "ea_inode feature disabled"
2579
2580         $LFS setstripe  -C $setcount $DIR/$tdir/ ||
2581                 error "setstripe failed"
2582
2583         echo 1 > $DIR/$tdir/$tfile
2584
2585         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2586         [ $count -eq $setcount ] ||
2587                 error "stripe count $count, should be $setcount"
2588
2589         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2590                 error "overstriped should be set in pattern"
2591
2592         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2593                 error "dd failed"
2594
2595         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2596 }
2597 run_test 27Cf "test default inheritance with overstriping"
2598
2599 test_27Cg() {
2600         $LFS setstripe -o 0,$OSTCOUNT $DIR/$tfile
2601         [ $? -ne 0 ] || error "must be an error for not existent OST#"
2602 }
2603 run_test 27Cg "test setstripe with wrong OST idx"
2604
2605 test_27Ch() {
2606         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2607                 skip "server does not support overstriping"
2608         (( $MDS1_VERSION >= $(version_code 2.15.55.102) )) ||
2609                 skip "need MDS >= 2.12.55.102 for mdt_dump_lmm fix"
2610
2611         stack_trap "rm -f $DIR/$tfile"
2612         # start_full_debug_logging
2613         $LFS setstripe -S 64K -C -1 $DIR/$tfile || error "create $tfile failed"
2614         $LFS getstripe -c $DIR/$tfile || error "getstripe $tfile failed"
2615         cancel_lru_locks
2616         $LFS getstripe -c $DIR/$tfile || error "getstripe failed after clear"
2617
2618         test_mkdir $DIR/$tdir
2619         stack_trap "rm -rf $DIR/$tdir/$tfile"
2620         $LFS setstripe -S 64K -C -1 $DIR/$tdir || error "mkdir $tdir failed"
2621         $LFS getstripe -y $DIR/$tdir || error "getstripe $tdir failed"
2622         touch $DIR/$tdir/$tfile || error "create $tdir/$tfile failed"
2623         cancel_lru_locks
2624         $LFS getstripe -c $DIR/$tdir/$tfile ||
2625                 error "getstripe $tdir/$tfile failed"
2626         #stop_full_debug_logging
2627 }
2628 run_test 27Ch "overstriping with -C -1 in mdt_dump_lmm"
2629
2630 test_27D() {
2631         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2632         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2633         remote_mds_nodsh && skip "remote MDS with nodsh"
2634
2635         local POOL=${POOL:-testpool}
2636         local first_ost=0
2637         local last_ost=$(($OSTCOUNT - 1))
2638         local ost_step=1
2639         local ost_list=$(seq $first_ost $ost_step $last_ost)
2640         local ost_range="$first_ost $last_ost $ost_step"
2641
2642         test_mkdir $DIR/$tdir
2643         pool_add $POOL || error "pool_add failed"
2644         pool_add_targets $POOL $ost_range || error "pool_add_targets failed"
2645
2646         local skip27D
2647         [ $MDS1_VERSION -lt $(version_code 2.8.55) ] &&
2648                 skip27D+="-s 29"
2649         [ $MDS1_VERSION -lt $(version_code 2.9.55) ] ||
2650                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2651                         skip27D+=" -s 30,31"
2652         [[ ! $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ||
2653           $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2654                 skip27D+=" -s 32,33"
2655         [[ $MDS_VERSION -lt $(version_code $SEL_VER) ]] &&
2656                 skip27D+=" -s 34"
2657         llapi_layout_test -d$DIR/$tdir -p$POOL -o$OSTCOUNT $skip27D ||
2658                 error "llapi_layout_test failed"
2659
2660         destroy_test_pools || error "destroy test pools failed"
2661 }
2662 run_test 27D "validate llapi_layout API"
2663
2664 # Verify that default_easize is increased from its initial value after
2665 # accessing a widely striped file.
2666 test_27E() {
2667         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2668         [ $CLIENT_VERSION -lt $(version_code 2.5.57) ] &&
2669                 skip "client does not have LU-3338 fix"
2670
2671         # 72 bytes is the minimum space required to store striping
2672         # information for a file striped across one OST:
2673         # (sizeof(struct lov_user_md_v3) +
2674         #  sizeof(struct lov_user_ost_data_v1))
2675         local min_easize=72
2676         $LCTL set_param -n llite.*.default_easize $min_easize ||
2677                 error "lctl set_param failed"
2678         local easize=$($LCTL get_param -n llite.*.default_easize)
2679
2680         [ $easize -eq $min_easize ] ||
2681                 error "failed to set default_easize"
2682
2683         $LFS setstripe -c $OSTCOUNT $DIR/$tfile ||
2684                 error "setstripe failed"
2685         # In order to ensure stat() call actually talks to MDS we need to
2686         # do something drastic to this file to shake off all lock, e.g.
2687         # rename it (kills lookup lock forcing cache cleaning)
2688         mv $DIR/$tfile $DIR/${tfile}-1
2689         ls -l $DIR/${tfile}-1
2690         rm $DIR/${tfile}-1
2691
2692         easize=$($LCTL get_param -n llite.*.default_easize)
2693
2694         [ $easize -gt $min_easize ] ||
2695                 error "default_easize not updated"
2696 }
2697 run_test 27E "check that default extended attribute size properly increases"
2698
2699 test_27F() { # LU-5346/LU-7975
2700         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2701         [[ $OSTCOUNT -lt 2 ]] && skip "needs >= 2 OSTs"
2702         [[ $MDS1_VERSION -lt $(version_code 2.8.51) ]] &&
2703                 skip "Need MDS version at least 2.8.51"
2704         remote_ost_nodsh && skip "remote OST with nodsh"
2705
2706         test_mkdir $DIR/$tdir
2707         rm -f $DIR/$tdir/f0
2708         $LFS setstripe -c 2 $DIR/$tdir
2709
2710         # stop all OSTs to reproduce situation for LU-7975 ticket
2711         for num in $(seq $OSTCOUNT); do
2712                 stop ost$num
2713         done
2714
2715         # open/create f0 with O_LOV_DELAY_CREATE
2716         # truncate f0 to a non-0 size
2717         # close
2718         multiop $DIR/$tdir/f0 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T1050000c
2719
2720         $CHECKSTAT -s 1050000 $DIR/$tdir/f0 || error "checkstat failed"
2721         # open/write it again to force delayed layout creation
2722         cat /etc/hosts > $DIR/$tdir/f0 &
2723         catpid=$!
2724
2725         # restart OSTs
2726         for num in $(seq $OSTCOUNT); do
2727                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS ||
2728                         error "ost$num failed to start"
2729         done
2730
2731         wait $catpid || error "cat failed"
2732
2733         cmp /etc/hosts $DIR/$tdir/f0 || error "cmp failed"
2734         [[ $($LFS getstripe -c $DIR/$tdir/f0) == 2 ]] ||
2735                 error "wrong stripecount"
2736
2737 }
2738 run_test 27F "Client resend delayed layout creation with non-zero size"
2739
2740 test_27G() { #LU-10629
2741         [ $MDS1_VERSION -lt $(version_code 2.11.51) ] &&
2742                 skip "Need MDS version at least 2.11.51"
2743         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2744         remote_mds_nodsh && skip "remote MDS with nodsh"
2745         local POOL=${POOL:-testpool}
2746         local ostrange="0 0 1"
2747
2748         test_mkdir $DIR/$tdir
2749         touch $DIR/$tdir/$tfile.nopool
2750         pool_add $POOL || error "pool_add failed"
2751         pool_add_targets $POOL $ostrange || error "pool_add_targets failed"
2752         $LFS setstripe -p $POOL $DIR/$tdir
2753
2754         local pool=$($LFS getstripe -p $DIR/$tdir)
2755
2756         [ "$pool" = "$POOL" ] || error "Striping failed got '$pool' not '$POOL'"
2757         touch $DIR/$tdir/$tfile.default
2758         $LFS setstripe -E 1M --pool $POOL -c 1 -E eof -c 1 $DIR/$tdir/$tfile.pfl
2759         $LFS find $DIR/$tdir -type f --pool $POOL
2760         local found=$($LFS find $DIR/$tdir -type f --pool $POOL | wc -l)
2761         [[ "$found" == "2" ]] ||
2762                 error "found $found != 2 files in '$DIR/$tdir' in '$POOL'"
2763
2764         $LFS setstripe -d $DIR/$tdir
2765
2766         pool=$($LFS getstripe -p -d $DIR/$tdir)
2767
2768         [[ "$pool" != "$POOL" ]] || error "$DIR/$tdir is still '$pool'"
2769 }
2770 run_test 27G "Clear OST pool from stripe"
2771
2772 test_27H() {
2773         [[ $MDS1_VERSION -le $(version_code 2.11.54) ]] &&
2774                 skip "Need MDS version newer than 2.11.54"
2775         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
2776         test_mkdir $DIR/$tdir
2777         $LFS setstripe -o 0 -o 2 $DIR/$tdir || error "setstripe failed"
2778         touch $DIR/$tdir/$tfile
2779         $LFS getstripe -c $DIR/$tdir/$tfile
2780         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
2781                 error "two-stripe file doesn't have two stripes"
2782
2783         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
2784         $LFS getstripe -y $DIR/$tdir/$tfile
2785         (( $($LFS getstripe -y $DIR/$tdir/$tfile |
2786              egrep -c "l_ost_idx: [02]$") == "2" )) ||
2787                 error "expected l_ost_idx: [02]$ not matched"
2788
2789         # make sure ost list has been cleared
2790         local stripesize=$($LFS getstripe -S $DIR/$tdir)
2791         $LFS setstripe -S $((stripesize * 4)) -i 1 \
2792                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
2793         touch $DIR/$tdir/f3
2794         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
2795 }
2796 run_test 27H "Set specific OSTs stripe"
2797
2798 test_27I() {
2799         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2800         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2801         [[ $MDS1_VERSION -gt $(version_code 2.12.52) ]] ||
2802                 skip "Need MDS version newer than 2.12.52"
2803         local pool=$TESTNAME
2804         local ostrange="1 1 1"
2805
2806         save_layout_restore_at_exit $MOUNT
2807         $LFS setstripe -c 2 -i 0 $MOUNT
2808         pool_add $pool || error "pool_add failed"
2809         pool_add_targets $pool $ostrange ||
2810                 error "pool_add_targets failed"
2811         test_mkdir $DIR/$tdir
2812         $LFS setstripe -p $pool $DIR/$tdir
2813         $MULTIOP $DIR/$tdir/$tfile Oc || error "multiop failed"
2814         $LFS getstripe $DIR/$tdir/$tfile
2815 }
2816 run_test 27I "check that root dir striping does not break parent dir one"
2817
2818 test_27J() {
2819         [[ $MDS1_VERSION -le $(version_code 2.12.51) ]] &&
2820                 skip "Need MDS version newer than 2.12.51"
2821
2822         test_mkdir $DIR/$tdir
2823         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2824         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2825
2826         # create foreign file (raw way)
2827         ! $LFS setstripe --flags 0xda08 $DIR/$tdir/$tfile ||
2828                 error "creating $tfile w/ hex flags w/o --foreign should fail"
2829
2830         ! $LFS setstripe --foreign --flags foo \
2831                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tfile ||
2832                         error "creating $tfile with '--flags foo' should fail"
2833
2834         ! $LFS setstripe --foreign --flags 0xffffffff \
2835                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tfile ||
2836                         error "creating $tfile w/ 0xffffffff flags should fail"
2837
2838         create_foreign_file -f $DIR/$tdir/$tfile -x "${uuid1}@${uuid2}" \
2839                 -t 1 -F 0xda08 || error "create_foreign_file failed"
2840
2841         # verify foreign file (raw way)
2842         parse_foreign_file -f $DIR/$tdir/$tfile |
2843                 grep "lov_foreign_magic: 0x0BD70BD0" ||
2844                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign magic"
2845         parse_foreign_file -f $DIR/$tdir/$tfile | grep "lov_xattr_size: 89" ||
2846                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2847         parse_foreign_file -f $DIR/$tdir/$tfile |
2848                 grep "lov_foreign_size: 73" ||
2849                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2850         parse_foreign_file -f $DIR/$tdir/$tfile |
2851                 grep "lov_foreign_type: 1" ||
2852                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign type"
2853         parse_foreign_file -f $DIR/$tdir/$tfile |
2854                 grep "lov_foreign_flags: 0x0000DA08" ||
2855                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign flags"
2856         local lov=$(parse_foreign_file -f $DIR/$tdir/$tfile |
2857                 grep "lov_foreign_value: 0x" |
2858                 sed -e 's/lov_foreign_value: 0x//')
2859         local lov2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160)
2860         [[ $lov = ${lov2// /} ]] ||
2861                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign value"
2862
2863         # create foreign file (lfs + API)
2864         $LFS setstripe --foreign=none --flags 0xda08 \
2865                 -x "${uuid1}@${uuid2}" $DIR/$tdir/${tfile}2 ||
2866                 error "$DIR/$tdir/${tfile}2: create failed"
2867
2868         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2869                 grep "lfm_magic:.*0x0BD70BD0" ||
2870                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign magic"
2871         # lfm_length is LOV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2872         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_length:.*73" ||
2873                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign size"
2874         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_type:.*none" ||
2875                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign type"
2876         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2877                 grep "lfm_flags:.*0x0000DA08" ||
2878                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign flags"
2879         $LFS getstripe $DIR/$tdir/${tfile}2 |
2880                 grep "lfm_value:.*${uuid1}@${uuid2}" ||
2881                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign value"
2882
2883         # modify striping should fail
2884         $LFS setstripe -c 2 $DIR/$tdir/$tfile &&
2885                 error "$DIR/$tdir/$tfile: setstripe should fail"
2886         $LFS setstripe -c 2 $DIR/$tdir/${tfile}2 &&
2887                 error "$DIR/$tdir/${tfile}2: setstripe should fail"
2888
2889         # R/W should fail
2890         cat $DIR/$tdir/$tfile && error "$DIR/$tdir/$tfile: read should fail"
2891         cat $DIR/$tdir/${tfile}2 &&
2892                 error "$DIR/$tdir/${tfile}2: read should fail"
2893         cat /etc/passwd > $DIR/$tdir/$tfile &&
2894                 error "$DIR/$tdir/$tfile: write should fail"
2895         cat /etc/passwd > $DIR/$tdir/${tfile}2 &&
2896                 error "$DIR/$tdir/${tfile}2: write should fail"
2897
2898         # chmod should work
2899         chmod 222 $DIR/$tdir/$tfile ||
2900                 error "$DIR/$tdir/$tfile: chmod failed"
2901         chmod 222 $DIR/$tdir/${tfile}2 ||
2902                 error "$DIR/$tdir/${tfile}2: chmod failed"
2903
2904         # chown should work
2905         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tfile ||
2906                 error "$DIR/$tdir/$tfile: chown failed"
2907         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tfile}2 ||
2908                 error "$DIR/$tdir/${tfile}2: chown failed"
2909
2910         # rename should work
2911         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}.new ||
2912                 error "$DIR/$tdir/$tfile: rename of foreign file has failed"
2913         mv $DIR/$tdir/${tfile}2 $DIR/$tdir/${tfile}2.new ||
2914                 error "$DIR/$tdir/${tfile}2: rename of foreign file has failed"
2915
2916         #remove foreign file
2917         rm $DIR/$tdir/${tfile}.new ||
2918                 error "$DIR/$tdir/${tfile}.new: remove of foreign file has failed"
2919         rm $DIR/$tdir/${tfile}2.new ||
2920                 error "$DIR/$tdir/${tfile}2.new: remove of foreign file has failed"
2921 }
2922 run_test 27J "basic ops on file with foreign LOV"
2923
2924 test_27K() {
2925         [[ $MDS1_VERSION -le $(version_code 2.12.49) ]] &&
2926                 skip "Need MDS version newer than 2.12.49"
2927
2928         test_mkdir $DIR/$tdir
2929         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2930         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2931
2932         # create foreign dir (raw way)
2933         ! $LFS setdirstripe --flags 0xda08 $DIR/$tdir/$tdir ||
2934                 error "creating $tdir w/ hex flags w/o --foreign should fail"
2935
2936         ! $LFS setdirstripe --foreign --flags foo \
2937                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tdir ||
2938                         error "creating $tdir with '--flags foo' should fail"
2939
2940         ! $LFS setdirstripe --foreign --flags 0xffffffff \
2941                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tdir ||
2942                         error "creating $tdir w/ 0xffffffff flags should fail"
2943
2944         create_foreign_dir -d $DIR/$tdir/$tdir -x "${uuid1}@${uuid2}" -t 1 ||
2945                 error "create_foreign_dir FAILED"
2946
2947         # verify foreign dir (raw way)
2948         parse_foreign_dir -d $DIR/$tdir/$tdir |
2949                 grep "lmv_foreign_magic:.*0xcd50cd0" ||
2950                 error "$DIR/$tdir/$tfile: invalid LMV EA magic"
2951         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_xattr_size:.*89$" ||
2952                 error "$DIR/$tdir/$tdir: invalid LMV EA size"
2953         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_foreign_type: 1$" ||
2954                 error "$DIR/$tdir/$tdir: invalid LMV EA type"
2955         parse_foreign_dir -d $DIR/$tdir/$tdir |
2956                 grep "lmv_foreign_flags: 55813$" ||
2957                 error "$DIR/$tdir/$tdir: invalid LMV EA flags"
2958         local lmv=$(parse_foreign_dir -d $DIR/$tdir/$tdir |
2959                 grep "lmv_foreign_value: 0x" |
2960                 sed 's/lmv_foreign_value: 0x//')
2961         local lmv2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160 |
2962                 sed 's/ //g')
2963         [[ $lmv == $lmv2 ]] || error "$DIR/$tdir/$tdir: invalid LMV EA value"
2964
2965         # create foreign dir (lfs + API)
2966         $LFS mkdir --foreign=none --xattr="${uuid1}@${uuid2}" --flags=0xda05 \
2967                 $DIR/$tdir/${tdir}2 ||
2968                 error "$DIR/$tdir/${tdir}2: create failed"
2969
2970         $LFS getdirstripe -v $DIR/$tdir/${tdir}2
2971
2972         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2973                 grep "lfm_magic:.*0x0CD50CD0" ||
2974                 error "$DIR/$tdir/${tdir}2: invalid LMV EA magic"
2975         # lfm_length is LMV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2976         # - sizeof(lfm_type) - sizeof(lfm_flags)
2977         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_length:.*73" ||
2978                 error "$DIR/$tdir/${tdir}2: invalid LMV EA size"
2979         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_type:.*none" ||
2980                 error "$DIR/$tdir/${tdir}2: invalid LMV EA type"
2981         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2982                 grep "lfm_flags:.*0x0000DA05" ||
2983                 error "$DIR/$tdir/${tdir}2: invalid LMV EA flags"
2984         $LFS getdirstripe $DIR/$tdir/${tdir}2 |
2985                 grep "lfm_value.*${uuid1}@${uuid2}" ||
2986                 error "$DIR/$tdir/${tdir}2: invalid LMV EA value"
2987
2988         # file create in dir should fail
2989         touch $DIR/$tdir/$tdir/$tfile && error "$DIR/$tdir: file create should fail"
2990         touch $DIR/$tdir/${tdir}2/$tfile &&
2991                 error "$DIR/${tdir}2: file create should fail"
2992
2993         # chmod should work
2994         chmod 777 $DIR/$tdir/$tdir ||
2995                 error "$DIR/$tdir: chmod failed"
2996         chmod 777 $DIR/$tdir/${tdir}2 ||
2997                 error "$DIR/${tdir}2: chmod failed"
2998
2999         # chown should work
3000         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tdir ||
3001                 error "$DIR/$tdir: chown failed"
3002         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tdir}2 ||
3003                 error "$DIR/${tdir}2: chown failed"
3004
3005         # rename should work
3006         mv $DIR/$tdir/$tdir $DIR/$tdir/${tdir}.new ||
3007                 error "$DIR/$tdir/$tdir: rename of foreign dir has failed"
3008         mv $DIR/$tdir/${tdir}2 $DIR/$tdir/${tdir}2.new ||
3009                 error "$DIR/$tdir/${tdir}2: rename of foreign dir has failed"
3010
3011         #remove foreign dir
3012         rmdir $DIR/$tdir/${tdir}.new ||
3013                 error "$DIR/$tdir/${tdir}.new: remove of foreign dir has failed"
3014         rmdir $DIR/$tdir/${tdir}2.new ||
3015                 error "$DIR/$tdir/${tdir}2.new: remove of foreign dir has failed"
3016 }
3017 run_test 27K "basic ops on dir with foreign LMV"
3018
3019 test_27L() {
3020         remote_mds_nodsh && skip "remote MDS with nodsh"
3021
3022         local POOL=${POOL:-$TESTNAME}
3023
3024         pool_add $POOL || error "pool_add failed"
3025
3026         lfs pool_list $MOUNT | grep -Fx "${FSNAME}.${POOL}" ||
3027                  error "pool_list does not contain ${FSNAME}.${POOL}:" \
3028                        "$(lfs pool_list $MOUNT | grep -F "${POOL}")"
3029 }
3030 run_test 27L "lfs pool_list gives correct pool name"
3031
3032 test_27M() {
3033         [[ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.12.57) ]] &&
3034                 skip "Need MDS version >= than 2.12.57"
3035         remote_mds_nodsh && skip "remote MDS with nodsh"
3036         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
3037
3038         # Set default striping on directory
3039         local setcount=4
3040         local stripe_opt
3041         local mdts=$(comma_list $(mdts_nodes))
3042
3043         # if we run against a 2.12 server which lacks overstring support
3044         # then the connect_flag will not report overstriping, even if client
3045         # is 2.14+
3046         if [[ $($LCTL get_param mdc.*.connect_flags) =~ overstriping ]]; then
3047                 stripe_opt="-C $setcount"
3048         elif (( $OSTCOUNT >= $setcount )); then
3049                 stripe_opt="-c $setcount"
3050         else
3051                 skip "server does not support overstriping"
3052         fi
3053
3054         test_mkdir $DIR/$tdir
3055
3056         # Validate existing append_* params and ensure restore
3057         local pool=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_pool)
3058         [[ "$pool" == "" ]] || error "expected append_pool == '', got '$pool'"
3059         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_pool=none"
3060
3061         local orig_count=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_stripe_count)
3062         ((orig_count == 1)) || error "expected append_stripe_count == 1, got $orig_count"
3063         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=1"
3064
3065         $LFS setstripe $stripe_opt $DIR/$tdir
3066
3067         echo 1 > $DIR/$tdir/${tfile}.1
3068         local count=$($LFS getstripe -c $DIR/$tdir/${tfile}.1)
3069         [ $count -eq $setcount ] ||
3070                 error "(1) stripe count $count, should be $setcount"
3071
3072         local appendcount=$orig_count
3073         echo 1 >> $DIR/$tdir/${tfile}.2_append
3074         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.2_append)
3075         [ $count -eq $appendcount ] ||
3076                 error "(2)stripe count $count, should be $appendcount for append"
3077
3078         # Disable O_APPEND striping, verify it works
3079         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
3080
3081         # Should now get the default striping, which is 4
3082         setcount=4
3083         echo 1 >> $DIR/$tdir/${tfile}.3_append
3084         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.3_append)
3085         [ $count -eq $setcount ] ||
3086                 error "(3) stripe count $count, should be $setcount"
3087
3088         # Try changing the stripe count for append files
3089         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=2
3090
3091         # Append striping is now 2 (directory default is still 4)
3092         appendcount=2
3093         echo 1 >> $DIR/$tdir/${tfile}.4_append
3094         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.4_append)
3095         [ $count -eq $appendcount ] ||
3096                 error "(4) stripe count $count, should be $appendcount for append"
3097
3098         # Test append stripe count of -1
3099         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=-1
3100         appendcount=$OSTCOUNT
3101         echo 1 >> $DIR/$tdir/${tfile}.5
3102         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.5)
3103         [ $count -eq $appendcount ] ||
3104                 error "(5) stripe count $count, should be $appendcount for append"
3105
3106         # Set append striping back to default of 1
3107         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=1
3108
3109         # Try a new default striping, PFL + DOM
3110         $LFS setstripe -L mdt -E 1M -E -1 -c 2 $DIR/$tdir
3111
3112         # Create normal DOM file, DOM returns stripe count == 0
3113         setcount=0
3114         touch $DIR/$tdir/${tfile}.6
3115         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.6)
3116         [ $count -eq $setcount ] ||
3117                 error "(6) stripe count $count, should be $setcount"
3118
3119         # Show
3120         appendcount=1
3121         echo 1 >> $DIR/$tdir/${tfile}.7_append
3122         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.7_append)
3123         [ $count -eq $appendcount ] ||
3124                 error "(7) stripe count $count, should be $appendcount for append"
3125
3126         # Clean up DOM layout
3127         $LFS setstripe -d $DIR/$tdir
3128
3129         save_layout_restore_at_exit $MOUNT
3130         # Now test that append striping works when layout is from root
3131         $LFS setstripe -c 2 $MOUNT
3132         # Make a special directory for this
3133         mkdir $DIR/${tdir}/${tdir}.2
3134
3135         # Verify for normal file
3136         setcount=2
3137         echo 1 > $DIR/${tdir}/${tdir}.2/${tfile}.8
3138         count=$($LFS getstripe -c $DIR/$tdir/${tdir}.2/${tfile}.8)
3139         [ $count -eq $setcount ] ||
3140                 error "(8) stripe count $count, should be $setcount"
3141
3142         appendcount=1
3143         echo 1 >> $DIR/${tdir}/${tdir}.2/${tfile}.9_append
3144         count=$($LFS getstripe -c $DIR/${tdir}/${tdir}.2/${tfile}.9_append)
3145         [ $count -eq $appendcount ] ||
3146                 error "(9) stripe count $count, should be $appendcount for append"
3147
3148         # Now test O_APPEND striping with pools
3149         pool_add $TESTNAME || error "pool creation failed"
3150         pool_add_targets $TESTNAME 0 1 || error "Pool add targets failed"
3151         do_nodes $mdts $LCTL set_param mdd.*.append_pool="$TESTNAME"
3152
3153         echo 1 >> $DIR/$tdir/${tfile}.10_append
3154
3155         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.10_append)
3156         [ "$pool" = "$TESTNAME" ] || error "(10) incorrect pool: $pool"
3157
3158         # Check that count is still correct
3159         appendcount=1
3160         echo 1 >> $DIR/$tdir/${tfile}.11_append
3161         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.11_append)
3162         [ $count -eq $appendcount ] ||
3163                 error "(11) stripe count $count, should be $appendcount for append"
3164
3165         # Disable O_APPEND stripe count, verify pool works separately
3166         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
3167
3168         echo 1 >> $DIR/$tdir/${tfile}.12_append
3169
3170         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.12_append)
3171         [ "$pool" = "$TESTNAME" ] || error "(12) incorrect pool: $pool"
3172
3173         # Remove pool setting, verify it's not applied
3174         do_nodes $mdts $LCTL set_param mdd.*.append_pool='none'
3175
3176         echo 1 >> $DIR/$tdir/${tfile}.13_append
3177
3178         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.13_append)
3179         [ "$pool" = "" ] || error "(13) pool found: $pool"
3180 }
3181 run_test 27M "test O_APPEND striping"
3182
3183 test_27N() {
3184         combined_mgs_mds && skip "needs separate MGS/MDT"
3185
3186         pool_add $TESTNAME || error "pool_add failed"
3187         do_facet mgs "$LCTL pool_list $FSNAME" |
3188                 grep -Fx "${FSNAME}.${TESTNAME}" ||
3189                 error "lctl pool_list on MGS failed"
3190 }
3191 run_test 27N "lctl pool_list on separate MGS gives correct pool name"
3192
3193 clean_foreign_symlink() {
3194         trap 0
3195         lctl set_param llite/$FSNAME-*/foreign_symlink_enable=0
3196         for i in $DIR/$tdir/* ; do
3197                 $LFS unlink_foreign $i || true
3198         done
3199 }
3200
3201 test_27O() {
3202         [[ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.12.51) ]] &&
3203                 skip "Need MDS version newer than 2.12.51"
3204
3205         test_mkdir $DIR/$tdir
3206         local uuid1=$(cat /proc/sys/kernel/random/uuid)
3207         local uuid2=$(cat /proc/sys/kernel/random/uuid)
3208
3209         trap clean_foreign_symlink EXIT
3210
3211         # enable foreign_symlink behaviour
3212         $LCTL set_param llite/$FSNAME-*/foreign_symlink_enable=1
3213
3214         # foreign symlink LOV format is a partial path by default
3215
3216         # create foreign file (lfs + API)
3217         $LFS setstripe --foreign=symlink --flags 0xda05 \
3218                 -x "${uuid1}/${uuid2}" --mode 0600 $DIR/$tdir/${tfile} ||
3219                 error "$DIR/$tdir/${tfile}: create failed"
3220
3221         $LFS getstripe -v $DIR/$tdir/${tfile} |
3222                 grep "lfm_magic:.*0x0BD70BD0" ||
3223                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign magic"
3224         $LFS getstripe -v $DIR/$tdir/${tfile} | grep "lfm_type:.*symlink" ||
3225                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign type"
3226         $LFS getstripe -v $DIR/$tdir/${tfile} |
3227                 grep "lfm_flags:.*0x0000DA05" ||
3228                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign flags"
3229         $LFS getstripe $DIR/$tdir/${tfile} |
3230                 grep "lfm_value:.*${uuid1}/${uuid2}" ||
3231                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign value"
3232
3233         # modify striping should fail
3234         $LFS setstripe -c 2 $DIR/$tdir/$tfile &&
3235                 error "$DIR/$tdir/$tfile: setstripe should fail"
3236
3237         # R/W should fail ("/{foreign_symlink_prefix}/${uuid1}/" missing)
3238         cat $DIR/$tdir/$tfile && error "$DIR/$tdir/$tfile: read should fail"
3239         cat /etc/passwd > $DIR/$tdir/$tfile &&
3240                 error "$DIR/$tdir/$tfile: write should fail"
3241
3242         # rename should succeed
3243         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}.new ||
3244                 error "$DIR/$tdir/$tfile: rename has failed"
3245
3246         #remove foreign_symlink file should fail
3247         rm $DIR/$tdir/${tfile}.new &&
3248                 error "$DIR/$tdir/${tfile}.new: remove of foreign_symlink file should fail"
3249
3250         #test fake symlink
3251         mkdir /tmp/${uuid1} ||
3252                 error "/tmp/${uuid1}: mkdir has failed"
3253         echo FOOFOO > /tmp/${uuid1}/${uuid2} ||
3254                 error "/tmp/${uuid1}/${uuid2}: echo has failed"
3255         $LCTL set_param llite/$FSNAME-*/foreign_symlink_prefix=/tmp/
3256         $CHECKSTAT -t link -l /tmp/${uuid1}/${uuid2} $DIR/$tdir/${tfile}.new ||
3257                 error "$DIR/$tdir/${tfile}.new: not seen as a symlink"
3258         #read should succeed now
3259         cat $DIR/$tdir/${tfile}.new | grep FOOFOO ||
3260                 error "$DIR/$tdir/${tfile}.new: symlink resolution has failed"
3261         #write should succeed now
3262         cat /etc/passwd > $DIR/$tdir/${tfile}.new ||
3263                 error "$DIR/$tdir/${tfile}.new: write should succeed"
3264         diff /etc/passwd $DIR/$tdir/${tfile}.new ||
3265                 error "$DIR/$tdir/${tfile}.new: diff has failed"
3266         diff /etc/passwd /tmp/${uuid1}/${uuid2} ||
3267                 error "/tmp/${uuid1}/${uuid2}: diff has failed"
3268
3269         #check that getstripe still works
3270         $LFS getstripe $DIR/$tdir/${tfile}.new ||
3271                 error "$DIR/$tdir/${tfile}.new: getstripe should still work with foreign_symlink enabled"
3272
3273         # chmod should still succeed
3274         chmod 644 $DIR/$tdir/${tfile}.new ||
3275                 error "$DIR/$tdir/${tfile}.new: chmod has failed"
3276
3277         # chown should still succeed
3278         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tfile}.new ||
3279                 error "$DIR/$tdir/${tfile}.new: chown has failed"
3280
3281         # rename should still succeed
3282         mv $DIR/$tdir/${tfile}.new $DIR/$tdir/${tfile} ||
3283                 error "$DIR/$tdir/${tfile}.new: rename has failed"
3284
3285         #remove foreign_symlink file should still fail
3286         rm $DIR/$tdir/${tfile} &&
3287                 error "$DIR/$tdir/${tfile}: remove of foreign_symlink file should fail"
3288
3289         #use special ioctl() to unlink foreign_symlink file
3290         $LFS unlink_foreign $DIR/$tdir/${tfile} ||
3291                 error "$DIR/$tdir/$tfile: unlink/ioctl failed"
3292
3293 }
3294 run_test 27O "basic ops on foreign file of symlink type"
3295
3296 test_27P() {
3297         [[ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.12.49) ]] &&
3298                 skip "Need MDS version newer than 2.12.49"
3299
3300         test_mkdir $DIR/$tdir
3301         local uuid1=$(cat /proc/sys/kernel/random/uuid)
3302         local uuid2=$(cat /proc/sys/kernel/random/uuid)
3303
3304         trap clean_foreign_symlink EXIT
3305
3306         # enable foreign_symlink behaviour
3307         $LCTL set_param llite/$FSNAME-*/foreign_symlink_enable=1
3308
3309         # foreign symlink LMV format is a partial path by default
3310
3311         # create foreign dir (lfs + API)
3312         $LFS mkdir --foreign=symlink --xattr="${uuid1}/${uuid2}" \
3313                 --flags=0xda05 --mode 0750 $DIR/$tdir/${tdir} ||
3314                 error "$DIR/$tdir/${tdir}: create failed"
3315
3316         $LFS getdirstripe -v $DIR/$tdir/${tdir}
3317
3318         $LFS getdirstripe -v $DIR/$tdir/${tdir} |
3319                 grep "lfm_magic:.*0x0CD50CD0" ||
3320                 error "$DIR/$tdir/${tdir}: invalid LMV EA magic"
3321         $LFS getdirstripe -v $DIR/$tdir/${tdir} | grep "lfm_type:.*symlink" ||
3322                 error "$DIR/$tdir/${tdir}: invalid LMV EA type"
3323         $LFS getdirstripe -v $DIR/$tdir/${tdir} |
3324                 grep "lfm_flags:.*0x0000DA05" ||
3325                 error "$DIR/$tdir/${tdir}: invalid LMV EA flags"
3326         $LFS getdirstripe $DIR/$tdir/${tdir} |
3327                 grep "lfm_value.*${uuid1}/${uuid2}" ||
3328                 error "$DIR/$tdir/${tdir}: invalid LMV EA value"
3329
3330         # file create in dir should fail
3331         # ("/{foreign_symlink_prefix}/${uuid1}/${uuid2}/" missing)
3332         touch $DIR/$tdir/$tdir/$tfile && error "$DIR/$tdir: file create should fail"
3333
3334         # rename should succeed
3335         mv $DIR/$tdir/$tdir $DIR/$tdir/${tdir}.new ||
3336                 error "$DIR/$tdir/$tdir: rename of foreign_symlink dir has failed"
3337
3338         #remove foreign_symlink dir should fail
3339         rmdir $DIR/$tdir/${tdir}.new &&
3340                 error "$DIR/$tdir/${tdir}.new: remove of foreign_symlink dir should fail"
3341
3342         #test fake symlink
3343         mkdir -p /tmp/${uuid1}/${uuid2} ||
3344                 error "/tmp/${uuid1}/${uuid2}: mkdir has failed"
3345         echo FOOFOO > /tmp/${uuid1}/${uuid2}/foo ||
3346                 error "/tmp/${uuid1}/${uuid2}/foo: echo has failed"
3347         $LCTL set_param llite/$FSNAME-*/foreign_symlink_prefix=/tmp/
3348         $CHECKSTAT -t link -l /tmp/${uuid1}/${uuid2} $DIR/$tdir/${tdir}.new ||
3349                 error "$DIR/$tdir/${tdir}.new: not seen as a symlink"
3350         cat $DIR/$tdir/${tdir}.new/foo | grep FOOFOO ||
3351                 error "$DIR/$tdir/${tdir}.new: symlink resolution has failed"
3352
3353         #check that getstripe fails now that foreign_symlink enabled
3354         $LFS getdirstripe $DIR/$tdir/${tdir}.new ||
3355                 error "$DIR/$tdir/${tdir}.new: getdirstripe should still work with foreign_symlink enabled"
3356
3357         # file create in dir should work now
3358         cp /etc/passwd $DIR/$tdir/${tdir}.new/$tfile ||
3359                 error "$DIR/$tdir/${tdir}.new/$tfile: file create should fail"
3360         diff /etc/passwd $DIR/$tdir/${tdir}.new/$tfile ||
3361                 error "$DIR/$tdir/${tdir}.new/$tfile: diff has failed"
3362         diff /etc/passwd /tmp/${uuid1}/${uuid2}/$tfile ||
3363                 error "/tmp/${uuid1}/${uuid2}/$tfile: diff has failed"
3364
3365         # chmod should still succeed
3366         chmod 755 $DIR/$tdir/${tdir}.new ||
3367                 error "$DIR/$tdir/${tdir}.new: chmod has failed"
3368
3369         # chown should still succeed
3370         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tdir}.new ||
3371                 error "$DIR/$tdir/${tdir}.new: chown has failed"
3372
3373         # rename should still succeed
3374         mv $DIR/$tdir/${tdir}.new $DIR/$tdir/${tdir} ||
3375                 error "$DIR/$tdir/${tdir}.new: rename of foreign_symlink dir has failed"
3376
3377         #remove foreign_symlink dir should still fail
3378         rmdir $DIR/$tdir/${tdir} &&
3379                 error "$DIR/$tdir/${tdir}: remove of foreign_symlink dir should fail"
3380
3381         #use special ioctl() to unlink foreign_symlink file
3382         $LFS unlink_foreign $DIR/$tdir/${tdir} ||
3383                 error "$DIR/$tdir/$tdir: unlink/ioctl failed"
3384
3385         #created file should still exist
3386         [[ -f /tmp/${uuid1}/${uuid2}/$tfile ]] ||
3387                 error "/tmp/${uuid1}/${uuid2}/$tfile has been removed"
3388         diff /etc/passwd /tmp/${uuid1}/${uuid2}/$tfile ||
3389                 error "/tmp/${uuid1}/${uuid2}/$tfile: diff has failed"
3390 }
3391 run_test 27P "basic ops on foreign dir of foreign_symlink type"
3392
3393 test_27Q() {
3394         rm -f $TMP/$tfile $TMP/$tfile.loop $TMP/$tfile.none $TMP/$tfile.broken
3395         stack_trap "rm -f $TMP/$tfile*"
3396
3397         test_mkdir $DIR/$tdir-1
3398         test_mkdir $DIR/$tdir-2
3399
3400         echo 'It is what it is' > $DIR/$tdir-1/$tfile
3401         lov_getstripe_old $DIR/$tdir-1/$tfile || error "$DIR/$tdir-1/$tfile: rc = $?"
3402
3403         ln -s $DIR/$tdir-1/$tfile $DIR/$tdir-2/$tfile
3404         lov_getstripe_old $DIR/$tdir-2/$tfile || error "$DIR/$tdir-2/$tfile: rc = $?"
3405
3406         ln -s $DIR/$tdir-1/$tfile $TMP/$tfile
3407         lov_getstripe_old $TMP/$tfile || error "$TMP/$tfile: rc = $?"
3408
3409         # Create some bad symlinks and ensure that we don't loop
3410         # forever or something. These should return ELOOP (40) and
3411         # ENOENT (2) but I don't want to test for that because there's
3412         # always some weirdo architecture that needs to ruin
3413         # everything by defining these error numbers differently.
3414
3415         ln -s $TMP/$tfile.loop $TMP/$tfile.loop
3416         lov_getstripe_old $TMP/$tfile.loop && error "$TMP/$tfile.loop: rc = $?"
3417
3418         ln -s $TMP/$tfile.none $TMP/$tfile.broken
3419         lov_getstripe_old $TMP/$tfile.broken && error "$TMP/$tfile.broken: rc = $?"
3420
3421         return 0
3422 }
3423 run_test 27Q "llapi_file_get_stripe() works on symlinks"
3424
3425 test_27R() {
3426         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
3427                 skip "need MDS 2.14.55 or later"
3428         (( $OSTCOUNT >= 2 )) || skip_env "needs at least 2 OSTs"
3429
3430         local testdir="$DIR/$tdir"
3431         test_mkdir -p $testdir
3432         stack_trap "rm -rf $testdir"
3433         $LFS setstripe -c -1 $testdir || error "setstripe failed"
3434
3435         local f1="$testdir/f1"
3436         touch $f1 || error "failed to touch $f1"
3437         local count=$($LFS getstripe -c $f1)
3438         (( $count == $OSTCOUNT )) || error "wrong stripe count"
3439
3440         do_facet $SINGLEMDS $LCTL set_param lod.*.max_stripecount=-1
3441         (( $? == 34 )) || error "setting max_stripecount to -1 should fail and return ERANGE"
3442
3443         local maxcount=$(($OSTCOUNT - 1))
3444         local mdts=$(comma_list $(mdts_nodes))
3445         do_nodes $mdts $LCTL set_param lod.*.max_stripecount=$maxcount
3446         stack_trap "do_nodes $mdts $LCTL set_param lod.*.max_stripecount=0"
3447
3448         local f2="$testdir/f2"
3449         touch $f2 || error "failed to touch $f2"
3450         local count=$($LFS getstripe -c $f2)
3451         (( $count == $maxcount )) || error "wrong stripe count"
3452 }
3453 run_test 27R "test max_stripecount limitation when stripe count is set to -1"
3454
3455 test_27T() {
3456         [ $(facet_host client) == $(facet_host ost1) ] &&
3457                 skip "need ost1 and client on different nodes"
3458
3459 #define OBD_FAIL_OSC_NO_GRANT            0x411
3460         $LCTL set_param fail_loc=0x20000411 fail_val=1
3461 #define OBD_FAIL_OST_ENOSPC              0x215
3462         do_facet ost1 "$LCTL set_param fail_loc=0x80000215"
3463         $LFS setstripe -i 0 -c 1 $DIR/$tfile
3464         $MULTIOP $DIR/$tfile oO_WRONLY:P$((4 * 1024 * 1024 + 10 * 4096))c ||
3465                 error "multiop failed"
3466 }
3467 run_test 27T "no eio on close on partial write due to enosp"
3468
3469 test_27U() {
3470         local dir=$DIR/$tdir
3471         local file=$dir/$tfile
3472         local append_pool=${TESTNAME}-append
3473         local normal_pool=${TESTNAME}-normal
3474         local pool
3475         local stripe_count
3476         local stripe_count2
3477         local mdts=$(comma_list $(mdts_nodes))
3478
3479         (( $MDS1_VERSION >= $(version_code 2.15.51) )) ||
3480                 skip "Need MDS version at least 2.15.51 for append pool feature"
3481
3482         # Validate existing append_* params and ensure restore
3483         pool=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_pool)
3484         [[ "$pool" == "" ]] || error "expected append_pool == '', got '$pool'"
3485         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_pool=none"
3486
3487         stripe_count=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_stripe_count)
3488         ((stripe_count == 1)) || error "expected append_stripe_count != 0, got $stripe_count"
3489         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=$stripe_count"
3490
3491         pool_add $append_pool || error "pool creation failed"
3492         pool_add_targets $append_pool 0 1 || error "Pool add targets failed"
3493
3494         pool_add $normal_pool || error "pool creation failed"
3495         pool_add_targets $normal_pool 0 1 || error "Pool add targets failed"
3496
3497         test_mkdir $dir
3498         $LFS setstripe -E 1M -c 1 -p $normal_pool -E 2M -c 2 -p $normal_pool -E eof -c -1 $dir
3499
3500         echo XXX >> $file.1
3501         $LFS getstripe $file.1
3502
3503         pool=$($LFS getstripe -p $file.1)
3504         [[ "$pool" == "$normal_pool" ]] || error "got pool '$pool', expected '$normal_pool'"
3505
3506         stripe_count2=$($LFS getstripe -c $file.1)
3507         ((stripe_count2 == stripe_count)) ||
3508                 error "got stripe_count '$stripe_count2', expected '$stripe_count'"
3509
3510         do_nodes $mdts $LCTL set_param mdd.*.append_pool=$append_pool
3511
3512         echo XXX >> $file.2
3513         $LFS getstripe $file.2
3514
3515         pool=$($LFS getstripe -p $file.2)
3516         [[ "$pool" == "$append_pool" ]] || error "got pool '$pool', expected '$append_pool'"
3517
3518         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=2
3519
3520         echo XXX >> $file.3
3521         $LFS getstripe $file.3
3522
3523         stripe_count2=$($LFS getstripe -c $file.3)
3524         ((stripe_count2 == 2)) || error "got stripe_count '$stripe_count2', expected 2"
3525 }
3526 run_test 27U "append pool and stripe count work with composite default layout"
3527
3528 # createtest also checks that device nodes are created and
3529 # then visible correctly (#2091)
3530 test_28() { # bug 2091
3531         test_mkdir $DIR/d28
3532         $CREATETEST $DIR/d28/ct || error "createtest failed"
3533 }
3534 run_test 28 "create/mknod/mkdir with bad file types ============"
3535
3536 test_29() {
3537         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3538
3539         [ $MDS1_VERSION -ge $(version_code 2.14.51) ] && {
3540                 disable_opencache
3541                 stack_trap "restore_opencache"
3542         }
3543
3544         sync; sleep 1; sync # flush out any dirty pages from previous tests
3545         cancel_lru_locks
3546         test_mkdir $DIR/d29
3547         touch $DIR/d29/foo
3548         log 'first d29'
3549         ls -l $DIR/d29
3550
3551         declare -i LOCKCOUNTORIG=0
3552         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
3553                 let LOCKCOUNTORIG=$LOCKCOUNTORIG+$lock_count
3554         done
3555         [ $LOCKCOUNTORIG -eq 0 ] && error "No mdc lock count" && return 1
3556
3557         declare -i LOCKUNUSEDCOUNTORIG=0
3558         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3559                 let LOCKUNUSEDCOUNTORIG=$LOCKUNUSEDCOUNTORIG+$unused_count
3560         done
3561
3562         log 'second d29'
3563         ls -l $DIR/d29
3564         log 'done'
3565
3566         declare -i LOCKCOUNTCURRENT=0
3567         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
3568                 let LOCKCOUNTCURRENT=$LOCKCOUNTCURRENT+$lock_count
3569         done
3570
3571         declare -i LOCKUNUSEDCOUNTCURRENT=0
3572         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3573                 let LOCKUNUSEDCOUNTCURRENT=$LOCKUNUSEDCOUNTCURRENT+$unused_count
3574         done
3575
3576         if [[ $LOCKCOUNTCURRENT -gt $LOCKCOUNTORIG ]]; then
3577                 $LCTL set_param -n ldlm.dump_namespaces ""
3578                 error "CURRENT: $LOCKCOUNTCURRENT > $LOCKCOUNTORIG"
3579                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3580                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3581                 return 2
3582         fi
3583         if [[ $LOCKUNUSEDCOUNTCURRENT -gt $LOCKUNUSEDCOUNTORIG ]]; then
3584                 error "UNUSED: $LOCKUNUSEDCOUNTCURRENT > $LOCKUNUSEDCOUNTORIG"
3585                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3586                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3587                 return 3
3588         fi
3589 }
3590 run_test 29 "IT_GETATTR regression  ============================"
3591
3592 test_30a() { # was test_30
3593         cp $(which ls) $DIR || cp /bin/ls $DIR
3594         $DIR/ls / || error "Can't execute binary from lustre"
3595         rm $DIR/ls
3596 }
3597 run_test 30a "execute binary from Lustre (execve) =============="
3598
3599 test_30b() {
3600         cp `which ls` $DIR || cp /bin/ls $DIR
3601         chmod go+rx $DIR/ls
3602         $RUNAS $DIR/ls / || error "Can't execute binary from lustre as non-root"
3603         rm $DIR/ls
3604 }
3605 run_test 30b "execute binary from Lustre as non-root ==========="
3606
3607 test_30c() { # b=22376
3608         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3609
3610         cp $(which ls) $DIR || cp /bin/ls $DIR
3611         chmod a-rw $DIR/ls
3612         cancel_lru_locks mdc
3613         cancel_lru_locks osc
3614         $RUNAS $DIR/ls / || error "Can't execute binary from lustre"
3615         rm -f $DIR/ls
3616 }
3617 run_test 30c "execute binary from Lustre without read perms ===="
3618
3619 test_30d() {
3620         cp $(which dd) $DIR || error "failed to copy dd to $DIR/dd"
3621
3622         for i in {1..10}; do
3623                 $DIR/dd bs=1M count=128 if=/dev/zero of=$DIR/$tfile &
3624                 local PID=$!
3625                 sleep 1
3626                 $LCTL set_param ldlm.namespaces.*MDT*.lru_size=clear
3627                 wait $PID || error "executing dd from Lustre failed"
3628                 rm -f $DIR/$tfile
3629         done
3630
3631         rm -f $DIR/dd
3632 }
3633 run_test 30d "execute binary from Lustre while clear locks"
3634
3635 test_31a() {
3636         $OPENUNLINK $DIR/f31 $DIR/f31 || error "openunlink failed"
3637         $CHECKSTAT -a $DIR/f31 || error "$DIR/f31 exists"
3638 }
3639 run_test 31a "open-unlink file =================================="
3640
3641 test_31b() {
3642         touch $DIR/f31 || error "touch $DIR/f31 failed"
3643         ln $DIR/f31 $DIR/f31b || error "ln failed"
3644         $MULTIOP $DIR/f31b Ouc || error "multiop failed"
3645         $CHECKSTAT -t file $DIR/f31 || error "$DIR/f31 not file type"
3646 }
3647 run_test 31b "unlink file with multiple links while open ======="
3648
3649 test_31c() {
3650         touch $DIR/f31 || error "touch $DIR/f31 failed"
3651         ln $DIR/f31 $DIR/f31c || error "ln failed"
3652         multiop_bg_pause $DIR/f31 O_uc ||
3653                 error "multiop_bg_pause for $DIR/f31 failed"
3654         MULTIPID=$!
3655         $MULTIOP $DIR/f31c Ouc
3656         kill -USR1 $MULTIPID
3657         wait $MULTIPID
3658 }
3659 run_test 31c "open-unlink file with multiple links ============="
3660
3661 test_31d() {
3662         opendirunlink $DIR/d31d $DIR/d31d || error "opendirunlink failed"
3663         $CHECKSTAT -a $DIR/d31d || error "$DIR/d31d exists"
3664 }
3665 run_test 31d "remove of open directory ========================="
3666
3667 test_31e() { # bug 2904
3668         openfilleddirunlink $DIR/d31e || error "openfilleddirunlink failed"
3669 }
3670 run_test 31e "remove of open non-empty directory ==============="
3671
3672 test_31f() { # bug 4554
3673         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3674
3675         set -vx
3676         test_mkdir $DIR/d31f
3677         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3678         cp /etc/hosts $DIR/d31f
3679         ls -l $DIR/d31f
3680         $LFS getstripe $DIR/d31f/hosts
3681         multiop_bg_pause $DIR/d31f D_c || return 1
3682         MULTIPID=$!
3683
3684         rm -rv $DIR/d31f || error "first of $DIR/d31f"
3685         test_mkdir $DIR/d31f
3686         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3687         cp /etc/hosts $DIR/d31f
3688         ls -l $DIR/d31f
3689         $LFS getstripe $DIR/d31f/hosts
3690         multiop_bg_pause $DIR/d31f D_c || return 1
3691         MULTIPID2=$!
3692
3693         kill -USR1 $MULTIPID || error "first opendir $MULTIPID not running"
3694         wait $MULTIPID || error "first opendir $MULTIPID failed"
3695
3696         sleep 6
3697
3698         kill -USR1 $MULTIPID2 || error "second opendir $MULTIPID not running"
3699         wait $MULTIPID2 || error "second opendir $MULTIPID2 failed"
3700         set +vx
3701 }
3702 run_test 31f "remove of open directory with open-unlink file ==="
3703
3704 test_31g() {
3705         echo "-- cross directory link --"
3706         test_mkdir -c1 $DIR/${tdir}ga
3707         test_mkdir -c1 $DIR/${tdir}gb
3708         touch $DIR/${tdir}ga/f
3709         ln $DIR/${tdir}ga/f $DIR/${tdir}gb/g
3710         $CHECKSTAT -t file $DIR/${tdir}ga/f || error "source"
3711         [ `stat -c%h $DIR/${tdir}ga/f` == '2' ] || error "source nlink"
3712         $CHECKSTAT -t file $DIR/${tdir}gb/g || error "target"
3713         [ `stat -c%h $DIR/${tdir}gb/g` == '2' ] || error "target nlink"
3714 }
3715 run_test 31g "cross directory link==============="
3716
3717 test_31h() {
3718         echo "-- cross directory link --"
3719         test_mkdir -c1 $DIR/${tdir}
3720         test_mkdir -c1 $DIR/${tdir}/dir
3721         touch $DIR/${tdir}/f
3722         ln $DIR/${tdir}/f $DIR/${tdir}/dir/g
3723         $CHECKSTAT -t file $DIR/${tdir}/f || error "source"
3724         [ `stat -c%h $DIR/${tdir}/f` == '2' ] || error "source nlink"
3725         $CHECKSTAT -t file $DIR/${tdir}/dir/g || error "target"
3726         [ `stat -c%h $DIR/${tdir}/dir/g` == '2' ] || error "target nlink"
3727 }
3728 run_test 31h "cross directory link under child==============="
3729
3730 test_31i() {
3731         echo "-- cross directory link --"
3732         test_mkdir -c1 $DIR/$tdir
3733         test_mkdir -c1 $DIR/$tdir/dir
3734         touch $DIR/$tdir/dir/f
3735         ln $DIR/$tdir/dir/f $DIR/$tdir/g
3736         $CHECKSTAT -t file $DIR/$tdir/dir/f || error "source"
3737         [ `stat -c%h $DIR/$tdir/dir/f` == '2' ] || error "source nlink"
3738         $CHECKSTAT -t file $DIR/$tdir/g || error "target"
3739         [ `stat -c%h $DIR/$tdir/g` == '2' ] || error "target nlink"
3740 }
3741 run_test 31i "cross directory link under parent==============="
3742
3743 test_31j() {
3744         test_mkdir -c1 -p $DIR/$tdir
3745         test_mkdir -c1 -p $DIR/$tdir/dir1
3746         ln $DIR/$tdir/dir1 $DIR/$tdir/dir2 && error "ln for dir"
3747         link $DIR/$tdir/dir1 $DIR/$tdir/dir3 && error "link for dir"
3748         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir4 && error "mlink for dir"
3749         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir1 && error "mlink to the same dir"
3750         return 0
3751 }
3752 run_test 31j "link for directory==============="
3753
3754 test_31k() {
3755         test_mkdir -c1 -p $DIR/$tdir
3756         touch $DIR/$tdir/s
3757         touch $DIR/$tdir/exist
3758         mlink $DIR/$tdir/s $DIR/$tdir/t || error "mlink"
3759         mlink $DIR/$tdir/s $DIR/$tdir/exist && error "mlink to exist file"
3760         mlink $DIR/$tdir/s $DIR/$tdir/s && error "mlink to the same file"
3761         mlink $DIR/$tdir/s $DIR/$tdir && error "mlink to parent dir"
3762         mlink $DIR/$tdir $DIR/$tdir/s && error "mlink parent dir to target"
3763         mlink $DIR/$tdir/not-exist $DIR/$tdir/foo && error "mlink non-existing to new"
3764         mlink $DIR/$tdir/not-exist $DIR/$tdir/s && error "mlink non-existing to exist"
3765         return 0
3766 }
3767 run_test 31k "link to file: the same, non-existing, dir==============="
3768
3769 test_31l() {
3770         local ln_ver=$(ln --version | awk '/coreutils/ { print $4 }')
3771
3772         (( $(version_code $ln_ver) < $(version_code 8.31) )) ||
3773         (( $(version_code $(uname -r)) >= $(version_code 5.18) )) ||
3774                 skip "need coreutils < 8.31 or kernel >= 5.18 for ln"
3775
3776         touch $DIR/$tfile || error "create failed"
3777         mkdir $DIR/$tdir || error "mkdir failed"
3778         ln $DIR/$tfile $DIR/$tdir/ || error "ln to '$tdir/' failed"
3779 }
3780 run_test 31l "link to file: target dir has trailing slash"
3781
3782 test_31m() {
3783         mkdir $DIR/d31m
3784         touch $DIR/d31m/s
3785         mkdir $DIR/d31m2
3786         touch $DIR/d31m2/exist
3787         mlink $DIR/d31m/s $DIR/d31m2/t || error "mlink"
3788         mlink $DIR/d31m/s $DIR/d31m2/exist && error "mlink to exist file"
3789         mlink $DIR/d31m/s $DIR/d31m2 && error "mlink to parent dir"
3790         mlink $DIR/d31m2 $DIR/d31m/s && error "mlink parent dir to target"
3791         mlink $DIR/d31m/not-exist $DIR/d31m2/foo && error "mlink non-existing to new"
3792         mlink $DIR/d31m/not-exist $DIR/d31m2/s && error "mlink non-existing to exist"
3793         return 0
3794 }
3795 run_test 31m "link to file: the same, non-existing, dir==============="
3796
3797 test_31n() {
3798         touch $DIR/$tfile || error "cannot create '$DIR/$tfile'"
3799         nlink=$(stat --format=%h $DIR/$tfile)
3800         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3801         local fd=$(free_fd)
3802         local cmd="exec $fd<$DIR/$tfile"
3803         eval $cmd
3804         cmd="exec $fd<&-"
3805         trap "eval $cmd" EXIT
3806         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3807         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3808         rm $DIR/$tfile || error "cannot remove '$DIR/$tfile'"
3809         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3810         [ ${nlink:--1} -eq 0 ] || error "nlink is $nlink, expected 0"
3811         eval $cmd
3812 }
3813 run_test 31n "check link count of unlinked file"
3814
3815 link_one() {
3816         local tempfile=$(mktemp $1_XXXXXX)
3817         mlink $tempfile $1 2> /dev/null &&
3818                 echo "$BASHPID: link $tempfile to $1 succeeded"
3819         munlink $tempfile
3820 }
3821
3822 test_31o() { # LU-2901
3823         test_mkdir $DIR/$tdir
3824         for LOOP in $(seq 100); do
3825                 rm -f $DIR/$tdir/$tfile*
3826                 for THREAD in $(seq 8); do
3827                         link_one $DIR/$tdir/$tfile.$LOOP &
3828                 done
3829                 wait
3830                 local LINKS=$(ls -1 $DIR/$tdir | grep -c $tfile.$LOOP)
3831                 [[ $LINKS -gt 1 ]] && ls $DIR/$tdir &&
3832                         error "$LINKS duplicate links to $tfile.$LOOP" &&
3833                         break || true
3834         done
3835 }
3836 run_test 31o "duplicate hard links with same filename"
3837
3838 test_31p() {
3839         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3840
3841         test_mkdir $DIR/$tdir
3842         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3843         $LFS setdirstripe -D -c2 -H all_char $DIR/$tdir/striped_dir
3844
3845         opendirunlink $DIR/$tdir/striped_dir/test1 ||
3846                 error "open unlink test1 failed"
3847         opendirunlink $DIR/$tdir/striped_dir/test2 ||
3848                 error "open unlink test2 failed"
3849
3850         $CHECKSTAT -a $DIR/$tdir/striped_dir/test1 ||
3851                 error "test1 still exists"
3852         $CHECKSTAT -a $DIR/$tdir/striped_dir/test2 ||
3853                 error "test2 still exists"
3854 }
3855 run_test 31p "remove of open striped directory"
3856
3857 test_31q() {
3858         [ $MDSCOUNT -lt 3 ] && skip_env "needs >= 3 MDTs"
3859
3860         $LFS mkdir -i 3,1 $DIR/$tdir || error "mkdir failed"
3861         index=$($LFS getdirstripe -i $DIR/$tdir)
3862         [ $index -eq 3 ] || error "first stripe index $index != 3"
3863         index=$($LFS getdirstripe $DIR/$tdir | tail -1 | awk '{print $1}')
3864         [ $index -eq 1 ] || error "second stripe index $index != 1"
3865
3866         # when "-c <stripe_count>" is set, the number of MDTs specified after
3867         # "-i" should equal to the stripe count
3868         $LFS mkdir -i 3,1 -c 3 $DIR/$tdir.2 && error "mkdir should fail" || true
3869 }
3870 run_test 31q "create striped directory on specific MDTs"
3871
3872 #LU-14949
3873 test_31r() {
3874         touch $DIR/$tfile.target
3875         touch $DIR/$tfile.source
3876
3877         #OBD_FAIL_LLITE_OPEN_DELAY 0x1419
3878         $LCTL set_param fail_loc=0x1419 fail_val=3
3879         cat $DIR/$tfile.target &
3880         CATPID=$!
3881
3882         # Guarantee open is waiting before we get here
3883         sleep 1
3884         mv $DIR/$tfile.source $DIR/$tfile.target
3885
3886         wait $CATPID
3887         RC=$?
3888         if [[ $RC -ne 0 ]]; then
3889                 error "open with cat failed, rc=$RC"
3890         fi
3891 }
3892 run_test 31r "open-rename(replace) race"
3893
3894 cleanup_test32_mount() {
3895         local rc=0
3896         trap 0
3897         local loopdev=$(losetup -a | grep $EXT2_DEV | sed -ne 's/:.*$//p')
3898         $UMOUNT $DIR/$tdir/ext2-mountpoint || rc=$?
3899         losetup -d $loopdev || true
3900         rm -rf $DIR/$tdir
3901         return $rc
3902 }
3903
3904 test_32a() {
3905         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3906
3907         echo "== more mountpoints and symlinks ================="
3908         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3909         trap cleanup_test32_mount EXIT
3910         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3911         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3912                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3913         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/.. ||
3914                 error "$DIR/$tdir/ext2-mountpoint/.. not dir type"
3915         cleanup_test32_mount
3916 }
3917 run_test 32a "stat d32a/ext2-mountpoint/.. ====================="
3918
3919 test_32b() {
3920         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3921
3922         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3923         trap cleanup_test32_mount EXIT
3924         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3925         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3926                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3927         ls -al $DIR/$tdir/ext2-mountpoint/.. ||
3928                 error "Can't list $DIR/$tdir/ext2-mountpoint/.."
3929         cleanup_test32_mount
3930 }
3931 run_test 32b "open d32b/ext2-mountpoint/.. ====================="
3932
3933 test_32c() {
3934         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3935
3936         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3937         trap cleanup_test32_mount EXIT
3938         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3939         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3940                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3941         test_mkdir -p $DIR/$tdir/d2/test_dir
3942         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3943                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_dir not dir type"
3944         cleanup_test32_mount
3945 }
3946 run_test 32c "stat d32c/ext2-mountpoint/../d2/test_dir ========="
3947
3948 test_32d() {
3949         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3950
3951         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3952         trap cleanup_test32_mount EXIT
3953         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3954         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3955                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3956         test_mkdir -p $DIR/$tdir/d2/test_dir
3957         ls -al $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3958                 error "Can't list $DIR/$tdir/ext2-mountpoint/../d2/test_dir"
3959         cleanup_test32_mount
3960 }
3961 run_test 32d "open d32d/ext2-mountpoint/../d2/test_dir"
3962
3963 test_32e() {
3964         rm -fr $DIR/$tdir
3965         test_mkdir -p $DIR/$tdir/tmp
3966         local tmp_dir=$DIR/$tdir/tmp
3967         ln -s $DIR/$tdir $tmp_dir/symlink11
3968         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3969         $CHECKSTAT -t link $DIR/$tdir/tmp/symlink11 || error "symlink11 bad"
3970         $CHECKSTAT -t link $DIR/$tdir/symlink01 || error "symlink01 bad"
3971 }
3972 run_test 32e "stat d32e/symlink->tmp/symlink->lustre-subdir"
3973
3974 test_32f() {
3975         rm -fr $DIR/$tdir
3976         test_mkdir -p $DIR/$tdir/tmp
3977         local tmp_dir=$DIR/$tdir/tmp
3978         ln -s $DIR/$tdir $tmp_dir/symlink11
3979         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3980         ls $DIR/$tdir/tmp/symlink11  || error "symlink11 bad"
3981         ls $DIR/$tdir/symlink01 || error "symlink01 bad"
3982 }
3983 run_test 32f "open d32f/symlink->tmp/symlink->lustre-subdir"
3984
3985 test_32g() {
3986         local tmp_dir=$DIR/$tdir/tmp
3987         test_mkdir -p $tmp_dir
3988         test_mkdir $DIR/${tdir}2
3989         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3990         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3991         $CHECKSTAT -t link $tmp_dir/symlink12 || error "symlink12 not a link"
3992         $CHECKSTAT -t link $DIR/$tdir/symlink02 || error "symlink02 not a link"
3993         $CHECKSTAT -t dir -f $tmp_dir/symlink12 || error "symlink12 not a dir"
3994         $CHECKSTAT -t dir -f $DIR/$tdir/symlink02 || error "symlink12 not a dir"
3995 }
3996 run_test 32g "stat d32g/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3997
3998 test_32h() {
3999         rm -fr $DIR/$tdir $DIR/${tdir}2
4000         tmp_dir=$DIR/$tdir/tmp
4001         test_mkdir -p $tmp_dir
4002         test_mkdir $DIR/${tdir}2
4003         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
4004         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
4005         ls $tmp_dir/symlink12 || error "listing symlink12"
4006         ls $DIR/$tdir/symlink02  || error "listing symlink02"
4007 }
4008 run_test 32h "open d32h/symlink->tmp/symlink->lustre-subdir/${tdir}2"
4009
4010 test_32i() {
4011         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4012
4013         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
4014         trap cleanup_test32_mount EXIT
4015         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4016         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4017                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4018         touch $DIR/$tdir/test_file
4019         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../test_file ||
4020                 error "$DIR/$tdir/ext2-mountpoint/../test_file not file type"
4021         cleanup_test32_mount
4022 }
4023 run_test 32i "stat d32i/ext2-mountpoint/../test_file ==========="
4024
4025 test_32j() {
4026         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4027
4028         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
4029         trap cleanup_test32_mount EXIT
4030         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4031         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4032                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4033         touch $DIR/$tdir/test_file
4034         cat $DIR/$tdir/ext2-mountpoint/../test_file ||
4035                 error "Can't open $DIR/$tdir/ext2-mountpoint/../test_file"
4036         cleanup_test32_mount
4037 }
4038 run_test 32j "open d32j/ext2-mountpoint/../test_file ==========="
4039
4040 test_32k() {
4041         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4042
4043         rm -fr $DIR/$tdir
4044         trap cleanup_test32_mount EXIT
4045         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4046         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4047                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4048         test_mkdir -p $DIR/$tdir/d2
4049         touch $DIR/$tdir/d2/test_file || error "touch failed"
4050         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
4051                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_file not file type"
4052         cleanup_test32_mount
4053 }
4054 run_test 32k "stat d32k/ext2-mountpoint/../d2/test_file ========"
4055
4056 test_32l() {
4057         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4058
4059         rm -fr $DIR/$tdir
4060         trap cleanup_test32_mount EXIT
4061         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4062         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4063                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4064         test_mkdir -p $DIR/$tdir/d2
4065         touch $DIR/$tdir/d2/test_file || error "touch failed"
4066         cat  $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
4067                 error "Can't open $DIR/$tdir/ext2-mountpoint/../d2/test_file"
4068         cleanup_test32_mount
4069 }
4070 run_test 32l "open d32l/ext2-mountpoint/../d2/test_file ========"
4071
4072 test_32m() {
4073         rm -fr $DIR/d32m
4074         test_mkdir -p $DIR/d32m/tmp
4075         TMP_DIR=$DIR/d32m/tmp
4076         ln -s $DIR $TMP_DIR/symlink11
4077         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
4078         $CHECKSTAT -t link $DIR/d32m/tmp/symlink11 ||
4079                 error "symlink11 not a link"
4080         $CHECKSTAT -t link $DIR/d32m/symlink01 ||
4081                 error "symlink01 not a link"
4082 }
4083 run_test 32m "stat d32m/symlink->tmp/symlink->lustre-root ======"
4084
4085 test_32n() {
4086         rm -fr $DIR/d32n
4087         test_mkdir -p $DIR/d32n/tmp
4088         TMP_DIR=$DIR/d32n/tmp
4089         ln -s $DIR $TMP_DIR/symlink11
4090         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
4091         ls -l $DIR/d32n/tmp/symlink11  || error "listing symlink11"
4092         ls -l $DIR/d32n/symlink01 || error "listing symlink01"
4093 }
4094 run_test 32n "open d32n/symlink->tmp/symlink->lustre-root ======"
4095
4096 test_32o() {
4097         touch $DIR/$tfile
4098         test_mkdir -p $DIR/d32o/tmp
4099         TMP_DIR=$DIR/d32o/tmp
4100         ln -s $DIR/$tfile $TMP_DIR/symlink12
4101         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
4102         $CHECKSTAT -t link $DIR/d32o/tmp/symlink12 ||
4103                 error "symlink12 not a link"
4104         $CHECKSTAT -t link $DIR/d32o/symlink02 || error "symlink02 not a link"
4105         $CHECKSTAT -t file -f $DIR/d32o/tmp/symlink12 ||
4106                 error "$DIR/d32o/tmp/symlink12 not file type"
4107         $CHECKSTAT -t file -f $DIR/d32o/symlink02 ||
4108                 error "$DIR/d32o/symlink02 not file type"
4109 }
4110 run_test 32o "stat d32o/symlink->tmp/symlink->lustre-root/$tfile"
4111
4112 test_32p() {
4113         log 32p_1
4114         rm -fr $DIR/d32p
4115         log 32p_2
4116         rm -f $DIR/$tfile
4117         log 32p_3
4118         touch $DIR/$tfile
4119         log 32p_4
4120         test_mkdir -p $DIR/d32p/tmp
4121         log 32p_5
4122         TMP_DIR=$DIR/d32p/tmp
4123         log 32p_6
4124         ln -s $DIR/$tfile $TMP_DIR/symlink12
4125         log 32p_7
4126         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
4127         log 32p_8
4128         cat $DIR/d32p/tmp/symlink12 ||
4129                 error "Can't open $DIR/d32p/tmp/symlink12"
4130         log 32p_9
4131         cat $DIR/d32p/symlink02 || error "Can't open $DIR/d32p/symlink02"
4132         log 32p_10
4133 }
4134 run_test 32p "open d32p/symlink->tmp/symlink->lustre-root/$tfile"
4135
4136 test_32q() {
4137         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4138
4139         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
4140         trap cleanup_test32_mount EXIT
4141         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4142         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
4143         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4144                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4145         ls $DIR/$tdir/ext2-mountpoint | grep "\<under_the_mount\>" && error
4146         cleanup_test32_mount
4147 }
4148 run_test 32q "stat follows mountpoints in Lustre (should return error)"
4149
4150 test_32r() {
4151         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4152
4153         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
4154         trap cleanup_test32_mount EXIT
4155         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4156         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
4157         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4158                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4159         ls $DIR/$tdir/ext2-mountpoint | grep -q under_the_mount && error || true
4160         cleanup_test32_mount
4161 }
4162 run_test 32r "opendir follows mountpoints in Lustre (should return error)"
4163
4164 test_33aa() {
4165         rm -f $DIR/$tfile
4166         touch $DIR/$tfile
4167         chmod 444 $DIR/$tfile
4168         chown $RUNAS_ID $DIR/$tfile
4169         log 33_1
4170         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
4171         log 33_2
4172 }
4173 run_test 33aa "write file with mode 444 (should return error)"
4174
4175 test_33a() {
4176         rm -fr $DIR/$tdir
4177         test_mkdir $DIR/$tdir
4178         chown $RUNAS_ID $DIR/$tdir
4179         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile ||
4180                 error "$RUNAS create $tdir/$tfile failed"
4181         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile &&
4182                 error "open RDWR" || true
4183 }
4184 run_test 33a "test open file(mode=0444) with O_RDWR (should return error)"
4185
4186 test_33b() {
4187         rm -fr $DIR/$tdir
4188         test_mkdir $DIR/$tdir
4189         chown $RUNAS_ID $DIR/$tdir
4190         $RUNAS $OPENFILE -f 1286739555 $DIR/$tdir/$tfile || true
4191 }
4192 run_test 33b "test open file with malformed flags (No panic)"
4193
4194 test_33c() {
4195         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4196         remote_ost_nodsh && skip "remote OST with nodsh"
4197
4198         local ostnum
4199         local ostname
4200         local write_bytes
4201         local all_zeros
4202
4203         all_zeros=true
4204         test_mkdir $DIR/$tdir
4205         # Read: 0, Write: 4, create/destroy: 2/0, stat: 1, punch: 0
4206
4207         sync
4208         for ostnum in $(seq $OSTCOUNT); do
4209                 # test-framework's OST numbering is one-based, while Lustre's
4210                 # is zero-based
4211                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4212                 # check if at least some write_bytes stats are counted
4213                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
4214                               obdfilter.$ostname.stats |
4215                               awk '/^write_bytes/ {print $7}' )
4216                 echo "baseline_write_bytes@ost$ostnum/$ostname=$write_bytes"
4217                 if (( ${write_bytes:-0} > 0 )); then
4218                         all_zeros=false
4219                         break
4220                 fi
4221         done
4222
4223         $all_zeros || return 0
4224
4225         # Write four bytes
4226         echo foo > $DIR/$tdir/bar
4227         # Really write them
4228         sync
4229
4230         # Total up write_bytes after writing.  We'd better find non-zeros.
4231         for ostnum in $(seq $OSTCOUNT); do
4232                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4233                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
4234                               obdfilter/$ostname/stats |
4235                               awk '/^write_bytes/ {print $7}' )
4236                 echo "write_bytes@ost$ostnum/$ostname=$write_bytes"
4237                 if (( ${write_bytes:-0} > 0 )); then
4238                         all_zeros=false
4239                         break
4240                 fi
4241         done
4242
4243         if $all_zeros; then
4244                 for ostnum in $(seq $OSTCOUNT); do
4245                         ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4246                         echo "Check write_bytes is in obdfilter.*.stats:"
4247                         do_facet ost$ostnum lctl get_param -n \
4248                                 obdfilter.$ostname.stats
4249                 done
4250                 error "OST not keeping write_bytes stats (b=22312)"
4251         fi
4252 }
4253 run_test 33c "test write_bytes stats"
4254
4255 test_33d() {
4256         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
4257         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4258
4259         local MDTIDX=1
4260         local remote_dir=$DIR/$tdir/remote_dir
4261
4262         test_mkdir $DIR/$tdir
4263         $LFS mkdir -i $MDTIDX $remote_dir ||
4264                 error "create remote directory failed"
4265
4266         touch $remote_dir/$tfile
4267         chmod 444 $remote_dir/$tfile
4268         chown $RUNAS_ID $remote_dir/$tfile
4269
4270         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
4271
4272         chown $RUNAS_ID $remote_dir
4273         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 ||
4274                                         error "create" || true
4275         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 &&
4276                                     error "open RDWR" || true
4277         $RUNAS $OPENFILE -f 1286739555 $remote_dir/f33 || true
4278 }
4279 run_test 33d "openfile with 444 modes and malformed flags under remote dir"
4280
4281 test_33e() {
4282         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4283
4284         mkdir $DIR/$tdir
4285
4286         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4287         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4288         mkdir $DIR/$tdir/local_dir
4289
4290         local s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4291         local s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4292         local l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4293
4294         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4295                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode"
4296
4297         rmdir $DIR/$tdir/* || error "rmdir failed"
4298
4299         umask 777
4300         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4301         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4302         mkdir $DIR/$tdir/local_dir
4303
4304         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4305         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4306         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4307
4308         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4309                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 777"
4310
4311         rmdir $DIR/$tdir/* || error "rmdir(umask 777) failed"
4312
4313         umask 000
4314         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4315         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4316         mkdir $DIR/$tdir/local_dir
4317
4318         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4319         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4320         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4321
4322         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4323                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 0"
4324 }
4325 run_test 33e "mkdir and striped directory should have same mode"
4326
4327 cleanup_33f() {
4328         trap 0
4329         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=0
4330 }
4331
4332 test_33f() {
4333         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4334         remote_mds_nodsh && skip "remote MDS with nodsh"
4335
4336         mkdir $DIR/$tdir
4337         chmod go+rwx $DIR/$tdir
4338         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=-1
4339         trap cleanup_33f EXIT
4340
4341         $RUNAS lfs mkdir -i 0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
4342                 error "cannot create striped directory"
4343
4344         $RUNAS touch $DIR/$tdir/striped_dir/{0..16} ||
4345                 error "cannot create files in striped directory"
4346
4347         $RUNAS rm $DIR/$tdir/striped_dir/{0..16} ||
4348                 error "cannot remove files in striped directory"
4349
4350         $RUNAS rmdir $DIR/$tdir/striped_dir ||
4351                 error "cannot remove striped directory"
4352
4353         cleanup_33f
4354 }
4355 run_test 33f "nonroot user can create, access, and remove a striped directory"
4356
4357 test_33g() {
4358         mkdir -p $DIR/$tdir/dir2
4359
4360         local err=$($RUNAS mkdir $DIR/$tdir/dir2 2>&1)
4361         echo $err
4362         [[ $err =~ "exists" ]] || error "Not exists error"
4363 }
4364 run_test 33g "nonroot user create already existing root created file"
4365
4366 sub_33h() {
4367         local hash_type=$1
4368         local count=250
4369
4370         test_mkdir -c $MDSCOUNT -H $hash_type $DIR/$tdir ||
4371                 error "lfs mkdir -H $hash_type $tdir failed"
4372         touch $DIR/$tdir/$tfile || error "touch $tfile failed"
4373
4374         local index=$($LFS getstripe -m $DIR/$tdir/$tfile)
4375         local index2
4376         local fname
4377
4378         for fname in $DIR/$tdir/$tfile.bak \
4379                      $DIR/$tdir/$tfile.SAV \
4380                      $DIR/$tdir/$tfile.orig \
4381                      $DIR/$tdir/$tfile~; do
4382                 touch $fname || error "touch $fname failed"
4383                 index2=$($LFS getstripe -m $fname)
4384                 (( $index == $index2 )) ||
4385                         error "$fname MDT index mismatch $index != $index2"
4386         done
4387
4388         local failed=0
4389         local patterns=(".$tfile.XXXXXX" "$tfile.XXXXXXXX")
4390         local pattern
4391
4392         for pattern in ${patterns[*]}; do
4393                 echo "pattern $pattern"
4394                 fname=$DIR/$tdir/$pattern
4395                 for (( i = 0; i < $count; i++ )); do
4396                         fname=$(mktemp $DIR/$tdir/$pattern) ||
4397                                 error "mktemp $DIR/$tdir/$pattern failed"
4398                         index2=$($LFS getstripe -m $fname)
4399                         (( $index == $index2 )) && continue
4400
4401                         failed=$((failed + 1))
4402                         echo "$fname MDT index mismatch $index != $index2"
4403                 done
4404         done
4405
4406         echo "$failed/$count MDT index mismatches, expect ~2-4"
4407         (( failed < 10 )) || error "MDT index mismatch $failed/$count times"
4408
4409         local same=0
4410         local expect
4411
4412         # verify that "crush" is still broken with all files on same MDT,
4413         # crush2 should have about 1/MDSCOUNT files on each MDT, with margin
4414         [[ "$hash_type" == "crush" ]] && expect=$count ||
4415                 expect=$((count / MDSCOUNT))
4416
4417         # crush2 doesn't put all-numeric suffixes on the same MDT,
4418         # filename like $tfile.12345678 should *not* be considered temp
4419         for pattern in ${patterns[*]}; do
4420                 local base=${pattern%%X*}
4421                 local suff=${pattern#$base}
4422
4423                 echo "pattern $pattern"
4424                 for (( i = 0; i < $count; i++ )); do
4425                         fname=$DIR/$tdir/$base$((${suff//X/1} + i))
4426                         touch $fname || error "touch $fname failed"
4427                         index2=$($LFS getstripe -m $fname)
4428                         (( $index != $index2 )) && continue
4429
4430                         same=$((same + 1))
4431                 done
4432         done
4433
4434         # the number of "bad" hashes is random, as it depends on the random
4435         # filenames generated by "mktemp".  Allow some margin in the results.
4436         echo "$((same/${#patterns[*]}))/$count matches, expect ~$expect for $1"
4437         (( same / ${#patterns[*]} <= expect * 9 / 7 &&
4438            same / ${#patterns[*]} > expect * 5 / 7 )) ||
4439                 error "MDT index match $((same / ${#patterns[*]}))/$count times"
4440         same=0
4441
4442         # crush2 doesn't put suffixes with special characters on the same MDT
4443         # filename like $tfile.txt.1234 should *not* be considered temp
4444         for pattern in ${patterns[*]}; do
4445                 local base=${pattern%%X*}
4446                 local suff=${pattern#$base}
4447
4448                 pattern=$base...${suff/XXX}
4449                 echo "pattern=$pattern"
4450                 for (( i = 0; i < $count; i++ )); do
4451                         fname=$(mktemp $DIR/$tdir/$pattern) ||
4452                                 error "touch $fname failed"
4453                         index2=$($LFS getstripe -m $fname)
4454                         (( $index != $index2 )) && continue
4455
4456                         same=$((same + 1))
4457                 done
4458         done
4459
4460         # the number of "bad" hashes is random, as it depends on the random
4461         # filenames generated by "mktemp".  Allow some margin in the results.
4462         echo "$((same/${#patterns[*]}))/$count matches, expect ~$expect for $1"
4463         (( same / ${#patterns[*]} <= expect * 9 / 7 &&
4464            same / ${#patterns[*]} > expect * 5 / 7 )) ||
4465                 error "MDT index match $((same / ${#patterns[*]}))/$count times"
4466 }
4467
4468 test_33h() {
4469         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
4470         (( $MDS1_VERSION >= $(version_code 2.13.50) )) ||
4471                 skip "Need MDS version at least 2.13.50"
4472
4473         sub_33h crush
4474 }
4475 run_test 33h "temp file is located on the same MDT as target (crush)"
4476
4477 test_33hh() {
4478         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
4479         echo "MDS1_VERSION=$MDS1_VERSION version_code=$(version_code 2.15.0)"
4480         (( $MDS1_VERSION > $(version_code 2.15.0) )) ||
4481                 skip "Need MDS version at least 2.15.0 for crush2"
4482
4483         sub_33h crush2
4484 }
4485 run_test 33hh "temp file is located on the same MDT as target (crush2)"
4486
4487 test_33i()
4488 {
4489         (( MDSCOUNT < 2 )) && skip "needs >= 2 MDTs"
4490
4491         local FNAME=$(str_repeat 'f' 250)
4492
4493         test_mkdir -i 0 -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
4494         createmany -o $DIR/$tdir/$FNAME 1000 || error "createmany failed"
4495
4496         local count
4497         local total
4498
4499         count=$($LFS getstripe -m $DIR/$tdir/* | grep -cw 1)
4500
4501         local MDC=$(lctl dl | awk '/MDT0001-mdc-[^M]/ { print $4 }')
4502
4503         lctl --device %$MDC deactivate
4504         stack_trap "lctl --device %$MDC activate"
4505         ls $DIR/$tdir > /dev/null && error "ls should return an error"
4506         total=$(\ls -l $DIR/$tdir | wc -l)
4507         # "ls -l" will list total in the first line
4508         total=$((total - 1))
4509         (( total + count == 1000 )) ||
4510                 error "ls list $total files, $count files on MDT1"
4511 }
4512 run_test 33i "striped directory can be accessed when one MDT is down"
4513
4514 test_33j() {
4515         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
4516
4517         mkdir -p $DIR/$tdir/
4518
4519         $LFS setdirstripe -D -i0,1 $DIR/$tdir/striped_dir_a &&
4520                 error "setdirstripe -D -i0,1 incorrectly succeeded"
4521
4522         $LFS setdirstripe -D -i0,1 -c1 $DIR/$tdir/striped_dir_b &&
4523                 error "setdirstripe -D -i0,1 -c1 incorrectly succeeded"
4524
4525         $LFS setdirstripe -D -i0,1 -c3 $DIR/$tdir/striped_dir_c &&
4526                 error "setdirstripe -D -i0,1 -c3 incorrectly succeeded"
4527
4528         $LFS setdirstripe -i0,1 $DIR/$tdir/striped_dir_e ||
4529                 error "-D was not specified, but still failed"
4530 }
4531 run_test 33j "lfs setdirstripe -D -i x,y,x should fail"
4532
4533 TEST_34_SIZE=${TEST_34_SIZE:-2000000000000}
4534 test_34a() {
4535         rm -f $DIR/f34
4536         $MCREATE $DIR/f34 || error "mcreate failed"
4537         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4538                 error "getstripe failed"
4539         $TRUNCATE $DIR/f34 $TEST_34_SIZE || error "truncate failed"
4540         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4541                 error "getstripe failed"
4542         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4543                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4544 }
4545 run_test 34a "truncate file that has not been opened ==========="
4546
4547 test_34b() {
4548         [ ! -f $DIR/f34 ] && test_34a
4549         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4550                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4551         $OPENFILE -f O_RDONLY $DIR/f34
4552         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4553                 error "getstripe failed"
4554         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4555                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4556 }
4557 run_test 34b "O_RDONLY opening file doesn't create objects ====="
4558
4559 test_34c() {
4560         [ ! -f $DIR/f34 ] && test_34a
4561         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4562                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4563         $OPENFILE -f O_RDWR $DIR/f34
4564         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" &&
4565                 error "$LFS getstripe failed"
4566         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4567                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4568 }
4569 run_test 34c "O_RDWR opening file-with-size works =============="
4570
4571 test_34d() {
4572         [ ! -f $DIR/f34 ] && test_34a
4573         dd if=/dev/zero of=$DIR/f34 conv=notrunc bs=4k count=1 ||
4574                 error "dd failed"
4575         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4576                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4577         rm $DIR/f34
4578 }
4579 run_test 34d "write to sparse file ============================="
4580
4581 test_34e() {
4582         rm -f $DIR/f34e
4583         $MCREATE $DIR/f34e || error "mcreate failed"
4584         $TRUNCATE $DIR/f34e 1000 || error "truncate failed"
4585         $CHECKSTAT -s 1000 $DIR/f34e ||
4586                 error "Size of $DIR/f34e not equal to 1000 bytes"
4587         $OPENFILE -f O_RDWR $DIR/f34e
4588         $CHECKSTAT -s 1000 $DIR/f34e ||
4589                 error "Size of $DIR/f34e not equal to 1000 bytes"
4590 }
4591 run_test 34e "create objects, some with size and some without =="
4592
4593 test_34f() { # bug 6242, 6243
4594         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4595
4596         SIZE34F=48000
4597         rm -f $DIR/f34f
4598         $MCREATE $DIR/f34f || error "mcreate failed"
4599         $TRUNCATE $DIR/f34f $SIZE34F || error "truncating $DIR/f3f to $SIZE34F"
4600         dd if=$DIR/f34f of=$TMP/f34f
4601         $CHECKSTAT -s $SIZE34F $TMP/f34f || error "$TMP/f34f not $SIZE34F bytes"
4602         dd if=/dev/zero of=$TMP/f34fzero bs=$SIZE34F count=1
4603         cmp $DIR/f34f $TMP/f34fzero || error "$DIR/f34f not all zero"
4604         cmp $TMP/f34f $TMP/f34fzero || error "$TMP/f34f not all zero"
4605         rm $TMP/f34f $TMP/f34fzero $DIR/f34f
4606 }
4607 run_test 34f "read from a file with no objects until EOF ======="
4608
4609 test_34g() {
4610         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4611
4612         dd if=/dev/zero of=$DIR/$tfile bs=1 count=100 seek=$TEST_34_SIZE ||
4613                 error "dd failed"
4614         $TRUNCATE $DIR/$tfile $((TEST_34_SIZE / 2))|| error "truncate failed"
4615         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
4616                 error "Size of $DIR/$tfile not equal to $((TEST_34_SIZE / 2))"
4617         cancel_lru_locks osc
4618         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
4619                 error "wrong size after lock cancel"
4620
4621         $TRUNCATE $DIR/$tfile $TEST_34_SIZE || error "truncate failed"
4622         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
4623                 error "expanding truncate failed"
4624         cancel_lru_locks osc
4625         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
4626                 error "wrong expanded size after lock cancel"
4627 }
4628 run_test 34g "truncate long file ==============================="
4629
4630 test_34h() {
4631         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4632
4633         local gid=10
4634         local sz=1000
4635
4636         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 || error "dd failed"
4637         sync # Flush the cache so that multiop below does not block on cache
4638              # flush when getting the group lock
4639         $MULTIOP $DIR/$tfile OG${gid}T${sz}g${gid}c &
4640         MULTIPID=$!
4641
4642         # Since just timed wait is not good enough, let's do a sync write
4643         # that way we are sure enough time for a roundtrip + processing
4644         # passed + 2 seconds of extra margin.
4645         dd if=/dev/zero of=$DIR/${tfile}-1 bs=$PAGE_SIZE oflag=direct count=1
4646         rm $DIR/${tfile}-1
4647         sleep 2
4648
4649         if [[ `ps h -o comm -p $MULTIPID` == "multiop" ]]; then
4650                 error "Multiop blocked on ftruncate, pid=$MULTIPID"
4651                 kill -9 $MULTIPID
4652         fi
4653         wait $MULTIPID
4654         local nsz=`stat -c %s $DIR/$tfile`
4655         [[ $nsz == $sz ]] || error "New size wrong $nsz != $sz"
4656 }
4657 run_test 34h "ftruncate file under grouplock should not block"
4658
4659 test_35a() {
4660         cp /bin/sh $DIR/f35a
4661         chmod 444 $DIR/f35a
4662         chown $RUNAS_ID $DIR/f35a
4663         $RUNAS $DIR/f35a && error || true
4664         rm $DIR/f35a
4665 }
4666 run_test 35a "exec file with mode 444 (should return and not leak)"
4667
4668 test_36a() {
4669         rm -f $DIR/f36
4670         utime $DIR/f36 || error "utime failed for MDS"
4671 }
4672 run_test 36a "MDS utime check (mknod, utime)"
4673
4674 test_36b() {
4675         echo "" > $DIR/f36
4676         utime $DIR/f36 || error "utime failed for OST"
4677 }
4678 run_test 36b "OST utime check (open, utime)"
4679
4680 test_36c() {
4681         rm -f $DIR/d36/f36
4682         test_mkdir $DIR/d36
4683         chown $RUNAS_ID $DIR/d36
4684         $RUNAS utime $DIR/d36/f36 || error "utime failed for MDS as non-root"
4685 }
4686 run_test 36c "non-root MDS utime check (mknod, utime)"
4687
4688 test_36d() {
4689         [ ! -d $DIR/d36 ] && test_36c
4690         echo "" > $DIR/d36/f36
4691         $RUNAS utime $DIR/d36/f36 || error "utime failed for OST as non-root"
4692 }
4693 run_test 36d "non-root OST utime check (open, utime)"
4694
4695 test_36e() {
4696         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID -- skipping"
4697
4698         test_mkdir $DIR/$tdir
4699         touch $DIR/$tdir/$tfile
4700         $RUNAS utime $DIR/$tdir/$tfile &&
4701                 error "utime worked, expected failure" || true
4702 }
4703 run_test 36e "utime on non-owned file (should return error)"
4704
4705 subr_36fh() {
4706         local fl="$1"
4707         local LANG_SAVE=$LANG
4708         local LC_LANG_SAVE=$LC_LANG
4709         export LANG=C LC_LANG=C # for date language
4710
4711         DATESTR="Dec 20  2000"
4712         test_mkdir $DIR/$tdir
4713         lctl set_param fail_loc=$fl
4714         date; date +%s
4715         cp /etc/hosts $DIR/$tdir/$tfile
4716         sync & # write RPC generated with "current" inode timestamp, but delayed
4717         sleep 1
4718         touch --date="$DATESTR" $DIR/$tdir/$tfile # setattr timestamp in past
4719         LS_BEFORE="`ls -l $DIR/$tdir/$tfile`" # old timestamp from client cache
4720         cancel_lru_locks $OSC
4721         LS_AFTER="`ls -l $DIR/$tdir/$tfile`"  # timestamp from OST object
4722         date; date +%s
4723         [ "$LS_BEFORE" != "$LS_AFTER" ] && \
4724                 echo "BEFORE: $LS_BEFORE" && \
4725                 echo "AFTER : $LS_AFTER" && \
4726                 echo "WANT  : $DATESTR" && \
4727                 error "$DIR/$tdir/$tfile timestamps changed" || true
4728
4729         export LANG=$LANG_SAVE LC_LANG=$LC_LANG_SAVE
4730 }
4731
4732 test_36f() {
4733         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4734
4735         #define OBD_FAIL_OST_BRW_PAUSE_BULK 0x214
4736         subr_36fh "0x80000214"
4737 }
4738 run_test 36f "utime on file racing with OST BRW write =========="
4739
4740 test_36g() {
4741         remote_ost_nodsh && skip "remote OST with nodsh"
4742         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4743         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
4744                 skip "Need MDS version at least 2.12.51"
4745
4746         local fmd_max_age
4747         local fmd
4748         local facet="ost1"
4749         local tgt="obdfilter"
4750
4751         [[ $OSC == "mdc" ]] && tgt="mdt" && facet="mds1"
4752
4753         test_mkdir $DIR/$tdir
4754         fmd_max_age=$(do_facet $facet \
4755                 "lctl get_param -n $tgt.*.tgt_fmd_seconds 2> /dev/null | \
4756                 head -n 1")
4757
4758         echo "FMD max age: ${fmd_max_age}s"
4759         touch $DIR/$tdir/$tfile
4760         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4761                 gawk '{cnt=cnt+$1}  END{print cnt}')
4762         echo "FMD before: $fmd"
4763         [[ $fmd == 0 ]] &&
4764                 error "FMD wasn't create by touch"
4765         sleep $((fmd_max_age + 12))
4766         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4767                 gawk '{cnt=cnt+$1}  END{print cnt}')
4768         echo "FMD after: $fmd"
4769         [[ $fmd == 0 ]] ||
4770                 error "FMD wasn't expired by ping"
4771 }
4772 run_test 36g "FMD cache expiry ====================="
4773
4774 test_36h() {
4775         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4776
4777         #define OBD_FAIL_OST_BRW_PAUSE_BULK2 0x227
4778         subr_36fh "0x80000227"
4779 }
4780 run_test 36h "utime on file racing with OST BRW write =========="
4781
4782 test_36i() {
4783         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4784
4785         test_mkdir $DIR/$tdir
4786         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir
4787
4788         local mtime=$(stat -c%Y $DIR/$tdir/striped_dir)
4789         local new_mtime=$((mtime + 200))
4790
4791         #change Modify time of striped dir
4792         touch -m -d @$new_mtime $DIR/$tdir/striped_dir ||
4793                         error "change mtime failed"
4794
4795         local got=$(stat -c%Y $DIR/$tdir/striped_dir)
4796
4797         [ "$new_mtime" = "$got" ] || error "expect $new_mtime got $got"
4798 }
4799 run_test 36i "change mtime on striped directory"
4800
4801 # test_37 - duplicate with tests 32q 32r
4802
4803 test_38() {
4804         local file=$DIR/$tfile
4805         touch $file
4806         openfile -f O_DIRECTORY $file
4807         local RC=$?
4808         local ENOTDIR=20
4809         [ $RC -eq 0 ] && error "opened file $file with O_DIRECTORY" || true
4810         [ $RC -eq $ENOTDIR ] || error "error $RC should be ENOTDIR ($ENOTDIR)"
4811 }
4812 run_test 38 "open a regular file with O_DIRECTORY should return -ENOTDIR ==="
4813
4814 test_39a() { # was test_39
4815         touch $DIR/$tfile
4816         touch $DIR/${tfile}2
4817 #       ls -l  $DIR/$tfile $DIR/${tfile}2
4818 #       ls -lu  $DIR/$tfile $DIR/${tfile}2
4819 #       ls -lc  $DIR/$tfile $DIR/${tfile}2
4820         sleep 2
4821         $OPENFILE -f O_CREAT:O_TRUNC:O_WRONLY $DIR/${tfile}2
4822         if [ ! $DIR/${tfile}2 -nt $DIR/$tfile ]; then
4823                 echo "mtime"
4824                 ls -l --full-time $DIR/$tfile $DIR/${tfile}2
4825                 echo "atime"
4826                 ls -lu --full-time $DIR/$tfile $DIR/${tfile}2
4827                 echo "ctime"
4828                 ls -lc --full-time $DIR/$tfile $DIR/${tfile}2
4829                 error "O_TRUNC didn't change timestamps"
4830         fi
4831 }
4832 run_test 39a "mtime changed on create"
4833
4834 test_39b() {
4835         test_mkdir -c1 $DIR/$tdir
4836         cp -p /etc/passwd $DIR/$tdir/fopen
4837         cp -p /etc/passwd $DIR/$tdir/flink
4838         cp -p /etc/passwd $DIR/$tdir/funlink
4839         cp -p /etc/passwd $DIR/$tdir/frename
4840         ln $DIR/$tdir/funlink $DIR/$tdir/funlink2
4841
4842         sleep 1
4843         echo "aaaaaa" >> $DIR/$tdir/fopen
4844         echo "aaaaaa" >> $DIR/$tdir/flink
4845         echo "aaaaaa" >> $DIR/$tdir/funlink
4846         echo "aaaaaa" >> $DIR/$tdir/frename
4847
4848         local open_new=`stat -c %Y $DIR/$tdir/fopen`
4849         local link_new=`stat -c %Y $DIR/$tdir/flink`
4850         local unlink_new=`stat -c %Y $DIR/$tdir/funlink`
4851         local rename_new=`stat -c %Y $DIR/$tdir/frename`
4852
4853         cat $DIR/$tdir/fopen > /dev/null
4854         ln $DIR/$tdir/flink $DIR/$tdir/flink2
4855         rm -f $DIR/$tdir/funlink2
4856         mv -f $DIR/$tdir/frename $DIR/$tdir/frename2
4857
4858         for (( i=0; i < 2; i++ )) ; do
4859                 local open_new2=`stat -c %Y $DIR/$tdir/fopen`
4860                 local link_new2=`stat -c %Y $DIR/$tdir/flink`
4861                 local unlink_new2=`stat -c %Y $DIR/$tdir/funlink`
4862                 local rename_new2=`stat -c %Y $DIR/$tdir/frename2`
4863
4864                 [ $open_new2 -eq $open_new ] || error "open file reverses mtime"
4865                 [ $link_new2 -eq $link_new ] || error "link file reverses mtime"
4866                 [ $unlink_new2 -eq $unlink_new ] || error "unlink file reverses mtime"
4867                 [ $rename_new2 -eq $rename_new ] || error "rename file reverses mtime"
4868
4869                 cancel_lru_locks $OSC
4870                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4871         done
4872 }
4873 run_test 39b "mtime change on open, link, unlink, rename  ======"
4874
4875 # this should be set to past
4876 TEST_39_MTIME=`date -d "1 year ago" +%s`
4877
4878 # bug 11063
4879 test_39c() {
4880         touch $DIR1/$tfile
4881         sleep 2
4882         local mtime0=`stat -c %Y $DIR1/$tfile`
4883
4884         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4885         local mtime1=`stat -c %Y $DIR1/$tfile`
4886         [ "$mtime1" = $TEST_39_MTIME ] || \
4887                 error "mtime is not set to past: $mtime1, should be $TEST_39_MTIME"
4888
4889         local d1=`date +%s`
4890         echo hello >> $DIR1/$tfile
4891         local d2=`date +%s`
4892         local mtime2=`stat -c %Y $DIR1/$tfile`
4893         [ "$mtime2" -ge "$d1" ] && [ "$mtime2" -le "$d2" ] || \
4894                 error "mtime is not updated on write: $d1 <= $mtime2 <= $d2"
4895
4896         mv $DIR1/$tfile $DIR1/$tfile-1
4897
4898         for (( i=0; i < 2; i++ )) ; do
4899                 local mtime3=`stat -c %Y $DIR1/$tfile-1`
4900                 [ "$mtime2" = "$mtime3" ] || \
4901                         error "mtime ($mtime2) changed (to $mtime3) on rename"
4902
4903                 cancel_lru_locks $OSC
4904                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4905         done
4906 }
4907 run_test 39c "mtime change on rename ==========================="
4908
4909 # bug 21114
4910 test_39d() {
4911         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4912
4913         touch $DIR1/$tfile
4914         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4915
4916         for (( i=0; i < 2; i++ )) ; do
4917                 local mtime=`stat -c %Y $DIR1/$tfile`
4918                 [ $mtime = $TEST_39_MTIME ] || \
4919                         error "mtime($mtime) is not set to $TEST_39_MTIME"
4920
4921                 cancel_lru_locks $OSC
4922                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4923         done
4924 }
4925 run_test 39d "create, utime, stat =============================="
4926
4927 # bug 21114
4928 test_39e() {
4929         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4930
4931         touch $DIR1/$tfile
4932         local mtime1=`stat -c %Y $DIR1/$tfile`
4933
4934         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4935
4936         for (( i=0; i < 2; i++ )) ; do
4937                 local mtime2=`stat -c %Y $DIR1/$tfile`
4938                 [ $mtime2 = $TEST_39_MTIME ] || \
4939                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4940
4941                 cancel_lru_locks $OSC
4942                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4943         done
4944 }
4945 run_test 39e "create, stat, utime, stat ========================"
4946
4947 # bug 21114
4948 test_39f() {
4949         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4950
4951         touch $DIR1/$tfile
4952         mtime1=`stat -c %Y $DIR1/$tfile`
4953
4954         sleep 2
4955         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4956
4957         for (( i=0; i < 2; i++ )) ; do
4958                 local mtime2=`stat -c %Y $DIR1/$tfile`
4959                 [ $mtime2 = $TEST_39_MTIME ] || \
4960                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4961
4962                 cancel_lru_locks $OSC
4963                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4964         done
4965 }
4966 run_test 39f "create, stat, sleep, utime, stat ================="
4967
4968 # bug 11063
4969 test_39g() {
4970         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4971
4972         echo hello >> $DIR1/$tfile
4973         local mtime1=`stat -c %Y $DIR1/$tfile`
4974
4975         sleep 2
4976         chmod o+r $DIR1/$tfile
4977
4978         for (( i=0; i < 2; i++ )) ; do
4979                 local mtime2=`stat -c %Y $DIR1/$tfile`
4980                 [ "$mtime1" = "$mtime2" ] || \
4981                         error "lost mtime: $mtime2, should be $mtime1"
4982
4983                 cancel_lru_locks $OSC
4984                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4985         done
4986 }
4987 run_test 39g "write, chmod, stat ==============================="
4988
4989 # bug 11063
4990 test_39h() {
4991         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4992
4993         touch $DIR1/$tfile
4994         sleep 1
4995
4996         local d1=`date`
4997         echo hello >> $DIR1/$tfile
4998         local mtime1=`stat -c %Y $DIR1/$tfile`
4999
5000         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
5001         local d2=`date`
5002         if [ "$d1" != "$d2" ]; then
5003                 echo "write and touch not within one second"
5004         else
5005                 for (( i=0; i < 2; i++ )) ; do
5006                         local mtime2=`stat -c %Y $DIR1/$tfile`
5007                         [ "$mtime2" = $TEST_39_MTIME ] || \
5008                                 error "lost mtime: $mtime2, should be $TEST_39_MTIME"
5009
5010                         cancel_lru_locks $OSC
5011                         if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
5012                 done
5013         fi
5014 }
5015 run_test 39h "write, utime within one second, stat ============="
5016
5017 test_39i() {
5018         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5019
5020         touch $DIR1/$tfile
5021         sleep 1
5022
5023         echo hello >> $DIR1/$tfile
5024         local mtime1=`stat -c %Y $DIR1/$tfile`
5025
5026         mv $DIR1/$tfile $DIR1/$tfile-1
5027
5028         for (( i=0; i < 2; i++ )) ; do
5029                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
5030
5031                 [ "$mtime1" = "$mtime2" ] || \
5032                         error "lost mtime: $mtime2, should be $mtime1"
5033
5034                 cancel_lru_locks $OSC
5035                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
5036         done
5037 }
5038 run_test 39i "write, rename, stat =============================="
5039
5040 test_39j() {
5041         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5042
5043         start_full_debug_logging
5044         touch $DIR1/$tfile
5045         sleep 1
5046
5047         #define OBD_FAIL_OSC_DELAY_SETTIME       0x412
5048         lctl set_param fail_loc=0x80000412
5049         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c ||
5050                 error "multiop failed"
5051         local multipid=$!
5052         local mtime1=`stat -c %Y $DIR1/$tfile`
5053
5054         mv $DIR1/$tfile $DIR1/$tfile-1
5055
5056         kill -USR1 $multipid
5057         wait $multipid || error "multiop close failed"
5058
5059         for (( i=0; i < 2; i++ )) ; do
5060                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
5061                 [ "$mtime1" = "$mtime2" ] ||
5062                         error "mtime is lost on close: $mtime2, " \
5063                               "should be $mtime1"
5064
5065                 cancel_lru_locks
5066                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
5067         done
5068         lctl set_param fail_loc=0
5069         stop_full_debug_logging
5070 }
5071 run_test 39j "write, rename, close, stat ======================="
5072
5073 test_39k() {
5074         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5075
5076         touch $DIR1/$tfile
5077         sleep 1
5078
5079         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c || error "multiop failed"
5080         local multipid=$!
5081         local mtime1=`stat -c %Y $DIR1/$tfile`
5082
5083         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
5084
5085         kill -USR1 $multipid
5086         wait $multipid || error "multiop close failed"
5087
5088         for (( i=0; i < 2; i++ )) ; do
5089                 local mtime2=`stat -c %Y $DIR1/$tfile`
5090
5091                 [ "$mtime2" = $TEST_39_MTIME ] || \
5092                         error "mtime is lost on close: $mtime2, should be $TEST_39_MTIME"
5093
5094                 cancel_lru_locks
5095                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
5096         done
5097 }
5098 run_test 39k "write, utime, close, stat ========================"
5099
5100 # this should be set to future
5101 TEST_39_ATIME=`date -d "1 year" +%s`
5102
5103 test_39l() {
5104         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5105         remote_mds_nodsh && skip "remote MDS with nodsh"
5106
5107         local atime_diff=$(do_facet $SINGLEMDS \
5108                                 lctl get_param -n mdd.*MDT0000*.atime_diff)
5109         rm -rf $DIR/$tdir
5110         mkdir_on_mdt0 $DIR/$tdir
5111
5112         # test setting directory atime to future
5113         touch -a -d @$TEST_39_ATIME $DIR/$tdir
5114         local atime=$(stat -c %X $DIR/$tdir)
5115         [ "$atime" = $TEST_39_ATIME ] ||
5116                 error "atime is not set to future: $atime, $TEST_39_ATIME"
5117
5118         # test setting directory atime from future to now
5119         local now=$(date +%s)
5120         touch -a -d @$now $DIR/$tdir
5121
5122         atime=$(stat -c %X $DIR/$tdir)
5123         [ "$atime" -eq "$now"  ] ||
5124                 error "atime is not updated from future: $atime, $now"
5125
5126         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=2
5127         sleep 3
5128
5129         # test setting directory atime when now > dir atime + atime_diff
5130         local d1=$(date +%s)
5131         ls $DIR/$tdir
5132         local d2=$(date +%s)
5133         cancel_lru_locks mdc
5134         atime=$(stat -c %X $DIR/$tdir)
5135         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
5136                 error "atime is not updated  : $atime, should be $d2"
5137
5138         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=60
5139         sleep 3
5140
5141         # test not setting directory atime when now < dir atime + atime_diff
5142         ls $DIR/$tdir
5143         cancel_lru_locks mdc
5144         atime=$(stat -c %X $DIR/$tdir)
5145         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
5146                 error "atime is updated to $atime, should remain $d1<atime<$d2"
5147
5148         do_facet $SINGLEMDS \
5149                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
5150 }
5151 run_test 39l "directory atime update ==========================="
5152
5153 test_39m() {
5154         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5155
5156         touch $DIR1/$tfile
5157         sleep 2
5158         local far_past_mtime=$(date -d "May 29 1953" +%s)
5159         local far_past_atime=$(date -d "Dec 17 1903" +%s)
5160
5161         touch -m -d @$far_past_mtime $DIR1/$tfile
5162         touch -a -d @$far_past_atime $DIR1/$tfile
5163
5164         for (( i=0; i < 2; i++ )) ; do
5165                 local timestamps=$(stat -c "%X %Y" $DIR1/$tfile)
5166                 [ "$timestamps" = "$far_past_atime $far_past_mtime" ] || \
5167                         error "atime or mtime set incorrectly"
5168
5169                 cancel_lru_locks $OSC
5170                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
5171         done
5172 }
5173 run_test 39m "test atime and mtime before 1970"
5174
5175 test_39n() { # LU-3832
5176         remote_mds_nodsh && skip "remote MDS with nodsh"
5177
5178         local atime_diff=$(do_facet $SINGLEMDS \
5179                 lctl get_param -n mdd.*MDT0000*.atime_diff)
5180         local atime0
5181         local atime1
5182         local atime2
5183
5184         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=1
5185
5186         rm -rf $DIR/$tfile
5187         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 status=noxfer
5188         atime0=$(stat -c %X $DIR/$tfile)
5189
5190         sleep 5
5191         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
5192         atime1=$(stat -c %X $DIR/$tfile)
5193
5194         sleep 5
5195         cancel_lru_locks mdc
5196         cancel_lru_locks osc
5197         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
5198         atime2=$(stat -c %X $DIR/$tfile)
5199
5200         do_facet $SINGLEMDS \
5201                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
5202
5203         [ "$atime0" -eq "$atime1" ] || error "atime0 $atime0 != atime1 $atime1"
5204         [ "$atime1" -eq "$atime2" ] || error "atime0 $atime0 != atime1 $atime1"
5205 }
5206 run_test 39n "check that O_NOATIME is honored"
5207
5208 test_39o() {
5209         TESTDIR=$DIR/$tdir/$tfile
5210         [ -e $TESTDIR ] && rm -rf $TESTDIR
5211         mkdir -p $TESTDIR
5212         cd $TESTDIR
5213         links1=2
5214         ls
5215         mkdir a b
5216         ls
5217         links2=$(stat -c %h .)
5218         [ $(($links1 + 2)) != $links2 ] &&
5219                 error "wrong links count $(($links1 + 2)) != $links2"
5220         rmdir b
5221         links3=$(stat -c %h .)
5222         [ $(($links1 + 1)) != $links3 ] &&
5223                 error "wrong links count $links1 != $links3"
5224         return 0
5225 }
5226 run_test 39o "directory cached attributes updated after create"
5227
5228 test_39p() {
5229         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
5230
5231         local MDTIDX=1
5232         TESTDIR=$DIR/$tdir/$tdir
5233         [ -e $TESTDIR ] && rm -rf $TESTDIR
5234         test_mkdir -p $TESTDIR
5235         cd $TESTDIR
5236         links1=2
5237         ls
5238         test_mkdir -i $MDTIDX $TESTDIR/remote_dir1
5239         test_mkdir -i $MDTIDX $TESTDIR/remote_dir2
5240         ls
5241         links2=$(stat -c %h .)
5242         [ $(($links1 + 2)) != $links2 ] &&
5243                 error "wrong links count $(($links1 + 2)) != $links2"
5244         rmdir remote_dir2
5245         links3=$(stat -c %h .)
5246         [ $(($links1 + 1)) != $links3 ] &&
5247                 error "wrong links count $links1 != $links3"
5248         return 0
5249 }
5250 run_test 39p "remote directory cached attributes updated after create ========"
5251
5252 test_39r() {
5253         [ $OST1_VERSION -ge $(version_code 2.13.52) ] ||
5254                 skip "no atime update on old OST"
5255         if [ "$ost1_FSTYPE" != ldiskfs ]; then
5256                 skip_env "ldiskfs only test"
5257         fi
5258
5259         local saved_adiff
5260         saved_adiff=$(do_facet ost1 \
5261                 lctl get_param -n obdfilter.*OST0000.atime_diff)
5262         stack_trap "do_facet ost1 \
5263                 lctl set_param obdfilter.*.atime_diff=$saved_adiff"
5264
5265         do_facet ost1 "lctl set_param obdfilter.*.atime_diff=5"
5266
5267         $LFS setstripe -i 0 $DIR/$tfile
5268         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 ||
5269                 error "can't write initial file"
5270         cancel_lru_locks osc
5271
5272         # exceed atime_diff and access file
5273         sleep 10
5274         dd if=$DIR/$tfile of=/dev/null bs=4k count=1 ||
5275                 error "can't udpate atime"
5276
5277         local atime_cli=$(stat -c %X $DIR/$tfile)
5278         echo "client atime: $atime_cli"
5279         # allow atime update to be written to device
5280         do_facet ost1 "$LCTL set_param -n osd*.*OST*.force_sync 1"
5281         sleep 5
5282
5283         local ostdev=$(ostdevname 1)
5284         local fid=($($LFS getstripe $DIR/$tfile | grep 0x))
5285         local seq=${fid[3]#0x}
5286         local oid=${fid[1]}
5287         local oid_hex
5288
5289         if [ $seq == 0 ]; then
5290                 oid_hex=${fid[1]}
5291         else
5292                 oid_hex=${fid[2]#0x}
5293         fi
5294         local objpath="O/$seq/d$(($oid % 32))/$oid_hex"
5295         local cmd="debugfs -c -R \\\"stat $objpath\\\" $ostdev"
5296
5297         echo "OST atime: $(do_facet ost1 "$cmd" |& grep atime)"
5298         local atime_ost=$(do_facet ost1 "$cmd" |&
5299                           awk -F'[: ]' '/atime:/ { print $4 }')
5300         (( atime_cli == atime_ost )) ||
5301                 error "atime on client $atime_cli != ost $atime_ost"
5302 }
5303 run_test 39r "lazy atime update on OST"
5304
5305 test_39q() { # LU-8041
5306         local testdir=$DIR/$tdir
5307         mkdir -p $testdir
5308         multiop_bg_pause $testdir D_c || error "multiop failed"
5309         local multipid=$!
5310         cancel_lru_locks mdc
5311         kill -USR1 $multipid
5312         local atime=$(stat -c %X $testdir)
5313         [ "$atime" -ne 0 ] || error "atime is zero"
5314 }
5315 run_test 39q "close won't zero out atime"
5316
5317 test_39s() {
5318         local atime0
5319         local atime1
5320         local atime2
5321         local atime3
5322         local atime4
5323
5324         umount_client $MOUNT
5325         mount_client $MOUNT relatime
5326
5327         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 status=noxfer conv=fsync
5328         atime0=$(stat -c %X $DIR/$tfile)
5329
5330         # First read updates atime
5331         sleep 1
5332         cat $DIR/$tfile >/dev/null
5333         atime1=$(stat -c %X $DIR/$tfile) # (atime = atime0 + 1)
5334
5335         # Next reads do not update atime
5336         sleep 1
5337         cat $DIR/$tfile >/dev/null
5338         atime2=$(stat -c %X $DIR/$tfile) # (atime = atime0 + 1)
5339
5340         # If mtime is greater than atime, atime is updated
5341         sleep 1
5342         touch -m $DIR/$tfile # (mtime = now)
5343         sleep 1
5344         cat $DIR/$tfile >/dev/null # (atime is updated because atime < mtime)
5345         atime3=$(stat -c %X $DIR/$tfile) # (atime = mtime = atime0 + 3)
5346
5347         # Next reads do not update atime
5348         sleep 1
5349         cat $DIR/$tfile >/dev/null
5350         atime4=$(stat -c %X $DIR/$tfile)
5351
5352         # Remount the client to clear 'relatime' option
5353         remount_client $MOUNT
5354
5355         (( atime0 < atime1 )) ||
5356                 error "atime $atime0 should be smaller than $atime1"
5357         (( atime1 == atime2 )) ||
5358                 error "atime $atime1 was updated to $atime2"
5359         (( atime1 < atime3 )) || error "atime1 $atime1 != atime3 $atime3"
5360         (( atime3 == atime4 )) || error "atime3 $atime3 != atime4 $atime4"
5361 }
5362 run_test 39s "relatime is supported"
5363
5364 test_40() {
5365         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
5366         $RUNAS $OPENFILE -f O_WRONLY:O_TRUNC $DIR/$tfile &&
5367                 error "openfile O_WRONLY:O_TRUNC $tfile failed"
5368         $CHECKSTAT -t file -s 4096 $DIR/$tfile ||
5369                 error "$tfile is not 4096 bytes in size"
5370 }
5371 run_test 40 "failed open(O_TRUNC) doesn't truncate ============="
5372
5373 test_41() {
5374         # bug 1553
5375         small_write $DIR/f41 18
5376 }
5377 run_test 41 "test small file write + fstat ====================="
5378
5379 count_ost_writes() {
5380         lctl get_param -n ${OSC}.*.stats |
5381                 awk -vwrites=0 '/ost_write/ { writes += $2 } \
5382                         END { printf("%0.0f", writes) }'
5383 }
5384
5385 # decent default
5386 WRITEBACK_SAVE=500
5387 DIRTY_RATIO_SAVE=40
5388 MAX_DIRTY_RATIO=50
5389 BG_DIRTY_RATIO_SAVE=10
5390 MAX_BG_DIRTY_RATIO=25
5391
5392 start_writeback() {
5393         trap 0
5394         # in 2.6, restore /proc/sys/vm/dirty_writeback_centisecs,
5395         # dirty_ratio, dirty_background_ratio
5396         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
5397                 sysctl -w vm.dirty_writeback_centisecs=$WRITEBACK_SAVE
5398                 sysctl -w vm.dirty_background_ratio=$BG_DIRTY_RATIO_SAVE
5399                 sysctl -w vm.dirty_ratio=$DIRTY_RATIO_SAVE
5400         else
5401                 # if file not here, we are a 2.4 kernel
5402                 kill -CONT `pidof kupdated`
5403         fi
5404 }
5405
5406 stop_writeback() {
5407         # setup the trap first, so someone cannot exit the test at the
5408         # exact wrong time and mess up a machine
5409         trap start_writeback EXIT
5410         # in 2.6, save and 0 /proc/sys/vm/dirty_writeback_centisecs
5411         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
5412                 WRITEBACK_SAVE=`sysctl -n vm.dirty_writeback_centisecs`
5413                 sysctl -w vm.dirty_writeback_centisecs=0
5414                 sysctl -w vm.dirty_writeback_centisecs=0
5415                 # save and increase /proc/sys/vm/dirty_ratio
5416                 DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_ratio`
5417                 sysctl -w vm.dirty_ratio=$MAX_DIRTY_RATIO
5418                 # save and increase /proc/sys/vm/dirty_background_ratio
5419                 BG_DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_background_ratio`
5420                 sysctl -w vm.dirty_background_ratio=$MAX_BG_DIRTY_RATIO
5421         else
5422                 # if file not here, we are a 2.4 kernel
5423                 kill -STOP `pidof kupdated`
5424         fi
5425 }
5426
5427 # ensure that all stripes have some grant before we test client-side cache
5428 setup_test42() {
5429         for i in `seq -f $DIR/f42-%g 1 $OSTCOUNT`; do
5430                 dd if=/dev/zero of=$i bs=4k count=1
5431                 rm $i
5432         done
5433 }
5434
5435 # Tests 42* verify that our behaviour is correct WRT caching, file closure,
5436 # file truncation, and file removal.
5437 test_42a() {
5438         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5439
5440         setup_test42
5441         cancel_lru_locks $OSC
5442         stop_writeback
5443         sync; sleep 1; sync # just to be safe
5444         BEFOREWRITES=`count_ost_writes`
5445         lctl get_param -n osc.*[oO][sS][cC][_-]*.cur_grant_bytes | grep "[0-9]"
5446         dd if=/dev/zero of=$DIR/f42a bs=1024 count=100
5447         AFTERWRITES=`count_ost_writes`
5448         [ $BEFOREWRITES -eq $AFTERWRITES ] || \
5449                 error "$BEFOREWRITES < $AFTERWRITES"
5450         start_writeback
5451 }
5452 run_test 42a "ensure that we don't flush on close"
5453
5454 test_42b() {
5455         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5456
5457         setup_test42
5458         cancel_lru_locks $OSC
5459         stop_writeback
5460         sync
5461         dd if=/dev/zero of=$DIR/f42b bs=1024 count=100
5462         BEFOREWRITES=$(count_ost_writes)
5463         $MUNLINK $DIR/f42b || error "$MUNLINK $DIR/f42b: $?"
5464         AFTERWRITES=$(count_ost_writes)
5465         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
5466                 error "$BEFOREWRITES < $AFTERWRITES on unlink"
5467         fi
5468         BEFOREWRITES=$(count_ost_writes)
5469         sync || error "sync: $?"
5470         AFTERWRITES=$(count_ost_writes)
5471         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
5472                 error "$BEFOREWRITES < $AFTERWRITES on sync"
5473         fi
5474         dmesg | grep 'error from obd_brw_async' && error 'error writing back'
5475         start_writeback
5476         return 0
5477 }
5478 run_test 42b "test destroy of file with cached dirty data ======"
5479
5480 # if these tests just want to test the effect of truncation,
5481 # they have to be very careful.  consider:
5482 # - the first open gets a {0,EOF}PR lock
5483 # - the first write conflicts and gets a {0, count-1}PW
5484 # - the rest of the writes are under {count,EOF}PW
5485 # - the open for truncate tries to match a {0,EOF}PR
5486 #   for the filesize and cancels the PWs.
5487 # any number of fixes (don't get {0,EOF} on open, match
5488 # composite locks, do smarter file size management) fix
5489 # this, but for now we want these tests to verify that
5490 # the cancellation with truncate intent works, so we
5491 # start the file with a full-file pw lock to match against
5492 # until the truncate.
5493 trunc_test() {
5494         test=$1
5495         file=$DIR/$test
5496         offset=$2
5497         cancel_lru_locks $OSC
5498         stop_writeback
5499         # prime the file with 0,EOF PW to match
5500         touch $file
5501         $TRUNCATE $file 0
5502         sync; sync
5503         # now the real test..
5504         dd if=/dev/zero of=$file bs=1024 count=100
5505         BEFOREWRITES=`count_ost_writes`
5506         $TRUNCATE $file $offset
5507         cancel_lru_locks $OSC
5508         AFTERWRITES=`count_ost_writes`
5509         start_writeback
5510 }
5511
5512 test_42c() {
5513         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5514
5515         trunc_test 42c 1024
5516         [ $BEFOREWRITES -eq $AFTERWRITES ] &&
5517                 error "beforewrites $BEFOREWRITES == afterwrites $AFTERWRITES on truncate"
5518         rm $file
5519 }
5520 run_test 42c "test partial truncate of file with cached dirty data"
5521
5522 test_42d() {
5523         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5524
5525         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
5526         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
5527         $LCTL set_param debug=+cache
5528
5529         trunc_test 42d 0
5530         [ $BEFOREWRITES -eq $AFTERWRITES ] ||
5531                 error "beforewrites $BEFOREWRITES != afterwrites $AFTERWRITES on truncate"
5532         rm $file
5533 }
5534 run_test 42d "test complete truncate of file with cached dirty data"
5535
5536 test_42e() { # bug22074
5537         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5538
5539         local TDIR=$DIR/${tdir}e
5540         local pages=16 # hardcoded 16 pages, don't change it.
5541         local files=$((OSTCOUNT * 500)) # hopefully 500 files on each OST
5542         local proc_osc0="osc.${FSNAME}-OST0000-osc-[^MDT]*"
5543         local max_dirty_mb
5544         local warmup_files
5545
5546         test_mkdir $DIR/${tdir}e
5547         $LFS setstripe -c 1 $TDIR
5548         createmany -o $TDIR/f $files
5549
5550         max_dirty_mb=$($LCTL get_param -n $proc_osc0/max_dirty_mb)
5551
5552         # we assume that with $OSTCOUNT files, at least one of them will
5553         # be allocated on OST0.
5554         warmup_files=$((OSTCOUNT * max_dirty_mb))
5555         createmany -o $TDIR/w $warmup_files
5556
5557         # write a large amount of data into one file and sync, to get good
5558         # avail_grant number from OST.
5559         for ((i=0; i<$warmup_files; i++)); do
5560                 idx=$($LFS getstripe -i $TDIR/w$i)
5561                 [ $idx -ne 0 ] && continue
5562                 dd if=/dev/zero of=$TDIR/w$i bs="$max_dirty_mb"M count=1
5563                 break
5564         done
5565         [[ $i -gt $warmup_files ]] && error "OST0 is still cold"
5566         sync
5567         $LCTL get_param $proc_osc0/cur_dirty_bytes
5568         $LCTL get_param $proc_osc0/cur_grant_bytes
5569
5570         # create as much dirty pages as we can while not to trigger the actual
5571         # RPCs directly. but depends on the env, VFS may trigger flush during this
5572         # period, hopefully we are good.
5573         for ((i=0; i<$warmup_files; i++)); do
5574                 idx=$($LFS getstripe -i $TDIR/w$i)
5575                 [ $idx -ne 0 ] && continue
5576                 dd if=/dev/zero of=$TDIR/w$i bs=1M count=1 2>/dev/null
5577         done
5578         $LCTL get_param $proc_osc0/cur_dirty_bytes
5579         $LCTL get_param $proc_osc0/cur_grant_bytes
5580
5581         # perform the real test
5582         $LCTL set_param $proc_osc0/rpc_stats 0
5583         for ((;i<$files; i++)); do
5584                 [ $($LFS getstripe -i $TDIR/f$i) -eq 0 ] || continue
5585                 dd if=/dev/zero of=$TDIR/f$i bs=$PAGE_SIZE count=$pages 2>/dev/null
5586         done
5587         sync
5588         $LCTL get_param $proc_osc0/rpc_stats
5589
5590         local percent=0
5591         local have_ppr=false
5592         $LCTL get_param $proc_osc0/rpc_stats |
5593                 while read PPR RRPC RPCT RCUM BAR WRPC WPCT WCUM; do
5594                         # skip lines until we are at the RPC histogram data
5595                         [ "$PPR" == "pages" ] && have_ppr=true && continue
5596                         $have_ppr || continue
5597
5598                         # we only want the percent stat for < 16 pages
5599                         [[ $(echo $PPR | tr -d ':') -ge $pages ]] && break
5600
5601                         percent=$((percent + WPCT))
5602                         if [[ $percent -gt 15 ]]; then
5603                                 error "less than 16-pages write RPCs" \
5604                                       "$percent% > 15%"
5605                                 break
5606                         fi
5607                 done
5608         rm -rf $TDIR
5609 }
5610 run_test 42e "verify sub-RPC writes are not done synchronously"
5611
5612 test_43A() { # was test_43
5613         test_mkdir $DIR/$tdir
5614         cp -p /bin/ls $DIR/$tdir/$tfile
5615         $MULTIOP $DIR/$tdir/$tfile Ow_c &
5616         pid=$!
5617         # give multiop a chance to open
5618         sleep 1
5619
5620         $DIR/$tdir/$tfile && error "execute $DIR/$tdir/$tfile succeeded" || true
5621         kill -USR1 $pid
5622         # Wait for multiop to exit
5623         wait $pid
5624 }
5625 run_test 43A "execution of file opened for write should return -ETXTBSY"
5626
5627 test_43a() {
5628         test_mkdir $DIR/$tdir
5629         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
5630         $DIR/$tdir/sleep 60 &
5631         SLEEP_PID=$!
5632         # Make sure exec of $tdir/sleep wins race with truncate
5633         sleep 1
5634         $MULTIOP $DIR/$tdir/sleep Oc && error "expected error, got success"
5635         kill $SLEEP_PID
5636 }
5637 run_test 43a "open(RDWR) of file being executed should return -ETXTBSY"
5638
5639 test_43b() {
5640         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5641
5642         test_mkdir $DIR/$tdir
5643         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
5644         $DIR/$tdir/sleep 60 &
5645         SLEEP_PID=$!
5646         # Make sure exec of $tdir/sleep wins race with truncate
5647         sleep 1
5648         $TRUNCATE $DIR/$tdir/sleep 0 && error "expected error, got success"
5649         kill $SLEEP_PID
5650 }
5651 run_test 43b "truncate of file being executed should return -ETXTBSY"
5652
5653 test_43c() {
5654         local testdir="$DIR/$tdir"
5655         test_mkdir $testdir
5656         cp $SHELL $testdir/
5657         ( cd $(dirname $SHELL) && md5sum $(basename $SHELL) ) |
5658                 ( cd $testdir && md5sum -c )
5659 }
5660 run_test 43c "md5sum of copy into lustre"
5661
5662 test_44A() { # was test_44
5663         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5664
5665         dd if=/dev/zero of=$DIR/f1 bs=4k count=1 seek=1023
5666         dd if=$DIR/f1 bs=4k count=1 > /dev/null
5667 }
5668 run_test 44A "zero length read from a sparse stripe"
5669
5670 test_44a() {
5671         local nstripe=$($LFS getstripe -c -d $DIR)
5672         [ -z "$nstripe" ] && skip "can't get stripe info"
5673         [[ $nstripe -gt $OSTCOUNT ]] &&
5674                 skip "Wrong default stripe_count: $nstripe OSTCOUNT: $OSTCOUNT"
5675
5676         local stride=$($LFS getstripe -S -d $DIR)
5677         if [[ $nstripe -eq 0 || $nstripe -eq -1 ]]; then
5678                 nstripe=$($LFS df $DIR | grep OST: | wc -l)
5679         fi
5680
5681         OFFSETS="0 $((stride/2)) $((stride-1))"
5682         for offset in $OFFSETS; do
5683                 for i in $(seq 0 $((nstripe-1))); do
5684                         local GLOBALOFFSETS=""
5685                         # size in Bytes
5686                         local size=$((((i + 2 * $nstripe )*$stride + $offset)))
5687                         local myfn=$DIR/d44a-$size
5688                         echo "--------writing $myfn at $size"
5689                         ll_sparseness_write $myfn $size ||
5690                                 error "ll_sparseness_write"
5691                         GLOBALOFFSETS="$GLOBALOFFSETS $size"
5692                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
5693                                 error "ll_sparseness_verify $GLOBALOFFSETS"
5694
5695                         for j in $(seq 0 $((nstripe-1))); do
5696                                 # size in Bytes
5697                                 size=$((((j + $nstripe )*$stride + $offset)))
5698                                 ll_sparseness_write $myfn $size ||
5699                                         error "ll_sparseness_write"
5700                                 GLOBALOFFSETS="$GLOBALOFFSETS $size"
5701                         done
5702                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
5703                                 error "ll_sparseness_verify $GLOBALOFFSETS"
5704                         rm -f $myfn
5705                 done
5706         done
5707 }
5708 run_test 44a "test sparse pwrite ==============================="
5709
5710 dirty_osc_total() {
5711         tot=0
5712         for d in `lctl get_param -n ${OSC}.*.cur_dirty_bytes`; do
5713                 tot=$(($tot + $d))
5714         done
5715         echo $tot
5716 }
5717 do_dirty_record() {
5718         before=`dirty_osc_total`
5719         echo executing "\"$*\""
5720         eval $*
5721         after=`dirty_osc_total`
5722         echo before $before, after $after
5723 }
5724 test_45() {
5725         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5726
5727         f="$DIR/f45"
5728         # Obtain grants from OST if it supports it
5729         echo blah > ${f}_grant
5730         stop_writeback
5731         sync
5732         do_dirty_record "echo blah > $f"
5733         [[ $before -eq $after ]] && error "write wasn't cached"
5734         do_dirty_record "> $f"
5735         [[ $before -gt $after ]] || error "truncate didn't lower dirty count"
5736         do_dirty_record "echo blah > $f"
5737         [[ $before -eq $after ]] && error "write wasn't cached"
5738         do_dirty_record "sync"
5739         [[ $before -gt $after ]] || error "writeback didn't lower dirty count"
5740         do_dirty_record "echo blah > $f"
5741         [[ $before -eq $after ]] && error "write wasn't cached"
5742         do_dirty_record "cancel_lru_locks osc"
5743         [[ $before -gt $after ]] ||
5744                 error "lock cancellation didn't lower dirty count"
5745         start_writeback
5746 }
5747 run_test 45 "osc io page accounting ============================"
5748
5749 # in a 2 stripe file (lov.sh), page 1023 maps to page 511 in its object.  this
5750 # test tickles a bug where re-dirtying a page was failing to be mapped to the
5751 # objects offset and an assert hit when an rpc was built with 1023's mapped
5752 # offset 511 and 511's raw 511 offset. it also found general redirtying bugs.
5753 test_46() {
5754         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5755
5756         f="$DIR/f46"
5757         stop_writeback
5758         sync
5759         dd if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5760         sync
5761         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=1023 count=1
5762         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5763         sync
5764         start_writeback
5765 }
5766 run_test 46 "dirtying a previously written page ================"
5767
5768 # test_47 is removed "Device nodes check" is moved to test_28
5769
5770 test_48a() { # bug 2399
5771         [ "$mds1_FSTYPE" = "zfs" ] &&
5772         [ $MDS1_VERSION -lt $(version_code 2.3.63) ] &&
5773                 skip "MDS prior to 2.3.63 handle ZFS dir .. incorrectly"
5774
5775         test_mkdir $DIR/$tdir
5776         cd $DIR/$tdir
5777         mv $DIR/$tdir $DIR/$tdir.new || error "move directory failed"
5778         test_mkdir $DIR/$tdir
5779         touch foo || error "'touch foo' failed after recreating cwd"
5780         test_mkdir bar
5781         touch .foo || error "'touch .foo' failed after recreating cwd"
5782         test_mkdir .bar
5783         ls . > /dev/null || error "'ls .' failed after recreating cwd"
5784         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5785         cd . || error "'cd .' failed after recreating cwd"
5786         mkdir . && error "'mkdir .' worked after recreating cwd"
5787         rmdir . && error "'rmdir .' worked after recreating cwd"
5788         ln -s . baz || error "'ln -s .' failed after recreating cwd"
5789         cd .. || error "'cd ..' failed after recreating cwd"
5790 }
5791 run_test 48a "Access renamed working dir (should return errors)="
5792
5793 test_48b() { # bug 2399
5794         rm -rf $DIR/$tdir
5795         test_mkdir $DIR/$tdir
5796         cd $DIR/$tdir
5797         rmdir $DIR/$tdir || error "remove cwd $DIR/$tdir failed"
5798         touch foo && error "'touch foo' worked after removing cwd"
5799         mkdir foo && error "'mkdir foo' worked after removing cwd"
5800         touch .foo && error "'touch .foo' worked after removing cwd"
5801         mkdir .foo && error "'mkdir .foo' worked after removing cwd"
5802         ls . > /dev/null && error "'ls .' worked after removing cwd"
5803         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5804         mkdir . && error "'mkdir .' worked after removing cwd"
5805         rmdir . && error "'rmdir .' worked after removing cwd"
5806         ln -s . foo && error "'ln -s .' worked after removing cwd"
5807         cd .. || echo "'cd ..' failed after removing cwd `pwd`"  #bug 3517
5808 }
5809 run_test 48b "Access removed working dir (should return errors)="
5810
5811 test_48c() { # bug 2350
5812         #lctl set_param debug=-1
5813         #set -vx
5814         rm -rf $DIR/$tdir
5815         test_mkdir -p $DIR/$tdir/dir
5816         cd $DIR/$tdir/dir
5817         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5818         $TRACE touch foo && error "touch foo worked after removing cwd"
5819         $TRACE mkdir foo && error "'mkdir foo' worked after removing cwd"
5820         touch .foo && error "touch .foo worked after removing cwd"
5821         mkdir .foo && error "mkdir .foo worked after removing cwd"
5822         $TRACE ls . && error "'ls .' worked after removing cwd"
5823         $TRACE ls .. || error "'ls ..' failed after removing cwd"
5824         $TRACE mkdir . && error "'mkdir .' worked after removing cwd"
5825         $TRACE rmdir . && error "'rmdir .' worked after removing cwd"
5826         $TRACE ln -s . foo && error "'ln -s .' worked after removing cwd"
5827         $TRACE cd .. || echo "'cd ..' failed after removing cwd `pwd`" #bug 3415
5828 }
5829 run_test 48c "Access removed working subdir (should return errors)"
5830
5831 test_48d() { # bug 2350
5832         #lctl set_param debug=-1
5833         #set -vx
5834         rm -rf $DIR/$tdir
5835         test_mkdir -p $DIR/$tdir/dir
5836         cd $DIR/$tdir/dir
5837         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5838         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5839         $TRACE touch foo && error "'touch foo' worked after removing parent"
5840         $TRACE mkdir foo && error "mkdir foo worked after removing parent"
5841         touch .foo && error "'touch .foo' worked after removing parent"
5842         mkdir .foo && error "mkdir .foo worked after removing parent"
5843         $TRACE ls . && error "'ls .' worked after removing parent"
5844         $TRACE ls .. && error "'ls ..' worked after removing parent"
5845         $TRACE mkdir . && error "'mkdir .' worked after removing parent"
5846         $TRACE rmdir . && error "'rmdir .' worked after removing parent"
5847         $TRACE ln -s . foo && error "'ln -s .' worked after removing parent"
5848         true
5849 }
5850 run_test 48d "Access removed parent subdir (should return errors)"
5851
5852 test_48e() { # bug 4134
5853         #lctl set_param debug=-1
5854         #set -vx
5855         rm -rf $DIR/$tdir
5856         test_mkdir -p $DIR/$tdir/dir
5857         cd $DIR/$tdir/dir
5858         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5859         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5860         $TRACE touch $DIR/$tdir || error "'touch $DIR/$tdir' failed"
5861         $TRACE chmod +x $DIR/$tdir || error "'chmod +x $DIR/$tdir' failed"
5862         # On a buggy kernel addition of "touch foo" after cd .. will
5863         # produce kernel oops in lookup_hash_it
5864         touch ../foo && error "'cd ..' worked after recreate parent"
5865         cd $DIR
5866         $TRACE rm $DIR/$tdir || error "rm '$DIR/$tdir' failed"
5867 }
5868 run_test 48e "Access to recreated parent subdir (should return errors)"
5869
5870 test_48f() {
5871         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
5872                 skip "need MDS >= 2.13.55"
5873         [[ $MDSCOUNT -ge 2 ]] || skip "needs >= 2 MDTs"
5874         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] ||
5875                 skip "needs different host for mdt1 mdt2"
5876         [[ $(facet_fstype mds1) == ldiskfs ]] || skip "ldiskfs only"
5877
5878         $LFS mkdir -i0 $DIR/$tdir
5879         $LFS mkdir -i 1 $DIR/$tdir/sub1 $DIR/$tdir/sub2 $DIR/$tdir/sub3
5880
5881         for d in sub1 sub2 sub3; do
5882                 #define OBD_FAIL_OSD_REF_DEL    0x19c
5883                 do_facet mds1 $LCTL set_param fail_loc=0x8000019c
5884                 rm -rf $DIR/$tdir/$d && error "rm $d should fail"
5885         done
5886
5887         rm -d --interactive=never $DIR/$tdir || error "rm $tdir fail"
5888 }
5889 run_test 48f "non-zero nlink dir unlink won't LBUG()"
5890
5891 test_49() { # LU-1030
5892         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5893         remote_ost_nodsh && skip "remote OST with nodsh"
5894
5895         # get ost1 size - $FSNAME-OST0000
5896         ost1_size=$(do_facet ost1 $LFS df | grep ${ost1_svc} |
5897                 awk '{ print $4 }')
5898         # write 800M at maximum
5899         [[ $ost1_size -lt 2 ]] && ost1_size=2
5900         [[ $ost1_size -gt 819200 ]] && ost1_size=819200
5901
5902         $LFS setstripe -c 1 -i 0 $DIR/$tfile
5903         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((ost1_size >> 2)) &
5904         local dd_pid=$!
5905
5906         # change max_pages_per_rpc while writing the file
5907         local osc1_mppc=osc.$(get_osc_import_name client ost1).max_pages_per_rpc
5908         local orig_mppc=$($LCTL get_param -n $osc1_mppc)
5909         # loop until dd process exits
5910         while ps ax -opid | grep -wq $dd_pid; do
5911                 $LCTL set_param $osc1_mppc=$((RANDOM % 256 + 1))
5912                 sleep $((RANDOM % 5 + 1))
5913         done
5914         # restore original max_pages_per_rpc
5915         $LCTL set_param $osc1_mppc=$orig_mppc
5916         rm $DIR/$tfile || error "rm $DIR/$tfile failed"
5917 }
5918 run_test 49 "Change max_pages_per_rpc won't break osc extent"
5919
5920 test_50() {
5921         # bug 1485
5922         test_mkdir $DIR/$tdir
5923         cd $DIR/$tdir
5924         ls /proc/$$/cwd || error "ls /proc/$$/cwd failed"
5925 }
5926 run_test 50 "special situations: /proc symlinks  ==============="
5927
5928 test_51a() {    # was test_51
5929         # bug 1516 - create an empty entry right after ".." then split dir
5930         test_mkdir -c1 $DIR/$tdir
5931         touch $DIR/$tdir/foo
5932         $MCREATE $DIR/$tdir/bar
5933         rm $DIR/$tdir/foo
5934         createmany -m $DIR/$tdir/longfile 201
5935         FNUM=202
5936         while [[ $(ls -sd $DIR/$tdir | awk '{ print $1 }') -eq 4 ]]; do
5937                 $MCREATE $DIR/$tdir/longfile$FNUM
5938                 FNUM=$(($FNUM + 1))
5939                 echo -n "+"
5940         done
5941         echo
5942         ls -l $DIR/$tdir > /dev/null || error "ls -l $DIR/$tdir failed"
5943 }
5944 run_test 51a "special situations: split htree with empty entry =="
5945
5946 cleanup_print_lfs_df () {
5947         trap 0
5948         $LFS df
5949         $LFS df -i
5950 }
5951
5952 test_51b() {
5953         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5954
5955         local dir=$DIR/$tdir
5956         local nrdirs=$((65536 + 100))
5957
5958         # cleanup the directory
5959         rm -fr $dir
5960
5961         mkdir_on_mdt -i $((RANDOM % MDSCOUNT)) $dir
5962
5963         $LFS df
5964         $LFS df -i
5965         local mdtidx=$(printf "%04x" $($LFS getstripe -m $dir))
5966         local numfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.filesfree)
5967         [[ $numfree -lt $nrdirs ]] &&
5968                 skip "not enough free inodes ($numfree) on MDT$mdtidx"
5969
5970         # need to check free space for the directories as well
5971         local blkfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.kbytesavail)
5972         numfree=$(( blkfree / $(fs_inode_ksize) ))
5973         [[ $numfree -lt $nrdirs ]] && skip "not enough blocks ($numfree)"
5974
5975         trap cleanup_print_lfs_df EXIT
5976
5977         # create files
5978         createmany -d $dir/d $nrdirs || {
5979                 unlinkmany $dir/d $nrdirs
5980                 error "failed to create $nrdirs subdirs in MDT$mdtidx:$dir"
5981         }
5982
5983         # really created :
5984         nrdirs=$(ls -U $dir | wc -l)
5985
5986         # unlink all but 100 subdirectories, then check it still works
5987         local left=100
5988         local delete=$((nrdirs - left))
5989
5990         $LFS df
5991         $LFS df -i
5992
5993         # for ldiskfs the nlink count should be 1, but this is OSD specific
5994         # and so this is listed for informational purposes only
5995         echo "nlink before: $(stat -c %h $dir), created before: $nrdirs"
5996         unlinkmany -d $dir/d $delete ||
5997                 error "unlink of first $delete subdirs failed"
5998
5999         echo "nlink between: $(stat -c %h $dir)"
6000         local found=$(ls -U $dir | wc -l)
6001         [ $found -ne $left ] &&
6002                 error "can't find subdirs: found only $found, expected $left"
6003
6004         unlinkmany -d $dir/d $delete $left ||
6005                 error "unlink of second $left subdirs failed"
6006         # regardless of whether the backing filesystem tracks nlink accurately
6007         # or not, the nlink count shouldn't be more than "." and ".." here
6008         local after=$(stat -c %h $dir)
6009         [[ $after -gt 2 ]] && error "nlink after: $after > 2" ||
6010                 echo "nlink after: $after"
6011
6012         cleanup_print_lfs_df
6013 }
6014 run_test 51b "exceed 64k subdirectory nlink limit on create, verify unlink"
6015
6016 test_51d_sub() {
6017         local stripecount=$1
6018         local nfiles=$2
6019
6020         log "create files with stripecount=$stripecount"
6021         $LFS setstripe -C $stripecount $DIR/$tdir
6022         createmany -o $DIR/$tdir/t- $nfiles
6023         $LFS getstripe $DIR/$tdir > $TMP/$tfile
6024         for ((n = 0; n < $OSTCOUNT; n++)); do
6025                 objs[$n]=$(awk -vobjs=0 '($1 == '$n') { objs += 1 } \
6026                            END { printf("%0.0f", objs) }' $TMP/$tfile)
6027                 objs0[$n]=$(grep -A 1 idx $TMP/$tfile | awk -vobjs=0 \
6028                             '($1 == '$n') { objs += 1 } \
6029                             END { printf("%0.0f", objs) }')
6030                 log "OST$n has ${objs[$n]} objects, ${objs0[$n]} are index 0"
6031         done
6032         unlinkmany $DIR/$tdir/t- $nfiles
6033         rm  -f $TMP/$tfile
6034
6035         local nlast
6036         local min=4
6037         local max=6 # allow variance of (1 - $min/$max) = 33% by default
6038
6039         # For some combinations of stripecount and OSTCOUNT current code
6040         # is not ideal, and allocates 50% fewer *first* objects to some OSTs
6041         # than others. Rather than skipping this test entirely, check that
6042         # and keep testing to ensure imbalance does not get worse. LU-15282
6043         (( (OSTCOUNT == 6 && stripecount == 4) ||
6044            (OSTCOUNT == 10 && (stripecount == 4 || stripecount == 8)) ||
6045            (OSTCOUNT == 12 && (stripecount == 8 || stripecount == 9)))) && max=9
6046         for ((nlast=0, n = 1; n < $OSTCOUNT; nlast=n,n++)); do
6047                 (( ${objs[$n]} > ${objs[$nlast]} * 4 / 5 )) ||
6048                         { $LFS df && $LFS df -i &&
6049                         error "stripecount=$stripecount: " \
6050                               "OST $n has fewer objects vs. OST $nlast " \
6051                               "(${objs[$n]} < ${objs[$nlast]} x 4/5)"; }
6052                 (( ${objs[$n]} < ${objs[$nlast]} * 5 / 4 )) ||
6053                         { $LFS df && $LFS df -i &&
6054                         error "stripecount=$stripecount: " \
6055                               "OST $n has more objects vs. OST $nlast " \
6056                               "(${objs[$n]} > ${objs[$nlast]} x 5/4)"; }
6057
6058                 (( ${objs0[$n]} > ${objs0[$nlast]} * $min / $max )) ||
6059                         { $LFS df && $LFS df -i &&
6060                         error "stripecount=$stripecount: " \
6061                               "OST $n has fewer #0 objects vs. OST $nlast " \
6062                               "(${objs0[$n]} < ${objs0[$nlast]} x $min/$max)"; }
6063                 (( ${objs0[$n]} < ${objs0[$nlast]} * $max / $min )) ||
6064                         { $LFS df && $LFS df -i &&
6065                         error "stripecount=$stripecount: " \
6066                               "OST $n has more #0 objects vs. OST $nlast " \
6067                               "(${objs0[$n]} > ${objs0[$nlast]} x $max/$min)"; }
6068         done
6069 }
6070
6071 test_51d() {
6072         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6073         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
6074
6075         local stripecount
6076         local per_ost=100
6077         local nfiles=$((per_ost * OSTCOUNT))
6078         local mdts=$(comma_list $(mdts_nodes))
6079         local param="osp.*.create_count"
6080         local qos_old=$(do_facet mds1 \
6081                 "$LCTL get_param -n lod.$FSNAME-*.qos_threshold_rr" | head -n 1)
6082
6083         do_nodes $mdts \
6084                 "$LCTL set_param lod.$FSNAME-*.qos_threshold_rr=100"
6085         stack_trap "do_nodes $mdts \
6086                 '$LCTL set_param lod.$FSNAME-*.qos_threshold_rr=${qos_old%%%}'"
6087
6088         test_mkdir $DIR/$tdir
6089         local dirstripes=$(lfs getdirstripe -c $DIR/$tdir)
6090         (( dirstripes > 0 )) || dirstripes=1
6091
6092         # Ensure enough OST objects precreated for tests to pass without
6093         # running out of objects.  This is an LOV r-r OST algorithm test,
6094         # not an OST object precreation test.
6095         local old=$(do_facet mds1 "$LCTL get_param -n $param" | head -n 1)
6096         (( old >= nfiles )) ||
6097         {
6098                 local create_count=$((nfiles * OSTCOUNT / dirstripes))
6099
6100                 do_nodes $mdts "$LCTL set_param $param=$create_count"
6101                 stack_trap "do_nodes $mdts $LCTL set_param $param=$old"
6102
6103                 # trigger precreation from all MDTs for all OSTs
6104                 for ((i = 0; i < $MDSCOUNT * 2; i++ )); do
6105                         $LFS setstripe -c -1 $DIR/$tdir/wide.$i
6106                 done
6107         }
6108
6109         for ((stripecount = 3; stripecount <= $OSTCOUNT; stripecount++)); do
6110                 sleep 8  # allow object precreation to catch up
6111                 test_51d_sub $stripecount $nfiles
6112         done
6113 }
6114 run_test 51d "check LOV round-robin OST object distribution"
6115
6116 test_51e() {
6117         if [ "$mds1_FSTYPE" != ldiskfs ]; then
6118                 skip_env "ldiskfs only test"
6119         fi
6120
6121         test_mkdir -c1 $DIR/$tdir
6122         test_mkdir -c1 $DIR/$tdir/d0
6123
6124         touch $DIR/$tdir/d0/foo
6125         createmany -l $DIR/$tdir/d0/foo $DIR/$tdir/d0/f- 65001 &&
6126                 error "file exceed 65000 nlink limit!"
6127         unlinkmany $DIR/$tdir/d0/f- 65001
6128         return 0
6129 }
6130 run_test 51e "check file nlink limit"
6131
6132 test_51f() {
6133         test_mkdir $DIR/$tdir
6134
6135         local max=100000
6136         local ulimit_old=$(ulimit -n)
6137         local spare=20 # number of spare fd's for scripts/libraries, etc.
6138         local mdt=$($LFS getstripe -m $DIR/$tdir)
6139         local numfree=$($LFS df -i $DIR/$tdir | awk '/MDT:'$mdt'/ { print $4 }')
6140
6141         echo "MDT$mdt numfree=$numfree, max=$max"
6142         [[ $numfree -gt $max ]] && numfree=$max || numfree=$((numfree * 7 / 8))
6143         if [ $((numfree + spare)) -gt $ulimit_old ]; then
6144                 while ! ulimit -n $((numfree + spare)); do
6145                         numfree=$((numfree * 3 / 4))
6146                 done
6147                 echo "changed ulimit from $ulimit_old to $((numfree + spare))"
6148         else
6149                 echo "left ulimit at $ulimit_old"
6150         fi
6151
6152         createmany -o -k -t 120 $DIR/$tdir/f $numfree || {
6153                 unlinkmany $DIR/$tdir/f $numfree
6154                 error "create+open $numfree files in $DIR/$tdir failed"
6155         }
6156         ulimit -n $ulimit_old
6157
6158         # if createmany exits at 120s there will be fewer than $numfree files
6159         unlinkmany $DIR/$tdir/f $numfree || true
6160 }
6161 run_test 51f "check many open files limit"
6162
6163 test_52a() {
6164         [ -f $DIR/$tdir/foo ] && chattr -a $DIR/$tdir/foo
6165         test_mkdir $DIR/$tdir
6166         touch $DIR/$tdir/foo
6167         chattr +a $DIR/$tdir/foo || error "chattr +a failed"
6168         echo bar >> $DIR/$tdir/foo || error "append bar failed"
6169         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
6170         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
6171         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
6172                                         error "link worked"
6173         echo foo >> $DIR/$tdir/foo || error "append foo failed"
6174         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
6175         lsattr $DIR/$tdir/foo | egrep -q "^-+a[-e]+ $DIR/$tdir/foo" ||
6176                                                      error "lsattr"
6177         chattr -a $DIR/$tdir/foo || error "chattr -a failed"
6178         cp -r $DIR/$tdir $TMP/
6179         rm -fr $DIR/$tdir $TMP/$tdir || error "cleanup rm failed"
6180 }
6181 run_test 52a "append-only flag test (should return errors)"
6182
6183 test_52b() {
6184         [ -f $DIR/$tdir/foo ] && chattr -i $DIR/$tdir/foo
6185         test_mkdir $DIR/$tdir
6186         touch $DIR/$tdir/foo
6187         chattr +i $DIR/$tdir/foo || error "chattr +i failed"
6188         cat test > $DIR/$tdir/foo && error "cat test worked"
6189         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
6190         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
6191         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
6192                                         error "link worked"
6193         echo foo >> $DIR/$tdir/foo && error "echo worked"
6194         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
6195         [ -f $DIR/$tdir/foo ] || error "$tdir/foo is not a file"
6196         [ -f $DIR/$tdir/foo_ren ] && error "$tdir/foo_ren is not a file"
6197         lsattr $DIR/$tdir/foo | egrep -q "^-+i[-e]+ $DIR/$tdir/foo" ||
6198                                                         error "lsattr"
6199         chattr -i $DIR/$tdir/foo || error "chattr failed"
6200
6201         rm -fr $DIR/$tdir || error "unable to remove $DIR/$tdir"
6202 }
6203 run_test 52b "immutable flag test (should return errors) ======="
6204
6205 test_53() {
6206         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6207         remote_mds_nodsh && skip "remote MDS with nodsh"
6208         remote_ost_nodsh && skip "remote OST with nodsh"
6209
6210         local param
6211         local param_seq
6212         local ostname
6213         local mds_last
6214         local mds_last_seq
6215         local ost_last
6216         local ost_last_seq
6217         local ost_last_id
6218         local ostnum
6219         local node
6220         local found=false
6221         local support_last_seq=true
6222
6223         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
6224                 support_last_seq=false
6225
6226         # only test MDT0000
6227         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS)
6228         local value
6229         for value in $(do_facet $SINGLEMDS \
6230                        $LCTL get_param osp.$mdtosc.prealloc_last_id) ; do
6231                 param=$(echo ${value[0]} | cut -d "=" -f1)
6232                 ostname=$(echo $param | cut -d "." -f2 | cut -d - -f 1-2)
6233
6234                 if $support_last_seq; then
6235                         param_seq=$(echo $param |
6236                                 sed -e s/prealloc_last_id/prealloc_last_seq/g)
6237                         mds_last_seq=$(do_facet $SINGLEMDS \
6238                                        $LCTL get_param -n $param_seq)
6239                 fi
6240                 mds_last=$(do_facet $SINGLEMDS $LCTL get_param -n $param)
6241
6242                 ostnum=$(index_from_ostuuid ${ostname}_UUID)
6243                 node=$(facet_active_host ost$((ostnum+1)))
6244                 param="obdfilter.$ostname.last_id"
6245                 for ost_last in $(do_node $node $LCTL get_param -n $param) ; do
6246                         echo "$ostname.last_id=$ost_last; MDS.last_id=$mds_last"
6247                         ost_last_id=$ost_last
6248
6249                         if $support_last_seq; then
6250                                 ost_last_id=$(echo $ost_last |
6251                                               awk -F':' '{print $2}' |
6252                                               sed -e "s/^0x//g")
6253                                 ost_last_seq=$(echo $ost_last |
6254                                                awk -F':' '{print $1}')
6255                                 [[ $ost_last_seq = $mds_last_seq ]] || continue
6256                         fi
6257
6258                         if [[ $ost_last_id != $mds_last ]]; then
6259                                 error "$ost_last_id != $mds_last"
6260                         else
6261                                 found=true
6262                                 break
6263                         fi
6264                 done
6265         done
6266         $found || error "can not match last_seq/last_id for $mdtosc"
6267         return 0
6268 }
6269 run_test 53 "verify that MDS and OSTs agree on pre-creation ===="
6270
6271 test_54a() {
6272         LANG=C perl -MSocket -e ';' || skip "no Socket perl module installed"
6273
6274         LANG=C $SOCKETSERVER $DIR/socket ||
6275                 error "$SOCKETSERVER $DIR/socket failed: $?"
6276         LANG=C $SOCKETCLIENT $DIR/socket ||
6277                 error "$SOCKETCLIENT $DIR/socket failed: $?"
6278         $MUNLINK $DIR/socket || error "$MUNLINK $DIR/socket failed: $?"
6279 }
6280 run_test 54a "unix domain socket test =========================="
6281
6282 test_54b() {
6283         f="$DIR/f54b"
6284         mknod $f c 1 3
6285         chmod 0666 $f
6286         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1
6287 }
6288 run_test 54b "char device works in lustre ======================"
6289
6290 find_loop_dev() {
6291         [ -b /dev/loop/0 ] && LOOPBASE=/dev/loop/
6292         [ -b /dev/loop0 ] && LOOPBASE=/dev/loop
6293         [ -z "$LOOPBASE" ] && echo "/dev/loop/0 and /dev/loop0 gone?" && return
6294
6295         for i in $(seq 3 7); do
6296                 losetup $LOOPBASE$i > /dev/null 2>&1 && continue
6297                 LOOPDEV=$LOOPBASE$i
6298                 LOOPNUM=$i
6299                 break
6300         done
6301 }
6302
6303 cleanup_54c() {
6304         local rc=0
6305         loopdev="$DIR/loop54c"
6306
6307         trap 0
6308         $UMOUNT $DIR/$tdir || rc=$?
6309         losetup -d $loopdev || true
6310         losetup -d $LOOPDEV || true
6311         rm -rf $loopdev $DIR/$tfile $DIR/$tdir
6312         return $rc
6313 }
6314
6315 test_54c() {
6316         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6317
6318         loopdev="$DIR/loop54c"
6319
6320         find_loop_dev
6321         [ -z "$LOOPNUM" ] && skip_env "couldn't find empty loop device"
6322         trap cleanup_54c EXIT
6323         mknod $loopdev b 7 $LOOPNUM
6324         echo "make a loop file system with $DIR/$tfile on $loopdev ($LOOPNUM)."
6325         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE seek=1024 count=1 > /dev/null
6326         losetup $loopdev $DIR/$tfile ||
6327                 error "can't set up $loopdev for $DIR/$tfile"
6328         mkfs.ext2 $loopdev || error "mke2fs on $loopdev"
6329         test_mkdir $DIR/$tdir
6330         mount -t ext2 $loopdev $DIR/$tdir ||
6331                 error "error mounting $loopdev on $DIR/$tdir"
6332         dd if=/dev/zero of=$DIR/$tdir/tmp bs=$PAGE_SIZE count=30 ||
6333                 error "dd write"
6334         df $DIR/$tdir
6335         dd if=$DIR/$tdir/tmp of=/dev/zero bs=$PAGE_SIZE count=30 ||
6336                 error "dd read"
6337         cleanup_54c
6338 }
6339 run_test 54c "block device works in lustre ====================="
6340
6341 test_54d() {
6342         local pipe="$DIR/$tfile.pipe"
6343         local string="aaaaaa"
6344
6345         mknod $pipe p
6346         echo -n "$string" > $pipe &
6347         local result=$(cat $pipe)
6348         [[ "$result" == "$string" ]] || error "$result != $string"
6349 }
6350 run_test 54d "fifo device works in lustre ======================"
6351
6352 test_54e() {
6353         f="$DIR/f54e"
6354         string="aaaaaa"
6355         cp -aL /dev/console $f
6356         echo $string > $f || error "echo $string to $f failed"
6357 }
6358 run_test 54e "console/tty device works in lustre ======================"
6359
6360 test_56a() {
6361         local numfiles=3
6362         local numdirs=2
6363         local dir=$DIR/$tdir
6364
6365         rm -rf $dir
6366         test_mkdir -p $dir/dir
6367         for i in $(seq $numfiles); do
6368                 touch $dir/file$i
6369                 touch $dir/dir/file$i
6370         done
6371
6372         local numcomp=$($LFS getstripe --component-count $dir)
6373
6374         [[ $numcomp == 0 ]] && numcomp=1
6375
6376         # test lfs getstripe with --recursive
6377         local filenum=$($LFS getstripe -r $dir | egrep -c "obdidx|l_ost_idx")
6378
6379         [[ $filenum -eq $((numfiles * 2)) ]] ||
6380                 error "$LFS getstripe -r: found $filenum != $((numfiles * 2))"
6381         filenum=$($LFS getstripe $dir | egrep -c "obdidx|l_ost_idx")
6382         [[ $filenum -eq $numfiles ]] ||
6383                 error "$LFS getstripe $dir: found $filenum, not $numfiles"
6384         echo "$LFS getstripe showed obdidx or l_ost_idx"
6385
6386         # test lfs getstripe with file instead of dir
6387         filenum=$($LFS getstripe $dir/file1 | egrep -c "obdidx|l_ost_idx")
6388         [[ $filenum -eq 1 ]] ||
6389                 error "$LFS getstripe $dir/file1: found $filenum, not 1"
6390         echo "$LFS getstripe file1 passed"
6391
6392         #test lfs getstripe with --verbose
6393         filenum=$($LFS getstripe --verbose $dir | grep -c lmm_magic)
6394         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
6395                 error "$LFS getstripe --verbose $dir: "\
6396                       "got $filenum want $((numfiles * numcomp)) lmm_magic"
6397         [[ $($LFS getstripe $dir | grep -c lmm_magic) -eq 0 ]] ||
6398                 error "$LFS getstripe $dir: showed lmm_magic"
6399
6400         #test lfs getstripe with -v prints lmm_fid
6401         filenum=$($LFS getstripe -v $dir | grep -c lmm_fid)
6402         local countfids=$((numdirs + numfiles * numcomp))
6403         [[ $filenum -eq $countfids ]] ||
6404                 error "$LFS getstripe -v $dir: "\
6405                       "got $filenum want $countfids lmm_fid"
6406         [[ $($LFS getstripe $dir | grep -c lmm_fid) -eq 0 ]] ||
6407                 error "$LFS getstripe $dir: showed lmm_fid by default"
6408         echo "$LFS getstripe --verbose passed"
6409
6410         #check for FID information
6411         local fid1=$($LFS getstripe --fid $dir/file1)
6412         local fid2=$($LFS getstripe --verbose $dir/file1 |
6413                      awk '/lmm_fid: / { print $2; exit; }')
6414         local fid3=$($LFS path2fid $dir/file1)
6415
6416         [ "$fid1" != "$fid2" ] &&
6417                 error "getstripe --fid '$fid1' != getstripe --verbose '$fid2'"
6418         [ "$fid1" != "$fid3" ] &&
6419                 error "getstripe --fid '$fid1' != lfs path2fid '$fid3'"
6420         echo "$LFS getstripe --fid passed"
6421
6422         #test lfs getstripe with --obd
6423         $LFS getstripe --obd wrong_uuid $dir 2>&1 | grep -q "unknown obduuid" ||
6424                 error "$LFS getstripe --obd wrong_uuid: should return error"
6425
6426         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6427
6428         local ostidx=1
6429         local obduuid=$(ostuuid_from_index $ostidx)
6430         local found=$($LFS getstripe -r --obd $obduuid $dir |
6431                 grep 'lmm_stripe_offset:' | grep -c " $ostidx\$")
6432
6433         filenum=$($LFS getstripe -ir $dir | grep -c "^$ostidx\$")
6434         [[ $($LFS getstripe -id $dir) -ne $ostidx ]] ||
6435                 ((filenum--))
6436         [[ $($LFS getstripe -id $dir/dir) -ne $ostidx ]] ||
6437                 ((filenum--))
6438
6439         [[ $found -eq $filenum ]] ||
6440                 error "$LFS getstripe --obd: found $found expect $filenum"
6441         [[ $($LFS getstripe -r -v --obd $obduuid $dir |
6442                 sed '/^[         ]*'${ostidx}'[  ]/d' |
6443                 sed -n '/^[      ]*[0-9][0-9]*[  ]/p' | wc -l) -eq 0 ]] ||
6444                 error "$LFS getstripe --obd: should not show file on other obd"
6445         echo "$LFS getstripe --obd passed"
6446 }
6447 run_test 56a "check $LFS getstripe"
6448
6449 test_56b() {
6450         local dir=$DIR/$tdir
6451         local numdirs=3
6452
6453         test_mkdir $dir
6454         for i in $(seq $numdirs); do
6455                 test_mkdir $dir/dir$i
6456         done
6457
6458         # test lfs getdirstripe default mode is non-recursion, which is
6459         # different from lfs getstripe
6460         local dircnt=$($LFS getdirstripe $dir | grep -c lmv_stripe_count)
6461
6462         [[ $dircnt -eq 1 ]] ||
6463                 error "$LFS getdirstripe: found $dircnt, not 1"
6464         dircnt=$($LFS getdirstripe --recursive $dir |
6465                 grep -c lmv_stripe_count)
6466         [[ $dircnt -eq $((numdirs + 1)) ]] ||
6467                 error "$LFS getdirstripe -r: $dircnt, != $((numdirs + 1))"
6468 }
6469 run_test 56b "check $LFS getdirstripe"
6470
6471 test_56bb() {
6472         verify_yaml_available || skip_env "YAML verification not installed"
6473         local output_file=$DIR/$tfile.out
6474
6475         $LFS getdirstripe -v -D -y $DIR 1> $output_file
6476
6477         cat $output_file
6478         cat $output_file | verify_yaml || error "layout is not valid YAML"
6479 }
6480 run_test 56bb "check $LFS getdirstripe layout is YAML"
6481
6482 test_56c() {
6483         remote_ost_nodsh && skip "remote OST with nodsh"
6484
6485         local ost_idx=0
6486         local ost_name=$(ostname_from_index $ost_idx)
6487         local old_status=$(ost_dev_status $ost_idx)
6488         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
6489
6490         [[ -z "$old_status" ]] ||
6491                 skip_env "OST $ost_name is in $old_status status"
6492
6493         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=1
6494         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
6495                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=1
6496         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
6497                 save_lustre_params ost1 osd-*.$ost_name.nonrotational > $p
6498                 do_facet ost1 $LCTL set_param -n osd-*.$ost_name.nonrotational=1
6499         fi
6500
6501         [[ $($LFS df -v $MOUNT |& grep -c "inactive device") -eq 0 ]] ||
6502                 error "$LFS df -v showing inactive devices"
6503         sleep_maxage
6504
6505         local new_status=$(ost_dev_status $ost_idx $MOUNT -v)
6506
6507         [[ "$new_status" =~ "D" ]] ||
6508                 error "$ost_name status is '$new_status', missing 'D'"
6509         if [[ $OST1_VERSION -ge $(version_code 2.12.55) ]]; then
6510                 [[ "$new_status" =~ "N" ]] ||
6511                         error "$ost_name status is '$new_status', missing 'N'"
6512         fi
6513         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
6514                 [[ "$new_status" =~ "f" ]] ||
6515                         error "$ost_name status is '$new_status', missing 'f'"
6516         fi
6517
6518         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=0
6519         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
6520                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=0
6521         [[ -z "$p" ]] && restore_lustre_params < $p || true
6522         sleep_maxage
6523
6524         new_status=$(ost_dev_status $ost_idx)
6525         [[ ! "$new_status" =~ "D" && ! "$new_status" =~ "N" ]] ||
6526                 error "$ost_name status is '$new_status', has 'D' and/or 'N'"
6527         # can't check 'f' as devices may actually be on flash
6528 }
6529 run_test 56c "check 'lfs df' showing device status"
6530
6531 test_56d() {
6532         local mdts=$($LFS df -v $MOUNT | grep -c MDT)
6533         local osts=$($LFS df -v $MOUNT | grep -c OST)
6534
6535         $LFS df $MOUNT
6536
6537         (( mdts == MDSCOUNT )) ||
6538                 error "lfs df -v showed $mdts MDTs, not $MDSCOUNT"
6539         (( osts == OSTCOUNT )) ||
6540                 error "lfs df -v showed $osts OSTs, not $OSTCOUNT"
6541 }
6542 run_test 56d "'lfs df -v' prints only configured devices"
6543
6544 test_56e() {
6545         err_enoent=2 # No such file or directory
6546         err_eopnotsupp=95 # Operation not supported
6547
6548         enoent_mnt=/pmt1 # Invalid dentry. Path not present
6549         notsup_mnt=/tmp  # Valid dentry, but Not a lustreFS
6550
6551         # Check for handling of path not exists
6552         output=$($LFS df $enoent_mnt 2>&1)
6553         ret=$?
6554
6555         fs=$(echo $output | awk -F: '{print $2}' | awk '{print $3}' | tr -d \')
6556         [[ $fs = $enoent_mnt && $ret -eq $err_enoent ]] ||
6557                 error "expect failure $err_enoent, not $ret"
6558
6559         # Check for handling of non-Lustre FS
6560         output=$($LFS df $notsup_mnt)
6561         ret=$?
6562
6563         fs=$(echo $output | awk '{print $1}' | awk -F: '{print $2}')
6564         [[ $fs = $notsup_mnt && $ret -eq $err_eopnotsupp ]] ||
6565                 error "expect success $err_eopnotsupp, not $ret"
6566
6567         # Check for multiple LustreFS argument
6568         output=$($LFS df $MOUNT $MOUNT $MOUNT | grep -c "filesystem_summary:")
6569         ret=$?
6570
6571         [[ $output -eq 3 && $ret -eq 0 ]] ||
6572                 error "expect success 3, not $output, rc = $ret"
6573
6574         # Check for correct non-Lustre FS handling among multiple
6575         # LustreFS argument
6576         output=$($LFS df $MOUNT $notsup_mnt $MOUNT |
6577                 grep -c "filesystem_summary:"; exit ${PIPESTATUS[0]})
6578         ret=$?
6579
6580         [[ $output -eq 2 && $ret -eq $err_eopnotsupp ]] ||
6581                 error "expect success 2, not $output, rc = $ret"
6582 }
6583 run_test 56e "'lfs df' Handle non LustreFS & multiple LustreFS"
6584
6585 NUMFILES=3
6586 NUMDIRS=3
6587 setup_56() {
6588         local local_tdir="$1"
6589         local local_numfiles="$2"
6590         local local_numdirs="$3"
6591         local dir_params="$4"
6592         local dir_stripe_params="$5"
6593
6594         if [ ! -d "$local_tdir" ] ; then
6595                 test_mkdir -p $dir_stripe_params $local_tdir
6596                 [ "$dir_params" ] && $LFS setstripe $dir_params $local_tdir
6597                 for i in $(seq $local_numfiles) ; do
6598                         touch $local_tdir/file$i
6599                 done
6600                 for i in $(seq $local_numdirs) ; do
6601                         test_mkdir $dir_stripe_params $local_tdir/dir$i
6602                         for j in $(seq $local_numfiles) ; do
6603                                 touch $local_tdir/dir$i/file$j
6604                         done
6605                 done
6606         fi
6607 }
6608
6609 setup_56_special() {
6610         local local_tdir=$1
6611         local local_numfiles=$2
6612         local local_numdirs=$3
6613
6614         setup_56 $local_tdir $local_numfiles $local_numdirs
6615
6616         if [ ! -e "$local_tdir/loop${local_numfiles}b" ] ; then
6617                 for i in $(seq $local_numfiles) ; do
6618                         mknod $local_tdir/loop${i}b b 7 $i
6619                         mknod $local_tdir/null${i}c c 1 3
6620                         ln -s $local_tdir/file1 $local_tdir/link${i}
6621                 done
6622                 for i in $(seq $local_numdirs) ; do
6623                         mknod $local_tdir/dir$i/loop${i}b b 7 $i
6624                         mknod $local_tdir/dir$i/null${i}c c 1 3
6625                         ln -s $local_tdir/dir$i/file1 $local_tdir/dir$i/link${i}
6626                 done
6627         fi
6628 }
6629
6630 test_56g() {
6631         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6632         local expected=$(($NUMDIRS + 2))
6633
6634         setup_56 $dir $NUMFILES $NUMDIRS
6635
6636         # test lfs find with -name
6637         for i in $(seq $NUMFILES) ; do
6638                 local nums=$($LFS find -name "*$i" $dir | wc -l)
6639
6640                 [ $nums -eq $expected ] ||
6641                         error "lfs find -name '*$i' $dir wrong: "\
6642                               "found $nums, expected $expected"
6643         done
6644 }
6645 run_test 56g "check lfs find -name"
6646
6647 test_56h() {
6648         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6649         local expected=$(((NUMDIRS + 1) * (NUMFILES - 1) + NUMFILES))
6650
6651         setup_56 $dir $NUMFILES $NUMDIRS
6652
6653         # test lfs find with ! -name
6654         for i in $(seq $NUMFILES) ; do
6655                 local nums=$($LFS find ! -name "*$i" $dir | wc -l)
6656
6657                 [ $nums -eq $expected ] ||
6658                         error "lfs find ! -name '*$i' $dir wrong: "\
6659                               "found $nums, expected $expected"
6660         done
6661 }
6662 run_test 56h "check lfs find ! -name"
6663
6664 test_56i() {
6665         local dir=$DIR/$tdir
6666
6667         test_mkdir $dir
6668
6669         local cmd="$LFS find -ost $(ostuuid_from_index 0 $dir) $dir"
6670         local out=$($cmd)
6671
6672         [ -z "$out" ] || error "'$cmd' returned directory '$out'"
6673 }
6674 run_test 56i "check 'lfs find -ost UUID' skips directories"
6675
6676 test_56j() {
6677         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6678
6679         setup_56_special $dir $NUMFILES $NUMDIRS
6680
6681         local expected=$((NUMDIRS + 1))
6682         local cmd="$LFS find -type d $dir"
6683         local nums=$($cmd | wc -l)
6684
6685         [ $nums -eq $expected ] ||
6686                 error "'$cmd' wrong: found $nums, expected $expected"
6687 }
6688 run_test 56j "check lfs find -type d"
6689
6690 test_56k() {
6691         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6692
6693         setup_56_special $dir $NUMFILES $NUMDIRS
6694
6695         local expected=$(((NUMDIRS + 1) * NUMFILES))
6696         local cmd="$LFS find -type f $dir"
6697         local nums=$($cmd | wc -l)
6698
6699         [ $nums -eq $expected ] ||
6700                 error "'$cmd' wrong: found $nums, expected $expected"
6701 }
6702 run_test 56k "check lfs find -type f"
6703
6704 test_56l() {
6705         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6706
6707         setup_56_special $dir $NUMFILES $NUMDIRS
6708
6709         local expected=$((NUMDIRS + NUMFILES))
6710         local cmd="$LFS find -type b $dir"
6711         local nums=$($cmd | wc -l)
6712
6713         [ $nums -eq $expected ] ||
6714                 error "'$cmd' wrong: found $nums, expected $expected"
6715 }
6716 run_test 56l "check lfs find -type b"
6717
6718 test_56m() {
6719         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6720
6721         setup_56_special $dir $NUMFILES $NUMDIRS
6722
6723         local expected=$((NUMDIRS + NUMFILES))
6724         local cmd="$LFS find -type c $dir"
6725         local nums=$($cmd | wc -l)
6726         [ $nums -eq $expected ] ||
6727                 error "'$cmd' wrong: found $nums, expected $expected"
6728 }
6729 run_test 56m "check lfs find -type c"
6730
6731 test_56n() {
6732         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6733         setup_56_special $dir $NUMFILES $NUMDIRS
6734
6735         local expected=$((NUMDIRS + NUMFILES))
6736         local cmd="$LFS find -type l $dir"
6737         local nums=$($cmd | wc -l)
6738
6739         [ $nums -eq $expected ] ||
6740                 error "'$cmd' wrong: found $nums, expected $expected"
6741 }
6742 run_test 56n "check lfs find -type l"
6743
6744 test_56o() {
6745         local dir=$DIR/$tdir
6746
6747         setup_56 $dir $NUMFILES $NUMDIRS
6748         utime $dir/file1 > /dev/null || error "utime (1)"
6749         utime $dir/file2 > /dev/null || error "utime (2)"
6750         utime $dir/dir1 > /dev/null || error "utime (3)"
6751         utime $dir/dir2 > /dev/null || error "utime (4)"
6752         utime $dir/dir1/file1 > /dev/null || error "utime (5)"
6753         dd if=/dev/zero count=1 >> $dir/dir1/file1 && sync
6754
6755         local expected=4
6756         local nums=$($LFS find -mtime +0 $dir | wc -l)
6757
6758         [ $nums -eq $expected ] ||
6759                 error "lfs find -mtime +0 $dir: found $nums expect $expected"
6760
6761         expected=12
6762         cmd="$LFS find -mtime 0 $dir"
6763         nums=$($cmd | wc -l)
6764         [ $nums -eq $expected ] ||
6765                 error "'$cmd' wrong: found $nums, expected $expected"
6766 }
6767 run_test 56o "check lfs find -mtime for old files"
6768
6769 test_56ob() {
6770         local dir=$DIR/$tdir
6771         local expected=1
6772         local count=0
6773
6774         # just to make sure there is something that won't be found
6775         test_mkdir $dir
6776         touch $dir/$tfile.now
6777
6778         for age in year week day hour min; do
6779                 count=$((count + 1))
6780
6781                 touch $dir/$tfile-a.$age $dir/$tfile-m.$age
6782                 touch --date="$count $age ago" -a $dir/$tfile-a.$age
6783                 touch --date="$count $age ago" -m $dir/$tfile-m.$age
6784
6785                 local cmd="$LFS find $dir -mtime $count${age:0:1}"
6786                 local nums=$($cmd | wc -l)
6787                 [ $nums -eq $expected ] ||
6788                         error "'$cmd' wrong: found $nums, expected $expected"
6789
6790                 cmd="$LFS find $dir -atime $count${age:0:1}"
6791                 nums=$($cmd | wc -l)
6792                 [ $nums -eq $expected ] ||
6793                         error "'$cmd' wrong: found $nums, expected $expected"
6794         done
6795
6796         sleep 2
6797         cmd="$LFS find $dir -ctime +1s -type f"
6798         nums=$($cmd | wc -l)
6799         (( $nums == $count * 2 + 1)) ||
6800                 error "'$cmd' wrong: found $nums, expected $((count * 2 + 1))"
6801 }
6802 run_test 56ob "check lfs find -atime -mtime -ctime with units"
6803
6804 test_newerXY_base() {
6805         local x=$1
6806         local y=$2
6807         local dir=$DIR/$tdir
6808         local ref
6809         local negref
6810
6811         if [ $y == "t" ]; then
6812                 if [ $x == "b" ]; then
6813                         ref=\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\"
6814                 else
6815                         ref=\"$(date +"%Y-%m-%d %H:%M:%S")\"
6816                 fi
6817         else
6818                 ref=$DIR/$tfile.newer.$x$y
6819                 touch $ref || error "touch $ref failed"
6820         fi
6821
6822         echo "before = $ref"
6823         sleep 2
6824         setup_56 $dir $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6825         sleep 2
6826         if [ $y == "t" ]; then
6827                 if [ $x == "b" ]; then
6828                         negref=\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\"
6829                 else
6830                         negref=\"$(date +"%Y-%m-%d %H:%M:%S")\"
6831                 fi
6832         else
6833                 negref=$DIR/$tfile.negnewer.$x$y
6834                 touch $negref || error "touch $negref failed"
6835         fi
6836
6837         echo "after = $negref"
6838         local cmd="$LFS find $dir -newer$x$y $ref"
6839         local nums=$(eval $cmd | wc -l)
6840         local expected=$(((NUMFILES + 2) * NUMDIRS + 1))
6841
6842         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6843                 error "'$cmd' wrong: found $nums newer, expected $expected"  ; }
6844
6845         cmd="$LFS find $dir ! -newer$x$y $negref"
6846         nums=$(eval $cmd | wc -l)
6847         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6848                 error "'$cmd' wrong: found $nums older, expected $expected"  ; }
6849
6850         cmd="$LFS find $dir -newer$x$y $ref ! -newer$x$y $negref"
6851         nums=$(eval $cmd | wc -l)
6852         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6853                 error "'$cmd' wrong: found $nums between, expected $expected"; }
6854
6855         rm -rf $DIR/*
6856 }
6857
6858 test_56oc() {
6859         test_newerXY_base "a" "a"
6860         test_newerXY_base "a" "m"
6861         test_newerXY_base "a" "c"
6862         test_newerXY_base "m" "a"
6863         test_newerXY_base "m" "m"
6864         test_newerXY_base "m" "c"
6865         test_newerXY_base "c" "a"
6866         test_newerXY_base "c" "m"
6867         test_newerXY_base "c" "c"
6868
6869         test_newerXY_base "a" "t"
6870         test_newerXY_base "m" "t"
6871         test_newerXY_base "c" "t"
6872
6873         [[ $MDS1_VERSION -lt $(version_code 2.13.54) ||
6874            $CLIENT_VERSION -lt $(version_code 2.13.54) ]] &&
6875                 ! btime_supported && echo "btime unsupported" && return 0
6876
6877         test_newerXY_base "b" "b"
6878         test_newerXY_base "b" "t"
6879 }
6880 run_test 56oc "check lfs find -newerXY work"
6881
6882 btime_supported() {
6883         local dir=$DIR/$tdir
6884         local rc
6885
6886         mkdir -p $dir
6887         touch $dir/$tfile
6888         $LFS find $dir -btime -1d -type f
6889         rc=$?
6890         rm -rf $dir
6891         return $rc
6892 }
6893
6894 test_56od() {
6895         [ $MDS1_VERSION -lt $(version_code 2.13.53) ] &&
6896                 ! btime_supported && skip "btime unsupported on MDS"
6897
6898         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
6899                 ! btime_supported && skip "btime unsupported on clients"
6900
6901         local dir=$DIR/$tdir
6902         local ref=$DIR/$tfile.ref
6903         local negref=$DIR/$tfile.negref
6904
6905         mkdir $dir || error "mkdir $dir failed"
6906         touch $dir/$tfile.n1 || error "touch $dir/$tfile.n1 failed"
6907         touch $dir/$tfile.n2 || error "touch $dir/$tfile.n2 failed"
6908         mkdir $dir/$tdir.n1 || error "mkdir $dir/$tdir.n1 failed"
6909         mkdir $dir/$tdir.n2 || error "mkdir $dir/$tdir.n2 failed"
6910         touch $ref || error "touch $ref failed"
6911         # sleep 3 seconds at least
6912         sleep 3
6913
6914         local before=$(do_facet mds1 date +%s)
6915         local skew=$(($(date +%s) - before + 1))
6916
6917         if (( skew < 0 && skew > -5 )); then
6918                 sleep $((0 - skew + 1))
6919                 skew=0
6920         fi
6921
6922         # Set the dir stripe params to limit files all on MDT0,
6923         # otherwise we need to calc the max clock skew between
6924         # the client and MDTs.
6925         setup_56 $dir/d.btime $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6926         sleep 2
6927         touch $negref || error "touch $negref failed"
6928
6929         local cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type f"
6930         local nums=$($cmd | wc -l)
6931         local expected=$(((NUMFILES + 1) * NUMDIRS))
6932
6933         [ $nums -eq $expected ] ||
6934                 error "'$cmd' wrong: found $nums, expected $expected"
6935
6936         cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type d"
6937         nums=$($cmd | wc -l)
6938         expected=$((NUMFILES + 1))
6939         [ $nums -eq $expected ] ||
6940                 error "'$cmd' wrong: found $nums, expected $expected"
6941
6942         [ $skew -lt 0 ] && return
6943
6944         local after=$(do_facet mds1 date +%s)
6945         local age=$((after - before + 1 + skew))
6946
6947         cmd="$LFS find $dir -btime -${age}s -type f"
6948         nums=$($cmd | wc -l)
6949         expected=$(((NUMFILES + 1) * NUMDIRS))
6950
6951         echo "Clock skew between client and server: $skew, age:$age"
6952         [ $nums -eq $expected ] ||
6953                 error "'$cmd' wrong: found $nums, expected $expected"
6954
6955         expected=$(($NUMDIRS + 1))
6956         cmd="$LFS find $dir -btime -${age}s -type d"
6957         nums=$($cmd | wc -l)
6958         [ $nums -eq $expected ] ||
6959                 error "'$cmd' wrong: found $nums, expected $expected"
6960         rm -f $ref $negref || error "Failed to remove $ref $negref"
6961 }
6962 run_test 56od "check lfs find -btime with units"
6963
6964 test_56p() {
6965         [ $RUNAS_ID -eq $UID ] &&
6966                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6967
6968         local dir=$DIR/$tdir
6969
6970         setup_56 $dir $NUMFILES $NUMDIRS
6971         chown $RUNAS_ID $dir/file* || error "chown $DIR/${tdir}g/file$i failed"
6972
6973         local expected=$NUMFILES
6974         local cmd="$LFS find -uid $RUNAS_ID $dir"
6975         local nums=$($cmd | wc -l)
6976
6977         [ $nums -eq $expected ] ||
6978                 error "'$cmd' wrong: found $nums, expected $expected"
6979
6980         expected=$(((NUMFILES + 1) * NUMDIRS + 1))
6981         cmd="$LFS find ! -uid $RUNAS_ID $dir"
6982         nums=$($cmd | wc -l)
6983         [ $nums -eq $expected ] ||
6984                 error "'$cmd' wrong: found $nums, expected $expected"
6985 }
6986 run_test 56p "check lfs find -uid and ! -uid"
6987
6988 test_56q() {
6989         [ $RUNAS_ID -eq $UID ] &&
6990                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6991
6992         local dir=$DIR/$tdir
6993
6994         setup_56 $dir $NUMFILES $NUMDIRS
6995         chgrp $RUNAS_GID $dir/file* || error "chown $dir/file$i failed"
6996
6997         local expected=$NUMFILES
6998         local cmd="$LFS find -gid $RUNAS_GID $dir"
6999         local nums=$($cmd | wc -l)
7000
7001         [ $nums -eq $expected ] ||
7002                 error "'$cmd' wrong: found $nums, expected $expected"
7003
7004         expected=$(( ($NUMFILES+1) * $NUMDIRS + 1))
7005         cmd="$LFS find ! -gid $RUNAS_GID $dir"
7006         nums=$($cmd | wc -l)
7007         [ $nums -eq $expected ] ||
7008                 error "'$cmd' wrong: found $nums, expected $expected"
7009 }
7010 run_test 56q "check lfs find -gid and ! -gid"
7011
7012 test_56r() {
7013         local dir=$DIR/$tdir
7014
7015         setup_56 $dir $NUMFILES $NUMDIRS
7016
7017         local expected=12
7018         local cmd="$LFS find -size 0 -type f -lazy $dir"
7019         local nums=$($cmd | wc -l)
7020
7021         [ $nums -eq $expected ] ||
7022                 error "'$cmd' wrong: found $nums, expected $expected"
7023         cmd="$LFS find -size 0 -type f $dir"
7024         nums=$($cmd | wc -l)
7025         [ $nums -eq $expected ] ||
7026                 error "'$cmd' wrong: found $nums, expected $expected"
7027
7028         expected=0
7029         cmd="$LFS find ! -size 0 -type f -lazy $dir"
7030         nums=$($cmd | wc -l)
7031         [ $nums -eq $expected ] ||
7032                 error "'$cmd' wrong: found $nums, expected $expected"
7033         cmd="$LFS find ! -size 0 -type f $dir"
7034         nums=$($cmd | wc -l)
7035         [ $nums -eq $expected ] ||
7036                 error "'$cmd' wrong: found $nums, expected $expected"
7037
7038         echo "test" > $dir/$tfile
7039         echo "test2" > $dir/$tfile.2 && sync
7040         expected=1
7041         cmd="$LFS find -size 5 -type f -lazy $dir"
7042         nums=$($cmd | wc -l)
7043         [ $nums -eq $expected ] ||
7044                 error "'$cmd' wrong: found $nums, expected $expected"
7045         cmd="$LFS find -size 5 -type f $dir"
7046         nums=$($cmd | wc -l)
7047         [ $nums -eq $expected ] ||
7048                 error "'$cmd' wrong: found $nums, expected $expected"
7049
7050         expected=1
7051         cmd="$LFS find -size +5 -type f -lazy $dir"
7052         nums=$($cmd | wc -l)
7053         [ $nums -eq $expected ] ||
7054                 error "'$cmd' wrong: found $nums, expected $expected"
7055         cmd="$LFS find -size +5 -type f $dir"
7056         nums=$($cmd | wc -l)
7057         [ $nums -eq $expected ] ||
7058                 error "'$cmd' wrong: found $nums, expected $expected"
7059
7060         expected=2
7061         cmd="$LFS find -size +0 -type f -lazy $dir"
7062         nums=$($cmd | wc -l)
7063         [ $nums -eq $expected ] ||
7064                 error "'$cmd' wrong: found $nums, expected $expected"
7065         cmd="$LFS find -size +0 -type f $dir"
7066         nums=$($cmd | wc -l)
7067         [ $nums -eq $expected ] ||
7068                 error "'$cmd' wrong: found $nums, expected $expected"
7069
7070         expected=2
7071         cmd="$LFS find ! -size -5 -type f -lazy $dir"
7072         nums=$($cmd | wc -l)
7073         [ $nums -eq $expected ] ||
7074                 error "'$cmd' wrong: found $nums, expected $expected"
7075         cmd="$LFS find ! -size -5 -type f $dir"
7076         nums=$($cmd | wc -l)
7077         [ $nums -eq $expected ] ||
7078                 error "'$cmd' wrong: found $nums, expected $expected"
7079
7080         expected=12
7081         cmd="$LFS find -size -5 -type f -lazy $dir"
7082         nums=$($cmd | wc -l)
7083         [ $nums -eq $expected ] ||
7084                 error "'$cmd' wrong: found $nums, expected $expected"
7085         cmd="$LFS find -size -5 -type f $dir"
7086         nums=$($cmd | wc -l)
7087         [ $nums -eq $expected ] ||
7088                 error "'$cmd' wrong: found $nums, expected $expected"
7089 }
7090 run_test 56r "check lfs find -size works"
7091
7092 test_56ra_sub() {
7093         local expected=$1
7094         local glimpses=$2
7095         local cmd="$3"
7096
7097         cancel_lru_locks $OSC
7098
7099         local rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
7100         local nums=$($cmd | wc -l)
7101
7102         [ $nums -eq $expected ] ||
7103                 error "'$cmd' wrong: found $nums, expected $expected"
7104
7105         local rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
7106
7107         if (( rpcs_before + glimpses != rpcs_after )); then
7108                 echo "Before: $rpcs_before After: $rpcs_after $NUMFILES"
7109                 $LCTL get_param osc.*.stats | grep ldlm_glimpse_enqueue
7110
7111                 if [[ $glimpses == 0 ]]; then
7112                         error "'$cmd' should not send glimpse RPCs to OST"
7113                 else
7114                         error "'$cmd' should send $glimpses glimpse RPCs to OST"
7115                 fi
7116         fi
7117 }
7118
7119 test_56ra() {
7120         [[ $MDS1_VERSION -gt $(version_code 2.12.58) ]] ||
7121                 skip "MDS < 2.12.58 doesn't return LSOM data"
7122         local dir=$DIR/$tdir
7123         local old_agl=$($LCTL get_param -n llite.*.statahead_agl)
7124
7125         [[ $OSC == "mdc" ]] && skip "statahead not needed for DoM files"
7126
7127         # statahead_agl may cause extra glimpse which confuses results. LU-13017
7128         $LCTL set_param -n llite.*.statahead_agl=0
7129         stack_trap "$LCTL set_param -n llite.*.statahead_agl=$old_agl"
7130
7131         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
7132         # open and close all files to ensure LSOM is updated
7133         cancel_lru_locks $OSC
7134         find $dir -type f | xargs cat > /dev/null
7135
7136         #   expect_found  glimpse_rpcs  command_to_run
7137         test_56ra_sub 12  0 "$LFS find -size 0 -type f -lazy $dir"
7138         test_56ra_sub 12 12 "$LFS find -size 0 -type f $dir"
7139         test_56ra_sub  0  0 "$LFS find ! -size 0 -type f -lazy $dir"
7140         test_56ra_sub  0 12 "$LFS find ! -size 0 -type f $dir"
7141
7142         echo "test" > $dir/$tfile
7143         echo "test2" > $dir/$tfile.2 && sync
7144         cancel_lru_locks $OSC
7145         cat $dir/$tfile $dir/$tfile.2 > /dev/null
7146
7147         test_56ra_sub  1  0 "$LFS find -size 5 -type f -lazy $dir"
7148         test_56ra_sub  1 14 "$LFS find -size 5 -type f $dir"
7149         test_56ra_sub  1  0 "$LFS find -size +5 -type f -lazy $dir"
7150         test_56ra_sub  1 14 "$LFS find -size +5 -type f $dir"
7151
7152         test_56ra_sub  2  0 "$LFS find -size +0 -type f -lazy $dir"
7153         test_56ra_sub  2 14 "$LFS find -size +0 -type f $dir"
7154         test_56ra_sub  2  0 "$LFS find ! -size -5 -type f -lazy $dir"
7155         test_56ra_sub  2 14 "$LFS find ! -size -5 -type f $dir"
7156         test_56ra_sub 12  0 "$LFS find -size -5 -type f -lazy $dir"
7157         test_56ra_sub 12 14 "$LFS find -size -5 -type f $dir"
7158 }
7159 run_test 56ra "check lfs find -size -lazy works for data on OSTs"
7160
7161 test_56rb() {
7162         local dir=$DIR/$tdir
7163         local tmp=$TMP/$tfile.log
7164         local mdt_idx;
7165
7166         test_mkdir -p $dir || error "failed to mkdir $dir"
7167         $LFS setstripe -c 1 -i 0 $dir/$tfile ||
7168                 error "failed to setstripe $dir/$tfile"
7169         mdt_idx=$($LFS getdirstripe -i $dir)
7170         dd if=/dev/zero of=$dir/$tfile bs=1M count=1
7171
7172         stack_trap "rm -f $tmp" EXIT
7173         $LFS find --size +100K --ost 0 $dir |& tee $tmp
7174         ! grep -q obd_uuid $tmp ||
7175                 error "failed to find --size +100K --ost 0 $dir"
7176         $LFS find --size +100K --mdt $mdt_idx $dir |& tee $tmp
7177         ! grep -q obd_uuid $tmp ||
7178                 error "failed to find --size +100K --mdt $mdt_idx $dir"
7179 }
7180 run_test 56rb "check lfs find --size --ost/--mdt works"
7181
7182 test_56rc() {
7183         (( MDSCOUNT >= 2 )) || skip "needs at least 2 MDTs"
7184         local dir=$DIR/$tdir
7185         local found
7186
7187         test_mkdir -c 2 -H all_char $dir || error "failed to mkdir $dir"
7188         $LFS mkdir -c 2 --mdt-hash all_char $dir/$tdir-all{1..10}
7189         (( $MDSCOUNT > 2 )) &&
7190                 $LFS mkdir -c 3 --mdt-hash fnv_1a_64 $dir/$tdir-fnv{1..10}
7191         mkdir $dir/$tdir-{1..10}
7192         touch $dir/$tfile-{1..10}
7193
7194         found=$($LFS find $dir --mdt-count 2 | wc -l)
7195         expect=11
7196         (( $found == $expect )) || error "found $found 2-stripe, expect $expect"
7197
7198         found=$($LFS find $dir -T +1 | wc -l)
7199         (( $MDSCOUNT > 2 )) && expect=$((expect + 10))
7200         (( $found == $expect )) || error "found $found 2+stripe, expect $expect"
7201
7202         found=$($LFS find $dir --mdt-hash all_char | wc -l)
7203         expect=11
7204         (( $found == $expect )) || error "found $found all_char, expect $expect"
7205
7206         found=$($LFS find $dir --mdt-hash fnv_1a_64 | wc -l)
7207         (( $MDSCOUNT > 2 )) && expect=10 || expect=0
7208         (( $found == $expect )) || error "found $found all_char, expect $expect"
7209 }
7210 run_test 56rc "check lfs find --mdt-count/--mdt-hash works"
7211
7212 test_56s() { # LU-611 #LU-9369
7213         [[ $OSTCOUNT -lt 2 ]] && skip_env "need at least 2 OSTs"
7214
7215         local dir=$DIR/$tdir
7216         local onestripe=$(((NUMDIRS + 1) * NUMFILES))
7217
7218         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
7219         for i in $(seq $NUMDIRS); do
7220                 $LFS setstripe -c $((OSTCOUNT + 1)) $dir/dir$i/$tfile
7221         done
7222
7223         local expected=$NUMDIRS
7224         local cmd="$LFS find -c $OSTCOUNT $dir"
7225         local nums=$($cmd | wc -l)
7226
7227         [ $nums -eq $expected ] || {
7228                 $LFS getstripe -R $dir
7229                 error "'$cmd' wrong: found $nums, expected $expected"
7230         }
7231
7232         expected=$((NUMDIRS + onestripe))
7233         cmd="$LFS find -stripe-count +0 -type f $dir"
7234         nums=$($cmd | wc -l)
7235         [ $nums -eq $expected ] || {
7236                 $LFS getstripe -R $dir
7237                 error "'$cmd' wrong: found $nums, expected $expected"
7238         }
7239
7240         expected=$onestripe
7241         cmd="$LFS find -stripe-count 1 -type f $dir"
7242         nums=$($cmd | wc -l)
7243         [ $nums -eq $expected ] || {
7244                 $LFS getstripe -R $dir
7245                 error "'$cmd' wrong: found $nums, expected $expected"
7246         }
7247
7248         cmd="$LFS find -stripe-count -2 -type f $dir"
7249         nums=$($cmd | wc -l)
7250         [ $nums -eq $expected ] || {
7251                 $LFS getstripe -R $dir
7252                 error "'$cmd' wrong: found $nums, expected $expected"
7253         }
7254
7255         expected=0
7256         cmd="$LFS find -stripe-count $((OSTCOUNT + 1)) -type f $dir"
7257         nums=$($cmd | wc -l)
7258         [ $nums -eq $expected ] || {
7259                 $LFS getstripe -R $dir
7260                 error "'$cmd' wrong: found $nums, expected $expected"
7261         }
7262 }
7263 run_test 56s "check lfs find -stripe-count works"
7264
7265 test_56t() { # LU-611 #LU-9369
7266         local dir=$DIR/$tdir
7267
7268         setup_56 $dir 0 $NUMDIRS
7269         for i in $(seq $NUMDIRS); do
7270                 $LFS setstripe -S 8M $dir/dir$i/$tfile
7271         done
7272
7273         local expected=$NUMDIRS
7274         local cmd="$LFS find -S 8M $dir"
7275         local nums=$($cmd | wc -l)
7276
7277         [ $nums -eq $expected ] || {
7278                 $LFS getstripe -R $dir
7279                 error "'$cmd' wrong: found $nums, expected $expected"
7280         }
7281         rm -rf $dir
7282
7283         setup_56 $dir $NUMFILES $NUMDIRS "--stripe-size 512k"
7284
7285         $LFS setstripe -S 256k $dir/$tfile.{0,1,2,3}
7286
7287         expected=$(((NUMDIRS + 1) * NUMFILES))
7288         cmd="$LFS find -stripe-size 512k -type f $dir"
7289         nums=$($cmd | wc -l)
7290         [ $nums -eq $expected ] ||
7291                 error "'$cmd' wrong: found $nums, expected $expected"
7292
7293         cmd="$LFS find -stripe-size +320k -type f $dir"
7294         nums=$($cmd | wc -l)
7295         [ $nums -eq $expected ] ||
7296                 error "'$cmd' wrong: found $nums, expected $expected"
7297
7298         expected=$(((NUMDIRS + 1) * NUMFILES + 4))
7299         cmd="$LFS find -stripe-size +200k -type f $dir"
7300         nums=$($cmd | wc -l)
7301         [ $nums -eq $expected ] ||
7302                 error "'$cmd' wrong: found $nums, expected $expected"
7303
7304         cmd="$LFS find -stripe-size -640k -type f $dir"
7305         nums=$($cmd | wc -l)
7306         [ $nums -eq $expected ] ||
7307                 error "'$cmd' wrong: found $nums, expected $expected"
7308
7309         expected=4
7310         cmd="$LFS find -stripe-size 256k -type f $dir"
7311         nums=$($cmd | wc -l)
7312         [ $nums -eq $expected ] ||
7313                 error "'$cmd' wrong: found $nums, expected $expected"
7314
7315         cmd="$LFS find -stripe-size -320k -type f $dir"
7316         nums=$($cmd | wc -l)
7317         [ $nums -eq $expected ] ||
7318                 error "'$cmd' wrong: found $nums, expected $expected"
7319
7320         expected=0
7321         cmd="$LFS find -stripe-size 1024k -type f $dir"
7322         nums=$($cmd | wc -l)
7323         [ $nums -eq $expected ] ||
7324                 error "'$cmd' wrong: found $nums, expected $expected"
7325 }
7326 run_test 56t "check lfs find -stripe-size works"
7327
7328 test_56u() { # LU-611
7329         local dir=$DIR/$tdir
7330
7331         setup_56 $dir $NUMFILES $NUMDIRS "-i 0 -c 1"
7332
7333         if [[ $OSTCOUNT -gt 1 ]]; then
7334                 $LFS setstripe -i 1 -c 1 $dir/$tfile.{0,1,2,3}
7335                 onestripe=4
7336         else
7337                 onestripe=0
7338         fi
7339
7340         local expected=$(((NUMDIRS + 1) * NUMFILES))
7341         local cmd="$LFS find -stripe-index 0 -type f $dir"
7342         local nums=$($cmd | wc -l)
7343
7344         [ $nums -eq $expected ] ||
7345                 error "'$cmd' wrong: found $nums, expected $expected"
7346
7347         expected=$onestripe
7348         cmd="$LFS find -stripe-index 1 -type f $dir"
7349         nums=$($cmd | wc -l)
7350         [ $nums -eq $expected ] ||
7351                 error "'$cmd' wrong: found $nums, expected $expected"
7352
7353         cmd="$LFS find ! -stripe-index 0 -type f $dir"
7354         nums=$($cmd | wc -l)
7355         [ $nums -eq $expected ] ||
7356                 error "'$cmd' wrong: found $nums, expected $expected"
7357
7358         expected=0
7359         # This should produce an error and not return any files
7360         cmd="$LFS find -stripe-index $OSTCOUNT -type f $dir"
7361         nums=$($cmd 2>/dev/null | wc -l)
7362         [ $nums -eq $expected ] ||
7363                 error "'$cmd' wrong: found $nums, expected $expected"
7364
7365         if [[ $OSTCOUNT -gt 1 ]]; then
7366                 expected=$(((NUMDIRS + 1) * NUMFILES + onestripe))
7367                 cmd="$LFS find -stripe-index 0,1 -type f $dir"
7368                 nums=$($cmd | wc -l)
7369                 [ $nums -eq $expected ] ||
7370                         error "'$cmd' wrong: found $nums, expected $expected"
7371         fi
7372 }
7373 run_test 56u "check lfs find -stripe-index works"
7374
7375 test_56v() {
7376         local mdt_idx=0
7377         local dir=$DIR/$tdir
7378
7379         setup_56 $dir $NUMFILES $NUMDIRS
7380
7381         UUID=$(mdtuuid_from_index $mdt_idx $dir)
7382         [ -z "$UUID" ] && error "mdtuuid_from_index cannot find MDT $mdt_idx"
7383
7384         for file in $($LFS find -m $UUID $dir); do
7385                 file_midx=$($LFS getstripe -m $file)
7386                 [ $file_midx -eq $mdt_idx ] ||
7387                         error "lfs find -m $UUID != getstripe -m $file_midx"
7388         done
7389 }
7390 run_test 56v "check 'lfs find -m match with lfs getstripe -m'"
7391
7392 test_56wa() {
7393         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
7394         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7395
7396         local dir=$DIR/$tdir
7397
7398         setup_56 $dir $NUMFILES $NUMDIRS "-c $OSTCOUNT" "-c1"
7399         stack_trap "rm -rf $dir"
7400
7401         local stripe_size=$($LFS getstripe -S -d $dir) ||
7402                 error "$LFS getstripe -S -d $dir failed"
7403         stripe_size=${stripe_size%% *}
7404
7405         local file_size=$((stripe_size * OSTCOUNT))
7406         local file_num=$((NUMDIRS * NUMFILES + NUMFILES))
7407         local required_space=$((file_num * file_size))
7408         local free_space=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
7409                            head -n1)
7410         (( free_space >= required_space / 1024 )) ||
7411                 skip_env "need $required_space, have $free_space kbytes"
7412
7413         local dd_bs=65536
7414         local dd_count=$((file_size / dd_bs))
7415
7416         # write data into the files
7417         local i
7418         local j
7419         local file
7420
7421         for ((i = 1; i <= NUMFILES; i++ )); do
7422                 file=$dir/file$i
7423                 yes | dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
7424                         error "write data into $file failed"
7425         done
7426         for ((i = 1; i <= NUMDIRS; i++ )); do
7427                 for ((j = 1; j <= NUMFILES; j++ )); do
7428                         file=$dir/dir$i/file$j
7429                         yes|dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
7430                                 error "write data into $file failed"
7431                 done
7432         done
7433
7434         # $LFS_MIGRATE will fail if hard link migration is unsupported
7435         if (( MDS1_VERSION > $(version_code 2.5.55) )); then
7436                 createmany -l$dir/dir1/file1 $dir/dir1/link 200 ||
7437                         error "creating links to $dir/dir1/file1 failed"
7438         fi
7439
7440         local expected=-1
7441
7442         (( OSTCOUNT <= 1 )) || expected=$((OSTCOUNT - 1))
7443
7444         # lfs_migrate file
7445         local cmd="$LFS_MIGRATE -y -c $expected $dir/file1"
7446
7447         echo "$cmd"
7448         eval $cmd || error "$cmd failed"
7449
7450         check_stripe_count $dir/file1 $expected
7451
7452         if (( $MDS1_VERSION >= $(version_code 2.6.90) )); then
7453                 # lfs_migrate file onto OST 0 if it is on OST 1, or onto
7454                 # OST 1 if it is on OST 0. This file is small enough to
7455                 # be on only one stripe.
7456                 file=$dir/migr_1_ost
7457                 dd bs=$dd_bs count=1 if=/dev/urandom of=$file >/dev/null 2>&1 ||
7458                         error "write data into $file failed"
7459                 local obdidx=$($LFS getstripe -i $file)
7460                 local oldmd5=$(md5sum $file)
7461                 local newobdidx=0
7462
7463                 (( obdidx != 0 )) || newobdidx=1
7464                 cmd="$LFS migrate -i $newobdidx $file"
7465                 echo $cmd
7466                 eval $cmd || error "$cmd failed"
7467
7468                 local realobdix=$($LFS getstripe -i $file)
7469                 local newmd5=$(md5sum $file)
7470
7471                 (( $newobdidx == $realobdix )) ||
7472                         error "new OST is different (was=$obdidx, wanted=$newobdidx, got=$realobdix)"
7473                 [[ "$oldmd5" == "$newmd5" ]] ||
7474                         error "md5sum differ: $oldmd5, $newmd5"
7475         fi
7476
7477         # lfs_migrate dir
7478         cmd="$LFS_MIGRATE -y -c $expected $dir/dir1"
7479         echo "$cmd"
7480         eval $cmd || error "$cmd failed"
7481
7482         for (( j = 1; j <= NUMFILES; j++ )); do
7483                 check_stripe_count $dir/dir1/file$j $expected
7484         done
7485
7486         # lfs_migrate works with lfs find
7487         cmd="$LFS find -stripe_count $OSTCOUNT -type f $dir |
7488              $LFS_MIGRATE -y -c $expected"
7489         echo "$cmd"
7490         eval $cmd || error "$cmd failed"
7491
7492         for (( i = 2; i <= NUMFILES; i++ )); do
7493                 check_stripe_count $dir/file$i $expected
7494         done
7495         for (( i = 2; i <= NUMDIRS; i++ )); do
7496                 for (( j = 1; j <= NUMFILES; j++ )); do
7497                         check_stripe_count $dir/dir$i/file$j $expected
7498                 done
7499         done
7500 }
7501 run_test 56wa "check lfs_migrate -c stripe_count works"
7502
7503 test_56wb() {
7504         local file1=$DIR/$tdir/file1
7505         local create_pool=false
7506         local initial_pool=$($LFS getstripe -p $DIR)
7507         local pool_list=()
7508         local pool=""
7509
7510         echo -n "Creating test dir..."
7511         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
7512         echo "done."
7513
7514         echo -n "Creating test file..."
7515         touch $file1 || error "cannot create file"
7516         echo "done."
7517
7518         echo -n "Detecting existing pools..."
7519         pool_list=($($LFS pool_list $FSNAME | grep "$FSNAME\." | cut -d. -f2))
7520
7521         if [ ${#pool_list[@]} -gt 0 ]; then
7522                 echo "${pool_list[@]}"
7523                 for thispool in "${pool_list[@]}"; do
7524                         if [[ -z "$initial_pool" ||
7525                               "$initial_pool" != "$thispool" ]]; then
7526                                 pool="$thispool"
7527                                 echo "Using existing pool '$pool'"
7528                                 break
7529                         fi
7530                 done
7531         else
7532                 echo "none detected."
7533         fi
7534         if [ -z "$pool" ]; then
7535                 pool=${POOL:-testpool}
7536                 [ "$initial_pool" = "$pool" ] && pool="testpool2"
7537                 echo -n "Creating pool '$pool'..."
7538                 create_pool=true
7539                 pool_add $pool &> /dev/null ||
7540                         error "pool_add failed"
7541                 echo "done."
7542
7543                 echo -n "Adding target to pool..."
7544                 pool_add_targets $pool 0 0 1 &> /dev/null ||
7545                         error "pool_add_targets failed"
7546                 echo "done."
7547         fi
7548
7549         echo -n "Setting pool using -p option..."
7550         $LFS_MIGRATE -y -q --no-rsync -p $pool $file1 &> /dev/null ||
7551                 error "migrate failed rc = $?"
7552         echo "done."
7553
7554         echo -n "Verifying test file is in pool after migrating..."
7555         [ "$($LFS getstripe -p $file1)" = $pool ] ||
7556                 error "file was not migrated to pool $pool"
7557         echo "done."
7558
7559         echo -n "Removing test file from pool '$pool'..."
7560         # "lfs migrate $file" won't remove the file from the pool
7561         # until some striping information is changed.
7562         $LFS migrate -c 1 $file1 &> /dev/null ||
7563                 error "cannot remove from pool"
7564         [ "$($LFS getstripe -p $file1)" ] &&
7565                 error "pool still set"
7566         echo "done."
7567
7568         echo -n "Setting pool using --pool option..."
7569         $LFS_MIGRATE -y -q --no-rsync --pool $pool $file1 &> /dev/null ||
7570                 error "migrate failed rc = $?"
7571         echo "done."
7572
7573         # Clean up
7574         rm -f $file1
7575         if $create_pool; then
7576                 destroy_test_pools 2> /dev/null ||
7577                         error "destroy test pools failed"
7578         fi
7579 }
7580 run_test 56wb "check lfs_migrate pool support"
7581
7582 test_56wc() {
7583         local file1="$DIR/$tdir/$tfile"
7584         local md5
7585         local parent_ssize
7586         local parent_scount
7587         local cur_ssize
7588         local cur_scount
7589         local orig_ssize
7590         local new_scount
7591         local cur_comp
7592
7593         echo -n "Creating test dir..."
7594         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
7595         $LFS setstripe -S 1M -c 1 "$DIR/$tdir" &> /dev/null ||
7596                 error "cannot set stripe by '-S 1M -c 1'"
7597         echo "done"
7598
7599         echo -n "Setting initial stripe for test file..."
7600         $LFS setstripe -S 512K -c 1 "$file1" &> /dev/null ||
7601                 error "cannot set stripe"
7602         cur_ssize=$($LFS getstripe -S "$file1")
7603         (( cur_ssize == 524288 )) || error "setstripe -S $cur_ssize != 524288"
7604         echo "done."
7605
7606         dd if=/dev/urandom of=$file1 bs=1M count=12 || error "dd $file1 failed"
7607         stack_trap "rm -f $file1"
7608         md5="$(md5sum $file1)"
7609
7610         # File currently set to -S 512K -c 1
7611
7612         # Ensure -c and -S options are rejected when -R is set
7613         echo -n "Verifying incompatible options are detected..."
7614         $LFS_MIGRATE -R -c 1 "$file1" &&
7615                 error "incompatible -R and -c options not detected"
7616         $LFS_MIGRATE -R -S 1M "$file1" &&
7617                 error "incompatible -R and -S options not detected"
7618         $LFS_MIGRATE -R -p pool "$file1" &&
7619                 error "incompatible -R and -p options not detected"
7620         $LFS_MIGRATE -R -E eof -c 1 "$file1" &&
7621                 error "incompatible -R and -E options not detected"
7622         $LFS_MIGRATE -R -A "$file1" &&
7623                 error "incompatible -R and -A options not detected"
7624         $LFS_MIGRATE -A -c 1 "$file1" &&
7625                 error "incompatible -A and -c options not detected"
7626         $LFS_MIGRATE -A -S 1M "$file1" &&
7627                 error "incompatible -A and -S options not detected"
7628         $LFS_MIGRATE -A -p pool "$file1" &&
7629                 error "incompatible -A and -p options not detected"
7630         $LFS_MIGRATE -A -E eof -c 1 "$file1" &&
7631                 error "incompatible -A and -E options not detected"
7632         echo "done."
7633
7634         # Ensure unrecognized options are passed through to 'lfs migrate'
7635         echo -n "Verifying -S option is passed through to lfs migrate..."
7636         $LFS_MIGRATE -y -S 1M "$file1" || error "migration failed"
7637         cur_ssize=$($LFS getstripe -S "$file1")
7638         (( cur_ssize == 1048576 )) || error "migrate -S $cur_ssize != 1048576"
7639         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (1)"
7640         echo "done."
7641
7642         # File currently set to -S 1M -c 1
7643
7644         # Ensure long options are supported
7645         echo -n "Verifying long options supported..."
7646         $LFS_MIGRATE --non-block "$file1" ||
7647                 error "long option without argument not supported"
7648         $LFS_MIGRATE --stripe-size 512K "$file1" ||
7649                 error "long option with argument not supported"
7650         cur_ssize=$($LFS getstripe -S "$file1")
7651         (( cur_ssize == 524288 )) ||
7652                 error "migrate --stripe-size $cur_ssize != 524288"
7653         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (2)"
7654         echo "done."
7655
7656         # File currently set to -S 512K -c 1
7657
7658         if (( OSTCOUNT > 1 )); then
7659                 echo -n "Verifying explicit stripe count can be set..."
7660                 $LFS_MIGRATE -c 2 "$file1" || error "migrate failed"
7661                 cur_scount=$($LFS getstripe -c "$file1")
7662                 (( cur_scount == 2 )) || error "migrate -c $cur_scount != 2"
7663                 [[ "$(md5sum $file1)" == "$md5" ]] ||
7664                         error "file data has changed (3)"
7665                 echo "done."
7666         fi
7667
7668         # File currently set to -S 512K -c 1 or -S 512K -c 2
7669
7670         # Ensure parent striping is used if -R is set, and no stripe
7671         # count or size is specified
7672         echo -n "Setting stripe for parent directory..."
7673         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
7674                 error "cannot set stripe '-S 2M -c 1'"
7675         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (4)"
7676         echo "done."
7677
7678         echo -n "Verifying restripe option uses parent stripe settings..."
7679         parent_ssize=$($LFS getstripe -S $DIR/$tdir 2>/dev/null)
7680         parent_scount=$($LFS getstripe -c $DIR/$tdir 2>/dev/null)
7681         $LFS_MIGRATE -R "$file1" || error "migrate failed"
7682         cur_ssize=$($LFS getstripe -S "$file1")
7683         (( cur_ssize == parent_ssize )) ||
7684                 error "migrate -R stripe_size $cur_ssize != $parent_ssize"
7685         cur_scount=$($LFS getstripe -c "$file1")
7686         (( cur_scount == parent_scount )) ||
7687                 error "migrate -R stripe_count $cur_scount != $parent_scount"
7688         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (5)"
7689         echo "done."
7690
7691         # File currently set to -S 1M -c 1
7692
7693         # Ensure striping is preserved if -R is not set, and no stripe
7694         # count or size is specified
7695         echo -n "Verifying striping size preserved when not specified..."
7696         orig_ssize=$($LFS getstripe -S "$file1" 2>/dev/null)
7697         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
7698                 error "cannot set stripe on parent directory"
7699         $LFS_MIGRATE "$file1" || error "migrate failed"
7700         cur_ssize=$($LFS getstripe -S "$file1")
7701         (( cur_ssize == orig_ssize )) ||
7702                 error "migrate by default $cur_ssize != $orig_ssize"
7703         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (6)"
7704         echo "done."
7705
7706         # Ensure file name properly detected when final option has no argument
7707         echo -n "Verifying file name properly detected..."
7708         $LFS_MIGRATE "$file1" ||
7709                 error "file name interpreted as option argument"
7710         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (7)"
7711         echo "done."
7712
7713         # Ensure PFL arguments are passed through properly
7714         echo -n "Verifying PFL options passed through..."
7715         new_scount=$(((OSTCOUNT + 1) / 2))
7716         $LFS_MIGRATE -E 1M -c 1 -E 16M -c $new_scount -E eof -c -1 "$file1" ||
7717                 error "migrate PFL arguments failed"
7718         cur_comp=$($LFS getstripe --comp-count $file1)
7719         (( cur_comp == 3 )) || error "component count '$cur_comp' != 3"
7720         cur_scount=$($LFS getstripe --stripe-count $file1)
7721         (( cur_scount == new_scount)) ||
7722                 error "PFL stripe count $cur_scount != $new_scount"
7723         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (8)"
7724         echo "done."
7725 }
7726 run_test 56wc "check unrecognized options for lfs_migrate are passed through"
7727
7728 test_56wd() {
7729         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
7730
7731         local file1=$DIR/$tdir/$tfile
7732
7733         echo -n "Creating test dir..."
7734         test_mkdir $DIR/$tdir || error "cannot create dir"
7735         echo "done."
7736
7737         echo -n "Creating test file..."
7738         echo "$tfile" > $file1
7739         echo "done."
7740
7741         # Ensure 'lfs migrate' will fail by using a non-existent option,
7742         # and make sure rsync is not called to recover
7743         echo -n "Make sure --no-rsync option works..."
7744         $LFS_MIGRATE -y --no-rsync --invalid-opt $file1 2>&1 |
7745                 grep -q 'refusing to fall back to rsync' ||
7746                 error "rsync was called with --no-rsync set"
7747         echo "done."
7748
7749         # Ensure rsync is called without trying 'lfs migrate' first
7750         echo -n "Make sure --rsync option works..."
7751         $LFS_MIGRATE -y --rsync --invalid-opt $file1 2>&1 |
7752                 grep -q 'falling back to rsync' &&
7753                 error "lfs migrate was called with --rsync set"
7754         echo "done."
7755 }
7756 run_test 56wd "check lfs_migrate --rsync and --no-rsync work"
7757
7758 test_56we() {
7759         local td=$DIR/$tdir
7760         local tf=$td/$tfile
7761
7762         test_mkdir $td || error "cannot create $td"
7763         touch $tf || error "cannot touch $tf"
7764
7765         echo -n "Make sure --non-direct|-D works..."
7766         $LFS_MIGRATE -y --non-direct -v $tf 2>&1 |
7767                 grep -q "lfs migrate --non-direct" ||
7768                 error "--non-direct option cannot work correctly"
7769         $LFS_MIGRATE -y -D -v $tf 2>&1 |
7770                 grep -q "lfs migrate -D" ||
7771                 error "-D option cannot work correctly"
7772         echo "done."
7773 }
7774 run_test 56we "check lfs_migrate --non-direct|-D support"
7775
7776 test_56x() {
7777         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7778         check_swap_layouts_support
7779
7780         local dir=$DIR/$tdir
7781         local ref1=/etc/passwd
7782         local file1=$dir/file1
7783
7784         test_mkdir $dir || error "creating dir $dir"
7785         $LFS setstripe -c 2 $file1
7786         cp $ref1 $file1
7787         $LFS migrate -c 1 $file1 || error "migrate failed rc = $?"
7788         stripe=$($LFS getstripe -c $file1)
7789         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
7790         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
7791
7792         # clean up
7793         rm -f $file1
7794 }
7795 run_test 56x "lfs migration support"
7796
7797 test_56xa() {
7798         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7799         check_swap_layouts_support
7800
7801         local dir=$DIR/$tdir/$testnum
7802
7803         test_mkdir -p $dir
7804
7805         local ref1=/etc/passwd
7806         local file1=$dir/file1
7807
7808         $LFS setstripe -c 2 $file1
7809         cp $ref1 $file1
7810         $LFS migrate --block -c 1 $file1 || error "migrate failed rc = $?"
7811
7812         local stripe=$($LFS getstripe -c $file1)
7813
7814         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
7815         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
7816
7817         # clean up
7818         rm -f $file1
7819 }
7820 run_test 56xa "lfs migration --block support"
7821
7822 check_migrate_links() {
7823         [[ "$1" == "--rsync" ]] && local opts="--rsync -y" && shift
7824         local dir="$1"
7825         local file1="$dir/file1"
7826         local begin="$2"
7827         local count="$3"
7828         local runas="$4"
7829         local total_count=$(($begin + $count - 1))
7830         local symlink_count=10
7831         local uniq_count=10
7832
7833         if [ ! -f "$file1" ]; then
7834                 echo -n "creating initial file..."
7835                 $LFS setstripe -c 1 -S "512k" "$file1" ||
7836                         error "cannot setstripe initial file"
7837                 echo "done"
7838
7839                 echo -n "creating symlinks..."
7840                 for s in $(seq 1 $symlink_count); do
7841                         ln -s "$file1" "$dir/slink$s" ||
7842                                 error "cannot create symlinks"
7843                 done
7844                 echo "done"
7845
7846                 echo -n "creating nonlinked files..."
7847                 createmany -o "$dir/uniq" 1 10 &> /dev/null ||
7848                         error "cannot create nonlinked files"
7849                 echo "done"
7850         fi
7851
7852         # create hard links
7853         if [ ! -f "$dir/file$total_count" ]; then
7854                 echo -n "creating hard links $begin:$total_count..."
7855                 createmany -l"$file1" "$dir/file" "$begin" "$count" &>  \
7856                         /dev/null || error "cannot create hard links"
7857                 echo "done"
7858         fi
7859
7860         echo -n "checking number of hard links listed in xattrs..."
7861         local fid=$($LFS getstripe -F "$file1")
7862         local paths=($($LFS fid2path "$MOUNT" "$fid" 2> /dev/null))
7863
7864         echo "${#paths[*]}"
7865         if [ ${#paths[*]} -lt $total_count -a "$begin" -eq 2  ]; then
7866                         skip "hard link list has unexpected size, skipping test"
7867         fi
7868         if [ ${#paths[*]} -ge $total_count -a "$begin" -ne 2  ]; then
7869                         error "link names should exceed xattrs size"
7870         fi
7871
7872         echo -n "migrating files..."
7873         local migrate_out=$($runas $LFS_MIGRATE $opts -S '1m' $dir)
7874         local rc=$?
7875         [ $rc -eq 0 ] || error "migrate failed rc = $rc"
7876         echo "done"
7877
7878         # make sure all links have been properly migrated
7879         echo -n "verifying files..."
7880         fid=$($LFS getstripe -F "$file1") ||
7881                 error "cannot get fid for file $file1"
7882         for i in $(seq 2 $total_count); do
7883                 local fid2=$($LFS getstripe -F $dir/file$i)
7884
7885                 [ "$fid2" == "$fid" ] ||
7886                         error "migrated hard link has mismatched FID"
7887         done
7888
7889         # make sure hard links were properly detected, and migration was
7890         # performed only once for the entire link set; nonlinked files should
7891         # also be migrated
7892         local actual=$(grep -c 'done' <<< "$migrate_out")
7893         local expected=$(($uniq_count + 1))
7894
7895         [ "$actual" -eq  "$expected" ] ||
7896                 error "hard links individually migrated ($actual != $expected)"
7897
7898         # make sure the correct number of hard links are present
7899         local hardlinks=$(stat -c '%h' "$file1")
7900
7901         [ $hardlinks -eq $total_count ] ||
7902                 error "num hard links $hardlinks != $total_count"
7903         echo "done"
7904
7905         return 0
7906 }
7907
7908 test_56xb() {
7909         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
7910                 skip "Need MDS version at least 2.10.55"
7911
7912         local dir="$DIR/$tdir"
7913
7914         test_mkdir "$dir" || error "cannot create dir $dir"
7915
7916         echo "testing lfs migrate mode when all links fit within xattrs"
7917         check_migrate_links "$dir" 2 99
7918
7919         echo "testing rsync mode when all links fit within xattrs"
7920         check_migrate_links --rsync "$dir" 2 99
7921
7922         echo "testing lfs migrate mode when all links do not fit within xattrs"
7923         check_migrate_links "$dir" 101 100
7924
7925         echo "testing rsync mode when all links do not fit within xattrs"
7926         check_migrate_links --rsync "$dir" 101 100
7927
7928         chown -R $RUNAS_ID $dir
7929         echo "testing non-root lfs migrate mode when not all links are in xattr"
7930         check_migrate_links "$dir" 101 100 "$RUNAS"
7931
7932         # clean up
7933         rm -rf $dir
7934 }
7935 run_test 56xb "lfs migration hard link support"
7936
7937 test_56xc() {
7938         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7939
7940         local dir="$DIR/$tdir"
7941
7942         test_mkdir "$dir" || error "cannot create dir $dir"
7943
7944         # Test 1: ensure file < 1 GB is always migrated with 1 stripe
7945         echo -n "Setting initial stripe for 20MB test file..."
7946         $LFS setstripe -c 2 -i 0 "$dir/20mb" ||
7947                 error "cannot setstripe 20MB file"
7948         echo "done"
7949         echo -n "Sizing 20MB test file..."
7950         $TRUNCATE "$dir/20mb" 20971520 || error "cannot create 20MB test file"
7951         echo "done"
7952         echo -n "Verifying small file autostripe count is 1..."
7953         $LFS_MIGRATE -y -A -C 1 "$dir/20mb" ||
7954                 error "cannot migrate 20MB file"
7955         local stripe_count=$($LFS getstripe -c "$dir/20mb") ||
7956                 error "cannot get stripe for $dir/20mb"
7957         [ $stripe_count -eq 1 ] ||
7958                 error "unexpected stripe count $stripe_count for 20MB file"
7959         rm -f "$dir/20mb"
7960         echo "done"
7961
7962         # Test 2: File is small enough to fit within the available space on
7963         # sqrt(size_in_gb) + 1 OSTs but is larger than 1GB.  The file must
7964         # have at least an additional 1KB for each desired stripe for test 3
7965         echo -n "Setting stripe for 1GB test file..."
7966         $LFS setstripe -c 1 -i 0 "$dir/1gb" || error "cannot setstripe 1GB file"
7967         echo "done"
7968         echo -n "Sizing 1GB test file..."
7969         # File size is 1GB + 3KB
7970         $TRUNCATE "$dir/1gb" 1073744896 || error "cannot create 1GB test file"
7971         echo "done"
7972
7973         # need at least 512MB per OST for 1GB file to fit in 2 stripes
7974         local avail=$($LCTL get_param -n llite.$FSNAME*.kbytesavail)
7975         if (( avail > 524288 * OSTCOUNT )); then
7976                 echo -n "Migrating 1GB file..."
7977                 $LFS_MIGRATE -y -A -C 1 "$dir/1gb" ||
7978                         error "cannot migrate 1GB file"
7979                 echo "done"
7980                 echo -n "Verifying autostripe count is sqrt(n) + 1..."
7981                 stripe_count=$($LFS getstripe -c "$dir/1gb") ||
7982                         error "cannot getstripe for 1GB file"
7983                 [ $stripe_count -eq 2 ] ||
7984                         error "unexpected stripe count $stripe_count != 2"
7985                 echo "done"
7986         fi
7987
7988         # Test 3: File is too large to fit within the available space on
7989         # sqrt(n) + 1 OSTs.  Simulate limited available space with -X
7990         if [ $OSTCOUNT -ge 3 ]; then
7991                 # The required available space is calculated as
7992                 # file size (1GB + 3KB) / OST count (3).
7993                 local kb_per_ost=349526
7994
7995                 echo -n "Migrating 1GB file with limit..."
7996                 $LFS_MIGRATE -y -A -C 1 -X $kb_per_ost "$dir/1gb" ||
7997                         error "cannot migrate 1GB file with limit"
7998                 echo "done"
7999
8000                 stripe_count=$($LFS getstripe -c "$dir/1gb")
8001                 echo -n "Verifying 1GB autostripe count with limited space..."
8002                 [ "$stripe_count" -a $stripe_count -ge 3 ] ||
8003                         error "unexpected stripe count $stripe_count (min 3)"
8004                 echo "done"
8005         fi
8006
8007         # clean up
8008         rm -rf $dir
8009 }
8010 run_test 56xc "lfs migration autostripe"
8011
8012 test_56xd() {
8013         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8014
8015         local dir=$DIR/$tdir
8016         local f_mgrt=$dir/$tfile.mgrt
8017         local f_yaml=$dir/$tfile.yaml
8018         local f_copy=$dir/$tfile.copy
8019         local layout_yaml="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
8020         local layout_copy="-c 2 -S 2M -i 1"
8021         local yamlfile=$dir/yamlfile
8022         local layout_before;
8023         local layout_after;
8024
8025         test_mkdir "$dir" || error "cannot create dir $dir"
8026         stack_trap "rm -rf $dir"
8027         $LFS setstripe $layout_yaml $f_yaml ||
8028                 error "cannot setstripe $f_yaml with layout $layout_yaml"
8029         $LFS getstripe --yaml $f_yaml > $yamlfile
8030         $LFS setstripe $layout_copy $f_copy ||
8031                 error "cannot setstripe $f_copy with layout $layout_copy"
8032         touch $f_mgrt
8033         dd if=/dev/zero of=$f_mgrt bs=1M count=4
8034
8035         # 1. test option --yaml
8036         $LFS_MIGRATE -y --yaml $yamlfile $f_mgrt ||
8037                 error "cannot migrate $f_mgrt with --yaml $yamlfile"
8038         layout_before=$(get_layout_param $f_yaml)
8039         layout_after=$(get_layout_param $f_mgrt)
8040         [ "$layout_after" == "$layout_before" ] ||
8041                 error "lfs_migrate --yaml: $layout_after != $layout_before"
8042
8043         # 2. test option --copy
8044         $LFS_MIGRATE -y --copy $f_copy $f_mgrt ||
8045                 error "cannot migrate $f_mgrt with --copy $f_copy"
8046         layout_before=$(SKIP_INDEX=yes get_layout_param $f_copy)
8047         layout_after=$(SKIP_INDEX=yes get_layout_param $f_mgrt)
8048         [ "$layout_after" == "$layout_before" ] ||
8049                 error "lfs_migrate --copy: $layout_after != $layout_before"
8050 }
8051 run_test 56xd "check lfs_migrate --yaml and --copy support"
8052
8053 test_56xe() {
8054         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8055
8056         local dir=$DIR/$tdir
8057         local f_comp=$dir/$tfile
8058         local layout="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
8059         local layout_before=""
8060         local layout_after=""
8061
8062         test_mkdir "$dir" || error "cannot create dir $dir"
8063         stack_trap "rm -rf $dir"
8064         $LFS setstripe $layout $f_comp ||
8065                 error "cannot setstripe $f_comp with layout $layout"
8066         layout_before=$(SKIP_INDEX=yes get_layout_param $f_comp)
8067         dd if=/dev/zero of=$f_comp bs=1M count=4
8068
8069         # 1. migrate a comp layout file by lfs_migrate
8070         $LFS_MIGRATE -y $f_comp || error "cannot migrate $f_comp by lfs_migrate"
8071         layout_after=$(SKIP_INDEX=yes get_layout_param $f_comp)
8072         [ "$layout_before" == "$layout_after" ] ||
8073                 error "lfs_migrate: $layout_before != $layout_after"
8074
8075         # 2. migrate a comp layout file by lfs migrate
8076         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
8077         layout_after=$(SKIP_INDEX=yes get_layout_param $f_comp)
8078         [ "$layout_before" == "$layout_after" ] ||
8079                 error "lfs migrate: $layout_before != $layout_after"
8080 }
8081 run_test 56xe "migrate a composite layout file"
8082
8083 test_56xf() {
8084         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
8085
8086         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
8087                 skip "Need server version at least 2.13.53"
8088
8089         local dir=$DIR/$tdir
8090         local f_comp=$dir/$tfile
8091         local layout="-E 1M -c1 -E -1 -c2"
8092         local fid_before=""
8093         local fid_after=""
8094
8095         test_mkdir "$dir" || error "cannot create dir $dir"
8096         stack_trap "rm -rf $dir"
8097         $LFS setstripe $layout $f_comp ||
8098                 error "cannot setstripe $f_comp with layout $layout"
8099         fid_before=$($LFS getstripe --fid $f_comp)
8100         dd if=/dev/zero of=$f_comp bs=1M count=4
8101
8102         # 1. migrate a comp layout file to a comp layout
8103         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
8104         fid_after=$($LFS getstripe --fid $f_comp)
8105         [ "$fid_before" == "$fid_after" ] ||
8106                 error "comp-to-comp migrate: $fid_before != $fid_after"
8107
8108         # 2. migrate a comp layout file to a plain layout
8109         $LFS migrate -c2 $f_comp ||
8110                 error "cannot migrate $f_comp by lfs migrate"
8111         fid_after=$($LFS getstripe --fid $f_comp)
8112         [ "$fid_before" == "$fid_after" ] ||
8113                 error "comp-to-plain migrate: $fid_before != $fid_after"
8114
8115         # 3. migrate a plain layout file to a comp layout
8116         $LFS migrate $layout $f_comp ||
8117                 error "cannot migrate $f_comp by lfs migrate"
8118         fid_after=$($LFS getstripe --fid $f_comp)
8119         [ "$fid_before" == "$fid_after" ] ||
8120                 error "plain-to-comp migrate: $fid_before != $fid_after"
8121 }
8122 run_test 56xf "FID is not lost during migration of a composite layout file"
8123
8124 check_file_ost_range() {
8125         local file="$1"
8126         shift
8127         local range="$*"
8128         local -a file_range
8129         local idx
8130
8131         file_range=($($LFS getstripe -y "$file" |
8132                 awk '/l_ost_idx:/ { print $NF }'))
8133
8134         if [[ "${#file_range[@]}" = 0 ]]; then
8135                 echo "No osts found for $file"
8136                 return 1
8137         fi
8138
8139         for idx in "${file_range[@]}"; do
8140                 [[ " $range " =~ " $idx " ]] ||
8141                         return 1
8142         done
8143
8144         return 0
8145 }
8146
8147 sub_test_56xg() {
8148         local stripe_opt="$1"
8149         local pool="$2"
8150         shift 2
8151         local pool_ostidx="$(seq $* | tr '\n' ' ')"
8152
8153         $LFS migrate $stripe_opt -p $pool $DIR/$tfile ||
8154                 error "Fail to migrate $tfile on $pool"
8155         [[ "$($LFS getstripe -p $DIR/$tfile)" = "$pool" ]] ||
8156                 error "$tfile is not in pool $pool"
8157         check_file_ost_range "$DIR/$tfile" $pool_ostidx ||
8158                 error "$tfile osts mismatch with pool $pool (osts $pool_ostidx)"
8159 }
8160
8161 test_56xg() {
8162         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
8163         [[ $OSTCOUNT -ge 2 ]] || skip "needs >= 2 OSTs"
8164         [[ $MDS1_VERSION -gt $(version_code 2.14.52) ]] ||
8165                 skip "Need MDS version newer than 2.14.52"
8166
8167         local -a pool_names=("${TESTNAME}_0" "${TESTNAME}_1" "${TESTNAME}_2")
8168         local -a pool_ranges=("0 0" "1 1" "0 1")
8169
8170         # init pools
8171         for i in "${!pool_names[@]}"; do
8172                 pool_add ${pool_names[$i]} ||
8173                         error "pool_add failed (pool: ${pool_names[$i]})"
8174                 pool_add_targets ${pool_names[$i]} ${pool_ranges[$i]} ||
8175                         error "pool_add_targets failed (pool: ${pool_names[$i]})"
8176         done
8177
8178         # init the file to migrate
8179         $LFS setstripe -c1 -i1 $DIR/$tfile ||
8180                 error "Unable to create $tfile on OST1"
8181         stack_trap "rm -f $DIR/$tfile"
8182         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=4 status=none ||
8183                 error "Unable to write on $tfile"
8184
8185         echo "1. migrate $tfile on pool ${pool_names[0]}"
8186         sub_test_56xg "-c-1" "${pool_names[0]}" ${pool_ranges[0]}
8187
8188         echo "2. migrate $tfile on pool ${pool_names[2]}"
8189         sub_test_56xg "-c-1 -S2M" "${pool_names[2]}" ${pool_ranges[2]}
8190
8191         echo "3. migrate $tfile on pool ${pool_names[1]}"
8192         sub_test_56xg "-n -c-1" "${pool_names[1]}" ${pool_ranges[1]}
8193
8194         echo "4. migrate $tfile on pool ${pool_names[2]} with default stripe parameters"
8195         sub_test_56xg "" "${pool_names[2]}" ${pool_ranges[2]}
8196         echo
8197
8198         # Clean pools
8199         destroy_test_pools ||
8200                 error "pool_destroy failed"
8201 }
8202 run_test 56xg "lfs migrate pool support"
8203
8204 test_56xh() {
8205         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
8206
8207         local size_mb=25
8208         local file1=$DIR/$tfile
8209         local tmp1=$TMP/$tfile.tmp
8210
8211         $LFS setstripe -c 2 $file1
8212
8213         stack_trap "rm -f $file1 $tmp1"
8214         dd if=/dev/urandom of=$tmp1 bs=1M count=$size_mb ||
8215                         error "error creating $tmp1"
8216         ls -lsh $tmp1
8217         cp $tmp1 $file1
8218
8219         local start=$SECONDS
8220
8221         $LFS migrate --stats --stats-interval=1 -W 1M -c 1 $file1 ||
8222                 error "migrate failed rc = $?"
8223
8224         local elapsed=$((SECONDS - start))
8225
8226         # with 1MB/s, elapsed should equal size_mb
8227         (( elapsed >= size_mb * 95 / 100 )) ||
8228                 error "'lfs migrate -W' too fast ($elapsed < 0.95 * $size_mb)?"
8229
8230         (( elapsed <= size_mb * 120 / 100 )) ||
8231                 error_not_in_vm "'lfs migrate -W' slow ($elapsed > 1.2 * $size_mb)"
8232
8233         (( elapsed <= size_mb * 350 / 100 )) ||
8234                 error "'lfs migrate -W' too slow in VM ($elapsed > 3.5 * $size_mb)"
8235
8236         stripe=$($LFS getstripe -c $file1)
8237         (( $stripe == 1 )) || error "stripe of $file1 is $stripe != 1"
8238         cmp $file1 $tmp1 || error "content mismatch $file1 differs from $tmp1"
8239
8240         # Clean up file (since it is multiple MB)
8241         rm -f $file1 $tmp1
8242 }
8243 run_test 56xh "lfs migrate bandwidth limitation support"
8244
8245 test_56xi() {
8246         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
8247         verify_yaml_available || skip_env "YAML verification not installed"
8248
8249         local size_mb=5
8250         local file1=$DIR/$tfile.1
8251         local file2=$DIR/$tfile.2
8252         local file3=$DIR/$tfile.3
8253         local output_file=$DIR/$tfile.out
8254         local tmp1=$TMP/$tfile.tmp
8255
8256         $LFS setstripe -c 2 $file1
8257         $LFS setstripe -c 2 $file2
8258         $LFS setstripe -c 2 $file3
8259
8260         stack_trap "rm -f $file1 $file2 $file3 $tmp1 $output_file"
8261         dd if=/dev/urandom of=$tmp1 bs=1M count=$size_mb ||
8262                         error "error creating $tmp1"
8263         ls -lsh $tmp1
8264         cp $tmp1 $file1
8265         cp $tmp1 $file2
8266         cp $tmp1 $file3
8267
8268         $LFS migrate --stats --stats-interval=1 \
8269                 -c 1 $file1 $file2 $file3 1> $output_file ||
8270                 error "migrate failed rc = $?"
8271
8272         cat $output_file
8273         cat $output_file | verify_yaml || error "rename_stats is not valid YAML"
8274
8275         # Clean up file (since it is multiple MB)
8276         rm -f $file1 $file2 $file3 $tmp1 $output_file
8277 }
8278 run_test 56xi "lfs migrate stats support"
8279
8280 test_56xj() { # LU-16571 "lfs migrate -b" can cause thread starvation on OSS
8281         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
8282
8283         local file=$DIR/$tfile
8284         local linkdir=$DIR/$tdir
8285
8286         test_mkdir $linkdir || error "fail to create $linkdir"
8287         $LFS setstripe -i 0 -c 1 -S1M $file
8288         stack_trap "rm -rf $file $linkdir"
8289         dd if=/dev/urandom of=$file bs=1M count=10 ||
8290                 error "fail to create $file"
8291
8292         # Create file links
8293         local cpts
8294         local threads_max
8295         local nlinks
8296
8297         thread_max=$(do_facet ost1 "$LCTL get_param -n ost.OSS.ost.threads_max")
8298         cpts=$(do_facet ost1 "$LCTL get_param -n cpu_partition_table | wc -l")
8299         (( nlinks = thread_max * 3 / 2 / cpts))
8300
8301         echo "create $nlinks hard links of $file"
8302         createmany -l $file $linkdir/link $nlinks
8303
8304         # Parallel migrates (should not block)
8305         local i
8306         for ((i = 0; i < nlinks; i++)); do
8307                 echo $linkdir/link$i
8308         done | xargs -n1 -P $nlinks $LFS migrate -c2
8309
8310         local stripe_count
8311         stripe_count=$($LFS getstripe -c $file) ||
8312                 error "fail to get stripe count on $file"
8313
8314         ((stripe_count == 2)) ||
8315                 error "fail to migrate $file (stripe_count = $stripe_count)"
8316 }
8317 run_test 56xj "lfs migrate -b should not cause starvation of threads on OSS"
8318
8319 test_56y() {
8320         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
8321                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
8322
8323         local res=""
8324         local dir=$DIR/$tdir
8325         local f1=$dir/file1
8326         local f2=$dir/file2
8327
8328         test_mkdir -p $dir || error "creating dir $dir"
8329         touch $f1 || error "creating std file $f1"
8330         $MULTIOP $f2 H2c || error "creating released file $f2"
8331
8332         # a directory can be raid0, so ask only for files
8333         res=$($LFS find $dir -L raid0 -type f | wc -l)
8334         [[ $res == 2 ]] || error "search raid0: found $res files != 2"
8335
8336         res=$($LFS find $dir \! -L raid0 -type f | wc -l)
8337         [[ $res == 0 ]] || error "search !raid0: found $res files != 0"
8338
8339         # only files can be released, so no need to force file search
8340         res=$($LFS find $dir -L released)
8341         [[ $res == $f2 ]] || error "search released: found $res != $f2"
8342
8343         res=$($LFS find $dir -type f \! -L released)
8344         [[ $res == $f1 ]] || error "search !released: found $res != $f1"
8345 }
8346 run_test 56y "lfs find -L raid0|released"
8347
8348 test_56z() { # LU-4824
8349         # This checks to make sure 'lfs find' continues after errors
8350         # There are two classes of errors that should be caught:
8351         # - If multiple paths are provided, all should be searched even if one
8352         #   errors out
8353         # - If errors are encountered during the search, it should not terminate
8354         #   early
8355         local dir=$DIR/$tdir
8356         local i
8357
8358         test_mkdir $dir
8359         for i in d{0..9}; do
8360                 test_mkdir $dir/$i
8361                 touch $dir/$i/$tfile
8362         done
8363         $LFS find $DIR/non_existent_dir $dir &&
8364                 error "$LFS find did not return an error"
8365         # Make a directory unsearchable. This should NOT be the last entry in
8366         # directory order.  Arbitrarily pick the 6th entry
8367         chmod 700 $($LFS find $dir -type d | sed '6!d')
8368
8369         $RUNAS $LFS find $DIR/non_existent $dir
8370         local count=$($RUNAS $LFS find $DIR/non_existent $dir | wc -l)
8371
8372         # The user should be able to see 10 directories and 9 files
8373         (( count == 19 )) ||
8374                 error "$LFS find found $count != 19 entries after error"
8375 }
8376 run_test 56z "lfs find should continue after an error"
8377
8378 test_56aa() { # LU-5937
8379         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
8380
8381         local dir=$DIR/$tdir
8382
8383         mkdir $dir
8384         $LFS setdirstripe -c$MDSCOUNT $dir/striped_dir
8385
8386         createmany -o $dir/striped_dir/${tfile}- 1024
8387         local dirs=$($LFS find --size +8k $dir/)
8388
8389         [ -n "$dirs" ] || error "lfs find --size wrong under striped dir"
8390 }
8391 run_test 56aa "lfs find --size under striped dir"
8392
8393 test_56ab() { # LU-10705
8394         test_mkdir $DIR/$tdir
8395         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=8k count=1 seek=2k
8396         dd if=/dev/zero of=$DIR/$tdir/$tfile.2 bs=4k count=1 seek=4k
8397         dd if=/dev/zero of=$DIR/$tdir/$tfile.3 bs=1M count=2 seek=16
8398         # Flush writes to ensure valid blocks.  Need to be more thorough for
8399         # ZFS, since blocks are not allocated/returned to client immediately.
8400         sync_all_data
8401         wait_zfs_commit ost1 2
8402         cancel_lru_locks osc
8403         ls -ls $DIR/$tdir
8404
8405         local files=$($LFS find --size +16M $DIR/$tdir | wc -l)
8406
8407         [[ $files == 3 ]] || error ">16M size files $files isn't 3 as expected"
8408
8409         files=$($LFS find --blocks +1M $DIR/$tdir | wc -l)
8410         [[ $files == 1 ]] || error ">1M blocks files $files isn't 1 as expected"
8411
8412         rm -f $DIR/$tdir/$tfile.[123]
8413 }
8414 run_test 56ab "lfs find --blocks"
8415
8416 # LU-11188
8417 test_56aca() {
8418         local dir="$DIR/$tdir"
8419         local perms=(001 002 003 004 005 006 007
8420                      010 020 030 040 050 060 070
8421                      100 200 300 400 500 600 700
8422                      111 222 333 444 555 666 777)
8423         local perm_minus=(8 8 4 8 4 4 2
8424                           8 8 4 8 4 4 2
8425                           8 8 4 8 4 4 2
8426                           4 4 2 4 2 2 1)
8427         local perm_slash=(8  8 12  8 12 12 14
8428                           8  8 12  8 12 12 14
8429                           8  8 12  8 12 12 14
8430                          16 16 24 16 24 24 28)
8431
8432         test_mkdir "$dir"
8433         for perm in ${perms[*]}; do
8434                 touch "$dir/$tfile.$perm"
8435                 chmod $perm "$dir/$tfile.$perm"
8436         done
8437
8438         for ((i = 0; i < ${#perms[*]}; i++)); do
8439                 local num=$($LFS find $dir -perm ${perms[i]} | wc -l)
8440                 (( $num == 1 )) ||
8441                         error "lfs find -perm ${perms[i]}:"\
8442                               "$num != 1"
8443
8444                 num=$($LFS find $dir -perm -${perms[i]} -type f| wc -l)
8445                 (( $num == ${perm_minus[i]} )) ||
8446                         error "lfs find -perm -${perms[i]}:"\
8447                               "$num != ${perm_minus[i]}"
8448
8449                 num=$($LFS find $dir -perm /${perms[i]} -type f| wc -l)
8450                 (( $num == ${perm_slash[i]} )) ||
8451                         error "lfs find -perm /${perms[i]}:"\
8452                               "$num != ${perm_slash[i]}"
8453         done
8454 }
8455 run_test 56aca "check lfs find -perm with octal representation"
8456
8457 test_56acb() {
8458         local dir=$DIR/$tdir
8459         # p is the permission of write and execute for user, group and other
8460         # without the umask. It is used to test +wx.
8461         local p=$(printf "%o" "$((0333 & ~$(umask)))")
8462         local perms=(1000 000 2000 4000 $p 644 111 110 100 004)
8463         local symbolic=(+t  a+t u+t g+t o+t
8464                         g+s u+s o+s +s o+sr
8465                         o=r,ug+o,u+w
8466                         u+ g+ o+ a+ ugo+
8467                         u- g- o- a- ugo-
8468                         u= g= o= a= ugo=
8469                         o=r,ug+o,u+w u=r,a+u,u+w
8470                         g=r,ugo=g,u+w u+x,+X +X
8471                         u+x,u+X u+X u+x,g+X o+r,+X
8472                         u+x,go+X +wx +rwx)
8473
8474         test_mkdir $dir
8475         for perm in ${perms[*]}; do
8476                 touch "$dir/$tfile.$perm"
8477                 chmod $perm "$dir/$tfile.$perm"
8478         done
8479
8480         for (( i = 0; i < ${#symbolic[*]}; i++ )); do
8481                 local num=$($LFS find $dir -perm ${symbolic[i]} | wc -l)
8482
8483                 (( $num == 1 )) ||
8484                         error "lfs find $dir -perm ${symbolic[i]}: $num != 1"
8485         done
8486 }
8487 run_test 56acb "check lfs find -perm with symbolic representation"
8488
8489 test_56acc() {
8490         local dir=$DIR/$tdir
8491         local tests="17777 787 789 abcd
8492                 ug=uu ug=a ug=gu uo=ou urw
8493                 u+xg+x a=r,u+x,"
8494
8495         test_mkdir $dir
8496         for err in $tests; do
8497                 if $LFS find $dir -perm $err 2>/dev/null; then
8498                         error "lfs find -perm $err: parsing should have failed"
8499                 fi
8500         done
8501 }
8502 run_test 56acc "check parsing error for lfs find -perm"
8503
8504 test_56ba() {
8505         [ $MDS1_VERSION -lt $(version_code 2.10.50) ] &&
8506                 skip "Need MDS version at least 2.10.50"
8507
8508         # Create composite files with one component
8509         local dir=$DIR/$tdir
8510
8511         setup_56 $dir/1Mfiles 5 1 "-S 1M --component-end 1M"
8512         # Create composite files with three components
8513         setup_56 $dir/2Mfiles 5 2 "-E 2M -S 1M -E 4M -E 6M"
8514         # Create non-composite files
8515         createmany -o $dir/${tfile}- 10
8516
8517         local nfiles=$($LFS find --component-end 1M --type f $dir | wc -l)
8518
8519         [[ $nfiles == 10 ]] ||
8520                 error "lfs find -E 1M found $nfiles != 10 files"
8521
8522         nfiles=$($LFS find ! -E 1M --type f $dir | wc -l)
8523         [[ $nfiles == 25 ]] ||
8524                 error "lfs find ! -E 1M found $nfiles != 25 files"
8525
8526         # All files have a component that starts at 0
8527         nfiles=$($LFS find --component-start 0 --type f $dir | wc -l)
8528         [[ $nfiles == 35 ]] ||
8529                 error "lfs find --component-start 0 - $nfiles != 35 files"
8530
8531         nfiles=$($LFS find --component-start 2M --type f $dir | wc -l)
8532         [[ $nfiles == 15 ]] ||
8533                 error "lfs find --component-start 2M - $nfiles != 15 files"
8534
8535         # All files created here have a componenet that does not starts at 2M
8536         nfiles=$($LFS find ! --component-start 2M --type f $dir | wc -l)
8537         [[ $nfiles == 35 ]] ||
8538                 error "lfs find ! --component-start 2M - $nfiles != 35 files"
8539
8540         # Find files with a specified number of components
8541         local nfiles=$($LFS find --component-count 3 --type f $dir | wc -l)
8542         [[ $nfiles == 15 ]] ||
8543                 error "lfs find --component-count 3 - $nfiles != 15 files"
8544
8545         # Remember non-composite files have a component count of zero
8546         local nfiles=$($LFS find --component-count 0 --type f $dir | wc -l)
8547         [[ $nfiles == 10 ]] ||
8548                 error "lfs find --component-count 0 - $nfiles != 10 files"
8549
8550         nfiles=$($LFS find ! --component-count 3 --type f $dir | wc -l)
8551         [[ $nfiles == 20 ]] ||
8552                 error "lfs find ! --component-count 3 - $nfiles != 20 files"
8553
8554         # All files have a flag called "init"
8555         local nfiles=$($LFS find --component-flags init --type f $dir | wc -l)
8556         [[ $nfiles == 35 ]] ||
8557                 error "lfs find --component-flags init - $nfiles != 35 files"
8558
8559         # Multi-component files will have a component not initialized
8560         local nfiles=$($LFS find ! --component-flags init --type f $dir | wc -l)
8561         [[ $nfiles == 15 ]] ||
8562                 error "lfs find !--component-flags init - $nfiles != 15 files"
8563
8564         rm -rf $dir
8565
8566 }
8567 run_test 56ba "test lfs find --component-end, -start, -count, and -flags"
8568
8569 test_56ca() {
8570         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
8571                 skip "Need MDS version at least 2.10.57"
8572
8573         local td=$DIR/$tdir
8574         local tf=$td/$tfile
8575         local dir
8576         local nfiles
8577         local cmd
8578         local i
8579         local j
8580
8581         # create mirrored directories and mirrored files
8582         mkdir $td || error "mkdir $td failed"
8583         $LFS mirror create -N3 $td || error "create mirrored dir $td failed"
8584         createmany -o $tf- 10 || error "create $tf- failed"
8585
8586         for i in $(seq 2); do
8587                 dir=$td/dir$i
8588                 mkdir $dir || error "mkdir $dir failed"
8589                 $LFS mirror create -N$((3 + i)) $dir ||
8590                         error "create mirrored dir $dir failed"
8591                 createmany -o $dir/$tfile- 10 ||
8592                         error "create $dir/$tfile- failed"
8593         done
8594
8595         # change the states of some mirrored files
8596         echo foo > $tf-6
8597         for i in $(seq 2); do
8598                 dir=$td/dir$i
8599                 for j in $(seq 4 9); do
8600                         echo foo > $dir/$tfile-$j
8601                 done
8602         done
8603
8604         # find mirrored files with specific mirror count
8605         cmd="$LFS find --mirror-count 3 --type f $td"
8606         nfiles=$($cmd | wc -l)
8607         [[ $nfiles = 10 ]] || error "$cmd: $nfiles != 10 files"
8608
8609         cmd="$LFS find ! --mirror-count 3 --type f $td"
8610         nfiles=$($cmd | wc -l)
8611         [[ $nfiles = 20 ]] || error "$cmd: $nfiles != 20 files"
8612
8613         cmd="$LFS find --mirror-count +2 --type f $td"
8614         nfiles=$($cmd | wc -l)
8615         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8616
8617         cmd="$LFS find --mirror-count -6 --type f $td"
8618         nfiles=$($cmd | wc -l)
8619         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8620
8621         # find mirrored files with specific file state
8622         cmd="$LFS find --maxdepth 1 --mirror-state=^ro --type f $td"
8623         [[ $($cmd) = $tf-6 ]] || error "$cmd: didn't return $tf-6"
8624
8625         cmd="$LFS find --mirror-state=ro --type f $td"
8626         nfiles=$($cmd | wc -l)
8627         [[ $nfiles = 17 ]] || error "$cmd: $nfiles != 17 files"
8628
8629         cmd="$LFS find ! --mirror-state=ro --type f $td"
8630         nfiles=$($cmd | wc -l)
8631         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
8632
8633         cmd="$LFS find --mirror-state=wp --type f $td"
8634         nfiles=$($cmd | wc -l)
8635         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
8636
8637         cmd="$LFS find ! --mirror-state=sp --type f $td"
8638         nfiles=$($cmd | wc -l)
8639         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8640 }
8641 run_test 56ca "check lfs find --mirror-count|-N and --mirror-state"
8642
8643 test_56da() { # LU-14179
8644         local path=$DIR/$tdir
8645
8646         test_mkdir $path
8647         cd $path
8648
8649         local longdir=$(str_repeat 'a' 255)
8650
8651         for i in {1..15}; do
8652                 path=$path/$longdir
8653                 test_mkdir $longdir
8654                 cd $longdir
8655         done
8656
8657         local len=${#path}
8658         local lastdir=$(str_repeat 'a' $((4096 - 1 - $len - 1)))
8659
8660         test_mkdir $lastdir
8661         cd $lastdir
8662         # PATH_MAX-1
8663         (( ${#PWD} == 4095 )) || error "bad PWD length ${#PWD}, expect 4095"
8664
8665         # NAME_MAX
8666         touch $(str_repeat 'f' 255)
8667
8668         $LFS find $DIR/$tdir --type d |& grep "lfs find: error" &&
8669                 error "lfs find reported an error"
8670
8671         rm -rf $DIR/$tdir
8672 }
8673 run_test 56da "test lfs find with long paths"
8674
8675 test_56ea() { #LU-10378
8676         local path=$DIR/$tdir
8677         local pool=$TESTNAME
8678
8679         # Create ost pool
8680         pool_add $pool || error "pool_add $pool failed"
8681         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
8682                 error "adding targets to $pool failed"
8683
8684         # Set default pool on directory before creating file
8685         mkdir $path || error "mkdir $path failed"
8686         $LFS setstripe -p $pool $path ||
8687                 error "set OST pool on $pool failed"
8688         touch $path/$tfile || error "touch $path/$tfile failed"
8689
8690         # Compare basic file attributes from -printf and stat
8691         local attr_printf=$($LFS find $path/$tfile -printf "%A@ %T@ %C@ %U %G %n")
8692         local attr_stat=$(stat -c "%X %Y %Z %u %g %h" $path/$tfile)
8693
8694         [[ "${attr_printf}" == "${attr_stat}" ]] ||
8695                 error "Attrs from lfs find and stat don't match"
8696
8697         # Compare Lustre attributes from lfs find and lfs getstripe
8698         local lattr_printf=$($LFS find $path/$tfile -printf "%Lc %LS %Li %Lp")
8699         local str_cnt=$($LFS getstripe --stripe-count $path/$tfile)
8700         local str_size=$($LFS getstripe --stripe-size $path/$tfile)
8701         local str_idx=$($LFS getstripe --stripe-index $path/$tfile)
8702         local fpool=$($LFS getstripe --pool $path/$tfile)
8703         local lattr_getstr="${str_cnt} ${str_size} ${str_idx} ${fpool}"
8704
8705         [[ "${lattr_printf}" == "${lattr_getstr}" ]] ||
8706                 error "Attrs from lfs find and lfs getstripe don't match"
8707
8708         # Verify behavior for unknown escape/format sequences
8709         local esc_printf=$($LFS find $path/$tfile -printf '\\ %% \Q %Q')
8710
8711         [[ "${esc_printf}" == '\ % \Q %Q' ]] ||
8712                 error "Escape/format codes don't match"
8713 }
8714 run_test 56ea "test lfs find -printf option"
8715
8716 test_56eb() {
8717         local dir=$DIR/$tdir
8718         local subdir_1=$dir/subdir_1
8719
8720         test_mkdir -p $subdir_1
8721         ln -s subdir_1 $dir/link_1
8722
8723         $LFS getstripe $dir | grep "^$dir/link_1$" -A1 ||
8724                 error "symlink is not followed"
8725
8726         $LFS getstripe --no-follow $dir |
8727                 grep "^$dir/link_1 has no stripe info$" ||
8728                 error "symlink should not have stripe info"
8729
8730         touch $dir/testfile
8731         ln -s testfile $dir/file_link_2
8732
8733         $LFS getstripe $dir | grep "^$dir/file_link_2$" -A1 ||
8734                 error "symlink is not followed"
8735
8736         $LFS getstripe --no-follow $dir |
8737                 grep "^$dir/file_link_2 has no stripe info$" ||
8738                 error "symlink should not have stripe info"
8739 }
8740 run_test 56eb "check lfs getstripe on symlink"
8741
8742 test_56ec() {
8743         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8744         local dir=$DIR/$tdir
8745         local srcfile=$dir/srcfile
8746         local srcyaml=$dir/srcyaml
8747         local destfile=$dir/destfile
8748
8749         test_mkdir -p $dir
8750
8751         $LFS setstripe -i 1 $srcfile
8752         $LFS getstripe --hex-idx --yaml $srcfile > $srcyaml
8753         # if the setstripe yaml parsing fails for any reason, the command can
8754         # randomly assign the correct OST index, leading to an erroneous
8755         # success. but the chance of false success is low enough that a
8756         # regression should still be quickly caught.
8757         $LFS setstripe --yaml=$srcyaml $destfile
8758
8759         local srcindex=$($LFS getstripe -i $srcfile)
8760         local destindex=$($LFS getstripe -i $destfile)
8761
8762         if [[ ! $srcindex -eq $destindex ]]; then
8763                 error "setstripe did not set OST index correctly"
8764         fi
8765 }
8766 run_test 56ec "check lfs getstripe,setstripe --hex --yaml"
8767
8768 test_56eda() {
8769         local dir=$DIR/$tdir
8770         local subdir=$dir/subdir
8771         local file1=$dir/$tfile
8772         local file2=$dir/$tfile\2
8773         local link=$dir/$tfile-link
8774         local nfiles
8775
8776         test_mkdir -p $dir
8777         $LFS setdirstripe -c1 $subdir
8778         touch $file1
8779         touch $file2
8780         ln $file2 $link
8781
8782         nfiles=$($LFS find --links 1 $dir | wc -l)
8783         (( $nfiles == 1 )) ||
8784                 error "lfs find --links expected 1 file, got $nfiles"
8785
8786         nfiles=$($LFS find --type f --links 2 $dir | wc -l)
8787         (( $nfiles == 2 )) ||
8788                 error "lfs find --links expected 2 files, got $nfiles"
8789
8790         nfiles=$($LFS find --type d --links 2 $dir | wc -l)
8791         (( $nfiles == 1 )) ||
8792                 error "lfs find --links expected 1 directory, got $nfiles"
8793 }
8794 run_test 56eda "check lfs find --links"
8795
8796 test_56edb() {
8797         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
8798
8799         local dir=$DIR/$tdir
8800         local stripedir=$dir/stripedir
8801         local nfiles
8802
8803         test_mkdir -p $dir
8804
8805         $LFS setdirstripe -c2 $stripedir
8806
8807         $LFS getdirstripe $stripedir
8808
8809         nfiles=$($LFS find --type d --links 2 $stripedir | wc -l)
8810         (( $nfiles == 1 )) ||
8811                 error "lfs find --links expected 1 directory, got $nfiles"
8812 }
8813 run_test 56edb "check lfs find --links for directory striped on multiple MDTs"
8814
8815 test_57a() {
8816         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8817         # note test will not do anything if MDS is not local
8818         if [ "$mds1_FSTYPE" != ldiskfs ]; then
8819                 skip_env "ldiskfs only test"
8820         fi
8821         remote_mds_nodsh && skip "remote MDS with nodsh"
8822
8823         local MNTDEV="osd*.*MDT*.mntdev"
8824         DEV=$(do_facet $SINGLEMDS lctl get_param -n $MNTDEV)
8825         [ -z "$DEV" ] && error "can't access $MNTDEV"
8826         for DEV in $(do_facet $SINGLEMDS lctl get_param -n $MNTDEV); do
8827                 do_facet $SINGLEMDS $DUMPE2FS -h $DEV > $TMP/t57a.dump ||
8828                         error "can't access $DEV"
8829                 DEVISIZE=$(awk '/Inode size:/ { print $3 }' $TMP/t57a.dump)
8830                 [[ $DEVISIZE -gt 128 ]] || error "inode size $DEVISIZE"
8831                 rm $TMP/t57a.dump
8832         done
8833 }
8834 run_test 57a "verify MDS filesystem created with large inodes =="
8835
8836 test_57b() {
8837         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8838         if [ "$mds1_FSTYPE" != ldiskfs ]; then
8839                 skip_env "ldiskfs only test"
8840         fi
8841         remote_mds_nodsh && skip "remote MDS with nodsh"
8842
8843         local dir=$DIR/$tdir
8844         local filecount=100
8845         local file1=$dir/f1
8846         local fileN=$dir/f$filecount
8847
8848         rm -rf $dir || error "removing $dir"
8849         test_mkdir -c1 $dir
8850         local mdtidx=$($LFS getstripe -m $dir)
8851         local mdtname=MDT$(printf %04x $mdtidx)
8852         local facet=mds$((mdtidx + 1))
8853
8854         echo "mcreating $filecount files"
8855         createmany -m $dir/f 1 $filecount || error "creating files in $dir"
8856
8857         # verify that files do not have EAs yet
8858         $LFS getstripe $file1 2>&1 | grep -q "no stripe" ||
8859                 error "$file1 has an EA"
8860         $LFS getstripe $fileN 2>&1 | grep -q "no stripe" ||
8861                 error "$fileN has an EA"
8862
8863         sync
8864         sleep 1
8865         df $dir  #make sure we get new statfs data
8866         local mdsfree=$(do_facet $facet \
8867                         lctl get_param -n osd*.*$mdtname.kbytesfree)
8868         local mdcfree=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
8869         local file
8870
8871         echo "opening files to create objects/EAs"
8872         for file in $(seq -f $dir/f%g 1 $filecount); do
8873                 $OPENFILE -f O_RDWR $file > /dev/null 2>&1 ||
8874                         error "opening $file"
8875         done
8876
8877         # verify that files have EAs now
8878         $LFS getstripe $file1 | grep -q "obdidx" || error "$file1 missing EA"
8879         $LFS getstripe $fileN | grep -q "obdidx" || error "$fileN missing EA"
8880
8881         sleep 1  #make sure we get new statfs data
8882         df $dir
8883         local mdsfree2=$(do_facet $facet \
8884                          lctl get_param -n osd*.*$mdtname.kbytesfree)
8885         local mdcfree2=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
8886
8887         if [[ $mdcfree2 -lt $((mdcfree - 16)) ]]; then
8888                 if [ "$mdsfree" != "$mdsfree2" ]; then
8889                         error "MDC before $mdcfree != after $mdcfree2"
8890                 else
8891                         echo "MDC before $mdcfree != after $mdcfree2"
8892                         echo "unable to confirm if MDS has large inodes"
8893                 fi
8894         fi
8895         rm -rf $dir
8896 }
8897 run_test 57b "default LOV EAs are stored inside large inodes ==="
8898
8899 test_58() {
8900         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8901         [ -z "$(which wiretest 2>/dev/null)" ] &&
8902                         skip_env "could not find wiretest"
8903
8904         wiretest
8905 }
8906 run_test 58 "verify cross-platform wire constants =============="
8907
8908 test_59() {
8909         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8910
8911         echo "touch 130 files"
8912         createmany -o $DIR/f59- 130
8913         echo "rm 130 files"
8914         unlinkmany $DIR/f59- 130
8915         sync
8916         # wait for commitment of removal
8917         wait_delete_completed
8918 }
8919 run_test 59 "verify cancellation of llog records async ========="
8920
8921 TEST60_HEAD="test_60 run $RANDOM"
8922 test_60a() {
8923         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8924         remote_mgs_nodsh && skip "remote MGS with nodsh"
8925         do_facet mgs "! which run-llog.sh &> /dev/null" &&
8926                 do_facet mgs "! ls run-llog.sh &> /dev/null" &&
8927                         skip_env "missing subtest run-llog.sh"
8928
8929         log "$TEST60_HEAD - from kernel mode"
8930         do_facet mgs "$LCTL dk > /dev/null"
8931         do_facet mgs "bash run-llog.sh" || error "run-llog.sh failed"
8932         do_facet mgs $LCTL dk > $TMP/$tfile
8933
8934         # LU-6388: test llog_reader
8935         local llog_reader=$(do_facet mgs "which llog_reader 2> /dev/null")
8936         llog_reader=${llog_reader:-$LUSTRE/utils/llog_reader}
8937         [ -z $(do_facet mgs ls -d $llog_reader 2> /dev/null) ] &&
8938                         skip_env "missing llog_reader"
8939         local fstype=$(facet_fstype mgs)
8940         [ $fstype != ldiskfs -a $fstype != zfs ] &&
8941                 skip_env "Only for ldiskfs or zfs type mgs"
8942
8943         local mntpt=$(facet_mntpt mgs)
8944         local mgsdev=$(mgsdevname 1)
8945         local fid_list
8946         local fid
8947         local rec_list
8948         local rec
8949         local rec_type
8950         local obj_file
8951         local path
8952         local seq
8953         local oid
8954         local pass=true
8955
8956         #get fid and record list
8957         fid_list=($(awk '/9_sub.*record/ { print $NF }' $TMP/$tfile |
8958                 tail -n 4))
8959         rec_list=($(awk '/9_sub.*record/ { print $((NF-3)) }' $TMP/$tfile |
8960                 tail -n 4))
8961         #remount mgs as ldiskfs or zfs type
8962         stop mgs || error "stop mgs failed"
8963         mount_fstype mgs || error "remount mgs failed"
8964         for ((i = 0; i < ${#fid_list[@]}; i++)); do
8965                 fid=${fid_list[i]}
8966                 rec=${rec_list[i]}
8967                 seq=$(echo $fid | awk -F ':' '{ print $1 }' | sed -e "s/^0x//g")
8968                 oid=$(echo $fid | awk -F ':' '{ print $2 }' | sed -e "s/^0x//g")
8969                 oid=$((16#$oid))
8970
8971                 case $fstype in
8972                         ldiskfs )
8973                                 obj_file=$mntpt/O/$seq/d$((oid%32))/$oid ;;
8974                         zfs )
8975                                 obj_file=$mntpt/oi.$(($((16#$seq))&127))/$fid ;;
8976                 esac
8977                 echo "obj_file is $obj_file"
8978                 do_facet mgs $llog_reader $obj_file
8979
8980                 rec_type=$(do_facet mgs $llog_reader $obj_file | grep "type=" |
8981                         awk '{ print $3 }' | sed -e "s/^type=//g")
8982                 if [ $rec_type != $rec ]; then
8983                         echo "FAILED test_60a wrong record type $rec_type," \
8984                               "should be $rec"
8985                         pass=false
8986                         break
8987                 fi
8988
8989                 #check obj path if record type is LLOG_LOGID_MAGIC
8990                 if [ "$rec" == "1064553b" ]; then
8991                         path=$(do_facet mgs $llog_reader $obj_file |
8992                                 grep "path=" | awk '{ print $NF }' |
8993                                 sed -e "s/^path=//g")
8994                         if [ $obj_file != $mntpt/$path ]; then
8995                                 echo "FAILED test_60a wrong obj path" \
8996                                       "$montpt/$path, should be $obj_file"
8997                                 pass=false
8998                                 break
8999                         fi
9000                 fi
9001         done
9002         rm -f $TMP/$tfile
9003         #restart mgs before "error", otherwise it will block the next test
9004         stop mgs || error "stop mgs failed"
9005         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
9006         $pass || error "test failed, see FAILED test_60a messages for specifics"
9007 }
9008 run_test 60a "llog_test run from kernel module and test llog_reader"
9009
9010 test_60b() { # bug 6411
9011         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9012
9013         dmesg > $DIR/$tfile
9014         LLOG_COUNT=$(do_facet mgs dmesg |
9015                      awk "/$TEST60_HEAD/ { marker = 1; from_marker = 0; }
9016                           /llog_[a-z]*.c:[0-9]/ {
9017                                 if (marker)
9018                                         from_marker++
9019                                 from_begin++
9020                           }
9021                           END {
9022                                 if (marker)
9023                                         print from_marker
9024                                 else
9025                                         print from_begin
9026                           }")
9027
9028         [[ $LLOG_COUNT -gt 120 ]] &&
9029                 error "CDEBUG_LIMIT not limiting messages ($LLOG_COUNT)" || true
9030 }
9031 run_test 60b "limit repeated messages from CERROR/CWARN"
9032
9033 test_60c() {
9034         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9035
9036         echo "create 5000 files"
9037         createmany -o $DIR/f60c- 5000
9038 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED  0x137
9039         lctl set_param fail_loc=0x80000137
9040         unlinkmany $DIR/f60c- 5000
9041         lctl set_param fail_loc=0
9042 }
9043 run_test 60c "unlink file when mds full"
9044
9045 test_60d() {
9046         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9047
9048         SAVEPRINTK=$(lctl get_param -n printk)
9049         # verify "lctl mark" is even working"
9050         MESSAGE="test message ID $RANDOM $$"
9051         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
9052         dmesg | grep -q "$MESSAGE" || error "didn't find debug marker in log"
9053
9054         lctl set_param printk=0 || error "set lnet.printk failed"
9055         lctl get_param -n printk | grep emerg || error "lnet.printk dropped emerg"
9056         MESSAGE="new test message ID $RANDOM $$"
9057         # Assume here that libcfs_debug_mark_buffer() uses D_WARNING
9058         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
9059         dmesg | grep -q "$MESSAGE" && error "D_WARNING wasn't masked" || true
9060
9061         lctl set_param -n printk="$SAVEPRINTK"
9062 }
9063 run_test 60d "test printk console message masking"
9064
9065 test_60e() {
9066         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9067         remote_mds_nodsh && skip "remote MDS with nodsh"
9068
9069         touch $DIR/$tfile
9070 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED2  0x15b
9071         do_facet mds1 lctl set_param fail_loc=0x15b
9072         rm $DIR/$tfile
9073 }
9074 run_test 60e "no space while new llog is being created"
9075
9076 test_60f() {
9077         local old_path=$($LCTL get_param -n debug_path)
9078
9079         stack_trap "$LCTL set_param debug_path=$old_path"
9080         stack_trap "rm -f $TMP/$tfile*"
9081         rm -f $TMP/$tfile* 2> /dev/null
9082         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
9083         $LCTL set_param debug_path=$TMP/$tfile fail_loc=0x8000050e
9084         test_mkdir $DIR/$tdir
9085         # retry in case the open is cached and not released
9086         for (( i = 0; i < 100 && $(ls $TMP/$tfile* | wc -l) == 0; i++ )); do
9087                 echo $i > $DIR/$tdir/$tfile.$i && cat $DIR/$tdir/$tfile.$i
9088                 sleep 0.1
9089         done
9090         ls $TMP/$tfile*
9091         (( $(ls $TMP/$tfile* | wc -l) > 0 )) || error "$TMP/$tfile not dumped"
9092 }
9093 run_test 60f "change debug_path works"
9094
9095 test_60g() {
9096         local pid
9097         local i
9098
9099         test_mkdir -c $MDSCOUNT $DIR/$tdir
9100
9101         (
9102                 local index=0
9103                 while true; do
9104                         $LFS setdirstripe -i $(($index % $MDSCOUNT)) \
9105                                 -c $MDSCOUNT $DIR/$tdir/subdir$index \
9106                                 2>/dev/null
9107                         mkdir $DIR/$tdir/subdir$index 2>/dev/null
9108                         rmdir $DIR/$tdir/subdir$index 2>/dev/null
9109                         index=$((index + 1))
9110                 done
9111         ) &
9112
9113         pid=$!
9114
9115         for i in {0..100}; do
9116                 # define OBD_FAIL_OSD_TXN_START    0x19a
9117                 local index=$((i % MDSCOUNT + 1))
9118
9119                 do_facet mds$index $LCTL set_param fail_loc=0x8000019a \
9120                         > /dev/null
9121                 sleep 0.01
9122         done
9123
9124         kill -9 $pid
9125
9126         for i in $(seq $MDSCOUNT); do
9127                 do_facet mds$i $LCTL set_param fail_loc=0 > /dev/null
9128         done
9129
9130         mkdir $DIR/$tdir/new || error "mkdir failed"
9131         rmdir $DIR/$tdir/new || error "rmdir failed"
9132
9133         do_facet mds1 $LCTL lfsck_start -M $(facet_svc mds1) -A -C \
9134                 -t namespace
9135         for i in $(seq $MDSCOUNT); do
9136                 wait_update_facet mds$i "$LCTL get_param -n \
9137                         mdd.$(facet_svc mds$i).lfsck_namespace |
9138                         awk '/^status/ { print \\\$2 }'" "completed"
9139         done
9140
9141         ls -R $DIR/$tdir
9142         rm -rf $DIR/$tdir || error "rmdir failed"
9143 }
9144 run_test 60g "transaction abort won't cause MDT hung"
9145
9146 test_60h() {
9147         [ $MDS1_VERSION -le $(version_code 2.12.52) ] &&
9148                 skip "Need MDS version at least 2.12.52"
9149         [ $MDSCOUNT -lt 2 ] && skip "Need at least 2 MDTs"
9150
9151         local f
9152
9153         #define OBD_FAIL_MDS_STRIPE_CREATE       0x188
9154         #define OBD_FAIL_MDS_STRIPE_FID          0x189
9155         for fail_loc in 0x80000188 0x80000189; do
9156                 do_facet mds1 "$LCTL set_param fail_loc=$fail_loc"
9157                 $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir-$fail_loc ||
9158                         error "mkdir $dir-$fail_loc failed"
9159                 for i in {0..10}; do
9160                         # create may fail on missing stripe
9161                         echo $i > $DIR/$tdir-$fail_loc/$i
9162                 done
9163                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
9164                         error "getdirstripe $tdir-$fail_loc failed"
9165                 $LFS migrate -m 1 $DIR/$tdir-$fail_loc ||
9166                         error "migrate $tdir-$fail_loc failed"
9167                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
9168                         error "getdirstripe $tdir-$fail_loc failed"
9169                 pushd $DIR/$tdir-$fail_loc
9170                 for f in *; do
9171                         echo $f | cmp $f - || error "$f data mismatch"
9172                 done
9173                 popd
9174                 rm -rf $DIR/$tdir-$fail_loc
9175         done
9176 }
9177 run_test 60h "striped directory with missing stripes can be accessed"
9178
9179 function t60i_load() {
9180         mkdir $DIR/$tdir
9181         #define OBD_FAIL_LLOG_PAUSE_AFTER_PAD               0x131c
9182         $LCTL set_param fail_loc=0x131c fail_val=1
9183         for ((i=0; i<5000; i++)); do
9184                 touch $DIR/$tdir/f$i
9185         done
9186 }
9187
9188 test_60i() {
9189         changelog_register || error "changelog_register failed"
9190         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
9191         changelog_users $SINGLEMDS | grep -q $cl_user ||
9192                 error "User $cl_user not found in changelog_users"
9193         changelog_chmask "ALL"
9194         t60i_load &
9195         local PID=$!
9196         for((i=0; i<100; i++)); do
9197                 changelog_dump >/dev/null ||
9198                         error "can't read changelog"
9199         done
9200         kill $PID
9201         wait $PID
9202         changelog_deregister || error "changelog_deregister failed"
9203         $LCTL set_param fail_loc=0
9204 }
9205 run_test 60i "llog: new record vs reader race"
9206
9207 test_60j() {
9208         (( $MDS1_VERSION >= $(version_code 2.15.50) )) ||
9209                 skip "need MDS version at least 2.15.50"
9210         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
9211         remote_mds_nodsh && skip "remote MDS with nodsh"
9212         [[ "$mds1_FSTYPE" == "ldiskfs" ]] || skip "ldiskfs only test"
9213
9214         changelog_users $SINGLEMDS | grep "^cl" &&
9215                 skip "active changelog user"
9216
9217         local llog_reader=$(do_facet $SINGLEMDS "which llog_reader 2> /dev/null")
9218
9219         [[ -z $(do_facet $SINGLEMDS ls -d $llog_reader 2> /dev/null) ]] &&
9220                 skip_env "missing llog_reader"
9221
9222         mkdir_on_mdt0 $DIR/$tdir
9223
9224         local f=$DIR/$tdir/$tfile
9225         local mdt_dev
9226         local tmpfile
9227         local plain
9228
9229         changelog_register || error "cannot register changelog user"
9230
9231         # set changelog_mask to ALL
9232         changelog_chmask "ALL"
9233         changelog_clear
9234
9235         createmany -o ${f}- 100 || error "createmany failed as $RUNAS_ID"
9236         unlinkmany ${f}- 100 || error "unlinkmany failed"
9237
9238         tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
9239         mdt_dev=$(facet_device $SINGLEMDS)
9240
9241         do_facet $SINGLEMDS sync
9242         plain=$(do_facet $SINGLEMDS "$DEBUGFS -c -R 'dump changelog_catalog \
9243                 $tmpfile' $mdt_dev; $llog_reader $tmpfile" |
9244                 awk '{match($0,"path=([^ ]+)",a)}END{print a[1]}')
9245
9246         stack_trap "do_facet $SINGLEMDS rm -f $tmpfile"
9247
9248         # if $tmpfile is not on EXT3 filesystem for some reason
9249         [[ ${plain:0:1} == 'O' ]] ||
9250                 skip "path $plain is not in 'O/1/d<n>/<n>' format"
9251
9252         size=$(do_facet $SINGLEMDS "$DEBUGFS -c -R 'dump $plain $tmpfile' \
9253                 $mdt_dev; stat -c %s $tmpfile")
9254         echo "Truncate llog from $size to $((size - size % 8192))"
9255         size=$((size - size % 8192))
9256         do_facet $SINGLEMDS $TRUNCATE $tmpfile $size
9257         errs=$(do_facet $SINGLEMDS "$llog_reader $tmpfile" |
9258                 grep -c 'in bitmap only')
9259         (( $errs > 0 )) || error "llog_reader didn't find lost records"
9260
9261         size=$((size - 9000))
9262         echo "Corrupt llog in the middle at $size"
9263         do_facet $SINGLEMDS dd if=/dev/urandom of=$tmpfile bs=1 seek=$size \
9264                 count=333 conv=notrunc
9265         errs=$(do_facet $SINGLEMDS "$llog_reader $tmpfile" |
9266                 grep -c 'next chunk')
9267         (( $errs > 0 )) || error "llog_reader didn't skip bad chunk"
9268 }
9269 run_test 60j "llog_reader reports corruptions"
9270
9271 test_61a() {
9272         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9273
9274         f="$DIR/f61"
9275         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1 || error "dd $f failed"
9276         cancel_lru_locks osc
9277         $MULTIOP $f OSMWUc || error "$MULTIOP $f failed"
9278         sync
9279 }
9280 run_test 61a "mmap() writes don't make sync hang ================"
9281
9282 test_61b() {
9283         mmap_mknod_test $DIR/$tfile || error "mmap_mknod_test failed"
9284 }
9285 run_test 61b "mmap() of unstriped file is successful"
9286
9287 # bug 2330 - insufficient obd_match error checking causes LBUG
9288 test_62() {
9289         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9290
9291         f="$DIR/f62"
9292         echo foo > $f
9293         cancel_lru_locks osc
9294         lctl set_param fail_loc=0x405
9295         cat $f && error "cat succeeded, expect -EIO"
9296         lctl set_param fail_loc=0
9297 }
9298 # This test is now irrelevant (as of bug 10718 inclusion), we no longer
9299 # match every page all of the time.
9300 #run_test 62 "verify obd_match failure doesn't LBUG (should -EIO)"
9301
9302 # bug 2319 - oig_wait() interrupted causes crash because of invalid waitq.
9303 # Though this test is irrelevant anymore, it helped to reveal some
9304 # other grant bugs (LU-4482), let's keep it.
9305 test_63a() {   # was test_63
9306         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9307
9308         MAX_DIRTY_MB=$(lctl get_param -n osc.*.max_dirty_mb | head -n 1)
9309
9310         for i in `seq 10` ; do
9311                 dd if=/dev/zero of=$DIR/f63 bs=8k &
9312                 sleep 5
9313                 kill $!
9314                 sleep 1
9315         done
9316
9317         rm -f $DIR/f63 || true
9318 }
9319 run_test 63a "Verify oig_wait interruption does not crash ======="
9320
9321 # bug 2248 - async write errors didn't return to application on sync
9322 # bug 3677 - async write errors left page locked
9323 test_63b() {
9324         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9325
9326         debugsave
9327         lctl set_param debug=-1
9328
9329         # ensure we have a grant to do async writes
9330         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1
9331         rm $DIR/$tfile
9332
9333         sync    # sync lest earlier test intercept the fail_loc
9334
9335         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
9336         lctl set_param fail_loc=0x80000406
9337         $MULTIOP $DIR/$tfile Owy && \
9338                 error "sync didn't return ENOMEM"
9339         sync; sleep 2; sync     # do a real sync this time to flush page
9340         lctl get_param -n llite.*.dump_page_cache | grep locked && \
9341                 error "locked page left in cache after async error" || true
9342         debugrestore
9343 }
9344 run_test 63b "async write errors should be returned to fsync ==="
9345
9346 test_64a () {
9347         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9348
9349         lfs df $DIR
9350         lctl get_param osc.*[oO][sS][cC][_-]*.cur* | grep "=[1-9]"
9351 }
9352 run_test 64a "verify filter grant calculations (in kernel) ====="
9353
9354 test_64b () {
9355         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9356
9357         bash oos.sh $MOUNT || error "oos.sh failed: $?"
9358 }
9359 run_test 64b "check out-of-space detection on client"
9360
9361 test_64c() {
9362         $LCTL set_param osc.*OST0000-osc-[^mM]*.cur_grant_bytes=0
9363 }
9364 run_test 64c "verify grant shrink"
9365
9366 import_param() {
9367         local tgt=$1
9368         local param=$2
9369
9370         $LCTL get_param osc.$tgt.import | awk "/$param/ { print \$2 }"
9371 }
9372
9373 # this does exactly what osc_request.c:osc_announce_cached() does in
9374 # order to calculate max amount of grants to ask from server
9375 want_grant() {
9376         local tgt=$1
9377
9378         local nrpages=$($LCTL get_param -n osc.$tgt.max_pages_per_rpc)
9379         local rpc_in_flight=$($LCTL get_param -n osc.$tgt.max_rpcs_in_flight)
9380
9381         ((rpc_in_flight++));
9382         nrpages=$((nrpages * rpc_in_flight))
9383
9384         local dirty_max_pages=$($LCTL get_param -n osc.$tgt.max_dirty_mb)
9385
9386         dirty_max_pages=$((dirty_max_pages * 1024 * 1024 / PAGE_SIZE))
9387
9388         [[ $dirty_max_pages -gt $nrpages ]] && nrpages=$dirty_max_pages
9389         local undirty=$((nrpages * PAGE_SIZE))
9390
9391         local max_extent_pages
9392         max_extent_pages=$(import_param $tgt grant_max_extent_size)
9393         max_extent_pages=$((max_extent_pages / PAGE_SIZE))
9394         local nrextents=$(((nrpages + max_extent_pages - 1) / max_extent_pages))
9395         local grant_extent_tax
9396         grant_extent_tax=$(import_param $tgt grant_extent_tax)
9397
9398         undirty=$((undirty + nrextents * grant_extent_tax))
9399
9400         echo $undirty
9401 }
9402
9403 # this is size of unit for grant allocation. It should be equal to
9404 # what tgt_grant.c:tgt_grant_chunk() calculates
9405 grant_chunk() {
9406         local tgt=$1
9407         local max_brw_size
9408         local grant_extent_tax
9409
9410         max_brw_size=$(import_param $tgt max_brw_size)
9411
9412         grant_extent_tax=$(import_param $tgt grant_extent_tax)
9413
9414         echo $(((max_brw_size + grant_extent_tax) * 2))
9415 }
9416
9417 test_64d() {
9418         [ $OST1_VERSION -ge $(version_code 2.10.56) ] ||
9419                 skip "OST < 2.10.55 doesn't limit grants enough"
9420
9421         local tgt=$($LCTL dl | awk '/OST0000-osc-[^mM]/ { print $4 }')
9422
9423         [[ "$($LCTL get_param osc.${tgt}.import)" =~ "grant_param" ]] ||
9424                 skip "no grant_param connect flag"
9425
9426         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
9427
9428         $LCTL set_param -n -n debug="$OLDDEBUG" || true
9429         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
9430
9431
9432         local max_cur_granted=$(($(want_grant $tgt) + $(grant_chunk $tgt)))
9433         stack_trap "rm -f $DIR/$tfile && wait_delete_completed" EXIT
9434
9435         $LFS setstripe $DIR/$tfile -i 0 -c 1
9436         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1000 &
9437         ddpid=$!
9438
9439         while kill -0 $ddpid; do
9440                 local cur_grant=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
9441
9442                 if [[ $cur_grant -gt $max_cur_granted ]]; then
9443                         kill $ddpid
9444                         error "cur_grant $cur_grant > $max_cur_granted"
9445                 fi
9446
9447                 sleep 1
9448         done
9449 }
9450 run_test 64d "check grant limit exceed"
9451
9452 check_grants() {
9453         local tgt=$1
9454         local expected=$2
9455         local msg=$3
9456         local cur_grants=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
9457
9458         ((cur_grants == expected)) ||
9459                 error "$msg: grants mismatch: $cur_grants, expected $expected"
9460 }
9461
9462 round_up_p2() {
9463         echo $((($1 + $2 - 1) & ~($2 - 1)))
9464 }
9465
9466 test_64e() {
9467         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9468         [ $OST1_VERSION -ge $(version_code 2.11.56) ] ||
9469                 skip "Need OSS version at least 2.11.56"
9470
9471         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
9472         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
9473         $LCTL set_param debug=+cache
9474
9475         # Remount client to reset grant
9476         remount_client $MOUNT || error "failed to remount client"
9477         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9478
9479         local init_grants=$(import_param $osc_tgt initial_grant)
9480
9481         check_grants $osc_tgt $init_grants "init grants"
9482
9483         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
9484         local max_brw_size=$(import_param $osc_tgt max_brw_size)
9485         local gbs=$(import_param $osc_tgt grant_block_size)
9486
9487         # write random number of bytes from max_brw_size / 4 to max_brw_size
9488         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
9489         # align for direct io
9490         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
9491         # round to grant consumption unit
9492         local wb_round_up=$(round_up_p2 $write_bytes gbs)
9493
9494         local grants=$((wb_round_up + extent_tax))
9495
9496         $LFS setstripe -c 1 -i 0 $DIR/$tfile  || error "lfs setstripe failed"
9497         stack_trap "rm -f $DIR/$tfile"
9498
9499         # define OBD_FAIL_TGT_NO_GRANT 0x725
9500         # make the server not grant more back
9501         do_facet ost1 $LCTL set_param fail_loc=0x725
9502         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct
9503
9504         do_facet ost1 $LCTL set_param fail_loc=0
9505
9506         check_grants $osc_tgt $((init_grants - grants)) "dio w/o grant alloc"
9507
9508         rm -f $DIR/$tfile || error "rm failed"
9509
9510         # Remount client to reset grant
9511         remount_client $MOUNT || error "failed to remount client"
9512         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9513
9514         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
9515
9516         # define OBD_FAIL_TGT_NO_GRANT 0x725
9517         # make the server not grant more back
9518         do_facet ost1 $LCTL set_param fail_loc=0x725
9519         $MULTIOP $DIR/$tfile "oO_WRONLY:w${write_bytes}yc"
9520         do_facet ost1 $LCTL set_param fail_loc=0
9521
9522         check_grants $osc_tgt $((init_grants - grants)) "buf io w/o grant alloc"
9523 }
9524 run_test 64e "check grant consumption (no grant allocation)"
9525
9526 test_64f() {
9527         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9528
9529         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
9530         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
9531         $LCTL set_param debug=+cache
9532
9533         # Remount client to reset grant
9534         remount_client $MOUNT || error "failed to remount client"
9535         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9536
9537         local init_grants=$(import_param $osc_tgt initial_grant)
9538         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
9539         local max_brw_size=$(import_param $osc_tgt max_brw_size)
9540         local gbs=$(import_param $osc_tgt grant_block_size)
9541         local chunk=$(grant_chunk $osc_tgt)
9542
9543         # write random number of bytes from max_brw_size / 4 to max_brw_size
9544         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
9545         # align for direct io
9546         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
9547         # round to grant consumption unit
9548         local wb_round_up=$(round_up_p2 $write_bytes gbs)
9549
9550         local grants=$((wb_round_up + extent_tax))
9551
9552         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
9553         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct ||
9554                 error "error writing to $DIR/$tfile"
9555
9556         check_grants $osc_tgt $((init_grants - grants + chunk)) \
9557                 "direct io with grant allocation"
9558
9559         rm -f $DIR/$tfile || error "rm failed"
9560
9561         # Remount client to reset grant
9562         remount_client $MOUNT || error "failed to remount client"
9563         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9564
9565         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
9566
9567         local cmd="oO_WRONLY:w${write_bytes}_yc"
9568
9569         $MULTIOP $DIR/$tfile $cmd &
9570         MULTIPID=$!
9571         sleep 1
9572
9573         check_grants $osc_tgt $((init_grants - grants)) \
9574                 "buffered io, not write rpc"
9575
9576         kill -USR1 $MULTIPID
9577         wait
9578
9579         check_grants $osc_tgt $((init_grants - grants + chunk)) \
9580                 "buffered io, one RPC"
9581 }
9582 run_test 64f "check grant consumption (with grant allocation)"
9583
9584 test_64g() {
9585         (( $MDS1_VERSION >= $(version_code 2.14.56) )) ||
9586                 skip "Need MDS version at least 2.14.56"
9587
9588         local mdts=$(comma_list $(mdts_nodes))
9589
9590         local old=$($LCTL get_param mdc.$FSNAME-*.grant_shrink_interval |
9591                         tr '\n' ' ')
9592         stack_trap "$LCTL set_param $old"
9593
9594         # generate dirty pages and increase dirty granted on MDT
9595         stack_trap "rm -f $DIR/$tfile-*"
9596         for (( i = 0; i < 10; i++)); do
9597                 $LFS setstripe -E 1M -L mdt $DIR/$tfile-$i ||
9598                         error "can't set stripe"
9599                 dd if=/dev/zero of=$DIR/$tfile-$i bs=128k count=1 ||
9600                         error "can't dd"
9601                 $LFS getstripe $DIR/$tfile-$i | grep -q pattern.*mdt || {
9602                         $LFS getstripe $DIR/$tfile-$i
9603                         error "not DoM file"
9604                 }
9605         done
9606
9607         # flush dirty pages
9608         sync
9609
9610         # wait until grant shrink reset grant dirty on MDTs
9611         for ((i = 0; i < 120; i++)); do
9612                 grant_dirty=$(do_nodes $mdts $LCTL get_param -n  mdt.*.tot_dirty |
9613                         awk '{sum=sum+$1} END {print sum}')
9614                 vm_dirty=$(awk '/Dirty:/{print $2}' /proc/meminfo)
9615                 echo "$grant_dirty grants, $vm_dirty pages"
9616                 (( grant_dirty + vm_dirty == 0 )) && break
9617                 (( i == 3 )) && sync &&
9618                         $LCTL set_param mdc.$FSNAME-*.grant_shrink_interval=5
9619                 sleep 1
9620         done
9621
9622         grant_dirty=$(do_nodes $mdts $LCTL get_param -n  mdt.*.tot_dirty |
9623                 awk '{sum=sum+$1} END {print sum}')
9624         (( grant_dirty == 0 )) || error "$grant_dirty on MDT"
9625 }
9626 run_test 64g "grant shrink on MDT"
9627
9628 test_64h() {
9629         (( $OST1_VERSION >= $(version_code 2.14.56) )) ||
9630                 skip "need OST at least 2.14.56 to avoid grant shrink on read"
9631
9632         local instance=$($LFS getname -i $DIR)
9633         local osc_tgt="$FSNAME-OST0000-osc-$instance"
9634         local num_exps=$(do_facet ost1 \
9635             $LCTL get_param -n obdfilter.*OST0000*.num_exports)
9636         local max_brw_size=$(import_param $osc_tgt max_brw_size)
9637         local avail=$($LCTL get_param -n osc.*OST0000-osc-$instance.kbytesavail)
9638         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
9639
9640         # 10MiB is for file to be written, max_brw_size * 16 *
9641         # num_exps is space reserve so that tgt_grant_shrink() decided
9642         # to not shrink
9643         local expect=$((max_brw_size * 16 * num_exps + 10 * 1048576))
9644         (( avail * 1024 < expect )) &&
9645                 skip "need $expect bytes on ost1, have $(( avail * 1024 )) only"
9646
9647         save_lustre_params client "osc.*OST0000*.grant_shrink" > $p
9648         save_lustre_params client "osc.*OST0000*.grant_shrink_interval" >> $p
9649         stack_trap "restore_lustre_params < $p; rm -f $save" EXIT
9650         $LCTL set_param osc.*OST0000*.grant_shrink=1
9651         $LCTL set_param osc.*OST0000*.grant_shrink_interval=10
9652
9653         $LFS setstripe -c 1 -i 0 $DIR/$tfile
9654         stack_trap "rm -f $DIR/$tfile"
9655         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 oflag=sync
9656
9657         # drop cache so that coming read would do rpc
9658         cancel_lru_locks osc
9659
9660         # shrink interval is set to 10, pause for 7 seconds so that
9661         # grant thread did not wake up yet but coming read entered
9662         # shrink mode for rpc (osc_should_shrink_grant())
9663         sleep 7
9664
9665         declare -a cur_grant_bytes
9666         declare -a tot_granted
9667         cur_grant_bytes[0]=$($LCTL get_param -n osc.*OST0000*.cur_grant_bytes)
9668         tot_granted[0]=$(do_facet ost1 \
9669             $LCTL get_param -n obdfilter.*OST0000*.tot_granted)
9670
9671         dd if=$DIR/$tfile bs=4K count=1 of=/dev/null
9672
9673         cur_grant_bytes[1]=$($LCTL get_param -n osc.*OST0000*.cur_grant_bytes)
9674         tot_granted[1]=$(do_facet ost1 \
9675             $LCTL get_param -n obdfilter.*OST0000*.tot_granted)
9676
9677         # grant change should be equal on both sides
9678         (( cur_grant_bytes[0] - cur_grant_bytes[1] ==
9679                 tot_granted[0] - tot_granted[1])) ||
9680                 error "grant change mismatch, "                                \
9681                         "server: ${tot_granted[0]} to ${tot_granted[1]}, "     \
9682                         "client: ${cur_grant_bytes[0]} to ${cur_grant_bytes[1]}"
9683 }
9684 run_test 64h "grant shrink on read"
9685
9686 test_64i() {
9687         (( $OST1_VERSION >= $(version_code 2.14.56) )) ||
9688                 skip "need OST at least 2.14.56 to avoid grant shrink on replay"
9689
9690         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9691         remote_ost_nodsh && skip "remote OSTs with nodsh"
9692
9693         $LFS setstripe -c 1 -i 0 $DIR/$tfile
9694         stack_trap "rm -f $DIR/$tfile"
9695
9696         dd if=/dev/zero of=$DIR/$tfile bs=1M count=64
9697
9698         # lustre-ffff9fc75e850800 /mnt/lustre -> ffff9fc75e850800
9699         local instance=$($LFS getname -i $DIR)
9700
9701         local osc_tgt="$FSNAME-OST0000-osc-$instance"
9702         local cgb=$($LCTL get_param -n osc.$osc_tgt.cur_grant_bytes)
9703
9704         # shrink grants and simulate rpc loss
9705         #define OBD_FAIL_PTLRPC_DROP_REQ_OPC     0x513
9706         do_facet ost1 "$LCTL set_param fail_loc=0x80000513 fail_val=17"
9707         $LCTL set_param osc.$osc_tgt.cur_grant_bytes=$((cgb/2))B
9708
9709         fail ost1
9710
9711         dd if=/dev/zero of=$DIR/$tfile oflag=append bs=1M count=8 conv=notrunc
9712
9713         local testid=$(echo $TESTNAME | tr '_' ' ')
9714
9715         do_facet ost1 dmesg | tac | sed "/$testid/,$ d" |
9716                 grep "GRANT, real grant" &&
9717                 error "client has more grants then it owns" || true
9718 }
9719 run_test 64i "shrink on reconnect"
9720
9721 # bug 1414 - set/get directories' stripe info
9722 test_65a() {
9723         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9724
9725         test_mkdir $DIR/$tdir
9726         touch $DIR/$tdir/f1
9727         $LVERIFY $DIR/$tdir $DIR/$tdir/f1 || error "lverify failed"
9728 }
9729 run_test 65a "directory with no stripe info"
9730
9731 test_65b() {
9732         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9733
9734         test_mkdir $DIR/$tdir
9735         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9736
9737         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
9738                                                 error "setstripe"
9739         touch $DIR/$tdir/f2
9740         $LVERIFY $DIR/$tdir $DIR/$tdir/f2 || error "lverify failed"
9741 }
9742 run_test 65b "directory setstripe -S stripe_size*2 -i 0 -c 1"
9743
9744 test_65c() {
9745         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9746         [ $OSTCOUNT -lt 2 ] && skip_env "need at least 2 OSTs"
9747
9748         test_mkdir $DIR/$tdir
9749         local stripesize=$($LFS getstripe -S $DIR/$tdir)
9750
9751         $LFS setstripe -S $((stripesize * 4)) -i 1 \
9752                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
9753         touch $DIR/$tdir/f3
9754         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
9755 }
9756 run_test 65c "directory setstripe -S stripe_size*4 -i 1 -c $((OSTCOUNT-1))"
9757
9758 test_65d() {
9759         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9760
9761         test_mkdir $DIR/$tdir
9762         local STRIPECOUNT=$($LFS getstripe -c $DIR/$tdir)
9763         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9764
9765         if [[ $STRIPECOUNT -le 0 ]]; then
9766                 sc=1
9767         elif [[ $STRIPECOUNT -gt $LOV_MAX_STRIPE_COUNT ]]; then
9768                 [[ $OSTCOUNT -gt $LOV_MAX_STRIPE_COUNT ]] &&
9769                         sc=$LOV_MAX_STRIPE_COUNT || sc=$(($OSTCOUNT - 1))
9770         else
9771                 sc=$(($STRIPECOUNT - 1))
9772         fi
9773         $LFS setstripe -S $STRIPESIZE -c $sc $DIR/$tdir || error "setstripe"
9774         touch $DIR/$tdir/f4 $DIR/$tdir/f5
9775         $LVERIFY $DIR/$tdir $DIR/$tdir/f4 $DIR/$tdir/f5 ||
9776                 error "lverify failed"
9777 }
9778 run_test 65d "directory setstripe -S stripe_size -c stripe_count"
9779
9780 test_65e() {
9781         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9782
9783         test_mkdir $DIR/$tdir
9784
9785         $LFS setstripe $DIR/$tdir || error "setstripe"
9786         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
9787                                         error "no stripe info failed"
9788         touch $DIR/$tdir/f6
9789         $LVERIFY $DIR/$tdir $DIR/$tdir/f6 || error "lverify failed"
9790 }
9791 run_test 65e "directory setstripe defaults"
9792
9793 test_65f() {
9794         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9795
9796         test_mkdir $DIR/${tdir}f
9797         $RUNAS $LFS setstripe $DIR/${tdir}f &&
9798                 error "setstripe succeeded" || true
9799 }
9800 run_test 65f "dir setstripe permission (should return error) ==="
9801
9802 test_65g() {
9803         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9804
9805         test_mkdir $DIR/$tdir
9806         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9807
9808         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
9809                 error "setstripe -S failed"
9810         $LFS setstripe -d $DIR/$tdir || error "setstripe -d failed"
9811         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
9812                 error "delete default stripe failed"
9813 }
9814 run_test 65g "directory setstripe -d"
9815
9816 test_65h() {
9817         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9818
9819         test_mkdir $DIR/$tdir
9820         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9821
9822         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
9823                 error "setstripe -S failed"
9824         test_mkdir $DIR/$tdir/dd1
9825         [ $($LFS getstripe -c $DIR/$tdir) = $($LFS getstripe -c $DIR/$tdir/dd1) ] ||
9826                 error "stripe info inherit failed"
9827 }
9828 run_test 65h "directory stripe info inherit ===================="
9829
9830 test_65i() {
9831         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9832
9833         save_layout_restore_at_exit $MOUNT
9834
9835         # bug6367: set non-default striping on root directory
9836         $LFS setstripe -S 65536 -c -1 $MOUNT || error "error setting stripe"
9837
9838         # bug12836: getstripe on -1 default directory striping
9839         $LFS getstripe $MOUNT || error "getstripe $MOUNT failed"
9840
9841         # bug12836: getstripe -v on -1 default directory striping
9842         $LFS getstripe -v $MOUNT || error "getstripe -v $MOUNT failed"
9843
9844         # bug12836: new find on -1 default directory striping
9845         $LFS find -mtime -1 $MOUNT > /dev/null || error "find $MOUNT failed"
9846 }
9847 run_test 65i "various tests to set root directory striping"
9848
9849 test_65j() { # bug6367
9850         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9851
9852         sync; sleep 1
9853
9854         # if we aren't already remounting for each test, do so for this test
9855         if [ "$I_MOUNTED" = "yes" ]; then
9856                 cleanup || error "failed to unmount"
9857                 setup
9858         fi
9859
9860         save_layout_restore_at_exit $MOUNT
9861
9862         $LFS setstripe -d $MOUNT || error "setstripe failed"
9863 }
9864 run_test 65j "set default striping on root directory (bug 6367)="
9865
9866 cleanup_65k() {
9867         rm -rf $DIR/$tdir
9868         wait_delete_completed
9869         do_facet $SINGLEMDS "lctl set_param -n \
9870                 osp.$ost*MDT0000.max_create_count=$max_count"
9871         do_facet $SINGLEMDS "lctl set_param -n \
9872                 osp.$ost*MDT0000.create_count=$count"
9873         do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
9874         echo $INACTIVE_OSC "is Activate"
9875
9876         wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
9877 }
9878
9879 test_65k() { # bug11679
9880         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9881         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9882         remote_mds_nodsh && skip "remote MDS with nodsh"
9883
9884         local disable_precreate=true
9885         [ $MDS1_VERSION -le $(version_code 2.8.54) ] &&
9886                 disable_precreate=false
9887
9888         echo "Check OST status: "
9889         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
9890                 awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
9891
9892         for OSC in $MDS_OSCS; do
9893                 echo $OSC "is active"
9894                 do_facet $SINGLEMDS lctl --device %$OSC activate
9895         done
9896
9897         for INACTIVE_OSC in $MDS_OSCS; do
9898                 local ost=$(osc_to_ost $INACTIVE_OSC)
9899                 local ostnum=$(do_facet $SINGLEMDS lctl get_param -n \
9900                                lov.*md*.target_obd |
9901                                awk -F: /$ost/'{ print $1 }' | head -n 1)
9902
9903                 mkdir -p $DIR/$tdir
9904                 $LFS setstripe -i $ostnum -c 1 $DIR/$tdir
9905                 createmany -o $DIR/$tdir/$tfile.$ostnum. 1000
9906
9907                 echo "Deactivate: " $INACTIVE_OSC
9908                 do_facet $SINGLEMDS lctl --device %$INACTIVE_OSC deactivate
9909
9910                 local count=$(do_facet $SINGLEMDS "lctl get_param -n \
9911                               osp.$ost*MDT0000.create_count")
9912                 local max_count=$(do_facet $SINGLEMDS "lctl get_param -n \
9913                                   osp.$ost*MDT0000.max_create_count")
9914                 $disable_precreate &&
9915                         do_facet $SINGLEMDS "lctl set_param -n \
9916                                 osp.$ost*MDT0000.max_create_count=0"
9917
9918                 for idx in $(seq 0 $((OSTCOUNT - 1))); do
9919                         [ -f $DIR/$tdir/$idx ] && continue
9920                         echo "$LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx"
9921                         $LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx ||
9922                                 { cleanup_65k;
9923                                   error "setstripe $idx should succeed"; }
9924                         rm -f $DIR/$tdir/$idx || error "rm $idx failed"
9925                 done
9926                 unlinkmany $DIR/$tdir/$tfile.$ostnum. 1000
9927                 rmdir $DIR/$tdir
9928
9929                 do_facet $SINGLEMDS "lctl set_param -n \
9930                         osp.$ost*MDT0000.max_create_count=$max_count"
9931                 do_facet $SINGLEMDS "lctl set_param -n \
9932                         osp.$ost*MDT0000.create_count=$count"
9933                 do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
9934                 echo $INACTIVE_OSC "is Activate"
9935
9936                 wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
9937         done
9938 }
9939 run_test 65k "validate manual striping works properly with deactivated OSCs"
9940
9941 test_65l() { # bug 12836
9942         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9943
9944         test_mkdir -p $DIR/$tdir/test_dir
9945         $LFS setstripe -c -1 $DIR/$tdir/test_dir
9946         $LFS find -mtime -1 $DIR/$tdir >/dev/null
9947 }
9948 run_test 65l "lfs find on -1 stripe dir ========================"
9949
9950 test_65m() {
9951         local layout=$(save_layout $MOUNT)
9952         $RUNAS $LFS setstripe -c 2 $MOUNT && {
9953                 restore_layout $MOUNT $layout
9954                 error "setstripe should fail by non-root users"
9955         }
9956         true
9957 }
9958 run_test 65m "normal user can't set filesystem default stripe"
9959
9960 test_65n() {
9961         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
9962         [[ $MDS1_VERSION -ge $(version_code 2.12.50) ]] ||
9963                 skip "Need MDS version at least 2.12.50"
9964         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
9965
9966         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
9967         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
9968         which setfattr > /dev/null 2>&1 || skip_env "no setfattr command"
9969
9970         save_layout_restore_at_exit $MOUNT
9971
9972         # new subdirectory under root directory should not inherit
9973         # the default layout from root
9974         local dir1=$MOUNT/$tdir-1
9975         mkdir $dir1 || error "mkdir $dir1 failed"
9976         ! getfattr -n trusted.lov $dir1 &> /dev/null ||
9977                 error "$dir1 shouldn't have LOV EA"
9978
9979         # delete the default layout on root directory
9980         $LFS setstripe -d $MOUNT || error "delete root default layout failed"
9981
9982         local dir2=$MOUNT/$tdir-2
9983         mkdir $dir2 || error "mkdir $dir2 failed"
9984         ! getfattr -n trusted.lov $dir2 &> /dev/null ||
9985                 error "$dir2 shouldn't have LOV EA"
9986
9987         # set a new striping pattern on root directory
9988         local def_stripe_size=$($LFS getstripe -S $MOUNT)
9989         local new_def_stripe_size=$((def_stripe_size * 2))
9990         $LFS setstripe -S $new_def_stripe_size $MOUNT ||
9991                 error "set stripe size on $MOUNT failed"
9992
9993         # new file created in $dir2 should inherit the new stripe size from
9994         # the filesystem default
9995         local file2=$dir2/$tfile-2
9996         touch $file2 || error "touch $file2 failed"
9997
9998         local file2_stripe_size=$($LFS getstripe -S $file2)
9999         [[ $file2_stripe_size -eq $new_def_stripe_size ]] ||
10000         {
10001                 echo "file2_stripe_size: '$file2_stripe_size'"
10002                 echo "new_def_stripe_size: '$new_def_stripe_size'"
10003                 error "$file2 didn't inherit stripe size $new_def_stripe_size"
10004         }
10005
10006         local dir3=$MOUNT/$tdir-3
10007         mkdir $dir3 || error "mkdir $dir3 failed"
10008         # $dir3 shouldn't have LOV EA, but "lfs getstripe -d $dir3" should show
10009         # the root layout, which is the actual default layout that will be used
10010         # when new files are created in $dir3.
10011         local dir3_layout=$(get_layout_param $dir3)
10012         local root_dir_layout=$(get_layout_param $MOUNT)
10013         [[ "$dir3_layout" = "$root_dir_layout" ]] ||
10014         {
10015                 echo "dir3_layout: '$dir3_layout'"
10016                 echo "root_dir_layout: '$root_dir_layout'"
10017                 error "$dir3 should show the default layout from $MOUNT"
10018         }
10019
10020         # set OST pool on root directory
10021         local pool=$TESTNAME
10022         pool_add $pool || error "add $pool failed"
10023         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
10024                 error "add targets to $pool failed"
10025
10026         $LFS setstripe -p $pool $MOUNT ||
10027                 error "set OST pool on $MOUNT failed"
10028
10029         # new file created in $dir3 should inherit the pool from
10030         # the filesystem default
10031         local file3=$dir3/$tfile-3
10032         touch $file3 || error "touch $file3 failed"
10033
10034         local file3_pool=$($LFS getstripe -p $file3)
10035         [[ "$file3_pool" = "$pool" ]] ||
10036                 error "$file3 ('$file3_pool') didn't inherit OST pool '$pool'"
10037
10038         local dir4=$MOUNT/$tdir-4
10039         mkdir $dir4 || error "mkdir $dir4 failed"
10040         local dir4_layout=$(get_layout_param $dir4)
10041         root_dir_layout=$(get_layout_param $MOUNT)
10042         echo "$LFS getstripe -d $dir4"
10043         $LFS getstripe -d $dir4
10044         echo "$LFS getstripe -d $MOUNT"
10045         $LFS getstripe -d $MOUNT
10046         [[ "$dir4_layout" = "$root_dir_layout" ]] ||
10047         {
10048                 echo "dir4_layout: '$dir4_layout'"
10049                 echo "root_dir_layout: '$root_dir_layout'"
10050                 error "$dir4 should show the default layout from $MOUNT"
10051         }
10052
10053         # new file created in $dir4 should inherit the pool from
10054         # the filesystem default
10055         local file4=$dir4/$tfile-4
10056         touch $file4 || error "touch $file4 failed"
10057
10058         local file4_pool=$($LFS getstripe -p $file4)
10059         [[ "$file4_pool" = "$pool" ]] ||
10060                 error "$file4 ('$file4_pool') didn't inherit OST pool $pool"
10061
10062         # new subdirectory under non-root directory should inherit
10063         # the default layout from its parent directory
10064         $LFS setstripe -S $new_def_stripe_size -p $pool $dir4 ||
10065                 error "set directory layout on $dir4 failed"
10066
10067         local dir5=$dir4/$tdir-5
10068         mkdir $dir5 || error "mkdir $dir5 failed"
10069
10070         dir4_layout=$(get_layout_param $dir4)
10071         local dir5_layout=$(get_layout_param $dir5)
10072         [[ "$dir4_layout" = "$dir5_layout" ]] ||
10073         {
10074                 echo "dir4_layout: '$dir4_layout'"
10075                 echo "dir5_layout: '$dir5_layout'"
10076                 error "$dir5 should inherit the default layout from $dir4"
10077         }
10078
10079         # though subdir under ROOT doesn't inherit default layout, but
10080         # its sub dir/file should be created with default layout.
10081         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
10082         [[ $MDS1_VERSION -ge $(version_code 2.12.59) ]] ||
10083                 skip "Need MDS version at least 2.12.59"
10084
10085         local default_lmv_count=$($LFS getdirstripe -D -c $MOUNT)
10086         local default_lmv_index=$($LFS getdirstripe -D -i $MOUNT)
10087         local default_lmv_hash=$($LFS getdirstripe -D -H $MOUNT)
10088
10089         if [ $default_lmv_hash == "none" ]; then
10090                 stack_trap "$LFS setdirstripe -D -d $MOUNT" EXIT
10091         else
10092                 stack_trap "$LFS setdirstripe -D -i $default_lmv_index \
10093                         -c $default_lmv_count -H $default_lmv_hash $MOUNT" EXIT
10094         fi
10095
10096         $LFS setdirstripe -D -c 2 $MOUNT ||
10097                 error "setdirstripe -D -c 2 failed"
10098         mkdir $MOUNT/$tdir-6 || error "mkdir $tdir-6 failed"
10099         local lmv_count=$($LFS getdirstripe -c $MOUNT/$tdir-6)
10100         [ $lmv_count -eq 2 ] || error "$tdir-6 stripe count $lmv_count"
10101
10102         # $dir4 layout includes pool
10103         $LFS setstripe -S $((new_def_stripe_size * 2)) $dir4
10104         [[ "$pool" = $($LFS getstripe -p -d $dir4) ]] ||
10105                 error "pool lost on setstripe"
10106         $LFS setstripe -E -1 -S $new_def_stripe_size $dir4
10107         [[ "$pool" = $($LFS getstripe -p -d $dir4) ]] ||
10108                 error "pool lost on compound layout setstripe"
10109 }
10110 run_test 65n "don't inherit default layout from root for new subdirectories"
10111
10112 test_65o() {
10113         (( $MDS1_VERSION >= $(version_code 2.14.57) )) ||
10114                 skip "need MDS version at least 2.14.57"
10115
10116         # set OST pool on root directory
10117         local pool=$TESTNAME
10118
10119         pool_add $pool || error "add $pool failed"
10120         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
10121                 error "add targets to $pool failed"
10122
10123         local dir1=$MOUNT/$tdir
10124
10125         mkdir $dir1 || error "mkdir $dir1 failed"
10126
10127         # set a new striping pattern on root directory
10128         local def_stripe_size=$($LFS getstripe -S $MOUNT)
10129
10130         $LFS setstripe -p $pool $dir1 ||
10131                 error "set directory layout on $dir1 failed"
10132
10133         # $dir1 layout includes pool
10134         $LFS setstripe -S $((def_stripe_size * 2)) $dir1
10135         [[ "$pool" = $($LFS getstripe -p -d $dir1) ]] ||
10136                 error "pool lost on setstripe"
10137         $LFS setstripe -E 1M -L mdt -E -1 -c 1 $dir1
10138         $LFS getstripe $dir1
10139         [[ "$pool" = $($LFS getstripe -p -d $dir1) ]] ||
10140                 error "pool lost on compound layout setstripe"
10141
10142         $LFS setdirstripe -i 0 -c 2 $dir1/dir2 ||
10143                 error "setdirstripe failed on sub-dir with inherited pool"
10144         $LFS getstripe $dir1/dir2
10145         [[ "$pool" = $($LFS getstripe -p -d $dir1/dir2) ]] ||
10146                 error "pool lost on compound layout setdirstripe"
10147
10148         $LFS setstripe -E -1 -c 1 $dir1
10149         $LFS getstripe -d $dir1
10150         [[ "$pool" = $($LFS getstripe -p -d $dir1) ]] ||
10151                 error "pool lost on setstripe"
10152 }
10153 run_test 65o "pool inheritance for mdt component"
10154
10155 test_65p () { # LU-16152
10156         local src_dir=$DIR/$tdir/src_dir
10157         local dst_dir=$DIR/$tdir/dst_dir
10158         local yaml_file=$DIR/$tdir/layout.yaml
10159         local border
10160
10161         (( $CLIENT_VERSION >= $(version_code 2.15.51) )) ||
10162                 skip "Need at least version 2.15.51"
10163
10164         test_mkdir -p $src_dir
10165         $LFS setstripe -E 2048M -c 4 -E EOF -c 8 $src_dir ||
10166                 error "failed to setstripe"
10167         $LFS getstripe --yaml -d $src_dir > $yaml_file ||
10168                 error "failed to getstripe"
10169
10170         test_mkdir -p $dst_dir
10171         $LFS setstripe --yaml $yaml_file $dst_dir ||
10172                 error "failed to setstripe with yaml file"
10173         border=$($LFS getstripe -d $dst_dir |
10174                 awk '/lcme_extent.e_end:/ { print $2; exit; }') ||
10175                 error "failed to getstripe"
10176
10177         # 2048M is 0x80000000, or 2147483648
10178         (( $border == 2147483648 )) ||
10179                 error "failed to handle huge number in yaml layout"
10180 }
10181 run_test 65p "setstripe with yaml file and huge number"
10182
10183 # bug 2543 - update blocks count on client
10184 test_66() {
10185         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10186
10187         local COUNT=${COUNT:-8}
10188         dd if=/dev/zero of=$DIR/f66 bs=1k count=$COUNT
10189         sync; sync_all_data; sync; sync_all_data
10190         cancel_lru_locks osc
10191         local BLOCKS=$(ls -s --block-size=1k $DIR/f66 | awk '{ print $1 }')
10192         (( BLOCKS >= COUNT )) || error "$DIR/f66 blocks $BLOCKS < $COUNT"
10193 }
10194 run_test 66 "update inode blocks count on client ==============="
10195
10196 meminfo() {
10197         awk '($1 == "'$1':") { print $2 }' /proc/meminfo
10198 }
10199
10200 swap_used() {
10201         swapon -s | awk '($1 == "'$1'") { print $4 }'
10202 }
10203
10204 # bug5265, obdfilter oa2dentry return -ENOENT
10205 # #define OBD_FAIL_SRV_ENOENT 0x217
10206 test_69() {
10207         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10208         remote_ost_nodsh && skip "remote OST with nodsh"
10209
10210         f="$DIR/$tfile"
10211         $LFS setstripe -c 1 -i 0 $f
10212         stack_trap "rm -f $f ${f}.2"
10213
10214         $DIRECTIO write ${f}.2 0 1 || error "directio write error"
10215
10216         do_facet ost1 lctl set_param fail_loc=0x217
10217         $TRUNCATE $f 1 # vmtruncate() will ignore truncate() error.
10218         $DIRECTIO write $f 0 2 && error "write succeeded, expect -ENOENT"
10219
10220         do_facet ost1 lctl set_param fail_loc=0
10221         $DIRECTIO write $f 0 2 || error "write error"
10222
10223         cancel_lru_locks osc
10224         $DIRECTIO read $f 0 1 || error "read error"
10225
10226         do_facet ost1 lctl set_param fail_loc=0x217
10227         $DIRECTIO read $f 1 1 && error "read succeeded, expect -ENOENT"
10228
10229         do_facet ost1 lctl set_param fail_loc=0
10230 }
10231 run_test 69 "verify oa2dentry return -ENOENT doesn't LBUG ======"
10232
10233 test_71() {
10234         test_mkdir $DIR/$tdir
10235         $LFS setdirstripe -D -c$MDSCOUNT $DIR/$tdir
10236         bash rundbench -C -D $DIR/$tdir 2 || error "dbench failed!"
10237 }
10238 run_test 71 "Running dbench on lustre (don't segment fault) ===="
10239
10240 test_72a() { # bug 5695 - Test that on 2.6 remove_suid works properly
10241         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10242         [ "$RUNAS_ID" = "$UID" ] &&
10243                 skip_env "RUNAS_ID = UID = $UID -- skipping"
10244         # Check that testing environment is properly set up. Skip if not
10245         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_GID $RUNAS ||
10246                 skip_env "User $RUNAS_ID does not exist - skipping"
10247
10248         touch $DIR/$tfile
10249         chmod 777 $DIR/$tfile
10250         chmod ug+s $DIR/$tfile
10251         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=512 count=1 ||
10252                 error "$RUNAS dd $DIR/$tfile failed"
10253         # See if we are still setuid/sgid
10254         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
10255                 error "S/gid is not dropped on write"
10256         # Now test that MDS is updated too
10257         cancel_lru_locks mdc
10258         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
10259                 error "S/gid is not dropped on MDS"
10260         rm -f $DIR/$tfile
10261 }
10262 run_test 72a "Test that remove suid works properly (bug5695) ===="
10263
10264 test_72b() { # bug 24226 -- keep mode setting when size is not changing
10265         local perm
10266
10267         [ "$RUNAS_ID" = "$UID" ] &&
10268                 skip_env "RUNAS_ID = UID = $UID -- skipping"
10269         [ "$RUNAS_ID" -eq 0 ] &&
10270                 skip_env "RUNAS_ID = 0 -- skipping"
10271         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10272         # Check that testing environment is properly set up. Skip if not
10273         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_ID $RUNAS ||
10274                 skip_env "User $RUNAS_ID does not exist - skipping"
10275
10276         touch $DIR/${tfile}-f{g,u}
10277         test_mkdir $DIR/${tfile}-dg
10278         test_mkdir $DIR/${tfile}-du
10279         chmod 770 $DIR/${tfile}-{f,d}{g,u}
10280         chmod g+s $DIR/${tfile}-{f,d}g
10281         chmod u+s $DIR/${tfile}-{f,d}u
10282         for perm in 777 2777 4777; do
10283                 $RUNAS chmod $perm $DIR/${tfile}-fg && error "S/gid file allowed improper chmod to $perm"
10284                 $RUNAS chmod $perm $DIR/${tfile}-fu && error "S/uid file allowed improper chmod to $perm"
10285                 $RUNAS chmod $perm $DIR/${tfile}-dg && error "S/gid dir allowed improper chmod to $perm"
10286                 $RUNAS chmod $perm $DIR/${tfile}-du && error "S/uid dir allowed improper chmod to $perm"
10287         done
10288         true
10289 }
10290 run_test 72b "Test that we keep mode setting if without file data changed (bug 24226)"
10291
10292 # bug 3462 - multiple simultaneous MDC requests
10293 test_73() {
10294         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10295
10296         test_mkdir $DIR/d73-1
10297         test_mkdir $DIR/d73-2
10298         multiop_bg_pause $DIR/d73-1/f73-1 O_c || return 1
10299         pid1=$!
10300
10301         lctl set_param fail_loc=0x80000129
10302         $MULTIOP $DIR/d73-1/f73-2 Oc &
10303         sleep 1
10304         lctl set_param fail_loc=0
10305
10306         $MULTIOP $DIR/d73-2/f73-3 Oc &
10307         pid3=$!
10308
10309         kill -USR1 $pid1
10310         wait $pid1 || return 1
10311
10312         sleep 25
10313
10314         $CHECKSTAT -t file $DIR/d73-1/f73-1 || return 4
10315         $CHECKSTAT -t file $DIR/d73-1/f73-2 || return 5
10316         $CHECKSTAT -t file $DIR/d73-2/f73-3 || return 6
10317
10318         rm -rf $DIR/d73-*
10319 }
10320 run_test 73 "multiple MDC requests (should not deadlock)"
10321
10322 test_74a() { # bug 6149, 6184
10323         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10324
10325         touch $DIR/f74a
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 any lock that won't be difficult - lookup works.
10332         ls $DIR/f74a
10333         $LCTL set_param fail_loc=0
10334         rm -f $DIR/f74a
10335         true
10336 }
10337 run_test 74a "ldlm_enqueue freed-export error path, ls (shouldn't LBUG)"
10338
10339 test_74b() { # bug 13310
10340         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10341
10342         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
10343         #
10344         # very important to OR with CFS_FAIL_ONCE (0x80000000) -- otherwise it
10345         # will spin in a tight reconnection loop
10346         $LCTL set_param fail_loc=0x8000030e
10347         # get a "difficult" lock
10348         touch $DIR/f74b
10349         $LCTL set_param fail_loc=0
10350         rm -f $DIR/f74b
10351         true
10352 }
10353 run_test 74b "ldlm_enqueue freed-export error path, touch (shouldn't LBUG)"
10354
10355 test_74c() {
10356         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10357
10358         #define OBD_FAIL_LDLM_NEW_LOCK
10359         $LCTL set_param fail_loc=0x319
10360         touch $DIR/$tfile && error "touch successful"
10361         $LCTL set_param fail_loc=0
10362         true
10363 }
10364 run_test 74c "ldlm_lock_create error path, (shouldn't LBUG)"
10365
10366 slab_lic=/sys/kernel/slab/lustre_inode_cache
10367 num_objects() {
10368         [ -f $slab_lic/shrink ] && echo 1 > $slab_lic/shrink
10369         [ -f $slab_lic/objects ] && awk '{ print $1 }' $slab_lic/objects ||
10370                 awk '/lustre_inode_cache/ { print $2; exit }' /proc/slabinfo
10371 }
10372
10373 test_76a() { # Now for b=20433, added originally in b=1443
10374         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10375
10376         cancel_lru_locks osc
10377         # there may be some slab objects cached per core
10378         local cpus=$(getconf _NPROCESSORS_ONLN 2>/dev/null)
10379         local before=$(num_objects)
10380         local count=$((512 * cpus))
10381         [ "$SLOW" = "no" ] && count=$((128 * cpus))
10382         local margin=$((count / 10))
10383         if [[ -f $slab_lic/aliases ]]; then
10384                 local aliases=$(cat $slab_lic/aliases)
10385                 (( aliases > 0 )) && margin=$((margin * aliases))
10386         fi
10387
10388         echo "before slab objects: $before"
10389         for i in $(seq $count); do
10390                 touch $DIR/$tfile
10391                 rm -f $DIR/$tfile
10392         done
10393         cancel_lru_locks osc
10394         local after=$(num_objects)
10395         echo "created: $count, after slab objects: $after"
10396         # shared slab counts are not very accurate, allow significant margin
10397         # the main goal is that the cache growth is not permanently > $count
10398         while (( after > before + margin )); do
10399                 sleep 1
10400                 after=$(num_objects)
10401                 wait=$((wait + 1))
10402                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
10403                 if (( wait > 60 )); then
10404                         error "inode slab grew from $before+$margin to $after"
10405                 fi
10406         done
10407 }
10408 run_test 76a "confirm clients recycle inodes properly ===="
10409
10410 test_76b() {
10411         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10412         [ $CLIENT_VERSION -ge $(version_code 2.13.55) ] || skip "not supported"
10413
10414         local count=512
10415         local before=$(num_objects)
10416
10417         for i in $(seq $count); do
10418                 mkdir $DIR/$tdir
10419                 rmdir $DIR/$tdir
10420         done
10421
10422         local after=$(num_objects)
10423         local wait=0
10424
10425         while (( after > before )); do
10426                 sleep 1
10427                 after=$(num_objects)
10428                 wait=$((wait + 1))
10429                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
10430                 if (( wait > 60 )); then
10431                         error "inode slab grew from $before to $after"
10432                 fi
10433         done
10434
10435         echo "slab objects before: $before, after: $after"
10436 }
10437 run_test 76b "confirm clients recycle directory inodes properly ===="
10438
10439 export ORIG_CSUM=""
10440 set_checksums()
10441 {
10442         # Note: in sptlrpc modes which enable its own bulk checksum, the
10443         # original crc32_le bulk checksum will be automatically disabled,
10444         # and the OBD_FAIL_OSC_CHECKSUM_SEND/OBD_FAIL_OSC_CHECKSUM_RECEIVE
10445         # will be checked by sptlrpc code against sptlrpc bulk checksum.
10446         # In this case set_checksums() will not be no-op, because sptlrpc
10447         # bulk checksum will be enabled all through the test.
10448
10449         [ "$ORIG_CSUM" ] || ORIG_CSUM=`lctl get_param -n osc.*.checksums | head -n1`
10450         lctl set_param -n osc.*.checksums $1
10451         return 0
10452 }
10453
10454 export ORIG_CSUM_TYPE="`lctl get_param -n osc.*osc-[^mM]*.checksum_type |
10455                         sed 's/.*\[\(.*\)\].*/\1/g' | head -n1`"
10456 CKSUM_TYPES=${CKSUM_TYPES:-$(lctl get_param -n osc.*osc-[^mM]*.checksum_type |
10457                              tr -d [] | head -n1)}
10458 set_checksum_type()
10459 {
10460         lctl set_param -n osc.*osc-[^mM]*.checksum_type $1
10461         rc=$?
10462         log "set checksum type to $1, rc = $rc"
10463         return $rc
10464 }
10465
10466 get_osc_checksum_type()
10467 {
10468         # arugment 1: OST name, like OST0000
10469         ost=$1
10470         checksum_type=$(lctl get_param -n osc.*${ost}-osc-[^mM]*.checksum_type |
10471                         sed 's/.*\[\(.*\)\].*/\1/g')
10472         rc=$?
10473         [ $rc -ne 0 ] && error "failed to get checksum type of $ost, rc = $rc, output = $checksum_type"
10474         echo $checksum_type
10475 }
10476
10477 F77_TMP=$TMP/f77-temp
10478 F77SZ=8
10479 setup_f77() {
10480         dd if=/dev/urandom of=$F77_TMP bs=1M count=$F77SZ || \
10481                 error "error writing to $F77_TMP"
10482 }
10483
10484 test_77a() { # bug 10889
10485         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10486         $GSS && skip_env "could not run with gss"
10487
10488         [ ! -f $F77_TMP ] && setup_f77
10489         set_checksums 1
10490         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ || error "dd error"
10491         set_checksums 0
10492         rm -f $DIR/$tfile
10493 }
10494 run_test 77a "normal checksum read/write operation"
10495
10496 test_77b() { # bug 10889
10497         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10498         $GSS && skip_env "could not run with gss"
10499
10500         [ ! -f $F77_TMP ] && setup_f77
10501         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
10502         $LCTL set_param fail_loc=0x80000409
10503         set_checksums 1
10504
10505         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
10506                 error "dd error: $?"
10507         $LCTL set_param fail_loc=0
10508
10509         for algo in $CKSUM_TYPES; do
10510                 cancel_lru_locks osc
10511                 set_checksum_type $algo
10512                 #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
10513                 $LCTL set_param fail_loc=0x80000408
10514                 cmp $F77_TMP $DIR/$tfile || error "file compare failed"
10515                 $LCTL set_param fail_loc=0
10516         done
10517         set_checksums 0
10518         set_checksum_type $ORIG_CSUM_TYPE
10519         rm -f $DIR/$tfile
10520 }
10521 run_test 77b "checksum error on client write, read"
10522
10523 cleanup_77c() {
10524         trap 0
10525         set_checksums 0
10526         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=0
10527         $check_ost &&
10528                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=0
10529         [ -n "$osc_file_prefix" ] && rm -f ${osc_file_prefix}*
10530         $check_ost && [ -n "$ost_file_prefix" ] &&
10531                 do_facet ost1 rm -f ${ost_file_prefix}\*
10532 }
10533
10534 test_77c() {
10535         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10536         $GSS && skip_env "could not run with gss"
10537         remote_ost_nodsh && skip "remote OST with nodsh"
10538
10539         local bad1
10540         local osc_file_prefix
10541         local osc_file
10542         local check_ost=false
10543         local ost_file_prefix
10544         local ost_file
10545         local orig_cksum
10546         local dump_cksum
10547         local fid
10548
10549         # ensure corruption will occur on first OSS/OST
10550         $LFS setstripe -i 0 $DIR/$tfile
10551
10552         [ ! -f $F77_TMP ] && setup_f77
10553         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
10554                 error "dd write error: $?"
10555         fid=$($LFS path2fid $DIR/$tfile)
10556
10557         if [ $OST1_VERSION -ge $(version_code 2.9.57) ]
10558         then
10559                 check_ost=true
10560                 ost_file_prefix=$(do_facet ost1 $LCTL get_param -n debug_path)
10561                 ost_file_prefix=${ost_file_prefix}-checksum_dump-ost-\\${fid}
10562         else
10563                 echo "OSS do not support bulk pages dump upon error"
10564         fi
10565
10566         osc_file_prefix=$($LCTL get_param -n debug_path)
10567         osc_file_prefix=${osc_file_prefix}-checksum_dump-osc-\\${fid}
10568
10569         trap cleanup_77c EXIT
10570
10571         set_checksums 1
10572         # enable bulk pages dump upon error on Client
10573         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=1
10574         # enable bulk pages dump upon error on OSS
10575         $check_ost &&
10576                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=1
10577
10578         # flush Client cache to allow next read to reach OSS
10579         cancel_lru_locks osc
10580
10581         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE       0x408
10582         $LCTL set_param fail_loc=0x80000408
10583         dd if=$DIR/$tfile of=/dev/null bs=1M || error "dd read error: $?"
10584         $LCTL set_param fail_loc=0
10585
10586         rm -f $DIR/$tfile
10587
10588         # check cksum dump on Client
10589         osc_file=$(ls ${osc_file_prefix}*)
10590         [ -n "$osc_file" ] || error "no checksum dump file on Client"
10591         # OBD_FAIL_OSC_CHECKSUM_RECEIVE corrupts with "bad1" at start of file
10592         bad1=$(dd if=$osc_file bs=1 count=4 2>/dev/null) || error "dd error: $?"
10593         [ $bad1 == "bad1" ] || error "unexpected corrupt pattern"
10594         orig_cksum=$(dd if=$F77_TMP bs=1 skip=4 count=1048572 2>/dev/null |
10595                      cksum)
10596         dump_cksum=$(dd if=$osc_file bs=1 skip=4 2>/dev/null | cksum)
10597         [[ "$orig_cksum" == "$dump_cksum" ]] ||
10598                 error "dump content does not match on Client"
10599
10600         $check_ost || skip "No need to check cksum dump on OSS"
10601
10602         # check cksum dump on OSS
10603         ost_file=$(do_facet ost1 ls ${ost_file_prefix}\*)
10604         [ -n "$ost_file" ] || error "no checksum dump file on OSS"
10605         orig_cksum=$(dd if=$F77_TMP bs=1048576 count=1 2>/dev/null | cksum)
10606         dump_cksum=$(do_facet ost1 dd if=$ost_file 2>/dev/null \| cksum)
10607         [[ "$orig_cksum" == "$dump_cksum" ]] ||
10608                 error "dump content does not match on OSS"
10609
10610         cleanup_77c
10611 }
10612 run_test 77c "checksum error on client read with debug"
10613
10614 test_77d() { # bug 10889
10615         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10616         $GSS && skip_env "could not run with gss"
10617
10618         stack_trap "rm -f $DIR/$tfile"
10619         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
10620         $LCTL set_param fail_loc=0x80000409
10621         set_checksums 1
10622         $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
10623                 error "direct write: rc=$?"
10624         $LCTL set_param fail_loc=0
10625         set_checksums 0
10626
10627         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
10628         $LCTL set_param fail_loc=0x80000408
10629         set_checksums 1
10630         cancel_lru_locks osc
10631         $DIRECTIO read $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
10632                 error "direct read: rc=$?"
10633         $LCTL set_param fail_loc=0
10634         set_checksums 0
10635 }
10636 run_test 77d "checksum error on OST direct write, read"
10637
10638 test_77f() { # bug 10889
10639         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10640         $GSS && skip_env "could not run with gss"
10641
10642         set_checksums 1
10643         stack_trap "rm -f $DIR/$tfile"
10644         for algo in $CKSUM_TYPES; do
10645                 cancel_lru_locks osc
10646                 set_checksum_type $algo
10647                 #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
10648                 $LCTL set_param fail_loc=0x409
10649                 $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) &&
10650                         error "direct write succeeded"
10651                 $LCTL set_param fail_loc=0
10652         done
10653         set_checksum_type $ORIG_CSUM_TYPE
10654         set_checksums 0
10655 }
10656 run_test 77f "repeat checksum error on write (expect error)"
10657
10658 test_77g() { # bug 10889
10659         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10660         $GSS && skip_env "could not run with gss"
10661         remote_ost_nodsh && skip "remote OST with nodsh"
10662
10663         [ ! -f $F77_TMP ] && setup_f77
10664
10665         local file=$DIR/$tfile
10666         stack_trap "rm -f $file" EXIT
10667
10668         $LFS setstripe -c 1 -i 0 $file
10669         #define OBD_FAIL_OST_CHECKSUM_RECEIVE       0x21a
10670         do_facet ost1 lctl set_param fail_loc=0x8000021a
10671         set_checksums 1
10672         dd if=$F77_TMP of=$file bs=1M count=$F77SZ ||
10673                 error "write error: rc=$?"
10674         do_facet ost1 lctl set_param fail_loc=0
10675         set_checksums 0
10676
10677         cancel_lru_locks osc
10678         #define OBD_FAIL_OST_CHECKSUM_SEND          0x21b
10679         do_facet ost1 lctl set_param fail_loc=0x8000021b
10680         set_checksums 1
10681         cmp $F77_TMP $file || error "file compare failed"
10682         do_facet ost1 lctl set_param fail_loc=0
10683         set_checksums 0
10684 }
10685 run_test 77g "checksum error on OST write, read"
10686
10687 test_77k() { # LU-10906
10688         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10689         $GSS && skip_env "could not run with gss"
10690
10691         local cksum_param="osc.$FSNAME*.checksums"
10692         local get_checksum="$LCTL get_param -n $cksum_param | head -n1"
10693         local checksum
10694         local i
10695
10696         [ "$ORIG_CSUM" ] || ORIG_CSUM=$(eval $get_checksum)
10697         stack_trap "wait_update $HOSTNAME '$get_checksum' $ORIG_CSUM || true"
10698         stack_trap "do_facet mgs $LCTL set_param -P $cksum_param=$ORIG_CSUM"
10699
10700         for i in 0 1; do
10701                 do_facet mgs $LCTL set_param -P $cksum_param=$i ||
10702                         error "failed to set checksum=$i on MGS"
10703                 wait_update $HOSTNAME "$get_checksum" $i
10704                 #remount
10705                 echo "remount client, checksum should be $i"
10706                 remount_client $MOUNT || error "failed to remount client"
10707                 checksum=$(eval $get_checksum)
10708                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
10709         done
10710         # remove persistent param to avoid races with checksum mountopt below
10711         do_facet mgs $LCTL set_param -P -d $cksum_param ||
10712                 error "failed to delete checksum on MGS"
10713
10714         for opt in "checksum" "nochecksum"; do
10715                 #remount with mount option
10716                 echo "remount client with option $opt, checksum should be $i"
10717                 umount_client $MOUNT || error "failed to umount client"
10718                 mount_client $MOUNT "$MOUNT_OPTS,$opt" ||
10719                         error "failed to mount client with option '$opt'"
10720                 checksum=$(eval $get_checksum)
10721                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
10722                 i=$((i - 1))
10723         done
10724
10725         remount_client $MOUNT || error "failed to remount client"
10726 }
10727 run_test 77k "enable/disable checksum correctly"
10728
10729 test_77l() {
10730         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10731         $GSS && skip_env "could not run with gss"
10732
10733         set_checksums 1
10734         stack_trap "set_checksums $ORIG_CSUM" EXIT
10735         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
10736
10737         set_checksum_type invalid && error "unexpected success of invalid checksum type"
10738
10739         $LFS setstripe -c 1 -i 0 $DIR/$tfile
10740         for algo in $CKSUM_TYPES; do
10741                 set_checksum_type $algo || error "fail to set checksum type $algo"
10742                 osc_algo=$(get_osc_checksum_type OST0000)
10743                 [ "$osc_algo" != "$algo" ] && error "checksum type is $osc_algo after setting it to $algo"
10744
10745                 # no locks, no reqs to let the connection idle
10746                 cancel_lru_locks osc
10747                 lru_resize_disable osc
10748                 wait_osc_import_state client ost1 IDLE
10749
10750                 # ensure ost1 is connected
10751                 stat $DIR/$tfile >/dev/null || error "can't stat"
10752                 wait_osc_import_state client ost1 FULL
10753
10754                 osc_algo=$(get_osc_checksum_type OST0000)
10755                 [ "$osc_algo" != "$algo" ] && error "checksum type changed from $algo to $osc_algo after reconnection"
10756         done
10757         return 0
10758 }
10759 run_test 77l "preferred checksum type is remembered after reconnected"
10760
10761 [ "$ORIG_CSUM" ] && set_checksums $ORIG_CSUM || true
10762 rm -f $F77_TMP
10763 unset F77_TMP
10764
10765 test_77m() {
10766         (( $CLIENT_VERSION >= $(version_code 2.14.52) )) ||
10767                 skip "Need at least version 2.14.52"
10768         local param=checksum_speed
10769
10770         $LCTL get_param $param || error "reading $param failed"
10771
10772         csum_speeds=$($LCTL get_param -n $param)
10773
10774         [[ "$csum_speeds" =~ "adler32" && "$csum_speeds" =~ "crc32" ]] ||
10775                 error "known checksum types are missing"
10776 }
10777 run_test 77m "Verify checksum_speed is correctly read"
10778
10779 check_filefrag_77n() {
10780         local nr_ext=0
10781         local starts=()
10782         local ends=()
10783
10784         while read extidx a b start end rest; do
10785                 if [[ "${extidx}" =~ ^[0-9]+: ]]; then
10786                         nr_ext=$(( $nr_ext + 1 ))
10787                         starts+=( ${start%..} )
10788                         ends+=( ${end%:} )
10789                 fi
10790         done < <( filefrag -sv $1 )
10791
10792         [[ $nr_ext -eq 2 ]] && [[ "${starts[-1]}" == $(( ${ends[0]} + 1 )) ]] && return 0
10793         return 1
10794 }
10795
10796 test_77n() {
10797         [[ "$CKSUM_TYPES" =~ t10 ]] || skip "no T10 checksum support on osc"
10798
10799         touch $DIR/$tfile
10800         $TRUNCATE $DIR/$tfile 0
10801         dd if=/dev/urandom of=$DIR/$tfile bs=4k conv=notrunc count=1 seek=0
10802         dd if=/dev/urandom of=$DIR/$tfile bs=4k conv=notrunc count=1 seek=2
10803         check_filefrag_77n $DIR/$tfile ||
10804                 skip "$tfile blocks not contiguous around hole"
10805
10806         set_checksums 1
10807         stack_trap "set_checksums $ORIG_CSUM" EXIT
10808         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
10809         stack_trap "rm -f $DIR/$tfile"
10810
10811         for algo in $CKSUM_TYPES; do
10812                 if [[ "$algo" =~ ^t10 ]]; then
10813                         set_checksum_type $algo ||
10814                                 error "fail to set checksum type $algo"
10815                         dd if=$DIR/$tfile of=/dev/null bs=12k count=1 iflag=direct ||
10816                                 error "fail to read $tfile with $algo"
10817                 fi
10818         done
10819         rm -f $DIR/$tfile
10820         return 0
10821 }
10822 run_test 77n "Verify read from a hole inside contiguous blocks with T10PI"
10823
10824 test_77o() {
10825         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
10826                 skip "Need MDS version at least 2.14.55"
10827         (( $OST1_VERSION >= $(version_code 2.14.55) )) ||
10828                 skip "Need OST version at least 2.14.55"
10829         local ofd=obdfilter
10830         local mdt=mdt
10831
10832         # print OST checksum_type
10833         echo "$ofd.$FSNAME-*.checksum_type:"
10834         do_nodes $(comma_list $(osts_nodes)) \
10835                 $LCTL get_param -n $ofd.$FSNAME-*.checksum_type
10836
10837         # print MDT checksum_type
10838         echo "$mdt.$FSNAME-*.checksum_type:"
10839         do_nodes $(comma_list $(mdts_nodes)) \
10840                 $LCTL get_param -n $mdt.$FSNAME-*.checksum_type
10841
10842         local o_count=$(do_nodes $(comma_list $(osts_nodes)) \
10843                    $LCTL get_param -n $ofd.$FSNAME-*.checksum_type | wc -l)
10844
10845         (( $o_count == $OSTCOUNT )) ||
10846                 error "found $o_count checksums, not \$MDSCOUNT=$OSTCOUNT"
10847
10848         local m_count=$(do_nodes $(comma_list $(mdts_nodes)) \
10849                    $LCTL get_param -n $mdt.$FSNAME-*.checksum_type | wc -l)
10850
10851         (( $m_count == $MDSCOUNT )) ||
10852                 error "found $m_count checksums, not \$MDSCOUNT=$MDSCOUNT"
10853 }
10854 run_test 77o "Verify checksum_type for server (mdt and ofd(obdfilter))"
10855
10856 cleanup_test_78() {
10857         trap 0
10858         rm -f $DIR/$tfile
10859 }
10860
10861 test_78() { # bug 10901
10862         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10863         remote_ost || skip_env "local OST"
10864
10865         NSEQ=5
10866         F78SIZE=$(($(awk '/MemFree:/ { print $2 }' /proc/meminfo) / 1024))
10867         echo "MemFree: $F78SIZE, Max file size: $MAXFREE"
10868         MEMTOTAL=$(($(awk '/MemTotal:/ { print $2 }' /proc/meminfo) / 1024))
10869         echo "MemTotal: $MEMTOTAL"
10870
10871         # reserve 256MB of memory for the kernel and other running processes,
10872         # and then take 1/2 of the remaining memory for the read/write buffers.
10873         if [ $MEMTOTAL -gt 512 ] ;then
10874                 MEMTOTAL=$(((MEMTOTAL - 256 ) / 2))
10875         else
10876                 # for those poor memory-starved high-end clusters...
10877                 MEMTOTAL=$((MEMTOTAL / 2))
10878         fi
10879         echo "Mem to use for directio: $MEMTOTAL"
10880
10881         [[ $F78SIZE -gt $MEMTOTAL ]] && F78SIZE=$MEMTOTAL
10882         [[ $F78SIZE -gt 512 ]] && F78SIZE=512
10883         [[ $F78SIZE -gt $((MAXFREE / 1024)) ]] && F78SIZE=$((MAXFREE / 1024))
10884         SMALLESTOST=$($LFS df $DIR | grep OST | awk '{ print $4 }' | sort -n |
10885                 head -n1)
10886         echo "Smallest OST: $SMALLESTOST"
10887         [[ $SMALLESTOST -lt 10240 ]] &&
10888                 skip "too small OSTSIZE, useless to run large O_DIRECT test"
10889
10890         trap cleanup_test_78 EXIT
10891
10892         [[ $F78SIZE -gt $((SMALLESTOST * $OSTCOUNT / 1024 - 80)) ]] &&
10893                 F78SIZE=$((SMALLESTOST * $OSTCOUNT / 1024 - 80))
10894
10895         [ "$SLOW" = "no" ] && NSEQ=1 && [ $F78SIZE -gt 32 ] && F78SIZE=32
10896         echo "File size: $F78SIZE"
10897         $LFS setstripe -c $OSTCOUNT $DIR/$tfile || error "setstripe failed"
10898         for i in $(seq 1 $NSEQ); do
10899                 FSIZE=$(($F78SIZE / ($NSEQ - $i + 1)))
10900                 echo directIO rdwr round $i of $NSEQ
10901                 $DIRECTIO rdwr $DIR/$tfile 0 $FSIZE 1048576||error "rdwr failed"
10902         done
10903
10904         cleanup_test_78
10905 }
10906 run_test 78 "handle large O_DIRECT writes correctly ============"
10907
10908 test_79() { # bug 12743
10909         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10910
10911         wait_delete_completed
10912
10913         BKTOTAL=$(calc_osc_kbytes kbytestotal)
10914         BKFREE=$(calc_osc_kbytes kbytesfree)
10915         BKAVAIL=$(calc_osc_kbytes kbytesavail)
10916
10917         STRING=`df -P $MOUNT | tail -n 1 | awk '{print $2","$3","$4}'`
10918         DFTOTAL=`echo $STRING | cut -d, -f1`
10919         DFUSED=`echo $STRING  | cut -d, -f2`
10920         DFAVAIL=`echo $STRING | cut -d, -f3`
10921         DFFREE=$(($DFTOTAL - $DFUSED))
10922
10923         ALLOWANCE=$((64 * $OSTCOUNT))
10924
10925         if [ $DFTOTAL -lt $(($BKTOTAL - $ALLOWANCE)) ] ||
10926            [ $DFTOTAL -gt $(($BKTOTAL + $ALLOWANCE)) ] ; then
10927                 error "df total($DFTOTAL) mismatch OST total($BKTOTAL)"
10928         fi
10929         if [ $DFFREE -lt $(($BKFREE - $ALLOWANCE)) ] ||
10930            [ $DFFREE -gt $(($BKFREE + $ALLOWANCE)) ] ; then
10931                 error "df free($DFFREE) mismatch OST free($BKFREE)"
10932         fi
10933         if [ $DFAVAIL -lt $(($BKAVAIL - $ALLOWANCE)) ] ||
10934            [ $DFAVAIL -gt $(($BKAVAIL + $ALLOWANCE)) ] ; then
10935                 error "df avail($DFAVAIL) mismatch OST avail($BKAVAIL)"
10936         fi
10937 }
10938 run_test 79 "df report consistency check ======================="
10939
10940 test_80() { # bug 10718
10941         remote_ost_nodsh && skip "remote OST with nodsh"
10942         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10943
10944         # relax strong synchronous semantics for slow backends like ZFS
10945         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
10946                 local soc="obdfilter.*.sync_lock_cancel"
10947                 local save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
10948
10949                 # "sync_on_lock_cancel" was broken by v2_11_55_0-26-g7059644e9a
10950                 if [ -z "$save" ]; then
10951                         soc="obdfilter.*.sync_on_lock_cancel"
10952                         save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
10953                 fi
10954
10955                 if [ "$save" != "never" ]; then
10956                         local hosts=$(comma_list $(osts_nodes))
10957
10958                         do_nodes $hosts $LCTL set_param $soc=never
10959                         stack_trap "do_nodes $hosts $LCTL set_param $soc=$save"
10960                 fi
10961         fi
10962
10963         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1M
10964         sync; sleep 1; sync
10965         local before=$(date +%s)
10966         cancel_lru_locks osc
10967         local after=$(date +%s)
10968         local diff=$((after - before))
10969         [ $diff -le 1 ] || error "elapsed for 1M@1T = $diff"
10970
10971         rm -f $DIR/$tfile
10972 }
10973 run_test 80 "Page eviction is equally fast at high offsets too"
10974
10975 test_81a() { # LU-456
10976         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10977         remote_ost_nodsh && skip "remote OST with nodsh"
10978
10979         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
10980         # MUST OR with the CFS_FAIL_ONCE (0x80000000)
10981         do_facet ost1 lctl set_param fail_loc=0x80000228
10982
10983         # write should trigger a retry and success
10984         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10985         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10986         RC=$?
10987         if [ $RC -ne 0 ] ; then
10988                 error "write should success, but failed for $RC"
10989         fi
10990 }
10991 run_test 81a "OST should retry write when get -ENOSPC ==============="
10992
10993 test_81b() { # LU-456
10994         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10995         remote_ost_nodsh && skip "remote OST with nodsh"
10996
10997         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
10998         # Don't OR with the CFS_FAIL_ONCE (0x80000000)
10999         do_facet ost1 lctl set_param fail_loc=0x228
11000
11001         # write should retry several times and return -ENOSPC finally
11002         $LFS setstripe -i 0 -c 1 $DIR/$tfile
11003         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11004         RC=$?
11005         ENOSPC=28
11006         if [ $RC -ne $ENOSPC ] ; then
11007                 error "dd should fail for -ENOSPC, but succeed."
11008         fi
11009 }
11010 run_test 81b "OST should return -ENOSPC when retry still fails ======="
11011
11012 test_99() {
11013         [ -z "$(which cvs 2>/dev/null)" ] && skip_env "could not find cvs"
11014
11015         test_mkdir $DIR/$tdir.cvsroot
11016         chown $RUNAS_ID $DIR/$tdir.cvsroot
11017
11018         cd $TMP
11019         $RUNAS cvs -d $DIR/$tdir.cvsroot init || error "cvs init failed"
11020
11021         cd /etc/init.d
11022         # some versions of cvs import exit(1) when asked to import links or
11023         # files they can't read.  ignore those files.
11024         local toignore=$(find . -type l -printf '-I %f\n' -o \
11025                          ! -perm /4 -printf '-I %f\n')
11026         $RUNAS cvs -d $DIR/$tdir.cvsroot import -m "nomesg" $toignore \
11027                 $tdir.reposname vtag rtag
11028
11029         cd $DIR
11030         test_mkdir $DIR/$tdir.reposname
11031         chown $RUNAS_ID $DIR/$tdir.reposname
11032         $RUNAS cvs -d $DIR/$tdir.cvsroot co $tdir.reposname
11033
11034         cd $DIR/$tdir.reposname
11035         $RUNAS touch foo99
11036         $RUNAS cvs add -m 'addmsg' foo99
11037         $RUNAS cvs update
11038         $RUNAS cvs commit -m 'nomsg' foo99
11039         rm -fr $DIR/$tdir.cvsroot
11040 }
11041 run_test 99 "cvs strange file/directory operations"
11042
11043 test_100() {
11044         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11045         [[ "$NETTYPE" =~ tcp ]] ||
11046                 skip_env "TCP secure port test, not useful for NETTYPE=$NETTYPE"
11047         [[ -n "$(type -p ss)" ]] || skip_env "ss not available"
11048         remote_ost_nodsh && skip "remote OST with nodsh"
11049         remote_mds_nodsh && skip "remote MDS with nodsh"
11050         remote_servers || skip "useless for local single node setup"
11051
11052         ss -tna | ( rc=1; while read STATE SND RCV LOCAL REMOTE STAT; do
11053                 [[ "${REMOTE/*:/}" == "$ACCEPTOR_PORT" ]] || continue
11054
11055                 rc=0
11056                 if (( ${LOCAL/*:/} >= 1024 )); then
11057                         echo "bad: $PROT $SND $RCV $LOCAL $REMOTE $STAT"
11058                         ss -tna
11059                         error "local: ${LOCAL/*:/} > 1024 remote: ${REMOTE/*:/}"
11060                 fi
11061         done
11062         (( $rc == 0 )) || error "privileged port not found" )
11063 }
11064 run_test 100 "check local port using privileged port"
11065
11066 function get_named_value()
11067 {
11068     local tag=$1
11069
11070     grep -w "$tag" | sed "s/^$tag  *\([0-9]*\)  *.*/\1/"
11071 }
11072
11073 export CACHE_MAX=$($LCTL get_param -n llite.*.max_cached_mb |
11074                    awk '/^max_cached_mb/ { print $2 }')
11075
11076 cleanup_101a() {
11077         $LCTL set_param -n llite.*.max_cached_mb $CACHE_MAX
11078         trap 0
11079 }
11080
11081 test_101a() {
11082         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11083
11084         local s
11085         local discard
11086         local nreads=10000
11087         local cache_limit=32
11088
11089         $LCTL set_param -n osc.*-osc*.rpc_stats=0
11090         trap cleanup_101a EXIT
11091         $LCTL set_param -n llite.*.read_ahead_stats=0
11092         $LCTL set_param -n llite.*.max_cached_mb=$cache_limit
11093
11094         #
11095         # randomly read 10000 of 64K chunks from file 3x 32MB in size
11096         #
11097         echo "nreads: $nreads file size: $((cache_limit * 3))MB"
11098         $READS -f $DIR/$tfile -s$((cache_limit * 3192 * 1024)) -b65536 -C -n$nreads -t 180
11099
11100         discard=0
11101         for s in $($LCTL get_param -n llite.*.read_ahead_stats |
11102                    get_named_value 'read.but.discarded'); do
11103                         discard=$(($discard + $s))
11104         done
11105         cleanup_101a
11106
11107         $LCTL get_param osc.*-osc*.rpc_stats
11108         $LCTL get_param llite.*.read_ahead_stats
11109
11110         # Discard is generally zero, but sometimes a few random reads line up
11111         # and trigger larger readahead, which is wasted & leads to discards.
11112         if [[ $(($discard)) -gt $nreads ]]; then
11113                 error "too many ($discard) discarded pages"
11114         fi
11115         rm -f $DIR/$tfile || true
11116 }
11117 run_test 101a "check read-ahead for random reads"
11118
11119 setup_test101bc() {
11120         test_mkdir $DIR/$tdir
11121         local ssize=$1
11122         local FILE_LENGTH=$2
11123         STRIPE_OFFSET=0
11124
11125         local FILE_SIZE_MB=$((FILE_LENGTH / ssize))
11126
11127         local list=$(comma_list $(osts_nodes))
11128         set_osd_param $list '' read_cache_enable 0
11129         set_osd_param $list '' writethrough_cache_enable 0
11130
11131         trap cleanup_test101bc EXIT
11132         # prepare the read-ahead file
11133         $LFS setstripe -S $ssize -i $STRIPE_OFFSET -c $OSTCOUNT $DIR/$tfile
11134
11135         dd if=/dev/zero of=$DIR/$tfile bs=$ssize \
11136                                 count=$FILE_SIZE_MB 2> /dev/null
11137
11138 }
11139
11140 cleanup_test101bc() {
11141         trap 0
11142         rm -rf $DIR/$tdir
11143         rm -f $DIR/$tfile
11144
11145         local list=$(comma_list $(osts_nodes))
11146         set_osd_param $list '' read_cache_enable 1
11147         set_osd_param $list '' writethrough_cache_enable 1
11148 }
11149
11150 calc_total() {
11151         awk 'BEGIN{total=0}; {total+=$1}; END{print total}'
11152 }
11153
11154 ra_check_101() {
11155         local read_size=$1
11156         local stripe_size=$2
11157         local stride_length=$((stripe_size / read_size))
11158         local stride_width=$((stride_length * OSTCOUNT))
11159         local discard_limit=$(( ((stride_length - 1) * 3 / stride_width) *
11160                                 (stride_width - stride_length) ))
11161         local discard=$($LCTL get_param -n llite.*.read_ahead_stats |
11162                   get_named_value 'read.but.discarded' | calc_total)
11163
11164         if [[ $discard -gt $discard_limit ]]; then
11165                 $LCTL get_param llite.*.read_ahead_stats
11166                 error "($discard limit ${discard_limit}) discarded pages with size (${read_size})"
11167         else
11168                 echo "Read-ahead success for size ${read_size}"
11169         fi
11170 }
11171
11172 test_101b() {
11173         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11174         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11175
11176         local STRIPE_SIZE=1048576
11177         local STRIDE_SIZE=$((STRIPE_SIZE*OSTCOUNT))
11178
11179         if [ $SLOW == "yes" ]; then
11180                 local FILE_LENGTH=$((STRIDE_SIZE * 64))
11181         else
11182                 local FILE_LENGTH=$((STRIDE_SIZE * 8))
11183         fi
11184
11185         local ITERATION=$((FILE_LENGTH / STRIDE_SIZE))
11186
11187         # prepare the read-ahead file
11188         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
11189         cancel_lru_locks osc
11190         for BIDX in 2 4 8 16 32 64 128 256
11191         do
11192                 local BSIZE=$((BIDX*4096))
11193                 local READ_COUNT=$((STRIPE_SIZE/BSIZE))
11194                 local STRIDE_LENGTH=$((STRIDE_SIZE/BSIZE))
11195                 local OFFSET=$((STRIPE_SIZE/BSIZE*(OSTCOUNT - 1)))
11196                 $LCTL set_param -n llite.*.read_ahead_stats=0
11197                 $READS -f $DIR/$tfile  -l $STRIDE_LENGTH -o $OFFSET \
11198                               -s $FILE_LENGTH -b $STRIPE_SIZE -a $READ_COUNT -n $ITERATION
11199                 cancel_lru_locks osc
11200                 ra_check_101 $BSIZE $STRIPE_SIZE $FILE_LENGTH
11201         done
11202         cleanup_test101bc
11203         true
11204 }
11205 run_test 101b "check stride-io mode read-ahead ================="
11206
11207 test_101c() {
11208         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11209
11210         local STRIPE_SIZE=1048576
11211         local FILE_LENGTH=$((STRIPE_SIZE*100))
11212         local nreads=10000
11213         local rsize=65536
11214         local osc_rpc_stats
11215
11216         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
11217
11218         cancel_lru_locks osc
11219         $LCTL set_param osc.*.rpc_stats=0
11220         $READS -f $DIR/$tfile -s$FILE_LENGTH -b$rsize -n$nreads -t 180
11221         $LCTL get_param osc.*.rpc_stats
11222         for osc_rpc_stats in $($LCTL get_param -N osc.*.rpc_stats); do
11223                 local stats=$($LCTL get_param -n $osc_rpc_stats)
11224                 local lines=$(echo "$stats" | awk 'END {print NR;}')
11225                 local size
11226
11227                 if [ $lines -le 20 ]; then
11228                         echo "continue debug"
11229                         continue
11230                 fi
11231                 for size in 1 2 4 8; do
11232                         local rpc=$(echo "$stats" |
11233                                     awk '($1 == "'$size':") {print $2; exit; }')
11234                         [ $rpc != 0 ] && ((size * PAGE_SIZE < rsize)) &&
11235                                 error "Small $((size*PAGE_SIZE)) read IO $rpc!"
11236                 done
11237                 echo "$osc_rpc_stats check passed!"
11238         done
11239         cleanup_test101bc
11240         true
11241 }
11242 run_test 101c "check stripe_size aligned read-ahead"
11243
11244 test_101d() {
11245         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11246
11247         local file=$DIR/$tfile
11248         local sz_MB=${FILESIZE_101d:-80}
11249         local ra_MB=${READAHEAD_MB:-40}
11250
11251         local free_MB=$(($(df -P $DIR | tail -n 1 | awk '{ print $4 }') / 1024))
11252         [ $free_MB -lt $sz_MB ] &&
11253                 skip "Need free space ${sz_MB}M, have ${free_MB}M"
11254
11255         echo "Create test file $file size ${sz_MB}M, ${free_MB}M free"
11256         $LFS setstripe -c -1 $file || error "setstripe failed"
11257
11258         dd if=/dev/zero of=$file bs=1M count=$sz_MB || error "dd failed"
11259         echo Cancel LRU locks on lustre client to flush the client cache
11260         cancel_lru_locks osc
11261
11262         echo Disable read-ahead
11263         local old_RA=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
11264         $LCTL set_param -n llite.*.max_read_ahead_mb=0
11265         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb=$old_RA" EXIT
11266         $LCTL get_param -n llite.*.max_read_ahead_mb
11267
11268         echo "Reading the test file $file with read-ahead disabled"
11269         local sz_KB=$((sz_MB * 1024 / 4))
11270         # 10485760 bytes transferred in 0.000938 secs (11179579337 bytes/sec)
11271         # 104857600 bytes (105 MB) copied, 0.00876352 s, 12.0 GB/s
11272         local raOFF=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
11273                       sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
11274
11275         echo "Cancel LRU locks on lustre client to flush the client cache"
11276         cancel_lru_locks osc
11277         echo Enable read-ahead with ${ra_MB}MB
11278         $LCTL set_param -n llite.*.max_read_ahead_mb=$ra_MB
11279
11280         echo "Reading the test file $file with read-ahead enabled"
11281         local raON=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
11282                      sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
11283
11284         echo "read-ahead disabled time read $raOFF"
11285         echo "read-ahead enabled time read $raON"
11286
11287         rm -f $file
11288         wait_delete_completed
11289
11290         # use awk for this check instead of bash because it handles decimals
11291         awk "{ exit !($raOFF < 1.0 || $raOFF > $raON) }" <<<"ignore_me" ||
11292                 error "readahead ${raON}s > no-readahead ${raOFF}s ${sz_MB}M"
11293 }
11294 run_test 101d "file read with and without read-ahead enabled"
11295
11296 test_101e() {
11297         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11298
11299         local file=$DIR/$tfile
11300         local size_KB=500  #KB
11301         local count=100
11302         local bsize=1024
11303
11304         local free_KB=$(df -P $DIR | tail -n 1 | awk '{ print $4 }')
11305         local need_KB=$((count * size_KB))
11306         [[ $free_KB -le $need_KB ]] &&
11307                 skip_env "Need free space $need_KB, have $free_KB"
11308
11309         echo "Creating $count ${size_KB}K test files"
11310         for ((i = 0; i < $count; i++)); do
11311                 dd if=/dev/zero of=$file.$i bs=$bsize count=$size_KB 2>/dev/null
11312         done
11313
11314         echo "Cancel LRU locks on lustre client to flush the client cache"
11315         cancel_lru_locks $OSC
11316
11317         echo "Reset readahead stats"
11318         $LCTL set_param -n llite.*.read_ahead_stats=0
11319
11320         for ((i = 0; i < $count; i++)); do
11321                 dd if=$file.$i of=/dev/null bs=$bsize count=$size_KB 2>/dev/null
11322         done
11323
11324         $LCTL get_param llite.*.max_cached_mb
11325         $LCTL get_param llite.*.read_ahead_stats
11326         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11327                      get_named_value 'misses' | calc_total)
11328
11329         for ((i = 0; i < $count; i++)); do
11330                 rm -rf $file.$i 2>/dev/null
11331         done
11332
11333         #10000 means 20% reads are missing in readahead
11334         [[ $miss -lt 10000 ]] ||  error "misses too much for small reads"
11335 }
11336 run_test 101e "check read-ahead for small read(1k) for small files(500k)"
11337
11338 test_101f() {
11339         which iozone || skip_env "no iozone installed"
11340
11341         local old_debug=$($LCTL get_param debug)
11342         old_debug=${old_debug#*=}
11343         $LCTL set_param debug="reada mmap"
11344
11345         # create a test file
11346         iozone -i 0 -+n -r 1m -s 128m -w -f $DIR/$tfile > /dev/null 2>&1
11347
11348         echo Cancel LRU locks on lustre client to flush the client cache
11349         cancel_lru_locks osc
11350
11351         echo Reset readahead stats
11352         $LCTL set_param -n llite.*.read_ahead_stats=0
11353
11354         echo mmap read the file with small block size
11355         iozone -i 1 -u 1 -l 1 -+n -r 32k -s 128m -B -f $DIR/$tfile \
11356                 > /dev/null 2>&1
11357
11358         echo checking missing pages
11359         $LCTL get_param llite.*.read_ahead_stats
11360         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11361                         get_named_value 'misses' | calc_total)
11362
11363         $LCTL set_param debug="$old_debug"
11364         [ $miss -lt 3 ] || error "misses too much pages ('$miss')!"
11365         rm -f $DIR/$tfile
11366 }
11367 run_test 101f "check mmap read performance"
11368
11369 test_101g_brw_size_test() {
11370         local mb=$1
11371         local pages=$((mb * 1048576 / PAGE_SIZE))
11372         local file=$DIR/$tfile
11373
11374         $LCTL set_param osc.*.max_pages_per_rpc=${mb}M ||
11375                 { error "unable to set max_pages_per_rpc=${mb}M"; return 1; }
11376         for mp in $($LCTL get_param -n osc.*.max_pages_per_rpc); do
11377                 [ $mp -ne $pages ] && error "max_pages_per_rpc $mp != $pages" &&
11378                         return 2
11379         done
11380
11381         stack_trap "rm -f $file" EXIT
11382         $LCTL set_param -n osc.*.rpc_stats=0
11383
11384         # 10 RPCs should be enough for the test
11385         local count=10
11386         dd if=/dev/zero of=$file bs=${mb}M count=$count ||
11387                 { error "dd write ${mb} MB blocks failed"; return 3; }
11388         cancel_lru_locks osc
11389         dd of=/dev/null if=$file bs=${mb}M count=$count ||
11390                 { error "dd write ${mb} MB blocks failed"; return 4; }
11391
11392         # calculate number of full-sized read and write RPCs
11393         rpcs=($($LCTL get_param -n 'osc.*.rpc_stats' |
11394                 sed -n '/pages per rpc/,/^$/p' |
11395                 awk '/'$pages':/ { reads += $2; writes += $6 }; \
11396                 END { print reads,writes }'))
11397         # allow one extra full-sized read RPC for async readahead
11398         [[ ${rpcs[0]} == $count || ${rpcs[0]} == $((count + 1)) ]] ||
11399                 { error "${rpcs[0]} != $count read RPCs"; return 5; }
11400         [[ ${rpcs[1]} == $count ]] ||
11401                 { error "${rpcs[1]} != $count write RPCs"; return 6; }
11402 }
11403
11404 test_101g() {
11405         remote_ost_nodsh && skip "remote OST with nodsh"
11406
11407         local rpcs
11408         local osts=$(get_facets OST)
11409         local list=$(comma_list $(osts_nodes))
11410         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
11411         local brw_size="obdfilter.*.brw_size"
11412
11413         $LFS setstripe -i 0 -c 1 $DIR/$tfile
11414
11415         local orig_mb=$(do_facet ost1 $LCTL get_param -n $brw_size | head -n 1)
11416
11417         if { [ $OST1_VERSION -ge $(version_code 2.8.52) ] ||
11418                 { [ $OST1_VERSION -ge $(version_code 2.7.17) ] &&
11419                   [ $OST1_VERSION -lt $(version_code 2.7.50) ]; }; } &&
11420            { [ $CLIENT_VERSION -ge $(version_code 2.8.52) ] ||
11421                 { [ $CLIENT_VERSION -ge $(version_code 2.7.17) ] &&
11422                   [ $CLIENT_VERSION -lt $(version_code 2.7.50) ]; }; }; then
11423
11424                 [ $OST1_VERSION -ge $(version_code 2.9.52) ] &&
11425                         suffix="M"
11426
11427                 if [[ $orig_mb -lt 16 ]]; then
11428                         save_lustre_params $osts "$brw_size" > $p
11429                         do_nodes $list $LCTL set_param -n $brw_size=16$suffix ||
11430                                 error "set 16MB RPC size failed"
11431
11432                         echo "remount client to enable new RPC size"
11433                         remount_client $MOUNT || error "remount_client failed"
11434                 fi
11435
11436                 test_101g_brw_size_test 16 || error "16MB RPC test failed"
11437                 # should be able to set brw_size=12, but no rpc_stats for that
11438                 test_101g_brw_size_test 8 || error "8MB RPC test failed"
11439         fi
11440
11441         test_101g_brw_size_test 4 || error "4MB RPC test failed"
11442
11443         if [[ $orig_mb -lt 16 ]]; then
11444                 restore_lustre_params < $p
11445                 remount_client $MOUNT || error "remount_client restore failed"
11446         fi
11447
11448         rm -f $p $DIR/$tfile
11449 }
11450 run_test 101g "Big bulk(4/16 MiB) readahead"
11451
11452 test_101h() {
11453         $LFS setstripe -i 0 -c 1 $DIR/$tfile
11454
11455         dd if=/dev/zero of=$DIR/$tfile bs=1M count=70 ||
11456                 error "dd 70M file failed"
11457         echo Cancel LRU locks on lustre client to flush the client cache
11458         cancel_lru_locks osc
11459
11460         echo "Reset readahead stats"
11461         $LCTL set_param -n llite.*.read_ahead_stats 0
11462
11463         echo "Read 10M of data but cross 64M bundary"
11464         dd if=$DIR/$tfile of=/dev/null bs=10M skip=6 count=1
11465         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11466                      get_named_value 'misses' | calc_total)
11467         [ $miss -eq 1 ] || error "expected miss 1 but got $miss"
11468         rm -f $p $DIR/$tfile
11469 }
11470 run_test 101h "Readahead should cover current read window"
11471
11472 test_101i() {
11473         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 ||
11474                 error "dd 10M file failed"
11475
11476         local max_per_file_mb=$($LCTL get_param -n \
11477                 llite.*.max_read_ahead_per_file_mb 2>/dev/null)
11478         cancel_lru_locks osc
11479         stack_trap "$LCTL set_param llite.*.max_read_ahead_per_file_mb=$max_per_file_mb"
11480         $LCTL set_param llite.*.max_read_ahead_per_file_mb=1 ||
11481                 error "set max_read_ahead_per_file_mb to 1 failed"
11482
11483         echo "Reset readahead stats"
11484         $LCTL set_param llite.*.read_ahead_stats=0
11485
11486         dd if=$DIR/$tfile of=/dev/null bs=2M
11487
11488         $LCTL get_param llite.*.read_ahead_stats
11489         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11490                      awk '/misses/ { print $2 }')
11491         [ $miss -eq 5 ] || error "expected misses 5 but got $miss"
11492         rm -f $DIR/$tfile
11493 }
11494 run_test 101i "allow current readahead to exceed reservation"
11495
11496 test_101j() {
11497         $LFS setstripe -i 0 -c 1 $DIR/$tfile ||
11498                 error "setstripe $DIR/$tfile failed"
11499         local file_size=$((1048576 * 16))
11500         local old_ra=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
11501         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb $old_ra" EXIT
11502
11503         echo Disable read-ahead
11504         $LCTL set_param -n llite.*.max_read_ahead_mb=0
11505
11506         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$(($file_size / 1048576))
11507         for blk in $PAGE_SIZE 1048576 $file_size; do
11508                 cancel_lru_locks osc
11509                 echo "Reset readahead stats"
11510                 $LCTL set_param -n llite.*.read_ahead_stats=0
11511                 local count=$(($file_size / $blk))
11512                 dd if=$DIR/$tfile bs=$blk count=$count of=/dev/null
11513                 local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11514                              get_named_value 'failed.to.fast.read' | calc_total)
11515                 $LCTL get_param -n llite.*.read_ahead_stats
11516                 [ $miss -eq $count ] || error "expected $count got $miss"
11517         done
11518
11519         rm -f $p $DIR/$tfile
11520 }
11521 run_test 101j "A complete read block should be submitted when no RA"
11522
11523 test_readahead_base() {
11524         local file=$DIR/$tfile
11525         local size=$1
11526         local iosz
11527         local ramax
11528         local ranum
11529
11530         $LCTL set_param -n llite.*.read_ahead_stats=0
11531         # The first page is not accounted into readahead
11532         ramax=$(((size + PAGE_SIZE - 1) / PAGE_SIZE - 1))
11533         iosz=$(((size + 1048575) / 1048576 * 1048576))
11534         echo "Test readahead: size=$size ramax=$ramx iosz=$iosz"
11535
11536         $LCTL mark  "Test readahead: size=$size ramax=$ramx iosz=$iosz"
11537         fallocate -l $size $file || error "failed to fallocate $file"
11538         cancel_lru_locks osc
11539         $MULTIOP $file or${iosz}c || error "failed to read $file"
11540         $LCTL get_param -n llite.*.read_ahead_stats
11541         ranum=$($LCTL get_param -n llite.*.read_ahead_stats |
11542                 awk '/readahead.pages/ { print $7 }' | calc_total)
11543         (( $ranum <= $ramax )) ||
11544                 error "read-ahead pages is $ranum more than $ramax"
11545         rm -rf $file || error "failed to remove $file"
11546 }
11547
11548 test_101m()
11549 {
11550         local file=$DIR/$tfile
11551         local ramax
11552         local ranum
11553         local size
11554         local iosz
11555
11556         check_set_fallocate_or_skip
11557         stack_trap "rm -f $file" EXIT
11558
11559         test_readahead_base 4096
11560
11561         # file size: 16K = 16384
11562         test_readahead_base 16384
11563         test_readahead_base 16385
11564         test_readahead_base 16383
11565
11566         # file size: 1M + 1 = 1048576 + 1
11567         test_readahead_base 1048577
11568         # file size: 1M + 16K
11569         test_readahead_base $((1048576 + 16384))
11570
11571         # file size: stripe_size * (stripe_count - 1) + 16K
11572         $LFS setstripe -c -1 $file || error "failed to setstripe $file"
11573         test_readahead_base $((1048576 * (OSTCOUNT - 1) + 16384))
11574         # file size: stripe_size * stripe_count + 16K
11575         $LFS setstripe -c -1 $file || error "failed to setstripe $file"
11576         test_readahead_base $((1048576 * OSTCOUNT + 16384))
11577         # file size: 2 * stripe_size * stripe_count + 16K
11578         $LFS setstripe -c -1 $file || error "failed to setstripe $file"
11579         test_readahead_base $((2 * 1048576 * OSTCOUNT + 16384))
11580 }
11581 run_test 101m "read ahead for small file and last stripe of the file"
11582
11583 setup_test102() {
11584         test_mkdir $DIR/$tdir
11585         chown $RUNAS_ID $DIR/$tdir
11586         STRIPE_SIZE=65536
11587         STRIPE_OFFSET=1
11588         STRIPE_COUNT=$OSTCOUNT
11589         [[ $OSTCOUNT -gt 4 ]] && STRIPE_COUNT=4
11590
11591         trap cleanup_test102 EXIT
11592         cd $DIR
11593         $1 $LFS setstripe -S $STRIPE_SIZE -i $STRIPE_OFFSET -c $STRIPE_COUNT $tdir
11594         cd $DIR/$tdir
11595         for num in 1 2 3 4; do
11596                 for count in $(seq 1 $STRIPE_COUNT); do
11597                         for idx in $(seq 0 $[$STRIPE_COUNT - 1]); do
11598                                 local size=`expr $STRIPE_SIZE \* $num`
11599                                 local file=file"$num-$idx-$count"
11600                                 $1 $LFS setstripe -S $size -i $idx -c $count $file
11601                         done
11602                 done
11603         done
11604
11605         cd $DIR
11606         $1 tar cf $TMP/f102.tar $tdir --xattrs
11607 }
11608
11609 cleanup_test102() {
11610         trap 0
11611         rm -f $TMP/f102.tar
11612         rm -rf $DIR/d0.sanity/d102
11613 }
11614
11615 test_102a() {
11616         [ "$UID" != 0 ] && skip "must run as root"
11617         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep xattr)" ] &&
11618                 skip_env "must have user_xattr"
11619
11620         [ -z "$(which setfattr 2>/dev/null)" ] &&
11621                 skip_env "could not find setfattr"
11622
11623         local testfile=$DIR/$tfile
11624
11625         touch $testfile
11626         echo "set/get xattr..."
11627         setfattr -n trusted.name1 -v value1 $testfile ||
11628                 error "setfattr -n trusted.name1=value1 $testfile failed"
11629         getfattr -n trusted.name1 $testfile 2> /dev/null |
11630           grep "trusted.name1=.value1" ||
11631                 error "$testfile missing trusted.name1=value1"
11632
11633         setfattr -n user.author1 -v author1 $testfile ||
11634                 error "setfattr -n user.author1=author1 $testfile failed"
11635         getfattr -n user.author1 $testfile 2> /dev/null |
11636           grep "user.author1=.author1" ||
11637                 error "$testfile missing trusted.author1=author1"
11638
11639         echo "listxattr..."
11640         setfattr -n trusted.name2 -v value2 $testfile ||
11641                 error "$testfile unable to set trusted.name2"
11642         setfattr -n trusted.name3 -v value3 $testfile ||
11643                 error "$testfile unable to set trusted.name3"
11644         [ $(getfattr -d -m "^trusted" $testfile 2> /dev/null |
11645             grep "trusted.name" | wc -l) -eq 3 ] ||
11646                 error "$testfile missing 3 trusted.name xattrs"
11647
11648         setfattr -n user.author2 -v author2 $testfile ||
11649                 error "$testfile unable to set user.author2"
11650         setfattr -n user.author3 -v author3 $testfile ||
11651                 error "$testfile unable to set user.author3"
11652         [ $(getfattr -d -m "^user" $testfile 2> /dev/null |
11653             grep "user.author" | wc -l) -eq 3 ] ||
11654                 error "$testfile missing 3 user.author xattrs"
11655
11656         echo "remove xattr..."
11657         setfattr -x trusted.name1 $testfile ||
11658                 error "$testfile error deleting trusted.name1"
11659         getfattr -d -m trusted $testfile 2> /dev/null | grep "trusted.name1" &&
11660                 error "$testfile did not delete trusted.name1 xattr"
11661
11662         setfattr -x user.author1 $testfile ||
11663                 error "$testfile error deleting user.author1"
11664         echo "set lustre special xattr ..."
11665         $LFS setstripe -c1 $testfile
11666         local lovea=$(getfattr -n "trusted.lov" -e hex $testfile |
11667                 awk -F "=" '/trusted.lov/ { print $2 }' )
11668         setfattr -n "trusted.lov" -v $lovea $testfile ||
11669                 error "$testfile doesn't ignore setting trusted.lov again"
11670         setfattr -n "trusted.lov" -v "invalid_value" $testfile &&
11671                 error "$testfile allow setting invalid trusted.lov"
11672         rm -f $testfile
11673 }
11674 run_test 102a "user xattr test =================================="
11675
11676 check_102b_layout() {
11677         local layout="$*"
11678         local testfile=$DIR/$tfile
11679
11680         echo "test layout '$layout'"
11681         $LFS setstripe $layout $testfile || error "setstripe failed"
11682         $LFS getstripe -y $testfile
11683
11684         echo "get/set/list trusted.lov xattr ..." # b=10930
11685         local value=$(getfattr -n trusted.lov -e hex $testfile | grep trusted)
11686         [[ "$value" =~ "trusted.lov" ]] ||
11687                 error "can't get trusted.lov from $testfile"
11688         local stripe_count_orig=$($LFS getstripe -c $testfile) ||
11689                 error "getstripe failed"
11690
11691         $MCREATE $testfile.2 || error "mcreate $testfile.2 failed"
11692
11693         value=$(cut -d= -f2 <<<$value)
11694         # LU-13168: truncated xattr should fail if short lov_user_md header
11695         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
11696                 lens="${#value}" || lens="$(seq 4 2 ${#value})"
11697         for len in $lens; do
11698                 echo "setfattr $len $testfile.2"
11699                 setfattr -n trusted.lov -v ${value:0:$len} $testfile.2 &&
11700                         [ $len -lt 66 ] && error "short xattr len=$len worked"
11701         done
11702         local stripe_size=$($LFS getstripe -S $testfile.2)
11703         local stripe_count=$($LFS getstripe -c $testfile.2)
11704         [[ $stripe_size -eq 65536 ]] ||
11705                 error "stripe size $stripe_size != 65536"
11706         [[ $stripe_count -eq $stripe_count_orig ]] ||
11707                 error "stripe count $stripe_count != $stripe_count_orig"
11708         rm $testfile $testfile.2
11709 }
11710
11711 test_102b() {
11712         [ -z "$(which setfattr 2>/dev/null)" ] &&
11713                 skip_env "could not find setfattr"
11714         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11715
11716         # check plain layout
11717         check_102b_layout -S 65536 -i 1 -c $OSTCOUNT
11718
11719         # and also check composite layout
11720         check_102b_layout -E 1M -S 65536 -i 1 -c $OSTCOUNT -Eeof -S4M
11721
11722 }
11723 run_test 102b "getfattr/setfattr for trusted.lov EAs"
11724
11725 test_102c() {
11726         [ -z "$(which setfattr 2>/dev/null)" ] &&
11727                 skip_env "could not find setfattr"
11728         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11729
11730         # b10930: get/set/list lustre.lov xattr
11731         echo "get/set/list lustre.lov xattr ..."
11732         test_mkdir $DIR/$tdir
11733         chown $RUNAS_ID $DIR/$tdir
11734         local testfile=$DIR/$tdir/$tfile
11735         $RUNAS $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
11736                 error "setstripe failed"
11737         local STRIPECOUNT=$($RUNAS $LFS getstripe -c $testfile) ||
11738                 error "getstripe failed"
11739         $RUNAS getfattr -d -m "^lustre" $testfile 2> /dev/null | \
11740         grep "lustre.lov" || error "can't get lustre.lov from $testfile"
11741
11742         local testfile2=${testfile}2
11743         local value=`getfattr -n lustre.lov $testfile 2> /dev/null | \
11744                      grep "lustre.lov" |sed -e 's/[^=]\+=//'  `
11745
11746         $RUNAS $MCREATE $testfile2
11747         $RUNAS setfattr -n lustre.lov -v $value $testfile2
11748         local stripe_size=$($RUNAS $LFS getstripe -S $testfile2)
11749         local stripe_count=$($RUNAS $LFS getstripe -c $testfile2)
11750         [ $stripe_size -eq 65536 ] || error "stripe size $stripe_size != 65536"
11751         [ $stripe_count -eq $STRIPECOUNT ] ||
11752                 error "stripe count $stripe_count != $STRIPECOUNT"
11753 }
11754 run_test 102c "non-root getfattr/setfattr for lustre.lov EAs ==========="
11755
11756 compare_stripe_info1() {
11757         local stripe_index_all_zero=true
11758
11759         for num in 1 2 3 4; do
11760                 for count in $(seq 1 $STRIPE_COUNT); do
11761                         for offset in $(seq 0 $[$STRIPE_COUNT - 1]); do
11762                                 local size=$((STRIPE_SIZE * num))
11763                                 local file=file"$num-$offset-$count"
11764                                 stripe_size=$($LFS getstripe -S $PWD/$file)
11765                                 [[ $stripe_size -ne $size ]] &&
11766                                     error "$file: size $stripe_size != $size"
11767                                 stripe_count=$($LFS getstripe -c $PWD/$file)
11768                                 # allow fewer stripes to be created, ORI-601
11769                                 [[ $stripe_count -lt $(((3 * count + 3) / 4)) ]] &&
11770                                     error "$file: count $stripe_count != $count"
11771                                 stripe_index=$($LFS getstripe -i $PWD/$file)
11772                                 [[ $stripe_index -ne 0 ]] &&
11773                                         stripe_index_all_zero=false
11774                         done
11775                 done
11776         done
11777         $stripe_index_all_zero &&
11778                 error "all files are being extracted starting from OST index 0"
11779         return 0
11780 }
11781
11782 have_xattrs_include() {
11783         tar --help | grep -q xattrs-include &&
11784                 echo --xattrs-include="lustre.*"
11785 }
11786
11787 test_102d() {
11788         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11789         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11790
11791         XINC=$(have_xattrs_include)
11792         setup_test102
11793         tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
11794         cd $DIR/$tdir/$tdir
11795         compare_stripe_info1
11796 }
11797 run_test 102d "tar restore stripe info from tarfile,not keep osts"
11798
11799 test_102f() {
11800         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11801         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11802
11803         XINC=$(have_xattrs_include)
11804         setup_test102
11805         test_mkdir $DIR/$tdir.restore
11806         cd $DIR
11807         tar cf - --xattrs $tdir | tar xf - \
11808                 -C $DIR/$tdir.restore --xattrs $XINC
11809         cd $DIR/$tdir.restore/$tdir
11810         compare_stripe_info1
11811 }
11812 run_test 102f "tar copy files, not keep osts"
11813
11814 grow_xattr() {
11815         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep xattr)" ] &&
11816                 skip "must have user_xattr"
11817         [ -z "$(which setfattr 2>/dev/null)" ] &&
11818                 skip_env "could not find setfattr"
11819         [ -z "$(which getfattr 2>/dev/null)" ] &&
11820                 skip_env "could not find getfattr"
11821
11822         local xsize=${1:-1024}  # in bytes
11823         local file=$DIR/$tfile
11824         local value="$(generate_string $xsize)"
11825         local xbig=trusted.big
11826         local toobig=$2
11827
11828         touch $file
11829         log "save $xbig on $file"
11830         if [ -z "$toobig" ]
11831         then
11832                 setfattr -n $xbig -v $value $file ||
11833                         error "saving $xbig on $file failed"
11834         else
11835                 setfattr -n $xbig -v $value $file &&
11836                         error "saving $xbig on $file succeeded"
11837                 return 0
11838         fi
11839
11840         local orig=$(get_xattr_value $xbig $file)
11841         [[ "$orig" != "$value" ]] && error "$xbig different after saving $xbig"
11842
11843         local xsml=trusted.sml
11844         log "save $xsml on $file"
11845         setfattr -n $xsml -v val $file || error "saving $xsml on $file failed"
11846
11847         local new=$(get_xattr_value $xbig $file)
11848         [[ "$new" != "$orig" ]] && error "$xbig different after saving $xsml"
11849
11850         log "grow $xsml on $file"
11851         setfattr -n $xsml -v "$value" $file ||
11852                 error "growing $xsml on $file failed"
11853
11854         new=$(get_xattr_value $xbig $file)
11855         [[ "$new" != "$orig" ]] && error "$xbig different after growing $xsml"
11856         log "$xbig still valid after growing $xsml"
11857
11858         rm -f $file
11859 }
11860
11861 test_102h() { # bug 15777
11862         grow_xattr 1024
11863 }
11864 run_test 102h "grow xattr from inside inode to external block"
11865
11866 test_102ha() {
11867         large_xattr_enabled || skip_env "ea_inode feature disabled"
11868
11869         echo "setting xattr of max xattr size: $(max_xattr_size)"
11870         grow_xattr $(max_xattr_size)
11871
11872         echo "setting xattr of > max xattr size: $(max_xattr_size) + 10"
11873         echo "This should fail:"
11874         grow_xattr $(($(max_xattr_size) + 10)) 1
11875 }
11876 run_test 102ha "grow xattr from inside inode to external inode"
11877
11878 test_102i() { # bug 17038
11879         [ -z "$(which getfattr 2>/dev/null)" ] &&
11880                 skip "could not find getfattr"
11881
11882         touch $DIR/$tfile
11883         ln -s $DIR/$tfile $DIR/${tfile}link
11884         getfattr -n trusted.lov $DIR/$tfile ||
11885                 error "lgetxattr on $DIR/$tfile failed"
11886         getfattr -h -n trusted.lov $DIR/${tfile}link 2>&1 |
11887                 grep -i "no such attr" ||
11888                 error "error for lgetxattr on $DIR/${tfile}link is not ENODATA"
11889         rm -f $DIR/$tfile $DIR/${tfile}link
11890 }
11891 run_test 102i "lgetxattr test on symbolic link ============"
11892
11893 test_102j() {
11894         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11895         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11896
11897         XINC=$(have_xattrs_include)
11898         setup_test102 "$RUNAS"
11899         chown $RUNAS_ID $DIR/$tdir
11900         $RUNAS tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
11901         cd $DIR/$tdir/$tdir
11902         compare_stripe_info1 "$RUNAS"
11903 }
11904 run_test 102j "non-root tar restore stripe info from tarfile, not keep osts ==="
11905
11906 test_102k() {
11907         [ -z "$(which setfattr 2>/dev/null)" ] &&
11908                 skip "could not find setfattr"
11909
11910         touch $DIR/$tfile
11911         # b22187 just check that does not crash for regular file.
11912         setfattr -n trusted.lov $DIR/$tfile
11913         # b22187 'setfattr -n trusted.lov' should remove LOV EA for directories
11914         local test_kdir=$DIR/$tdir
11915         test_mkdir $test_kdir
11916         local default_size=$($LFS getstripe -S $test_kdir)
11917         local default_count=$($LFS getstripe -c $test_kdir)
11918         local default_offset=$($LFS getstripe -i $test_kdir)
11919         $LFS setstripe -S 65536 -i 0 -c $OSTCOUNT $test_kdir ||
11920                 error 'dir setstripe failed'
11921         setfattr -n trusted.lov $test_kdir
11922         local stripe_size=$($LFS getstripe -S $test_kdir)
11923         local stripe_count=$($LFS getstripe -c $test_kdir)
11924         local stripe_offset=$($LFS getstripe -i $test_kdir)
11925         [ $stripe_size -eq $default_size ] ||
11926                 error "stripe size $stripe_size != $default_size"
11927         [ $stripe_count -eq $default_count ] ||
11928                 error "stripe count $stripe_count != $default_count"
11929         [ $stripe_offset -eq $default_offset ] ||
11930                 error "stripe offset $stripe_offset != $default_offset"
11931         rm -rf $DIR/$tfile $test_kdir
11932 }
11933 run_test 102k "setfattr without parameter of value shouldn't cause a crash"
11934
11935 test_102l() {
11936         [ -z "$(which getfattr 2>/dev/null)" ] &&
11937                 skip "could not find getfattr"
11938
11939         # LU-532 trusted. xattr is invisible to non-root
11940         local testfile=$DIR/$tfile
11941
11942         touch $testfile
11943
11944         echo "listxattr as user..."
11945         chown $RUNAS_ID $testfile
11946         $RUNAS getfattr -d -m '.*' $testfile 2>&1 |
11947             grep -q "trusted" &&
11948                 error "$testfile trusted xattrs are user visible"
11949
11950         return 0;
11951 }
11952 run_test 102l "listxattr size test =================================="
11953
11954 test_102m() { # LU-3403 llite: error of listxattr when buffer is small
11955         local path=$DIR/$tfile
11956         touch $path
11957
11958         listxattr_size_check $path || error "listattr_size_check $path failed"
11959 }
11960 run_test 102m "Ensure listxattr fails on small bufffer ========"
11961
11962 cleanup_test102
11963
11964 getxattr() { # getxattr path name
11965         # Return the base64 encoding of the value of xattr name on path.
11966         local path=$1
11967         local name=$2
11968
11969         # # getfattr --absolute-names --encoding=base64 --name=trusted.lov $path
11970         # file: $path
11971         # trusted.lov=0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
11972         #
11973         # We print just 0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
11974
11975         getfattr --absolute-names --encoding=base64 --name=$name $path |
11976                 awk -F= -v name=$name '$1 == name {
11977                         print substr($0, index($0, "=") + 1);
11978         }'
11979 }
11980
11981 test_102n() { # LU-4101 mdt: protect internal xattrs
11982         [ -z "$(which setfattr 2>/dev/null)" ] &&
11983                 skip "could not find setfattr"
11984         if [ $MDS1_VERSION -lt $(version_code 2.5.50) ]
11985         then
11986                 skip "MDT < 2.5.50 allows setxattr on internal trusted xattrs"
11987         fi
11988
11989         local file0=$DIR/$tfile.0
11990         local file1=$DIR/$tfile.1
11991         local xattr0=$TMP/$tfile.0
11992         local xattr1=$TMP/$tfile.1
11993         local namelist="lov lma lmv link fid version som hsm"
11994         local name
11995         local value
11996
11997         rm -rf $file0 $file1 $xattr0 $xattr1
11998         touch $file0 $file1
11999
12000         # Get 'before' xattrs of $file1.
12001         getfattr --absolute-names --dump --match=- $file1 > $xattr0
12002
12003         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
12004                 namelist+=" lfsck_namespace"
12005         for name in $namelist; do
12006                 # Try to copy xattr from $file0 to $file1.
12007                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
12008
12009                 setfattr --name=trusted.$name --value="$value" $file1 ||
12010                         error "setxattr 'trusted.$name' failed"
12011
12012                 # Try to set a garbage xattr.
12013                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
12014
12015                 if [[ x$name == "xlov" ]]; then
12016                         setfattr --name=trusted.lov --value="$value" $file1 &&
12017                         error "setxattr invalid 'trusted.lov' success"
12018                 else
12019                         setfattr --name=trusted.$name --value="$value" $file1 ||
12020                                 error "setxattr invalid 'trusted.$name' failed"
12021                 fi
12022
12023                 # Try to remove the xattr from $file1. We don't care if this
12024                 # appears to succeed or fail, we just don't want there to be
12025                 # any changes or crashes.
12026                 setfattr --remove=$trusted.$name $file1 2> /dev/null
12027         done
12028
12029         if [ $MDS1_VERSION -gt $(version_code 2.6.50) ]
12030         then
12031                 name="lfsck_ns"
12032                 # Try to copy xattr from $file0 to $file1.
12033                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
12034
12035                 setfattr --name=trusted.$name --value="$value" $file1 ||
12036                         error "setxattr 'trusted.$name' failed"
12037
12038                 # Try to set a garbage xattr.
12039                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
12040
12041                 setfattr --name=trusted.$name --value="$value" $file1 ||
12042                         error "setxattr 'trusted.$name' failed"
12043
12044                 # Try to remove the xattr from $file1. We don't care if this
12045                 # appears to succeed or fail, we just don't want there to be
12046                 # any changes or crashes.
12047                 setfattr --remove=$trusted.$name $file1 2> /dev/null
12048         fi
12049
12050         # Get 'after' xattrs of file1.
12051         getfattr --absolute-names --dump --match=- $file1 > $xattr1
12052
12053         if ! diff $xattr0 $xattr1; then
12054                 error "before and after xattrs of '$file1' differ"
12055         fi
12056
12057         rm -rf $file0 $file1 $xattr0 $xattr1
12058
12059         return 0
12060 }
12061 run_test 102n "silently ignore setxattr on internal trusted xattrs"
12062
12063 test_102p() { # LU-4703 setxattr did not check ownership
12064         [ $MDS1_VERSION -lt $(version_code 2.5.56) ] &&
12065                 skip "MDS needs to be at least 2.5.56"
12066
12067         local testfile=$DIR/$tfile
12068
12069         touch $testfile
12070
12071         echo "setfacl as user..."
12072         $RUNAS setfacl -m "u:$RUNAS_ID:rwx" $testfile
12073         [ $? -ne 0 ] || error "setfacl by $RUNAS_ID was allowed on $testfile"
12074
12075         echo "setfattr as user..."
12076         setfacl -m "u:$RUNAS_ID:---" $testfile
12077         $RUNAS setfattr -x system.posix_acl_access $testfile
12078         [ $? -ne 0 ] || error "setfattr by $RUNAS_ID was allowed on $testfile"
12079 }
12080 run_test 102p "check setxattr(2) correctly fails without permission"
12081
12082 test_102q() {
12083         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] &&
12084                 skip "MDS needs to be at least 2.6.92"
12085
12086         orphan_linkea_check $DIR/$tfile || error "orphan_linkea_check"
12087 }
12088 run_test 102q "flistxattr should not return trusted.link EAs for orphans"
12089
12090 test_102r() {
12091         [ $MDS1_VERSION -lt $(version_code 2.6.93) ] &&
12092                 skip "MDS needs to be at least 2.6.93"
12093
12094         touch $DIR/$tfile || error "touch"
12095         setfattr -n user.$(basename $tfile) $DIR/$tfile || error "setfattr"
12096         getfattr -n user.$(basename $tfile) $DIR/$tfile || error "getfattr"
12097         rm $DIR/$tfile || error "rm"
12098
12099         #normal directory
12100         mkdir -p $DIR/$tdir || error "mkdir"
12101         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
12102         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
12103         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
12104                 error "$testfile error deleting user.author1"
12105         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
12106                 grep "user.$(basename $tdir)" &&
12107                 error "$tdir did not delete user.$(basename $tdir)"
12108         rmdir $DIR/$tdir || error "rmdir"
12109
12110         #striped directory
12111         test_mkdir $DIR/$tdir
12112         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
12113         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
12114         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
12115                 error "$testfile error deleting user.author1"
12116         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
12117                 grep "user.$(basename $tdir)" &&
12118                 error "$tdir did not delete user.$(basename $tdir)"
12119         rmdir $DIR/$tdir || error "rm striped dir"
12120 }
12121 run_test 102r "set EAs with empty values"
12122
12123 test_102s() {
12124         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
12125                 skip "MDS needs to be at least 2.11.52"
12126
12127         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
12128
12129         save_lustre_params client "llite.*.xattr_cache" > $save
12130
12131         for cache in 0 1; do
12132                 lctl set_param llite.*.xattr_cache=$cache
12133
12134                 rm -f $DIR/$tfile
12135                 touch $DIR/$tfile || error "touch"
12136                 for prefix in lustre security system trusted user; do
12137                         # Note getxattr() may fail with 'Operation not
12138                         # supported' or 'No such attribute' depending
12139                         # on prefix and cache.
12140                         getfattr -n $prefix.n102s $DIR/$tfile &&
12141                                 error "getxattr '$prefix.n102s' should fail (cache = $cache)"
12142                 done
12143         done
12144
12145         restore_lustre_params < $save
12146 }
12147 run_test 102s "getting nonexistent xattrs should fail"
12148
12149 test_102t() {
12150         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
12151                 skip "MDS needs to be at least 2.11.52"
12152
12153         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
12154
12155         save_lustre_params client "llite.*.xattr_cache" > $save
12156
12157         for cache in 0 1; do
12158                 lctl set_param llite.*.xattr_cache=$cache
12159
12160                 for buf_size in 0 256; do
12161                         rm -f $DIR/$tfile
12162                         touch $DIR/$tfile || error "touch"
12163                         setfattr -n user.multiop $DIR/$tfile
12164                         $MULTIOP $DIR/$tfile oa$buf_size ||
12165                                 error "cannot get zero length xattr value (buf_size = $buf_size)"
12166                 done
12167         done
12168
12169         restore_lustre_params < $save
12170 }
12171 run_test 102t "zero length xattr values handled correctly"
12172
12173 run_acl_subtest()
12174 {
12175         local test=$LUSTRE/tests/acl/$1.test
12176         local tmp=$(mktemp -t $1-XXXXXX).test
12177         local bin=$2
12178         local dmn=$3
12179         local grp=$4
12180         local nbd=$5
12181         export LANG=C
12182
12183
12184         local sedusers="-e s/bin/$bin/g -e s/daemon/$dmn/g"
12185         local sedgroups="-e s/:users/:$grp/g"
12186         [[ -z "$nbd" ]] || sedusers+=" -e s/nobody/$nbd/g"
12187
12188         sed $sedusers $sedgroups < $test > $tmp
12189         stack_trap "rm -f $tmp"
12190         [[ -s $tmp ]] || error "sed failed to create test script"
12191
12192         echo "performing $1 with bin='$bin' daemon='$dmn' users='$grp'..."
12193         $LUSTRE/tests/acl/run $tmp || error "run_acl_subtest '$1' failed"
12194 }
12195
12196 test_103a() {
12197         [ "$UID" != 0 ] && skip "must run as root"
12198         $GSS && skip_env "could not run under gss"
12199         [[ "$(lctl get_param -n mdc.*-mdc-*.connect_flags)" =~ "acl" ]] ||
12200                 skip_env "must have acl enabled"
12201         which setfacl || skip_env "could not find setfacl"
12202         remote_mds_nodsh && skip "remote MDS with nodsh"
12203
12204         ACLBIN=${ACLBIN:-"bin"}
12205         ACLDMN=${ACLDMN:-"daemon"}
12206         ACLGRP=${ACLGRP:-"users"}
12207         ACLNBD=${ACLNBD:-"nobody"}
12208
12209         if ! id $ACLBIN ||
12210            [[ "$(id -u $ACLBIN)" != "$(do_facet mds1 id -u $ACLBIN)" ]]; then
12211                 echo "bad 'bin' user '$ACLBIN', using '$USER0'"
12212                 ACLBIN=$USER0
12213                 if ! id $ACLBIN ; then
12214                         cat /etc/passwd
12215                         skip_env "can't find suitable ACL 'bin' $ACLBIN"
12216                 fi
12217         fi
12218         if ! id $ACLDMN || (( $(id -u $ACLDMN) < $(id -u $ACLBIN) )) ||
12219            [[ "$(id -u $ACLDMN)" != "$(do_facet mds1 id -u $ACLDMN)" ]]; then
12220                 echo "bad 'daemon' user '$ACLDMN', using '$USER1'"
12221                 ACLDMN=$USER1
12222                 if ! id $ACLDMN ; then
12223                         cat /etc/passwd
12224                         skip_env "can't find suitable ACL 'daemon' $ACLDMN"
12225                 fi
12226         fi
12227         if ! getent group $ACLGRP; then
12228                 echo "missing 'users' group '$ACLGRP', using '$TSTUSR'"
12229                 ACLGRP="$TSTUSR"
12230                 if ! getent group $ACLGRP; then
12231                         echo "cannot find group '$ACLGRP', adding it"
12232                         cat /etc/group
12233                         add_group 60000 $ACLGRP
12234                 fi
12235         fi
12236
12237         local bingid=$(getent group $ACLBIN | cut -d: -f 3)
12238         local dmngid=$(getent group $ACLDMN | cut -d: -f 3)
12239         local grpgid=$(getent group $ACLGRP | cut -d: -f 3)
12240
12241         if (( $bingid > $grpgid || $dmngid > $grpgid )); then
12242                 echo "group '$ACLGRP' has low gid=$grpgid, use '$TSTUSR'"
12243                 ACLGRP="$TSTUSR"
12244                 if ! getent group $ACLGRP; then
12245                         echo "cannot find group '$ACLGRP', adding it"
12246                         cat /etc/group
12247                         add_group 60000 $ACLGRP
12248                 fi
12249                 grpgid=$(getent group $ACLGRP | cut -d: -f 3)
12250                 if (( $bingid > $grpgid || $dmngid > $grpgid )); then
12251                         cat /etc/group
12252                         skip_env "$ACLGRP gid=$grpgid less than $bingid|$dmngid"
12253                 fi
12254         fi
12255
12256         gpasswd -a $ACLDMN $ACLBIN ||
12257                 error "setting client group failed"             # LU-5641
12258         do_facet mds1 gpasswd -a $ACLDMN $ACLBIN ||
12259                 error "setting MDS group failed"                # LU-5641
12260
12261         declare -a identity_old
12262
12263         for num in $(seq $MDSCOUNT); do
12264                 switch_identity $num true || identity_old[$num]=$?
12265         done
12266
12267         SAVE_UMASK=$(umask)
12268         umask 0022
12269         mkdir -p $DIR/$tdir
12270         cd $DIR/$tdir
12271
12272         run_acl_subtest cp $ACLBIN $ACLDMN $ACLGRP
12273         run_acl_subtest getfacl-noacl $ACLBIN $ACLDMN $ACLGRP
12274         run_acl_subtest misc $ACLBIN $ACLDMN $ACLGRP
12275         run_acl_subtest permissions $ACLBIN $ACLDMN $ACLGRP
12276         # LU-1482 mdd: Setting xattr are properly checked with and without ACLs
12277         # CentOS7- uses nobody=99, while newer distros use nobody=65534
12278         if ! id -u $ACLNBD ||
12279            (( $(id -u nobody) != $(do_facet mds1 id -u nobody) )); then
12280                 ACLNBD="nfsnobody"
12281                 if ! id -u $ACLNBD; then
12282                         ACLNBD=""
12283                 fi
12284         fi
12285         if [[ -n "$ACLNBD" ]] && ! getent group $ACLNBD; then
12286                 add_group $(id -u $ACLNBD) $ACLNBD
12287                 if ! getent group $ACLNBD; then
12288                         ACLNBD=""
12289                 fi
12290         fi
12291         if (( $MDS1_VERSION > $(version_code 2.8.55) )) &&
12292            [[ -n "$ACLNBD" ]] && which setfattr; then
12293                 run_acl_subtest permissions_xattr \
12294                         $ACLBIN $ACLDMN $ACLGRP $ACLNBD
12295         elif [[ -z "$ACLNBD" ]]; then
12296                 echo "skip 'permission_xattr' test - missing 'nobody' user/grp"
12297         else
12298                 echo "skip 'permission_xattr' test - missing setfattr command"
12299         fi
12300         run_acl_subtest setfacl $ACLBIN $ACLDMN $ACLGRP
12301
12302         # inheritance test got from HP
12303         cp $LUSTRE/tests/acl/make-tree . || error "cannot copy make-tree"
12304         chmod +x make-tree || error "chmod +x failed"
12305         run_acl_subtest inheritance $ACLBIN $ACLDMN $ACLGRP
12306         rm -f make-tree
12307
12308         echo "LU-974 ignore umask when acl is enabled..."
12309         run_acl_subtest 974 $ACLBIN $ACLDMN $ACLGRP
12310         if [ $MDSCOUNT -ge 2 ]; then
12311                 run_acl_subtest 974_remote $ACLBIN $ACLDMN $ACLGRP
12312         fi
12313
12314         echo "LU-2561 newly created file is same size as directory..."
12315         if [ "$mds1_FSTYPE" != "zfs" ]; then
12316                 run_acl_subtest 2561 $ACLBIN $ACLDMN $ACLGRP
12317         else
12318                 run_acl_subtest 2561_zfs $ACLBIN $ACLDMN $ACLGRP
12319         fi
12320
12321         run_acl_subtest 4924 $ACLBIN $ACLDMN $ACLGRP
12322
12323         cd $SAVE_PWD
12324         umask $SAVE_UMASK
12325
12326         for num in $(seq $MDSCOUNT); do
12327                 if [ "${identity_old[$num]}" = 1 ]; then
12328                         switch_identity $num false || identity_old[$num]=$?
12329                 fi
12330         done
12331 }
12332 run_test 103a "acl test"
12333
12334 test_103b() {
12335         declare -a pids
12336         local U
12337
12338         stack_trap "rm -f $DIR/$tfile.*"
12339         for U in {0..511}; do
12340                 {
12341                 local O=$(printf "%04o" $U)
12342
12343                 umask $(printf "%04o" $((511 ^ $O)))
12344                 $LFS setstripe -c 1 $DIR/$tfile.s$O
12345                 local S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.s$O))
12346
12347                 (( $S == ($O & 0666) )) ||
12348                         error "lfs setstripe $DIR/$tfile.s$O '$S' != '$O'"
12349
12350                 $LFS setstripe -E16M -c 1 -E1G -S4M $DIR/$tfile.p$O
12351                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.p$O))
12352                 (( $S == ($O & 0666) )) ||
12353                         error "lfs setstripe -E $DIR/$tfile.p$O '$S' != '$O'"
12354
12355                 $LFS setstripe -N2 -c 1 $DIR/$tfile.m$O
12356                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.m$O))
12357                 (( $S == ($O & 0666) )) ||
12358                         error "lfs setstripe -N2 $DIR/$tfile.m$O '$S' != '$O'"
12359                 rm -f $DIR/$tfile.[smp]$0
12360                 } &
12361                 local pid=$!
12362
12363                 # limit the concurrently running threads to 64. LU-11878
12364                 local idx=$((U % 64))
12365                 [ -z "${pids[idx]}" ] || wait ${pids[idx]}
12366                 pids[idx]=$pid
12367         done
12368         wait
12369 }
12370 run_test 103b "umask lfs setstripe"
12371
12372 test_103c() {
12373         mkdir -p $DIR/$tdir
12374         cp -rp $DIR/$tdir $DIR/$tdir.bak
12375
12376         [ -n "$(getfattr -d -m. $DIR/$tdir | grep posix_acl_default)" ] &&
12377                 error "$DIR/$tdir shouldn't contain default ACL"
12378         [ -n "$(getfattr -d -m. $DIR/$tdir.bak | grep posix_acl_default)" ] &&
12379                 error "$DIR/$tdir.bak shouldn't contain default ACL"
12380         true
12381 }
12382 run_test 103c "'cp -rp' won't set empty acl"
12383
12384 test_103e() {
12385         local numacl
12386         local fileacl
12387         local saved_debug=$($LCTL get_param -n debug)
12388
12389         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
12390                 skip "MDS needs to be at least 2.14.52"
12391
12392         large_xattr_enabled || skip_env "ea_inode feature disabled"
12393
12394         mkdir -p $DIR/$tdir
12395         # add big LOV EA to cause reply buffer overflow earlier
12396         $LFS setstripe -C 1000 $DIR/$tdir
12397         lctl set_param mdc.*-mdc*.stats=clear
12398
12399         $LCTL set_param debug=0
12400         stack_trap "$LCTL set_param debug=\"$saved_debug\"" EXIT
12401         stack_trap "$LCTL get_param mdc.*-mdc*.stats" EXIT
12402
12403         # add a large number of default ACLs (expect 8000+ for 2.13+)
12404         for U in {2..7000}; do
12405                 setfacl -d -m user:$U:rwx $DIR/$tdir ||
12406                         error "Able to add just $U default ACLs"
12407         done
12408         numacl=$(getfacl $DIR/$tdir |& grep -c "default:user")
12409         echo "$numacl default ACLs created"
12410
12411         stat $DIR/$tdir || error "Cannot stat directory"
12412         # check file creation
12413         touch $DIR/$tdir/$tfile ||
12414                 error "failed to create $tfile with $numacl default ACLs"
12415         stat $DIR/$tdir/$tfile  || error "Cannot stat file"
12416         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
12417         echo "$fileacl ACLs were inherited"
12418         (( $fileacl == $numacl )) ||
12419                 error "Not all default ACLs were inherited: $numacl != $fileacl"
12420         # check that new ACLs creation adds new ACLs to inherited ACLs
12421         setfacl -m user:19000:rwx $DIR/$tdir/$tfile ||
12422                 error "Cannot set new ACL"
12423         numacl=$((numacl + 1))
12424         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
12425         (( $fileacl == $numacl )) ||
12426                 error "failed to add new ACL: $fileacl != $numacl as expected"
12427         # adds more ACLs to a file to reach their maximum at 8000+
12428         numacl=0
12429         for U in {20000..25000}; do
12430                 setfacl -m user:$U:rwx $DIR/$tdir/$tfile || break
12431                 numacl=$((numacl + 1))
12432         done
12433         echo "Added $numacl more ACLs to the file"
12434         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
12435         echo "Total $fileacl ACLs in file"
12436         stat $DIR/$tdir/$tfile > /dev/null || error "Cannot stat file"
12437         rm -f $DIR/$tdir/$tfile || error "Cannot remove file"
12438         rmdir $DIR/$tdir || error "Cannot remove directory"
12439 }
12440 run_test 103e "inheritance of big amount of default ACLs"
12441
12442 test_103f() {
12443         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
12444                 skip "MDS needs to be at least 2.14.51"
12445
12446         large_xattr_enabled || skip_env "ea_inode feature disabled"
12447
12448         # enable changelog to consume more internal MDD buffers
12449         changelog_register
12450
12451         mkdir -p $DIR/$tdir
12452         # add big LOV EA
12453         $LFS setstripe -C 1000 $DIR/$tdir
12454         setfacl -d -m user:$U:rwx $DIR/$tdir || error "Cannot add default ACLs"
12455         mkdir $DIR/$tdir/inherited || error "failed to create subdirectory"
12456         rmdir $DIR/$tdir/inherited || error "Cannot remove subdirectory"
12457         rmdir $DIR/$tdir || error "Cannot remove directory"
12458 }
12459 run_test 103f "changelog doesn't interfere with default ACLs buffers"
12460
12461 test_104a() {
12462         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12463
12464         touch $DIR/$tfile
12465         lfs df || error "lfs df failed"
12466         lfs df -ih || error "lfs df -ih failed"
12467         lfs df -h $DIR || error "lfs df -h $DIR failed"
12468         lfs df -i $DIR || error "lfs df -i $DIR failed"
12469         lfs df $DIR/$tfile || error "lfs df $DIR/$tfile failed"
12470         lfs df -ih $DIR/$tfile || error "lfs df -ih $DIR/$tfile failed"
12471
12472         local OSC=$(lctl dl | grep OST0000-osc-[^M] | awk '{ print $4 }')
12473         lctl --device %$OSC deactivate
12474         lfs df || error "lfs df with deactivated OSC failed"
12475         lctl --device %$OSC activate
12476         # wait the osc back to normal
12477         wait_osc_import_ready client ost
12478
12479         lfs df || error "lfs df with reactivated OSC failed"
12480         rm -f $DIR/$tfile
12481 }
12482 run_test 104a "lfs df [-ih] [path] test ========================="
12483
12484 test_104b() {
12485         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12486         [ $RUNAS_ID -eq $UID ] &&
12487                 skip_env "RUNAS_ID = UID = $UID -- skipping"
12488
12489         denied_cnt=$(($($RUNAS $LFS check servers 2>&1 |
12490                         grep "Permission denied" | wc -l)))
12491         if [ $denied_cnt -ne 0 ]; then
12492                 error "lfs check servers test failed"
12493         fi
12494 }
12495 run_test 104b "$RUNAS lfs check servers test ===================="
12496
12497 #
12498 # Verify $1 is within range of $2.
12499 # Success when $1 is within range. That is, when $1 is >= 2% of $2 and
12500 # $1 is <= 2% of $2. Else Fail.
12501 #
12502 value_in_range() {
12503         # Strip all units (M, G, T)
12504         actual=$(echo $1 | tr -d A-Z)
12505         expect=$(echo $2 | tr -d A-Z)
12506
12507         expect_lo=$(($expect * 98 / 100)) # 2% below
12508         expect_hi=$(($expect * 102 / 100)) # 2% above
12509
12510         # permit 2% drift above and below
12511         (( $actual >= $expect_lo && $actual <= $expect_hi ))
12512 }
12513
12514 test_104c() {
12515         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12516         [ "$ost1_FSTYPE" == "zfs" ] || skip "zfs only test"
12517
12518         local ost_param="osd-zfs.$FSNAME-OST0000."
12519         local mdt_param="osd-zfs.$FSNAME-MDT0000."
12520         local ofacets=$(get_facets OST)
12521         local mfacets=$(get_facets MDS)
12522         local saved_ost_blocks=
12523         local saved_mdt_blocks=
12524
12525         echo "Before recordsize change"
12526         lfs_df=($($LFS df -h | grep "filesystem_summary:"))
12527         df=($(df -h | grep "$MOUNT"$))
12528
12529         # For checking.
12530         echo "lfs output : ${lfs_df[*]}"
12531         echo "df  output : ${df[*]}"
12532
12533         for facet in ${ofacets//,/ }; do
12534                 if [ -z $saved_ost_blocks ]; then
12535                         saved_ost_blocks=$(do_facet $facet \
12536                                 lctl get_param -n $ost_param.blocksize)
12537                         echo "OST Blocksize: $saved_ost_blocks"
12538                 fi
12539                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
12540                 do_facet $facet zfs set recordsize=32768 $ost
12541         done
12542
12543         # BS too small. Sufficient for functional testing.
12544         for facet in ${mfacets//,/ }; do
12545                 if [ -z $saved_mdt_blocks ]; then
12546                         saved_mdt_blocks=$(do_facet $facet \
12547                                 lctl get_param -n $mdt_param.blocksize)
12548                         echo "MDT Blocksize: $saved_mdt_blocks"
12549                 fi
12550                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
12551                 do_facet $facet zfs set recordsize=32768 $mdt
12552         done
12553
12554         # Give new values chance to reflect change
12555         sleep 2
12556
12557         echo "After recordsize change"
12558         lfs_df_after=($($LFS df -h | grep "filesystem_summary:"))
12559         df_after=($(df -h | grep "$MOUNT"$))
12560
12561         # For checking.
12562         echo "lfs output : ${lfs_df_after[*]}"
12563         echo "df  output : ${df_after[*]}"
12564
12565         # Verify lfs df
12566         value_in_range ${lfs_df_after[1]%.*} ${lfs_df[1]%.*} ||
12567                 error "lfs_df bytes: ${lfs_df_after[1]%.*} != ${lfs_df[1]%.*}"
12568         value_in_range ${lfs_df_after[2]%.*} ${lfs_df[2]%.*} ||
12569                 error "lfs_df used: ${lfs_df_after[2]%.*} != ${lfs_df[2]%.*}"
12570         value_in_range ${lfs_df_after[3]%.*} ${lfs_df[3]%.*} ||
12571                 error "lfs_df avail: ${lfs_df_after[3]%.*} != ${lfs_df[3]%.*}"
12572
12573         # Verify df
12574         value_in_range ${df_after[1]%.*} ${df[1]%.*} ||
12575                 error "df bytes: ${df_after[1]%.*} != ${df[1]%.*}"
12576         value_in_range ${df_after[2]%.*} ${df[2]%.*} ||
12577                 error "df used: ${df_after[2]%.*} != ${df[2]%.*}"
12578         value_in_range ${df_after[3]%.*} ${df[3]%.*} ||
12579                 error "df avail: ${df_after[3]%.*} != ${df[3]%.*}"
12580
12581         # Restore MDT recordize back to original
12582         for facet in ${mfacets//,/ }; do
12583                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
12584                 do_facet $facet zfs set recordsize=$saved_mdt_blocks $mdt
12585         done
12586
12587         # Restore OST recordize back to original
12588         for facet in ${ofacets//,/ }; do
12589                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
12590                 do_facet $facet zfs set recordsize=$saved_ost_blocks $ost
12591         done
12592
12593         return 0
12594 }
12595 run_test 104c "Verify df vs lfs_df stays same after recordsize change"
12596
12597 test_104d() {
12598         (( $RUNAS_ID != $UID )) ||
12599                 skip_env "RUNAS_ID = UID = $UID -- skipping"
12600
12601         (( $CLIENT_VERSION >= $(version_code 2.15.51) )) ||
12602                 skip "lustre version doesn't support lctl dl with non-root"
12603
12604         # debugfs only allows root users to access files, so the
12605         # previous move of the "devices" file to debugfs broke
12606         # "lctl dl" for non-root users. The LU-9680 Netlink
12607         # interface again allows non-root users to list devices.
12608         [ "$($RUNAS $LCTL dl | wc -l)" -ge 3 ] ||
12609                 error "lctl dl doesn't work for non root"
12610
12611         ost_count="$($RUNAS $LCTL dl | grep $FSNAME-OST* | wc -l)"
12612         [ "$ost_count" -eq $OSTCOUNT ]  ||
12613                 error "lctl dl reports wrong number of OST devices"
12614
12615         mdt_count="$($RUNAS $LCTL dl | grep $FSNAME-MDT* | wc -l)"
12616         [ "$mdt_count" -eq $MDSCOUNT ]  ||
12617                 error "lctl dl reports wrong number of MDT devices"
12618 }
12619 run_test 104d "$RUNAS lctl dl test"
12620
12621 test_105a() {
12622         # doesn't work on 2.4 kernels
12623         touch $DIR/$tfile
12624         if $(flock_is_enabled); then
12625                 flocks_test 1 on -f $DIR/$tfile || error "fail flock on"
12626         else
12627                 flocks_test 1 off -f $DIR/$tfile || error "fail flock off"
12628         fi
12629         rm -f $DIR/$tfile
12630 }
12631 run_test 105a "flock when mounted without -o flock test ========"
12632
12633 test_105b() {
12634         touch $DIR/$tfile
12635         if $(flock_is_enabled); then
12636                 flocks_test 1 on -c $DIR/$tfile || error "fail flock on"
12637         else
12638                 flocks_test 1 off -c $DIR/$tfile || error "fail flock off"
12639         fi
12640         rm -f $DIR/$tfile
12641 }
12642 run_test 105b "fcntl when mounted without -o flock test ========"
12643
12644 test_105c() {
12645         touch $DIR/$tfile
12646         if $(flock_is_enabled); then
12647                 flocks_test 1 on -l $DIR/$tfile || error "fail flock on"
12648         else
12649                 flocks_test 1 off -l $DIR/$tfile || error "fail flock off"
12650         fi
12651         rm -f $DIR/$tfile
12652 }
12653 run_test 105c "lockf when mounted without -o flock test"
12654
12655 test_105d() { # bug 15924
12656         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12657
12658         test_mkdir $DIR/$tdir
12659         flock_is_enabled || skip_env "mount w/o flock enabled"
12660         #define OBD_FAIL_LDLM_CP_CB_WAIT  0x315
12661         $LCTL set_param fail_loc=0x80000315
12662         flocks_test 2 $DIR/$tdir
12663 }
12664 run_test 105d "flock race (should not freeze) ========"
12665
12666 test_105e() { # bug 22660 && 22040
12667         flock_is_enabled || skip_env "mount w/o flock enabled"
12668
12669         touch $DIR/$tfile
12670         flocks_test 3 $DIR/$tfile
12671 }
12672 run_test 105e "Two conflicting flocks from same process"
12673
12674 test_106() { #bug 10921
12675         test_mkdir $DIR/$tdir
12676         $DIR/$tdir && error "exec $DIR/$tdir succeeded"
12677         chmod 777 $DIR/$tdir || error "chmod $DIR/$tdir failed"
12678 }
12679 run_test 106 "attempt exec of dir followed by chown of that dir"
12680
12681 test_107() {
12682         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12683
12684         CDIR=`pwd`
12685         local file=core
12686
12687         cd $DIR
12688         rm -f $file
12689
12690         local save_pattern=$(sysctl -n kernel.core_pattern)
12691         local save_uses_pid=$(sysctl -n kernel.core_uses_pid)
12692         sysctl -w kernel.core_pattern=$file
12693         sysctl -w kernel.core_uses_pid=0
12694
12695         ulimit -c unlimited
12696         sleep 60 &
12697         SLEEPPID=$!
12698
12699         sleep 1
12700
12701         kill -s 11 $SLEEPPID
12702         wait $SLEEPPID
12703         if [ -e $file ]; then
12704                 size=`stat -c%s $file`
12705                 [ $size -eq 0 ] && error "Fail to create core file $file"
12706         else
12707                 error "Fail to create core file $file"
12708         fi
12709         rm -f $file
12710         sysctl -w kernel.core_pattern=$save_pattern
12711         sysctl -w kernel.core_uses_pid=$save_uses_pid
12712         cd $CDIR
12713 }
12714 run_test 107 "Coredump on SIG"
12715
12716 test_110() {
12717         test_mkdir $DIR/$tdir
12718         test_mkdir $DIR/$tdir/$(str_repeat 'a' 255)
12719         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/$(str_repeat 'b' 256) &&
12720                 error "mkdir with 256 char should fail, but did not"
12721         touch $DIR/$tdir/$(str_repeat 'x' 255) ||
12722                 error "create with 255 char failed"
12723         touch $DIR/$tdir/$(str_repeat 'y' 256) &&
12724                 error "create with 256 char should fail, but did not"
12725
12726         ls -l $DIR/$tdir
12727         rm -rf $DIR/$tdir
12728 }
12729 run_test 110 "filename length checking"
12730
12731 test_116a() { # was previously test_116()
12732         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12733         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12734         remote_mds_nodsh && skip "remote MDS with nodsh"
12735
12736         echo -n "Free space priority "
12737         do_facet $SINGLEMDS lctl get_param -n lo[vd].*-mdtlov.qos_prio_free |
12738                 head -n1
12739         declare -a AVAIL
12740         free_min_max
12741
12742         [ $MINV -eq 0 ] && skip "no free space in OST$MINI, skip"
12743         [ $MINV -gt 10000000 ] && skip "too much free space in OST$MINI, skip"
12744         stack_trap simple_cleanup_common
12745
12746         # Check if we need to generate uneven OSTs
12747         test_mkdir -p $DIR/$tdir/OST${MINI}
12748         local FILL=$((MINV / 4))
12749         local DIFF=$((MAXV - MINV))
12750         local DIFF2=$((DIFF * 100 / MINV))
12751
12752         local threshold=$(do_facet $SINGLEMDS \
12753                 lctl get_param -n *.*MDT0000-mdtlov.qos_threshold_rr | head -n1)
12754         threshold=${threshold%%%}
12755         echo -n "Check for uneven OSTs: "
12756         echo -n "diff=${DIFF}KB (${DIFF2}%) must be > ${threshold}% ..."
12757
12758         if [[ $DIFF2 -gt $threshold ]]; then
12759                 echo "ok"
12760                 echo "Don't need to fill OST$MINI"
12761         else
12762                 # generate uneven OSTs. Write 2% over the QOS threshold value
12763                 echo "no"
12764                 DIFF=$((threshold - DIFF2 + 2))
12765                 DIFF2=$((MINV * DIFF / 100))
12766                 echo "Fill $DIFF% remaining space in OST$MINI with ${DIFF2}KB"
12767                 $LFS setstripe -i $MINI -c 1 $DIR/$tdir/OST${MINI} ||
12768                         error "setstripe failed"
12769                 DIFF=$((DIFF2 / 2048))
12770                 i=0
12771                 while [ $i -lt $DIFF ]; do
12772                         i=$((i + 1))
12773                         dd if=/dev/zero of=$DIR/$tdir/OST${MINI}/$tfile-$i \
12774                                 bs=2M count=1 2>/dev/null
12775                         echo -n .
12776                 done
12777                 echo .
12778                 sync
12779                 sleep_maxage
12780                 free_min_max
12781         fi
12782
12783         DIFF=$((MAXV - MINV))
12784         DIFF2=$((DIFF * 100 / MINV))
12785         echo -n "diff=$DIFF=$DIFF2% must be > $threshold% for QOS mode..."
12786         if [ $DIFF2 -gt $threshold ]; then
12787                 echo "ok"
12788         else
12789                 skip "QOS imbalance criteria not met"
12790         fi
12791
12792         MINI1=$MINI
12793         MINV1=$MINV
12794         MAXI1=$MAXI
12795         MAXV1=$MAXV
12796
12797         # now fill using QOS
12798         $LFS setstripe -c 1 $DIR/$tdir
12799         FILL=$((FILL / 200))
12800         if [ $FILL -gt 600 ]; then
12801                 FILL=600
12802         fi
12803         echo "writing $FILL files to QOS-assigned OSTs"
12804         i=0
12805         while [ $i -lt $FILL ]; do
12806                 i=$((i + 1))
12807                 dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=200k \
12808                         count=1 2>/dev/null
12809                 echo -n .
12810         done
12811         echo "wrote $i 200k files"
12812         sync
12813         sleep_maxage
12814
12815         echo "Note: free space may not be updated, so measurements might be off"
12816         free_min_max
12817         DIFF2=$((MAXV - MINV))
12818         echo "free space delta: orig $DIFF final $DIFF2"
12819         [ $DIFF2 -gt $DIFF ] && echo "delta got worse!"
12820         DIFF=$((MINV1 - ${AVAIL[$MINI1]}))
12821         echo "Wrote ${DIFF}KB to smaller OST $MINI1"
12822         DIFF2=$((MAXV1 - ${AVAIL[$MAXI1]}))
12823         echo "Wrote ${DIFF2}KB to larger OST $MAXI1"
12824         if [[ $DIFF -gt 0 ]]; then
12825                 FILL=$((DIFF2 * 100 / DIFF - 100))
12826                 echo "Wrote ${FILL}% more data to larger OST $MAXI1"
12827         fi
12828
12829         # Figure out which files were written where
12830         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
12831                awk '/'$MINI1': / {print $2; exit}')
12832         echo $UUID
12833         MINC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
12834         echo "$MINC files created on smaller OST $MINI1"
12835         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
12836                awk '/'$MAXI1': / {print $2; exit}')
12837         echo $UUID
12838         MAXC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
12839         echo "$MAXC files created on larger OST $MAXI1"
12840         if [[ $MINC -gt 0 ]]; then
12841                 FILL=$((MAXC * 100 / MINC - 100))
12842                 echo "Wrote ${FILL}% more files to larger OST $MAXI1"
12843         fi
12844         [[ $MAXC -gt $MINC ]] ||
12845                 error_ignore LU-9 "stripe QOS didn't balance free space"
12846 }
12847 run_test 116a "stripe QOS: free space balance ==================="
12848
12849 test_116b() { # LU-2093
12850         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12851         remote_mds_nodsh && skip "remote MDS with nodsh"
12852
12853 #define OBD_FAIL_MDS_OSC_CREATE_FAIL     0x147
12854         local old_rr=$(do_facet $SINGLEMDS lctl get_param -n \
12855                        lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr | head -1)
12856         [ -z "$old_rr" ] && skip "no QOS"
12857         do_facet $SINGLEMDS lctl set_param \
12858                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=0
12859         mkdir -p $DIR/$tdir
12860         do_facet $SINGLEMDS lctl set_param fail_loc=0x147
12861         createmany -o $DIR/$tdir/f- 20 || error "can't create"
12862         do_facet $SINGLEMDS lctl set_param fail_loc=0
12863         rm -rf $DIR/$tdir
12864         do_facet $SINGLEMDS lctl set_param \
12865                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=$old_rr
12866 }
12867 run_test 116b "QoS shouldn't LBUG if not enough OSTs found on the 2nd pass"
12868
12869 test_117() # bug 10891
12870 {
12871         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12872
12873         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
12874         #define OBD_FAIL_OST_SETATTR_CREDITS 0x21e
12875         lctl set_param fail_loc=0x21e
12876         > $DIR/$tfile || error "truncate failed"
12877         lctl set_param fail_loc=0
12878         echo "Truncate succeeded."
12879         rm -f $DIR/$tfile
12880 }
12881 run_test 117 "verify osd extend =========="
12882
12883 NO_SLOW_RESENDCOUNT=4
12884 export OLD_RESENDCOUNT=""
12885 set_resend_count () {
12886         local PROC_RESENDCOUNT="osc.${FSNAME}-OST*-osc-*.resend_count"
12887         OLD_RESENDCOUNT=$(lctl get_param -n $PROC_RESENDCOUNT | head -n1)
12888         lctl set_param -n $PROC_RESENDCOUNT $1
12889         echo resend_count is set to $(lctl get_param -n $PROC_RESENDCOUNT)
12890 }
12891
12892 # for reduce test_118* time (b=14842)
12893 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
12894
12895 # Reset async IO behavior after error case
12896 reset_async() {
12897         FILE=$DIR/reset_async
12898
12899         # Ensure all OSCs are cleared
12900         $LFS setstripe -c -1 $FILE
12901         dd if=/dev/zero of=$FILE bs=64k count=$OSTCOUNT
12902         sync
12903         rm $FILE
12904 }
12905
12906 test_118a() #bug 11710
12907 {
12908         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12909
12910         reset_async
12911
12912         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12913         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12914         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
12915
12916         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12917                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12918                 return 1;
12919         fi
12920         rm -f $DIR/$tfile
12921 }
12922 run_test 118a "verify O_SYNC works =========="
12923
12924 test_118b()
12925 {
12926         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12927         remote_ost_nodsh && skip "remote OST with nodsh"
12928
12929         reset_async
12930
12931         #define OBD_FAIL_SRV_ENOENT 0x217
12932         set_nodes_failloc "$(osts_nodes)" 0x217
12933         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12934         RC=$?
12935         set_nodes_failloc "$(osts_nodes)" 0
12936         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12937         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12938                     grep -c writeback)
12939
12940         if [[ $RC -eq 0 ]]; then
12941                 error "Must return error due to dropped pages, rc=$RC"
12942                 return 1;
12943         fi
12944
12945         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12946                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12947                 return 1;
12948         fi
12949
12950         echo "Dirty pages not leaked on ENOENT"
12951
12952         # Due to the above error the OSC will issue all RPCs syncronously
12953         # until a subsequent RPC completes successfully without error.
12954         $MULTIOP $DIR/$tfile Ow4096yc
12955         rm -f $DIR/$tfile
12956
12957         return 0
12958 }
12959 run_test 118b "Reclaim dirty pages on fatal error =========="
12960
12961 test_118c()
12962 {
12963         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12964
12965         # for 118c, restore the original resend count, LU-1940
12966         [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] &&
12967                                 set_resend_count $OLD_RESENDCOUNT
12968         remote_ost_nodsh && skip "remote OST with nodsh"
12969
12970         reset_async
12971
12972         #define OBD_FAIL_OST_EROFS               0x216
12973         set_nodes_failloc "$(osts_nodes)" 0x216
12974
12975         # multiop should block due to fsync until pages are written
12976         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
12977         MULTIPID=$!
12978         sleep 1
12979
12980         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
12981                 error "Multiop failed to block on fsync, pid=$MULTIPID"
12982         fi
12983
12984         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12985                     grep -c writeback)
12986         if [[ $WRITEBACK -eq 0 ]]; then
12987                 error "No page in writeback, writeback=$WRITEBACK"
12988         fi
12989
12990         set_nodes_failloc "$(osts_nodes)" 0
12991         wait $MULTIPID
12992         RC=$?
12993         if [[ $RC -ne 0 ]]; then
12994                 error "Multiop fsync failed, rc=$RC"
12995         fi
12996
12997         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12998         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12999                     grep -c writeback)
13000         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13001                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13002         fi
13003
13004         rm -f $DIR/$tfile
13005         echo "Dirty pages flushed via fsync on EROFS"
13006         return 0
13007 }
13008 run_test 118c "Fsync blocks on EROFS until dirty pages are flushed =========="
13009
13010 # continue to use small resend count to reduce test_118* time (b=14842)
13011 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
13012
13013 test_118d()
13014 {
13015         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13016         remote_ost_nodsh && skip "remote OST with nodsh"
13017
13018         reset_async
13019
13020         #define OBD_FAIL_OST_BRW_PAUSE_BULK
13021         set_nodes_failloc "$(osts_nodes)" 0x214
13022         # multiop should block due to fsync until pages are written
13023         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
13024         MULTIPID=$!
13025         sleep 1
13026
13027         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
13028                 error "Multiop failed to block on fsync, pid=$MULTIPID"
13029         fi
13030
13031         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13032                     grep -c writeback)
13033         if [[ $WRITEBACK -eq 0 ]]; then
13034                 error "No page in writeback, writeback=$WRITEBACK"
13035         fi
13036
13037         wait $MULTIPID || error "Multiop fsync failed, rc=$?"
13038         set_nodes_failloc "$(osts_nodes)" 0
13039
13040         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13041         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13042                     grep -c writeback)
13043         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13044                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13045         fi
13046
13047         rm -f $DIR/$tfile
13048         echo "Dirty pages gaurenteed flushed via fsync"
13049         return 0
13050 }
13051 run_test 118d "Fsync validation inject a delay of the bulk =========="
13052
13053 test_118f() {
13054         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13055
13056         reset_async
13057
13058         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
13059         lctl set_param fail_loc=0x8000040a
13060
13061         # Should simulate EINVAL error which is fatal
13062         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13063         RC=$?
13064         if [[ $RC -eq 0 ]]; then
13065                 error "Must return error due to dropped pages, rc=$RC"
13066         fi
13067
13068         lctl set_param fail_loc=0x0
13069
13070         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
13071         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13072         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13073                     grep -c writeback)
13074         if [[ $LOCKED -ne 0 ]]; then
13075                 error "Locked pages remain in cache, locked=$LOCKED"
13076         fi
13077
13078         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13079                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13080         fi
13081
13082         rm -f $DIR/$tfile
13083         echo "No pages locked after fsync"
13084
13085         reset_async
13086         return 0
13087 }
13088 run_test 118f "Simulate unrecoverable OSC side error =========="
13089
13090 test_118g() {
13091         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13092
13093         reset_async
13094
13095         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
13096         lctl set_param fail_loc=0x406
13097
13098         # simulate local -ENOMEM
13099         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13100         RC=$?
13101
13102         lctl set_param fail_loc=0
13103         if [[ $RC -eq 0 ]]; then
13104                 error "Must return error due to dropped pages, rc=$RC"
13105         fi
13106
13107         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
13108         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13109         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13110                         grep -c writeback)
13111         if [[ $LOCKED -ne 0 ]]; then
13112                 error "Locked pages remain in cache, locked=$LOCKED"
13113         fi
13114
13115         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13116                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13117         fi
13118
13119         rm -f $DIR/$tfile
13120         echo "No pages locked after fsync"
13121
13122         reset_async
13123         return 0
13124 }
13125 run_test 118g "Don't stay in wait if we got local -ENOMEM  =========="
13126
13127 test_118h() {
13128         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13129         remote_ost_nodsh && skip "remote OST with nodsh"
13130
13131         reset_async
13132
13133         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
13134         set_nodes_failloc "$(osts_nodes)" 0x20e
13135         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
13136         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13137         RC=$?
13138
13139         set_nodes_failloc "$(osts_nodes)" 0
13140         if [[ $RC -eq 0 ]]; then
13141                 error "Must return error due to dropped pages, rc=$RC"
13142         fi
13143
13144         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
13145         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13146         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13147                     grep -c writeback)
13148         if [[ $LOCKED -ne 0 ]]; then
13149                 error "Locked pages remain in cache, locked=$LOCKED"
13150         fi
13151
13152         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13153                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13154         fi
13155
13156         rm -f $DIR/$tfile
13157         echo "No pages locked after fsync"
13158
13159         return 0
13160 }
13161 run_test 118h "Verify timeout in handling recoverables errors  =========="
13162
13163 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
13164
13165 test_118i() {
13166         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13167         remote_ost_nodsh && skip "remote OST with nodsh"
13168
13169         reset_async
13170
13171         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
13172         set_nodes_failloc "$(osts_nodes)" 0x20e
13173
13174         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
13175         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
13176         PID=$!
13177         sleep 5
13178         set_nodes_failloc "$(osts_nodes)" 0
13179
13180         wait $PID
13181         RC=$?
13182         if [[ $RC -ne 0 ]]; then
13183                 error "got error, but should be not, rc=$RC"
13184         fi
13185
13186         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
13187         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13188         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
13189         if [[ $LOCKED -ne 0 ]]; then
13190                 error "Locked pages remain in cache, locked=$LOCKED"
13191         fi
13192
13193         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13194                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13195         fi
13196
13197         rm -f $DIR/$tfile
13198         echo "No pages locked after fsync"
13199
13200         return 0
13201 }
13202 run_test 118i "Fix error before timeout in recoverable error  =========="
13203
13204 [ "$SLOW" = "no" ] && set_resend_count 4
13205
13206 test_118j() {
13207         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13208         remote_ost_nodsh && skip "remote OST with nodsh"
13209
13210         reset_async
13211
13212         #define OBD_FAIL_OST_BRW_WRITE_BULK2     0x220
13213         set_nodes_failloc "$(osts_nodes)" 0x220
13214
13215         # return -EIO from OST
13216         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13217         RC=$?
13218         set_nodes_failloc "$(osts_nodes)" 0x0
13219         if [[ $RC -eq 0 ]]; then
13220                 error "Must return error due to dropped pages, rc=$RC"
13221         fi
13222
13223         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
13224         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13225         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
13226         if [[ $LOCKED -ne 0 ]]; then
13227                 error "Locked pages remain in cache, locked=$LOCKED"
13228         fi
13229
13230         # in recoverable error on OST we want resend and stay until it finished
13231         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13232                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13233         fi
13234
13235         rm -f $DIR/$tfile
13236         echo "No pages locked after fsync"
13237
13238         return 0
13239 }
13240 run_test 118j "Simulate unrecoverable OST side error =========="
13241
13242 test_118k()
13243 {
13244         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13245         remote_ost_nodsh && skip "remote OSTs with nodsh"
13246
13247         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
13248         set_nodes_failloc "$(osts_nodes)" 0x20e
13249         test_mkdir $DIR/$tdir
13250
13251         for ((i=0;i<10;i++)); do
13252                 (dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=1M count=10 || \
13253                         error "dd to $DIR/$tdir/$tfile-$i failed" )&
13254                 SLEEPPID=$!
13255                 sleep 0.500s
13256                 kill $SLEEPPID
13257                 wait $SLEEPPID
13258         done
13259
13260         set_nodes_failloc "$(osts_nodes)" 0
13261         rm -rf $DIR/$tdir
13262 }
13263 run_test 118k "bio alloc -ENOMEM and IO TERM handling ========="
13264
13265 test_118l() # LU-646
13266 {
13267         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13268
13269         test_mkdir $DIR/$tdir
13270         $MULTIOP $DIR/$tdir Dy || error "fsync dir failed"
13271         rm -rf $DIR/$tdir
13272 }
13273 run_test 118l "fsync dir"
13274
13275 test_118m() # LU-3066
13276 {
13277         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13278
13279         test_mkdir $DIR/$tdir
13280         $MULTIOP $DIR/$tdir DY || error "fdatasync dir failed"
13281         rm -rf $DIR/$tdir
13282 }
13283 run_test 118m "fdatasync dir ========="
13284
13285 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
13286
13287 test_118n()
13288 {
13289         local begin
13290         local end
13291
13292         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13293         remote_ost_nodsh && skip "remote OSTs with nodsh"
13294
13295         # Sleep to avoid a cached response.
13296         #define OBD_STATFS_CACHE_SECONDS 1
13297         sleep 2
13298
13299         # Inject a 10 second delay in the OST_STATFS handler.
13300         #define OBD_FAIL_OST_STATFS_DELAY 0x242
13301         set_nodes_failloc "$(osts_nodes)" 0x242
13302
13303         begin=$SECONDS
13304         stat --file-system $MOUNT > /dev/null
13305         end=$SECONDS
13306
13307         set_nodes_failloc "$(osts_nodes)" 0
13308
13309         if ((end - begin > 20)); then
13310             error "statfs took $((end - begin)) seconds, expected 10"
13311         fi
13312 }
13313 run_test 118n "statfs() sends OST_STATFS requests in parallel"
13314
13315 test_119a() # bug 11737
13316 {
13317         BSIZE=$((512 * 1024))
13318         directio write $DIR/$tfile 0 1 $BSIZE
13319         # We ask to read two blocks, which is more than a file size.
13320         # directio will indicate an error when requested and actual
13321         # sizes aren't equeal (a normal situation in this case) and
13322         # print actual read amount.
13323         NOB=`directio read $DIR/$tfile 0 2 $BSIZE | awk '/error/ {print $6}'`
13324         if [ "$NOB" != "$BSIZE" ]; then
13325                 error "read $NOB bytes instead of $BSIZE"
13326         fi
13327         rm -f $DIR/$tfile
13328 }
13329 run_test 119a "Short directIO read must return actual read amount"
13330
13331 test_119b() # bug 11737
13332 {
13333         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
13334
13335         $LFS setstripe -c 2 $DIR/$tfile || error "setstripe failed"
13336         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1 || error "dd failed"
13337         sync
13338         $MULTIOP $DIR/$tfile oO_RDONLY:O_DIRECT:r$((2048 * 1024)) ||
13339                 error "direct read failed"
13340         rm -f $DIR/$tfile
13341 }
13342 run_test 119b "Sparse directIO read must return actual read amount"
13343
13344 test_119c() # bug 13099
13345 {
13346         BSIZE=1048576
13347         directio write $DIR/$tfile 3 1 $BSIZE || error "direct write failed"
13348         directio readhole $DIR/$tfile 0 2 $BSIZE || error "reading hole failed"
13349         rm -f $DIR/$tfile
13350 }
13351 run_test 119c "Testing for direct read hitting hole"
13352
13353 test_120a() {
13354         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13355         remote_mds_nodsh && skip "remote MDS with nodsh"
13356         test_mkdir -i0 -c1 $DIR/$tdir
13357         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13358                 skip_env "no early lock cancel on server"
13359
13360         lru_resize_disable mdc
13361         lru_resize_disable osc
13362         cancel_lru_locks mdc
13363         # asynchronous object destroy at MDT could cause bl ast to client
13364         cancel_lru_locks osc
13365
13366         stat $DIR/$tdir > /dev/null
13367         can1=$(do_facet mds1 \
13368                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13369                awk '/ldlm_cancel/ {print $2}')
13370         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13371                awk '/ldlm_bl_callback/ {print $2}')
13372         test_mkdir -i0 -c1 $DIR/$tdir/d1
13373         can2=$(do_facet mds1 \
13374                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13375                awk '/ldlm_cancel/ {print $2}')
13376         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13377                awk '/ldlm_bl_callback/ {print $2}')
13378         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
13379         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
13380         lru_resize_enable mdc
13381         lru_resize_enable osc
13382 }
13383 run_test 120a "Early Lock Cancel: mkdir test"
13384
13385 test_120b() {
13386         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13387         remote_mds_nodsh && skip "remote MDS with nodsh"
13388         test_mkdir $DIR/$tdir
13389         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13390                 skip_env "no early lock cancel on server"
13391
13392         lru_resize_disable mdc
13393         lru_resize_disable osc
13394         cancel_lru_locks mdc
13395         stat $DIR/$tdir > /dev/null
13396         can1=$(do_facet $SINGLEMDS \
13397                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13398                awk '/ldlm_cancel/ {print $2}')
13399         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13400                awk '/ldlm_bl_callback/ {print $2}')
13401         touch $DIR/$tdir/f1
13402         can2=$(do_facet $SINGLEMDS \
13403                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13404                awk '/ldlm_cancel/ {print $2}')
13405         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13406                awk '/ldlm_bl_callback/ {print $2}')
13407         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
13408         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
13409         lru_resize_enable mdc
13410         lru_resize_enable osc
13411 }
13412 run_test 120b "Early Lock Cancel: create test"
13413
13414 test_120c() {
13415         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13416         remote_mds_nodsh && skip "remote MDS with nodsh"
13417         test_mkdir -i0 -c1 $DIR/$tdir
13418         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13419                 skip "no early lock cancel on server"
13420
13421         lru_resize_disable mdc
13422         lru_resize_disable osc
13423         test_mkdir -i0 -c1 $DIR/$tdir/d1
13424         test_mkdir -i0 -c1 $DIR/$tdir/d2
13425         touch $DIR/$tdir/d1/f1
13426         cancel_lru_locks mdc
13427         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 > /dev/null
13428         can1=$(do_facet mds1 \
13429                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13430                awk '/ldlm_cancel/ {print $2}')
13431         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13432                awk '/ldlm_bl_callback/ {print $2}')
13433         ln $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
13434         can2=$(do_facet mds1 \
13435                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13436                awk '/ldlm_cancel/ {print $2}')
13437         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13438                awk '/ldlm_bl_callback/ {print $2}')
13439         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
13440         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
13441         lru_resize_enable mdc
13442         lru_resize_enable osc
13443 }
13444 run_test 120c "Early Lock Cancel: link test"
13445
13446 test_120d() {
13447         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13448         remote_mds_nodsh && skip "remote MDS with nodsh"
13449         test_mkdir -i0 -c1 $DIR/$tdir
13450         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13451                 skip_env "no early lock cancel on server"
13452
13453         lru_resize_disable mdc
13454         lru_resize_disable osc
13455         touch $DIR/$tdir
13456         cancel_lru_locks mdc
13457         stat $DIR/$tdir > /dev/null
13458         can1=$(do_facet mds1 \
13459                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13460                awk '/ldlm_cancel/ {print $2}')
13461         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13462                awk '/ldlm_bl_callback/ {print $2}')
13463         chmod a+x $DIR/$tdir
13464         can2=$(do_facet mds1 \
13465                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13466                awk '/ldlm_cancel/ {print $2}')
13467         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13468                awk '/ldlm_bl_callback/ {print $2}')
13469         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
13470         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
13471         lru_resize_enable mdc
13472         lru_resize_enable osc
13473 }
13474 run_test 120d "Early Lock Cancel: setattr test"
13475
13476 test_120e() {
13477         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13478         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13479                 skip_env "no early lock cancel on server"
13480         remote_mds_nodsh && skip "remote MDS with nodsh"
13481
13482         local dlmtrace_set=false
13483
13484         test_mkdir -i0 -c1 $DIR/$tdir
13485         lru_resize_disable mdc
13486         lru_resize_disable osc
13487         ! $LCTL get_param debug | grep -q dlmtrace &&
13488                 $LCTL set_param debug=+dlmtrace && dlmtrace_set=true
13489         dd if=/dev/zero of=$DIR/$tdir/f1 count=1
13490         cancel_lru_locks mdc
13491         cancel_lru_locks osc
13492         dd if=$DIR/$tdir/f1 of=/dev/null
13493         stat $DIR/$tdir $DIR/$tdir/f1 > /dev/null
13494         # XXX client can not do early lock cancel of OST lock
13495         # during unlink (LU-4206), so cancel osc lock now.
13496         sleep 2
13497         cancel_lru_locks osc
13498         can1=$(do_facet mds1 \
13499                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13500                awk '/ldlm_cancel/ {print $2}')
13501         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13502                awk '/ldlm_bl_callback/ {print $2}')
13503         unlink $DIR/$tdir/f1
13504         sleep 5
13505         can2=$(do_facet mds1 \
13506                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13507                awk '/ldlm_cancel/ {print $2}')
13508         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13509                awk '/ldlm_bl_callback/ {print $2}')
13510         [ $can1 -ne $can2 ] && error "$((can2 - can1)) cancel RPC occured" &&
13511                 $LCTL dk $TMP/cancel.debug.txt
13512         [ $blk1 -ne $blk2 ] && error "$((blk2 - blk1)) blocking RPC occured" &&
13513                 $LCTL dk $TMP/blocking.debug.txt
13514         $dlmtrace_set && $LCTL set_param debug=-dlmtrace
13515         lru_resize_enable mdc
13516         lru_resize_enable osc
13517 }
13518 run_test 120e "Early Lock Cancel: unlink test"
13519
13520 test_120f() {
13521         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13522         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13523                 skip_env "no early lock cancel on server"
13524         remote_mds_nodsh && skip "remote MDS with nodsh"
13525
13526         test_mkdir -i0 -c1 $DIR/$tdir
13527         lru_resize_disable mdc
13528         lru_resize_disable osc
13529         test_mkdir -i0 -c1 $DIR/$tdir/d1
13530         test_mkdir -i0 -c1 $DIR/$tdir/d2
13531         dd if=/dev/zero of=$DIR/$tdir/d1/f1 count=1
13532         dd if=/dev/zero of=$DIR/$tdir/d2/f2 count=1
13533         cancel_lru_locks mdc
13534         cancel_lru_locks osc
13535         dd if=$DIR/$tdir/d1/f1 of=/dev/null
13536         dd if=$DIR/$tdir/d2/f2 of=/dev/null
13537         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2 > /dev/null
13538         # XXX client can not do early lock cancel of OST lock
13539         # during rename (LU-4206), so cancel osc lock now.
13540         sleep 2
13541         cancel_lru_locks osc
13542         can1=$(do_facet mds1 \
13543                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13544                awk '/ldlm_cancel/ {print $2}')
13545         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13546                awk '/ldlm_bl_callback/ {print $2}')
13547         mrename $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
13548         sleep 5
13549         can2=$(do_facet mds1 \
13550                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13551                awk '/ldlm_cancel/ {print $2}')
13552         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13553                awk '/ldlm_bl_callback/ {print $2}')
13554         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
13555         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
13556         lru_resize_enable mdc
13557         lru_resize_enable osc
13558 }
13559 run_test 120f "Early Lock Cancel: rename test"
13560
13561 test_120g() {
13562         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13563         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13564                 skip_env "no early lock cancel on server"
13565         remote_mds_nodsh && skip "remote MDS with nodsh"
13566
13567         lru_resize_disable mdc
13568         lru_resize_disable osc
13569         count=10000
13570         echo create $count files
13571         test_mkdir $DIR/$tdir
13572         cancel_lru_locks mdc
13573         cancel_lru_locks osc
13574         t0=$(date +%s)
13575
13576         can0=$(do_facet $SINGLEMDS \
13577                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13578                awk '/ldlm_cancel/ {print $2}')
13579         blk0=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13580                awk '/ldlm_bl_callback/ {print $2}')
13581         createmany -o $DIR/$tdir/f $count
13582         sync
13583         can1=$(do_facet $SINGLEMDS \
13584                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13585                awk '/ldlm_cancel/ {print $2}')
13586         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13587                awk '/ldlm_bl_callback/ {print $2}')
13588         t1=$(date +%s)
13589         echo total: $((can1-can0)) cancels, $((blk1-blk0)) blockings
13590         echo rm $count files
13591         rm -r $DIR/$tdir
13592         sync
13593         can2=$(do_facet $SINGLEMDS \
13594                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13595                awk '/ldlm_cancel/ {print $2}')
13596         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13597                awk '/ldlm_bl_callback/ {print $2}')
13598         t2=$(date +%s)
13599         echo total: $count removes in $((t2-t1))
13600         echo total: $((can2-can1)) cancels, $((blk2-blk1)) blockings
13601         sleep 2
13602         # wait for commitment of removal
13603         lru_resize_enable mdc
13604         lru_resize_enable osc
13605 }
13606 run_test 120g "Early Lock Cancel: performance test"
13607
13608 test_121() { #bug #10589
13609         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13610
13611         rm -rf $DIR/$tfile
13612         writes=$(LANG=C dd if=/dev/zero of=$DIR/$tfile count=1 2>&1 | awk -F '+' '/out$/ {print $1}')
13613 #define OBD_FAIL_LDLM_CANCEL_RACE        0x310
13614         lctl set_param fail_loc=0x310
13615         cancel_lru_locks osc > /dev/null
13616         reads=$(LANG=C dd if=$DIR/$tfile of=/dev/null 2>&1 | awk -F '+' '/in$/ {print $1}')
13617         lctl set_param fail_loc=0
13618         [[ $reads -eq $writes ]] ||
13619                 error "read $reads blocks, must be $writes blocks"
13620 }
13621 run_test 121 "read cancel race ========="
13622
13623 test_123a_base() { # was test 123, statahead(bug 11401)
13624         local lsx="$1"
13625
13626         ost_set_temp_seq_width_all $DATA_SEQ_MAX_WIDTH
13627
13628         SLOWOK=0
13629         if ! grep -q "processor.*: 1" /proc/cpuinfo; then
13630                 log "testing UP system. Performance may be lower than expected."
13631                 SLOWOK=1
13632         fi
13633         running_in_vm && SLOWOK=1
13634
13635         $LCTL set_param mdc.*.batch_stats=0
13636
13637         rm -rf $DIR/$tdir
13638         test_mkdir $DIR/$tdir
13639         NUMFREE=$(df -i -P $DIR | tail -n 1 | awk '{ print $4 }')
13640         [[ $NUMFREE -gt 100000 ]] && NUMFREE=100000 || NUMFREE=$((NUMFREE-1000))
13641         MULT=10
13642         for ((i=100, j=0; i<=$NUMFREE; j=$i, i=$((i * MULT)) )); do
13643                 createmany -o $DIR/$tdir/$tfile $j $((i - j))
13644
13645                 max=$(lctl get_param -n llite.*.statahead_max | head -n 1)
13646                 lctl set_param -n llite.*.statahead_max 0
13647                 lctl get_param llite.*.statahead_max
13648                 cancel_lru_locks mdc
13649                 cancel_lru_locks osc
13650                 stime=$(date +%s)
13651                 time $lsx $DIR/$tdir | wc -l
13652                 etime=$(date +%s)
13653                 delta=$((etime - stime))
13654                 log "$lsx $i files without statahead: $delta sec"
13655                 lctl set_param llite.*.statahead_max=$max
13656
13657                 swrong=$(lctl get_param -n llite.*.statahead_stats |
13658                          awk '/statahead.wrong:/ { print $NF }')
13659                 lctl get_param -n llite.*.statahead_max | grep '[0-9]'
13660                 cancel_lru_locks mdc
13661                 cancel_lru_locks osc
13662                 stime=$(date +%s)
13663                 time $lsx $DIR/$tdir | wc -l
13664                 etime=$(date +%s)
13665                 delta_sa=$((etime - stime))
13666                 log "$lsx $i files with statahead: $delta_sa sec"
13667                 lctl get_param -n llite.*.statahead_stats
13668                 ewrong=$(lctl get_param -n llite.*.statahead_stats |
13669                          awk '/statahead.wrong:/ { print $NF }')
13670
13671                 [[ $swrong -lt $ewrong ]] &&
13672                         log "statahead was stopped, maybe too many locks held!"
13673                 [[ $delta -eq 0 || $delta_sa -eq 0 ]] && continue
13674
13675                 if (( $delta_sa*100 > $delta*105 && $delta_sa > $delta+2)); then
13676                         max=$(lctl get_param -n llite.*.statahead_max |
13677                                 head -n 1)
13678                         lctl set_param -n llite.*.statahead_max 0
13679                         lctl get_param llite.*.statahead_max
13680                         cancel_lru_locks mdc
13681                         cancel_lru_locks osc
13682                         stime=$(date +%s)
13683                         time $lsx $DIR/$tdir | wc -l
13684                         etime=$(date +%s)
13685                         delta=$((etime - stime))
13686                         log "$lsx $i files again without statahead: $delta sec"
13687                         lctl set_param llite.*.statahead_max=$max
13688                         if (( $delta_sa*100 > delta*105 && delta_sa > delta+2 )); then
13689                                 if [ $SLOWOK -eq 0 ]; then
13690                                         error "$lsx $i files is slower with statahead!"
13691                                 else
13692                                         log "$lsx $i files is slower with statahead!"
13693                                 fi
13694                                 break
13695                         fi
13696                 fi
13697
13698                 [ $delta -gt 20 ] && break
13699                 [ $delta -gt 8 ] && MULT=$((50 / delta))
13700                 [ "$SLOW" = "no" -a $delta -gt 5 ] && break
13701         done
13702         log "$lsx done"
13703
13704         stime=$(date +%s)
13705         rm -r $DIR/$tdir
13706         sync
13707         etime=$(date +%s)
13708         delta=$((etime - stime))
13709         log "rm -r $DIR/$tdir/: $delta seconds"
13710         log "rm done"
13711         lctl get_param -n llite.*.statahead_stats
13712         $LCTL get_param mdc.*.batch_stats
13713 }
13714
13715 test_123aa() {
13716         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13717
13718         test_123a_base "ls -l"
13719 }
13720 run_test 123aa "verify statahead work"
13721
13722 test_123ab() {
13723         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13724
13725         statx_supported || skip_env "Test must be statx() syscall supported"
13726
13727         test_123a_base "$STATX -l"
13728 }
13729 run_test 123ab "verify statahead work by using statx"
13730
13731 test_123ac() {
13732         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13733
13734         statx_supported || skip_env "Test must be statx() syscall supported"
13735
13736         local rpcs_before
13737         local rpcs_after
13738         local agl_before
13739         local agl_after
13740
13741         cancel_lru_locks $OSC
13742         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
13743         agl_before=$($LCTL get_param -n llite.*.statahead_stats |
13744                      awk '/agl.total:/ { print $NF }')
13745         test_123a_base "$STATX -c \"%n %i %A %h %u %g %W %X %Z\" -D"
13746         test_123a_base "$STATX --cached=always -D"
13747         agl_after=$($LCTL get_param -n llite.*.statahead_stats |
13748                     awk '/agl.total:/ { print $NF }')
13749         [ $agl_before -eq $agl_after ] ||
13750                 error "Should not trigger AGL thread - $agl_before:$agl_after"
13751         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
13752         [ $rpcs_after -eq $rpcs_before ] ||
13753                 error "$STATX should not send glimpse RPCs to $OSC"
13754 }
13755 run_test 123ac "verify statahead work by using statx without glimpse RPCs"
13756
13757 test_batch_statahead() {
13758         local max=$1
13759         local batch_max=$2
13760         local num=10000
13761         local batch_rpcs
13762         local unbatch_rpcs
13763         local hit_total
13764
13765         echo -e "\nbatching: statahead_max=$max statahead_batch_max=$batch_max"
13766         $LCTL set_param mdc.*.batch_stats=0
13767         $LCTL set_param llite.*.statahead_max=$max
13768         $LCTL set_param llite.*.statahead_batch_max=$batch_max
13769         # Verify that batched statahead is faster than one without statahead
13770         test_123a_base "ls -l"
13771
13772         stack_trap "rm -rf $DIR/$tdir" EXIT
13773         mkdir $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
13774         createmany -o $DIR/$tdir/$tfile $num || error "failed to create files"
13775
13776         # unbatched statahead
13777         $LCTL set_param llite.*.statahead_batch_max=0
13778         $LCTL set_param llite.*.statahead_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         unbatch_rpcs=$(calc_stats mdc.*.stats ldlm_ibits_enqueue)
13784         sleep 2
13785         hit_total=$($LCTL get_param -n llite.*.statahead_stats |
13786                     awk '/hit.total:/ { print $NF }')
13787         # hit ratio should be larger than 75% (7500).
13788         (( $hit_total > 7500 )) ||
13789                 error "unbatched statahead hit count ($hit_total) is too low"
13790
13791         # batched statahead
13792         $LCTL set_param llite.*.statahead_batch_max=$batch_max
13793         $LCTL set_param llite.*.statahead_stats=clear
13794         $LCTL set_param mdc.*.batch_stats=clear
13795         $LCTL set_param mdc.*.stats=clear
13796         cancel_lru_locks mdc
13797         cancel_lru_locks osc
13798         time ls -l $DIR/$tdir | wc -l
13799         batch_rpcs=$(calc_stats mdc.*.stats mds_batch)
13800         # wait for statahead thread to quit and update statahead stats
13801         sleep 2
13802         hit_total=$($LCTL get_param -n llite.*.statahead_stats |
13803                     awk '/hit.total:/ { print $NF }')
13804         # hit ratio should be larger than 75% (7500).
13805         (( $hit_total > 7500 )) ||
13806                 error "batched statahead hit count ($hit_total) is too low"
13807
13808         echo "unbatched RPCs: $unbatch_rpcs, batched RPCs: $batch_rpcs"
13809         (( $unbatch_rpcs > $batch_rpcs )) ||
13810                 error "batched statahead does not reduce RPC count"
13811         $LCTL get_param mdc.*.batch_stats
13812 }
13813
13814 test_123ad() {
13815         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13816
13817         (( $MDS1_VERSION >= $(version_code 2.15.53) )) ||
13818                 skip "Need server version at least 2.15.53"
13819
13820         local max
13821         local batch_max
13822
13823         max=$($LCTL get_param -n llite.*.statahead_max | head -n 1)
13824         batch_max=$($LCTL get_param -n llite.*.statahead_batch_max | head -n 1)
13825
13826         stack_trap "$LCTL set_param llite.*.statahead_max=$max" EXIT
13827         stack_trap "$LCTL set_param llite.*.statahead_batch_max=$batch_max" EXIT
13828
13829         test_batch_statahead 32 32
13830         test_batch_statahead 2048 256
13831 }
13832 run_test 123ad "Verify batching statahead works correctly"
13833
13834 test_123b () { # statahead(bug 15027)
13835         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13836
13837         test_mkdir $DIR/$tdir
13838         createmany -o $DIR/$tdir/$tfile-%d 1000
13839
13840         cancel_lru_locks mdc
13841         cancel_lru_locks osc
13842
13843 #define OBD_FAIL_MDC_GETATTR_ENQUEUE     0x803
13844         lctl set_param fail_loc=0x80000803
13845         ls -lR $DIR/$tdir > /dev/null
13846         log "ls done"
13847         lctl set_param fail_loc=0x0
13848         lctl get_param -n llite.*.statahead_stats
13849         rm -r $DIR/$tdir
13850         sync
13851
13852 }
13853 run_test 123b "not panic with network error in statahead enqueue (bug 15027)"
13854
13855 test_123c() {
13856         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
13857
13858         test_mkdir -i 0 -c 1 $DIR/$tdir.0
13859         test_mkdir -i 1 -c 1 $DIR/$tdir.1
13860         touch $DIR/$tdir.1/{1..3}
13861         mv $DIR/$tdir.1/{1..3} $DIR/$tdir.0
13862
13863         remount_client $MOUNT
13864
13865         $MULTIOP $DIR/$tdir.0 Q
13866
13867         # let statahead to complete
13868         ls -l $DIR/$tdir.0 > /dev/null
13869
13870         testid=$(echo $TESTNAME | tr '_' ' ')
13871         dmesg | tac | sed "/$testid/,$ d" | grep "Can not initialize inode" &&
13872                 error "statahead warning" || true
13873 }
13874 run_test 123c "Can not initialize inode warning on DNE statahead"
13875
13876 test_123d() {
13877         local num=100
13878         local swrong
13879         local ewrong
13880
13881         test_mkdir -c -1 $DIR/$tdir || error "test_mkdir $DIR/$tdir failed"
13882         $LFS setdirstripe -D -c $MDSCOUNT $DIR/$tdir ||
13883                 error "setdirstripe $DIR/$tdir failed"
13884         createmany -d $DIR/$tdir/$tfile $num || error "createmany $num failed"
13885         remount_client $MOUNT
13886         $LCTL get_param llite.*.statahead_max
13887         $LCTL set_param llite.*.statahead_stats=0 ||
13888                 error "clear statahead_stats failed"
13889         swrong=$(lctl get_param -n llite.*.statahead_stats |
13890                  awk '/statahead.wrong:/ { print $NF }')
13891         ls -l $DIR/$tdir || error "ls -l $DIR/$tdir failed"
13892         # wait for statahead thread finished to update hit/miss stats.
13893         sleep 1
13894         $LCTL get_param -n llite.*.statahead_stats
13895         ewrong=$(lctl get_param -n llite.*.statahead_stats |
13896                  awk '/statahead.wrong:/ { print $NF }')
13897         (( $swrong == $ewrong )) ||
13898                 log "statahead was stopped, maybe too many locks held!"
13899 }
13900 run_test 123d "Statahead on striped directories works correctly"
13901
13902 test_123e() {
13903         local max
13904         local batch_max
13905         local dir=$DIR/$tdir
13906
13907         mkdir $dir || error "mkdir $dir failed"
13908         $LFS setstripe -C 32 $dir || error "setstripe $dir failed"
13909         stack_trap "rm -rf $dir"
13910
13911         touch $dir/$tfile.{0..1000} || error "touch 1000 files failed"
13912
13913         max=$($LCTL get_param -n llite.*.statahead_max | head -n 1)
13914         batch_max=$($LCTL get_param -n llite.*.statahead_batch_max | head -n 1)
13915         stack_trap "$LCTL set_param llite.*.statahead_max=$max" EXIT
13916         stack_trap "$LCTL set_param llite.*.statahead_batch_max=$batch_max" EXIT
13917
13918         $LCTL set_param llite.*.statahead_max=2048
13919         $LCTL set_param llite.*.statahead_batch_max=1024
13920
13921         ls -l $dir
13922         $LCTL get_param mdc.*.batch_stats
13923         $LCTL get_param llite.*.statahead_*
13924 }
13925 run_test 123e "statahead with large wide striping"
13926
13927 test_123f() {
13928         local max
13929         local batch_max
13930         local dir=$DIR/$tdir
13931
13932         mkdir $dir || error "mkdir $dir failed"
13933         $LFS setstripe -C 1000 $dir || error "setstripe $dir failed"
13934         stack_trap "rm -rf $dir"
13935
13936         touch $dir/$tfile.{0..200} || error "touch 200 files failed"
13937
13938         max=$($LCTL get_param -n llite.*.statahead_max | head -n 1)
13939         batch_max=$($LCTL get_param -n llite.*.statahead_batch_max | head -n 1)
13940
13941         $LCTL set_param llite.*.statahead_max=64
13942         $LCTL set_param llite.*.statahead_batch_max=64
13943
13944         ls -l $dir
13945         lctl get_param mdc.*.batch_stats
13946         lctl get_param llite.*.statahead_*
13947
13948         $LCTL set_param llite.*.statahead_max=$max
13949         $LCTL set_param llite.*.statahead_batch_max=$batch_max
13950 }
13951 run_test 123f "Retry mechanism with large wide striping files"
13952
13953 test_124a() {
13954         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13955         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13956                 skip_env "no lru resize on server"
13957
13958         local NR=2000
13959
13960         test_mkdir $DIR/$tdir
13961
13962         log "create $NR files at $DIR/$tdir"
13963         createmany -o $DIR/$tdir/f $NR ||
13964                 error "failed to create $NR files in $DIR/$tdir"
13965
13966         cancel_lru_locks mdc
13967         ls -l $DIR/$tdir > /dev/null
13968
13969         local NSDIR=""
13970         local LRU_SIZE=0
13971         for VALUE in $($LCTL get_param ldlm.namespaces.*mdc-*.lru_size); do
13972                 local PARAM=$(echo ${VALUE[0]} | cut -d "=" -f1)
13973                 LRU_SIZE=$($LCTL get_param -n $PARAM)
13974                 if [[ $LRU_SIZE -gt $(default_lru_size) ]]; then
13975                         NSDIR=$(echo $PARAM | cut -d "." -f1-3)
13976                         log "NSDIR=$NSDIR"
13977                         log "NS=$(basename $NSDIR)"
13978                         break
13979                 fi
13980         done
13981
13982         if [[ -z "$NSDIR" || $LRU_SIZE -lt $(default_lru_size) ]]; then
13983                 skip "Not enough cached locks created!"
13984         fi
13985         log "LRU=$LRU_SIZE"
13986
13987         local SLEEP=30
13988
13989         # We know that lru resize allows one client to hold $LIMIT locks
13990         # for 10h. After that locks begin to be killed by client.
13991         local MAX_HRS=10
13992         local LIMIT=$($LCTL get_param -n $NSDIR.pool.limit)
13993         log "LIMIT=$LIMIT"
13994         if [ $LIMIT -lt $LRU_SIZE ]; then
13995                 skip "Limit is too small $LIMIT"
13996         fi
13997
13998         # Make LVF so higher that sleeping for $SLEEP is enough to _start_
13999         # killing locks. Some time was spent for creating locks. This means
14000         # that up to the moment of sleep finish we must have killed some of
14001         # them (10-100 locks). This depends on how fast ther were created.
14002         # Many of them were touched in almost the same moment and thus will
14003         # be killed in groups.
14004         local LVF=$(($MAX_HRS * 60 * 60 / $SLEEP * $LIMIT / $LRU_SIZE * 100))
14005
14006         # Use $LRU_SIZE_B here to take into account real number of locks
14007         # created in the case of CMD, LRU_SIZE_B != $NR in most of cases
14008         local LRU_SIZE_B=$LRU_SIZE
14009         log "LVF=$LVF"
14010         local OLD_LVF=$($LCTL get_param -n $NSDIR.pool.lock_volume_factor)
14011         log "OLD_LVF=$OLD_LVF"
14012         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $LVF
14013
14014         # Let's make sure that we really have some margin. Client checks
14015         # cached locks every 10 sec.
14016         SLEEP=$((SLEEP+20))
14017         log "Sleep ${SLEEP} sec"
14018         local SEC=0
14019         while ((SEC<$SLEEP)); do
14020                 echo -n "..."
14021                 sleep 5
14022                 SEC=$((SEC+5))
14023                 LRU_SIZE=$($LCTL get_param -n $NSDIR/lru_size)
14024                 echo -n "$LRU_SIZE"
14025         done
14026         echo ""
14027         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $OLD_LVF
14028         local LRU_SIZE_A=$($LCTL get_param -n $NSDIR.lru_size)
14029
14030         [[ $LRU_SIZE_B -gt $LRU_SIZE_A ]] || {
14031                 error "No locks dropped in ${SLEEP}s. LRU size: $LRU_SIZE_A"
14032                 unlinkmany $DIR/$tdir/f $NR
14033                 return
14034         }
14035
14036         log "Dropped "$((LRU_SIZE_B-LRU_SIZE_A))" locks in ${SLEEP}s"
14037         log "unlink $NR files at $DIR/$tdir"
14038         unlinkmany $DIR/$tdir/f $NR
14039 }
14040 run_test 124a "lru resize ======================================="
14041
14042 get_max_pool_limit()
14043 {
14044         local limit=$($LCTL get_param \
14045                       -n ldlm.namespaces.*-MDT0000-mdc-*.pool.limit)
14046         local max=0
14047         for l in $limit; do
14048                 if [[ $l -gt $max ]]; then
14049                         max=$l
14050                 fi
14051         done
14052         echo $max
14053 }
14054
14055 test_124b() {
14056         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14057         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
14058                 skip_env "no lru resize on server"
14059
14060         LIMIT=$(get_max_pool_limit)
14061
14062         NR=$(($(default_lru_size)*20))
14063         if [[ $NR -gt $LIMIT ]]; then
14064                 log "Limit lock number by $LIMIT locks"
14065                 NR=$LIMIT
14066         fi
14067
14068         IFree=$(mdsrate_inodes_available)
14069         if [ $IFree -lt $NR ]; then
14070                 log "Limit lock number by $IFree inodes"
14071                 NR=$IFree
14072         fi
14073
14074         lru_resize_disable mdc
14075         test_mkdir -p $DIR/$tdir/disable_lru_resize
14076
14077         createmany -o $DIR/$tdir/disable_lru_resize/f $NR
14078         log "doing ls -la $DIR/$tdir/disable_lru_resize 3 times"
14079         cancel_lru_locks mdc
14080         stime=`date +%s`
14081         PID=""
14082         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
14083         PID="$PID $!"
14084         sleep 2
14085         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
14086         PID="$PID $!"
14087         sleep 2
14088         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
14089         PID="$PID $!"
14090         wait $PID
14091         etime=`date +%s`
14092         nolruresize_delta=$((etime-stime))
14093         log "ls -la time: $nolruresize_delta seconds"
14094         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
14095         unlinkmany $DIR/$tdir/disable_lru_resize/f $NR
14096
14097         lru_resize_enable mdc
14098         test_mkdir -p $DIR/$tdir/enable_lru_resize
14099
14100         createmany -o $DIR/$tdir/enable_lru_resize/f $NR
14101         log "doing ls -la $DIR/$tdir/enable_lru_resize 3 times"
14102         cancel_lru_locks mdc
14103         stime=`date +%s`
14104         PID=""
14105         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
14106         PID="$PID $!"
14107         sleep 2
14108         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
14109         PID="$PID $!"
14110         sleep 2
14111         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
14112         PID="$PID $!"
14113         wait $PID
14114         etime=`date +%s`
14115         lruresize_delta=$((etime-stime))
14116         log "ls -la time: $lruresize_delta seconds"
14117         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
14118
14119         if [ $lruresize_delta -gt $nolruresize_delta ]; then
14120                 log "ls -la is $(((lruresize_delta - $nolruresize_delta) * 100 / $nolruresize_delta))% slower with lru resize enabled"
14121         elif [ $nolruresize_delta -gt $lruresize_delta ]; then
14122                 log "ls -la is $(((nolruresize_delta - $lruresize_delta) * 100 / $nolruresize_delta))% faster with lru resize enabled"
14123         else
14124                 log "lru resize performs the same with no lru resize"
14125         fi
14126         unlinkmany $DIR/$tdir/enable_lru_resize/f $NR
14127 }
14128 run_test 124b "lru resize (performance test) ======================="
14129
14130 test_124c() {
14131         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14132         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
14133                 skip_env "no lru resize on server"
14134
14135         # cache ununsed locks on client
14136         local nr=100
14137         cancel_lru_locks mdc
14138         test_mkdir $DIR/$tdir
14139         createmany -o $DIR/$tdir/f $nr ||
14140                 error "failed to create $nr files in $DIR/$tdir"
14141         ls -l $DIR/$tdir > /dev/null
14142
14143         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
14144         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
14145         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
14146         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
14147         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
14148
14149         # set lru_max_age to 1 sec
14150         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
14151         echo "sleep $((recalc_p * 2)) seconds..."
14152         sleep $((recalc_p * 2))
14153
14154         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
14155         # restore lru_max_age
14156         $LCTL set_param -n $nsdir.lru_max_age $max_age
14157         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
14158         unlinkmany $DIR/$tdir/f $nr
14159 }
14160 run_test 124c "LRUR cancel very aged locks"
14161
14162 test_124d() {
14163         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14164         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
14165                 skip_env "no lru resize on server"
14166
14167         # cache ununsed locks on client
14168         local nr=100
14169
14170         lru_resize_disable mdc
14171         stack_trap "lru_resize_enable mdc" EXIT
14172
14173         cancel_lru_locks mdc
14174
14175         # asynchronous object destroy at MDT could cause bl ast to client
14176         test_mkdir $DIR/$tdir
14177         createmany -o $DIR/$tdir/f $nr ||
14178                 error "failed to create $nr files in $DIR/$tdir"
14179         stack_trap "unlinkmany $DIR/$tdir/f $nr" EXIT
14180
14181         ls -l $DIR/$tdir > /dev/null
14182
14183         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
14184         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
14185         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
14186         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
14187
14188         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
14189
14190         # set lru_max_age to 1 sec
14191         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
14192         stack_trap "$LCTL set_param -n $nsdir.lru_max_age $max_age" EXIT
14193
14194         echo "sleep $((recalc_p * 2)) seconds..."
14195         sleep $((recalc_p * 2))
14196
14197         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
14198
14199         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
14200 }
14201 run_test 124d "cancel very aged locks if lru-resize diasbaled"
14202
14203 test_125() { # 13358
14204         $LCTL get_param -n llite.*.client_type | grep -q local ||
14205                 skip "must run as local client"
14206         $LCTL get_param -n mdc.*-mdc-*.connect_flags | grep -q acl ||
14207                 skip_env "must have acl enabled"
14208         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
14209
14210         test_mkdir $DIR/$tdir
14211         $LFS setstripe -S 65536 -c -1 $DIR/$tdir || error "setstripe failed"
14212         setfacl -R -m u:$USER0:rwx $DIR/$tdir ||
14213                 error "setfacl $DIR/$tdir failed"
14214         ls -ld $DIR/$tdir || error "cannot access $DIR/$tdir"
14215 }
14216 run_test 125 "don't return EPROTO when a dir has a non-default striping and ACLs"
14217
14218 test_126() { # bug 12829/13455
14219         $GSS && skip_env "must run as gss disabled"
14220         $LCTL get_param -n llite.*.client_type | grep -q local ||
14221                 skip "must run as local client"
14222         [ "$UID" != 0 ] && skip "must run as root, not UID $UID"
14223
14224         $RUNAS -u 0 -g 1 touch $DIR/$tfile || error "touch failed"
14225         gid=`ls -n $DIR/$tfile | awk '{print $4}'`
14226         rm -f $DIR/$tfile
14227         [ $gid -eq "1" ] || error "gid is set to" $gid "instead of 1"
14228 }
14229 run_test 126 "check that the fsgid provided by the client is taken into account"
14230
14231 test_127a() { # bug 15521
14232         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14233         local name count samp unit min max sum sumsq
14234         local tmpfile=$TMP/$tfile.tmp
14235
14236         $LFS setstripe -i 0 -c 1 $DIR/$tfile || error "setstripe failed"
14237         echo "stats before reset"
14238         stack_trap "rm -f $tmpfile"
14239         local now=$(date +%s)
14240
14241         $LCTL get_param osc.*.stats | tee $tmpfile
14242
14243         local snapshot_time=$(awk '/snapshot_time/ { print $2; exit }' $tmpfile)
14244         local start_time=$(awk '/start_time/ { print $2; exit }' $tmpfile)
14245         local elapsed=$(awk '/elapsed_time/ { print $2; exit }' $tmpfile)
14246         local uptime=$(awk '{ print $1 }' /proc/uptime)
14247
14248         # snapshot_time should match POSIX epoch time, allow some delta for VMs
14249         (( ${snapshot_time%\.*} >= $now - 5 &&
14250            ${snapshot_time%\.*} <= $now + 5 )) ||
14251                 error "snapshot_time=$snapshot_time != now=$now"
14252         # elapsed _should_ be from mount, but at least less than uptime
14253         (( ${elapsed%\.*} < ${uptime%\.*} )) ||
14254                 error "elapsed=$elapsed > uptime=$uptime"
14255         (( ${snapshot_time%\.*} - ${start_time%\.*} >= ${elapsed%\.*} - 2 &&
14256            ${snapshot_time%\.*} - ${start_time%\.*} <= ${elapsed%\.*} + 2 )) ||
14257                 error "elapsed=$elapsed != $snapshot_time - $start_time"
14258
14259         $LCTL set_param osc.*.stats=0
14260         local reset=$(date +%s)
14261         local fsize=$((2048 * 1024))
14262
14263         dd if=/dev/zero of=$DIR/$tfile bs=$fsize count=1
14264         cancel_lru_locks osc
14265         dd if=$DIR/$tfile of=/dev/null bs=$fsize
14266
14267         now=$(date +%s)
14268         $LCTL get_param osc.*0000-osc-*.stats > $tmpfile
14269         while read name count samp unit min max sum sumsq; do
14270                 [[ "$samp" == "samples" ]] || continue
14271
14272                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
14273                 [ ! $min ] && error "Missing min value for $name proc entry"
14274                 eval $name=$count || error "Wrong proc format"
14275
14276                 case $name in
14277                 read_bytes|write_bytes)
14278                         [[ "$unit" =~ "bytes" ]] ||
14279                                 error "unit is not 'bytes': $unit"
14280                         (( $min >= 4096 )) || error "min is too small: $min"
14281                         (( $min <= $fsize )) || error "min is too big: $min"
14282                         (( $max >= 4096 )) || error "max is too small: $max"
14283                         (( $max <= $fsize )) || error "max is too big: $max"
14284                         (( $sum == $fsize )) || error "sum is wrong: $sum"
14285                         (( $sumsq >= ($fsize / 4096) * (4096 * 4096) )) ||
14286                                 error "sumsquare is too small: $sumsq"
14287                         (( $sumsq <= $fsize * $fsize )) ||
14288                                 error "sumsquare is too big: $sumsq"
14289                         ;;
14290                 ost_read|ost_write)
14291                         [[ "$unit" =~ "usec" ]] ||
14292                                 error "unit is not 'usec': $unit"
14293                         ;;
14294                 *)      ;;
14295                 esac
14296         done < $tmpfile
14297
14298         #check that we actually got some stats
14299         [ "$read_bytes" ] || error "Missing read_bytes stats"
14300         [ "$write_bytes" ] || error "Missing write_bytes stats"
14301         [ "$read_bytes" != 0 ] || error "no read done"
14302         [ "$write_bytes" != 0 ] || error "no write done"
14303
14304         snapshot_time=$(awk '/snapshot_time/ { print $2; exit }' $tmpfile)
14305         start_time=$(awk '/start_time/ { print $2; exit }' $tmpfile)
14306         elapsed=$(awk '/elapsed_time/ { print $2; exit }' $tmpfile)
14307
14308         # snapshot_time should match POSIX epoch time, allow some delta for VMs
14309         (( ${snapshot_time%\.*} >= $now - 5 &&
14310            ${snapshot_time%\.*} <= $now + 5 )) ||
14311                 error "reset snapshot_time=$snapshot_time != now=$now"
14312         # elapsed should be from time of stats reset
14313         (( ${elapsed%\.*} >= $now - $reset - 2 &&
14314            ${elapsed%\.*} <= $now - $reset + 2 )) ||
14315                 error "reset elapsed=$elapsed > $now - $reset"
14316         (( ${snapshot_time%\.*} - ${start_time%\.*} >= ${elapsed%\.*} - 2 &&
14317            ${snapshot_time%\.*} - ${start_time%\.*} <= ${elapsed%\.*} + 2 )) ||
14318                 error "reset elapsed=$elapsed != $snapshot_time - $start_time"
14319 }
14320 run_test 127a "verify the client stats are sane"
14321
14322 test_127b() { # bug LU-333
14323         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14324         local name count samp unit min max sum sumsq
14325
14326         echo "stats before reset"
14327         $LCTL get_param llite.*.stats
14328         $LCTL set_param llite.*.stats=0
14329
14330         # perform 2 reads and writes so MAX is different from SUM.
14331         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
14332         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
14333         cancel_lru_locks osc
14334         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
14335         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
14336
14337         $LCTL get_param llite.*.stats | grep samples > $TMP/$tfile.tmp
14338         stack_trap "rm -f $TMP/$tfile.tmp"
14339         while read name count samp unit min max sum sumsq; do
14340                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
14341                 eval $name=$count || error "Wrong proc format"
14342
14343                 case $name in
14344                 read_bytes|write_bytes)
14345                         [[ "$unit" =~ "bytes" ]] ||
14346                                 error "unit is not 'bytes': $unit"
14347                         (( $count == 2 )) || error "count is not 2: $count"
14348                         (( $min == $PAGE_SIZE )) ||
14349                                 error "min is not $PAGE_SIZE: $min"
14350                         (( $max == $PAGE_SIZE )) ||
14351                                 error "max is not $PAGE_SIZE: $max"
14352                         (( $sum == $PAGE_SIZE * 2 )) ||
14353                                 error "sum is not $((PAGE_SIZE * 2)): $sum"
14354                         ;;
14355                 read|write)
14356                         [[ "$unit" =~ "usec" ]] ||
14357                                 error "unit is not 'usec': $unit"
14358                         ;;
14359                 *)      ;;
14360                 esac
14361         done < $TMP/$tfile.tmp
14362
14363         #check that we actually got some stats
14364         [ "$read_bytes" ] || error "Missing read_bytes stats"
14365         [ "$write_bytes" ] || error "Missing write_bytes stats"
14366         [ "$read_bytes" != 0 ] || error "no read done"
14367         [ "$write_bytes" != 0 ] || error "no write done"
14368 }
14369 run_test 127b "verify the llite client stats are sane"
14370
14371 test_127c() { # LU-12394
14372         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
14373         local size
14374         local bsize
14375         local reads
14376         local writes
14377         local count
14378
14379         $LCTL set_param llite.*.extents_stats=1
14380         stack_trap "$LCTL set_param llite.*.extents_stats=0" EXIT
14381
14382         # Use two stripes so there is enough space in default config
14383         $LFS setstripe -c 2 $DIR/$tfile
14384
14385         # Extent stats start at 0-4K and go in power of two buckets
14386         # LL_HIST_START = 12 --> 2^12 = 4K
14387         # We do 3K*2^i, so 3K, 6K, 12K, 24K... hitting each bucket.
14388         # We do not do buckets larger than 64 MiB to avoid ENOSPC issues on
14389         # small configs
14390         for size in 3K 6K 12K 24K 48K 96K 192K 384K 768K 1536K 3M 6M 12M 24M 48M;
14391                 do
14392                 # Write and read, 2x each, second time at a non-zero offset
14393                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1
14394                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1 seek=10
14395                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1
14396                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1 seek=10
14397                 rm -f $DIR/$tfile
14398         done
14399
14400         $LCTL get_param llite.*.extents_stats
14401
14402         count=2
14403         for bsize in 4K 8K 16K 32K 64K 128K 256K 512K 1M 2M 4M 8M 16M 32M 64M;
14404                 do
14405                 local bucket=$($LCTL get_param -n llite.*.extents_stats |
14406                                 grep -m 1 $bsize)
14407                 reads=$(echo $bucket | awk '{print $5}')
14408                 writes=$(echo $bucket | awk '{print $9}')
14409                 [ "$reads" -eq $count ] ||
14410                         error "$reads reads in < $bsize bucket, expect $count"
14411                 [ "$writes" -eq $count ] ||
14412                         error "$writes writes in < $bsize bucket, expect $count"
14413         done
14414
14415         # Test mmap write and read
14416         $LCTL set_param llite.*.extents_stats=c
14417         size=512
14418         dd if=/dev/zero of=$DIR/$tfile bs=${size}K count=1
14419         $MULTIOP $DIR/$tfile OSMRUc || error "$MULTIOP $DIR/$tfile failed"
14420         $MULTIOP $DIR/$tfile OSMWUc || error "$MULTIOP $DIR/$tfile failed"
14421
14422         $LCTL get_param llite.*.extents_stats
14423
14424         count=$(((size*1024) / PAGE_SIZE))
14425
14426         bsize=$((2 * PAGE_SIZE / 1024))K
14427
14428         bucket=$($LCTL get_param -n llite.*.extents_stats |
14429                         grep -m 1 $bsize)
14430         reads=$(echo $bucket | awk '{print $5}')
14431         writes=$(echo $bucket | awk '{print $9}')
14432         # mmap writes fault in the page first, creating an additonal read
14433         [ "$reads" -eq $((2 * count)) ] ||
14434                 error "$reads reads in < $bsize bucket, expect $count"
14435         [ "$writes" -eq $count ] ||
14436                 error "$writes writes in < $bsize bucket, expect $count"
14437 }
14438 run_test 127c "test llite extent stats with regular & mmap i/o"
14439
14440 test_128() { # bug 15212
14441         touch $DIR/$tfile
14442         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
14443                 find $DIR/$tfile
14444                 find $DIR/$tfile
14445         EOF
14446
14447         result=$(grep error $TMP/$tfile.log)
14448         rm -f $DIR/$tfile $TMP/$tfile.log
14449         [ -z "$result" ] ||
14450                 error "consecutive find's under interactive lfs failed"
14451 }
14452 run_test 128 "interactive lfs for 2 consecutive find's"
14453
14454 set_dir_limits () {
14455         local mntdev
14456         local canondev
14457         local node
14458
14459         local ldproc=/proc/fs/ldiskfs
14460         local facets=$(get_facets MDS)
14461
14462         for facet in ${facets//,/ }; do
14463                 canondev=$(ldiskfs_canon \
14464                            *.$(convert_facet2label $facet).mntdev $facet)
14465                 do_facet $facet "test -e $ldproc/$canondev/max_dir_size" ||
14466                         ldproc=/sys/fs/ldiskfs
14467                 do_facet $facet "echo $1 >$ldproc/$canondev/max_dir_size"
14468                 do_facet $facet "echo $2 >$ldproc/$canondev/warning_dir_size"
14469         done
14470 }
14471
14472 check_mds_dmesg() {
14473         local facets=$(get_facets MDS)
14474         for facet in ${facets//,/ }; do
14475                 do_facet $facet "dmesg | tail -3 | grep $1" && return 0
14476         done
14477         return 1
14478 }
14479
14480 test_129() {
14481         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14482         [[ $MDS1_VERSION -ge $(version_code 2.5.56) ]] ||
14483                 skip "Need MDS version with at least 2.5.56"
14484         if [ "$mds1_FSTYPE" != ldiskfs ]; then
14485                 skip_env "ldiskfs only test"
14486         fi
14487         remote_mds_nodsh && skip "remote MDS with nodsh"
14488
14489         local ENOSPC=28
14490         local has_warning=false
14491
14492         rm -rf $DIR/$tdir
14493         mkdir -p $DIR/$tdir
14494
14495         # block size of mds1
14496         local maxsize=$(($($LCTL get_param -n mdc.*MDT0000*.blocksize) * 8))
14497         set_dir_limits $maxsize $((maxsize * 6 / 8))
14498         stack_trap "set_dir_limits 0 0"
14499         stack_trap "unlinkmany $DIR/$tdir/file_base_ 2000 || true"
14500         local dirsize=$(stat -c%s "$DIR/$tdir")
14501         local nfiles=0
14502         while (( $dirsize <= $maxsize )); do
14503                 $MCREATE $DIR/$tdir/file_base_$nfiles
14504                 rc=$?
14505                 # check two errors:
14506                 # ENOSPC for ext4 max_dir_size, which has been used since
14507                 # kernel v3.6-rc1-8-gdf981d03ee, lustre v2_4_50_0-79-gaed82035c0
14508                 if (( rc == ENOSPC )); then
14509                         set_dir_limits 0 0
14510                         echo "rc=$rc returned as expected after $nfiles files"
14511
14512                         createmany -o $DIR/$tdir/file_extra_$nfiles. 5 ||
14513                                 error "create failed w/o dir size limit"
14514
14515                         # messages may be rate limited if test is run repeatedly
14516                         check_mds_dmesg '"is approaching max"' ||
14517                                 echo "warning message should be output"
14518                         check_mds_dmesg '"has reached max"' ||
14519                                 echo "reached message should be output"
14520
14521                         dirsize=$(stat -c%s "$DIR/$tdir")
14522
14523                         [[ $dirsize -ge $maxsize ]] && return 0
14524                         error "dirsize $dirsize < $maxsize after $nfiles files"
14525                 elif (( rc != 0 )); then
14526                         break
14527                 fi
14528                 nfiles=$((nfiles + 1))
14529                 dirsize=$(stat -c%s "$DIR/$tdir")
14530         done
14531
14532         error "rc=$rc, size=$dirsize/$maxsize, mdt=$MDSCOUNT, nfiles=$nfiles"
14533 }
14534 run_test 129 "test directory size limit ========================"
14535
14536 OLDIFS="$IFS"
14537 cleanup_130() {
14538         trap 0
14539         IFS="$OLDIFS"
14540         rm -f $DIR/$tfile
14541 }
14542
14543 test_130a() {
14544         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
14545         [[ -z "$filefrag_op" ]] || skip_env "filefrag does not support FIEMAP"
14546
14547         trap cleanup_130 EXIT RETURN
14548
14549         local fm_file=$DIR/$tfile
14550         $LFS setstripe -S 65536 -c 1 $fm_file || error "setstripe on $fm_file"
14551         dd if=/dev/zero of=$fm_file bs=65536 count=1 ||
14552                 error "dd failed for $fm_file"
14553
14554         # LU-1795: test filefrag/FIEMAP once, even if unsupported on ZFS
14555         filefrag -ves $fm_file
14556         local rc=$?
14557         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14558                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14559         (( $rc == 0 )) || error "filefrag $fm_file failed"
14560
14561         filefrag_op=$(filefrag -ve -k $fm_file |
14562                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
14563         local lun=$($LFS getstripe -i $fm_file)
14564
14565         local start_blk=$(echo $filefrag_op | cut -d: -f2 | cut -d. -f1)
14566         IFS=$'\n'
14567         local tot_len=0
14568         for line in $filefrag_op; do
14569                 local frag_lun=$(echo $line | cut -d: -f5)
14570                 local ext_len=$(echo $line | cut -d: -f4)
14571
14572                 if (( $frag_lun != $lun )); then
14573                         error "FIEMAP on 1-stripe file($fm_file) failed"
14574                         return
14575                 fi
14576                 (( tot_len += ext_len ))
14577         done
14578
14579         if (( lun != frag_lun || start_blk != 0 || tot_len != 64 )); then
14580                 error "FIEMAP on 1-stripe file($fm_file) failed"
14581                 return
14582         fi
14583
14584         echo "FIEMAP on single striped file succeeded"
14585 }
14586 run_test 130a "FIEMAP (1-stripe file)"
14587
14588 test_130b() {
14589         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
14590
14591         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
14592         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
14593         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14594                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14595
14596         trap cleanup_130 EXIT RETURN
14597
14598         local fm_file=$DIR/$tfile
14599         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
14600                 error "setstripe on $fm_file"
14601
14602         dd if=/dev/zero of=$fm_file bs=1M count=$OSTCOUNT ||
14603                 error "dd failed on $fm_file"
14604
14605         filefrag -ves $fm_file || error "filefrag $fm_file failed"
14606         filefrag_op=$(filefrag -ve -k $fm_file |
14607                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
14608
14609         local last_lun=$(echo $filefrag_op | cut -d: -f5 |
14610                          sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14611
14612         IFS=$'\n'
14613         local tot_len=0
14614         local num_luns=1
14615
14616         for line in $filefrag_op; do
14617                 local frag_lun=$(echo $line | cut -d: -f5 |
14618                                  sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14619                 local ext_len=$(echo $line | cut -d: -f4)
14620                 if (( $frag_lun != $last_lun )); then
14621                         if (( tot_len != 1024 )); then
14622                                 error "FIEMAP on $fm_file failed; returned len $tot_len for OST $last_lun instead of 1024"
14623                                 return
14624                         else
14625                                 (( num_luns += 1 ))
14626                                 tot_len=0
14627                         fi
14628                 fi
14629                 (( tot_len += ext_len ))
14630                 last_lun=$frag_lun
14631         done
14632         if (( num_luns != $OSTCOUNT || tot_len != 1024 )); then
14633                 error "FIEMAP on $fm_file failed; returned wrong number of luns or wrong len for OST $last_lun"
14634                 return
14635         fi
14636
14637         echo "FIEMAP on $OSTCOUNT-stripe file succeeded"
14638 }
14639 run_test 130b "FIEMAP ($OSTCOUNT-stripe file)"
14640
14641 test_130c() {
14642         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
14643
14644         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
14645         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
14646         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14647                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14648
14649         trap cleanup_130 EXIT RETURN
14650
14651         local fm_file=$DIR/$tfile
14652         $LFS setstripe -S 65536 -c 2 $fm_file || error "setstripe on $fm_file"
14653
14654         dd if=/dev/zero of=$fm_file seek=1 bs=1M count=1 ||
14655                 error "dd failed on $fm_file"
14656
14657         filefrag -ves $fm_file || error "filefrag $fm_file failed"
14658         filefrag_op=$(filefrag -ve -k $fm_file |
14659                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
14660
14661         local last_lun=$(echo $filefrag_op | cut -d: -f5 |
14662                          sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14663
14664         IFS=$'\n'
14665         local tot_len=0
14666         local num_luns=1
14667         for line in $filefrag_op; do
14668                 local frag_lun=$(echo $line | cut -d: -f5 |
14669                                  sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14670                 local ext_len=$(echo $line | cut -d: -f4)
14671                 if (( $frag_lun != $last_lun )); then
14672                         local logical=$(echo $line | cut -d: -f2 | cut -d. -f1)
14673                         if (( logical != 512 )); then
14674                                 error "FIEMAP on $fm_file failed; returned logical start for lun $logical instead of 512"
14675                                 return
14676                         fi
14677                         if (( tot_len != 512 )); then
14678                                 error "FIEMAP on $fm_file failed; returned len $tot_len for OST $last_lun instead of 1024"
14679                                 return
14680                         else
14681                                 (( num_luns += 1 ))
14682                                 tot_len=0
14683                         fi
14684                 fi
14685                 (( tot_len += ext_len ))
14686                 last_lun=$frag_lun
14687         done
14688         if (( num_luns != 2 || tot_len != 512 )); then
14689                 error "FIEMAP on $fm_file failed; returned wrong number of luns or wrong len for OST $last_lun"
14690                 return
14691         fi
14692
14693         echo "FIEMAP on 2-stripe file with hole succeeded"
14694 }
14695 run_test 130c "FIEMAP (2-stripe file with hole)"
14696
14697 test_130d() {
14698         (( $OSTCOUNT >= 3 )) || skip "needs >= 3 OSTs"
14699
14700         filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
14701         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
14702         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14703                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14704
14705         trap cleanup_130 EXIT RETURN
14706
14707         local fm_file=$DIR/$tfile
14708         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
14709                         error "setstripe on $fm_file"
14710
14711         local actual_stripe_count=$($LFS getstripe -c $fm_file)
14712         dd if=/dev/zero of=$fm_file bs=1M count=$actual_stripe_count ||
14713                 error "dd failed on $fm_file"
14714
14715         filefrag -ves $fm_file || error "filefrag $fm_file failed"
14716         filefrag_op=$(filefrag -ve -k $fm_file |
14717                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
14718
14719         local last_lun=$(echo $filefrag_op | cut -d: -f5 |
14720                          sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14721
14722         IFS=$'\n'
14723         local tot_len=0
14724         local num_luns=1
14725         for line in $filefrag_op; do
14726                 local frag_lun=$(echo $line | cut -d: -f5 |
14727                                  sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14728                 local ext_len=$(echo $line | cut -d: -f4)
14729                 if (( $frag_lun != $last_lun )); then
14730                         if (( tot_len != 1024 )); then
14731                                 error "FIEMAP on $fm_file failed; returned len $tot_len for OST $last_lun instead of 1024"
14732                                 return
14733                         else
14734                                 (( num_luns += 1 ))
14735                                 local tot_len=0
14736                         fi
14737                 fi
14738                 (( tot_len += ext_len ))
14739                 last_lun=$frag_lun
14740         done
14741         if (( num_luns != actual_stripe_count || tot_len != 1024 )); then
14742                 error "FIEMAP on $fm_file failed; returned wrong number of luns or wrong len for OST $last_lun"
14743                 return
14744         fi
14745
14746         echo "FIEMAP on N-stripe file succeeded"
14747 }
14748 run_test 130d "FIEMAP (N-stripe file)"
14749
14750 test_130e() {
14751         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
14752
14753         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
14754         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
14755         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14756                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14757
14758         trap cleanup_130 EXIT RETURN
14759
14760         local fm_file=$DIR/$tfile
14761         $LFS setstripe -S 131072 -c 2 $fm_file || error "setstripe on $fm_file"
14762         stack_trap "rm -f $fm_file"
14763
14764         local num_blks=512
14765         local expected_len=$(( (num_blks / 2) * 64 ))
14766         for ((i = 0; i < $num_blks; i++)); do
14767                 dd if=/dev/zero of=$fm_file count=1 bs=64k seek=$((2*$i)) \
14768                         conv=notrunc > /dev/null 2>&1
14769         done
14770
14771         filefrag -ves $fm_file || error "filefrag $fm_file failed"
14772         filefrag_op=$(filefrag -ve -k $fm_file |
14773                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
14774
14775         local last_lun=$(echo $filefrag_op | cut -d: -f5)
14776
14777         IFS=$'\n'
14778         local tot_len=0
14779         local num_luns=1
14780         for line in $filefrag_op; do
14781                 local frag_lun=$(echo $line | cut -d: -f5)
14782                 local ext_len=$(echo $line | cut -d: -f4)
14783                 if (( $frag_lun != $last_lun )); then
14784                         if (( tot_len != $expected_len )); then
14785                                 error "OST$last_lun $tot_len != $expected_len"
14786                         else
14787                                 (( num_luns += 1 ))
14788                                 tot_len=0
14789                         fi
14790                 fi
14791                 (( tot_len += ext_len ))
14792                 last_lun=$frag_lun
14793         done
14794         if (( num_luns != 2 || tot_len != $expected_len )); then
14795                 error "OST$last_lun $num_luns != 2, $tot_len != $expected_len"
14796         fi
14797
14798         echo "FIEMAP with continuation calls succeeded"
14799 }
14800 run_test 130e "FIEMAP (test continuation FIEMAP calls)"
14801
14802 test_130f() {
14803         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
14804         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
14805         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14806                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14807
14808         local fm_file=$DIR/$tfile
14809         $MULTIOP $fm_file oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T33554432c ||
14810                 error "multiop create with lov_delay_create on $fm_file"
14811
14812         filefrag -ves $fm_file || error "filefrag $fm_file failed"
14813         filefrag_extents=$(filefrag -vek $fm_file |
14814                            awk '/extents? found/ { print $2 }')
14815         if (( $filefrag_extents != 0 )); then
14816                 error "$fm_file: filefrag_extents=$filefrag_extents != 0"
14817         fi
14818
14819         rm -f $fm_file
14820 }
14821 run_test 130f "FIEMAP (unstriped file)"
14822
14823 test_130g() {
14824         (( $MDS1_VERSION >= $(version_code 2.12.53) )) ||
14825                 skip "Need MDS version with at least 2.12.53 for overstriping"
14826         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
14827         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
14828         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14829                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14830
14831         local file=$DIR/$tfile
14832         local nr=$((OSTCOUNT * 100))
14833
14834         $LFS setstripe -C $nr $file || error "failed to setstripe -C $nr $file"
14835
14836         stack_trap "rm -f $file"
14837         dd if=/dev/zero of=$file count=$nr bs=1M
14838         sync
14839         nr=$($LFS getstripe -c $file)
14840
14841         local extents=$(filefrag -v $file |
14842                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}' | wc -l)
14843
14844         echo "filefrag list $extents extents in file with stripecount $nr"
14845         if (( extents < nr )); then
14846                 $LFS getstripe $file
14847                 filefrag -v $file
14848                 error "filefrag printed $extents < $nr extents"
14849         fi
14850 }
14851 run_test 130g "FIEMAP (overstripe file)"
14852
14853 # Test for writev/readv
14854 test_131a() {
14855         rwv -f $DIR/$tfile -w -n 3 524288 1048576 1572864 ||
14856                 error "writev test failed"
14857         rwv -f $DIR/$tfile -r -v -n 2 1572864 1048576 ||
14858                 error "readv failed"
14859         rm -f $DIR/$tfile
14860 }
14861 run_test 131a "test iov's crossing stripe boundary for writev/readv"
14862
14863 test_131b() {
14864         local fsize=$((524288 + 1048576 + 1572864))
14865         rwv -f $DIR/$tfile -w -a -n 3 524288 1048576 1572864 &&
14866                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
14867                         error "append writev test failed"
14868
14869         ((fsize += 1572864 + 1048576))
14870         rwv -f $DIR/$tfile -w -a -n 2 1572864 1048576 &&
14871                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
14872                         error "append writev test failed"
14873         rm -f $DIR/$tfile
14874 }
14875 run_test 131b "test append writev"
14876
14877 test_131c() {
14878         rwv -f $DIR/$tfile -w -d -n 1 1048576 || return 0
14879         error "NOT PASS"
14880 }
14881 run_test 131c "test read/write on file w/o objects"
14882
14883 test_131d() {
14884         rwv -f $DIR/$tfile -w -n 1 1572864
14885         NOB=`rwv -f $DIR/$tfile -r -n 3 524288 524288 1048576 | awk '/error/ {print $6}'`
14886         if [ "$NOB" != 1572864 ]; then
14887                 error "Short read filed: read $NOB bytes instead of 1572864"
14888         fi
14889         rm -f $DIR/$tfile
14890 }
14891 run_test 131d "test short read"
14892
14893 test_131e() {
14894         rwv -f $DIR/$tfile -w -s 1048576 -n 1 1048576
14895         rwv -f $DIR/$tfile -r -z -s 0 -n 1 524288 || \
14896         error "read hitting hole failed"
14897         rm -f $DIR/$tfile
14898 }
14899 run_test 131e "test read hitting hole"
14900
14901 check_stats() {
14902         local facet=$1
14903         local op=$2
14904         local want=${3:-0}
14905         local res
14906
14907         # open             11 samples [usecs] 468 4793 13658 35791898
14908         case $facet in
14909         mds*) res=($(do_facet $facet \
14910                    $LCTL get_param mdt.$FSNAME-MDT0000.md_stats | grep "$op"))
14911                  ;;
14912         ost*) res=($(do_facet $facet \
14913                   $LCTL get_param obdfilter.$FSNAME-OST0000.stats | grep "$op"))
14914                  ;;
14915         *) error "Wrong facet '$facet'" ;;
14916         esac
14917         [[ -n "$res" ]] || error "counter for $op on $facet not incremented"
14918         # if $want is zero, it means any stat increment is ok.
14919         if (( $want > 0 )); then
14920                 local count=${res[1]}
14921
14922                 if (( $count != $want )); then
14923                         if [[ $facet =~ "mds" ]]; then
14924                                 do_nodes $(comma_list $(mdts_nodes)) \
14925                                         $LCTL get_param mdt.*.md_stats
14926                         else
14927                                 do_nodes $(comma_list $(osts-nodes)) \
14928                                         $LCTL get_param obdfilter.*.stats
14929                         fi
14930                         error "The $op counter on $facet is $count, not $want"
14931                 fi
14932         fi
14933 }
14934
14935 test_133a() {
14936         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14937         remote_ost_nodsh && skip "remote OST with nodsh"
14938         remote_mds_nodsh && skip "remote MDS with nodsh"
14939         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
14940                 skip_env "MDS doesn't support rename stats"
14941
14942         local testdir=$DIR/${tdir}/stats_testdir
14943
14944         mkdir -p $DIR/${tdir}
14945
14946         # clear stats.
14947         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14948         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
14949
14950         # verify mdt stats first.
14951         mkdir_on_mdt0 ${testdir} || error "mkdir_on_mdt0 failed"
14952         check_stats $SINGLEMDS "mkdir" 1
14953
14954         # clear "open" from "lfs mkdir" above
14955         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14956         touch ${testdir}/${tfile} || error "touch failed"
14957         check_stats $SINGLEMDS "open" 1
14958         check_stats $SINGLEMDS "close" 1
14959         [ $MDS1_VERSION -ge $(version_code 2.8.54) ] && {
14960                 mknod ${testdir}/${tfile}-pipe p || error "mknod failed"
14961                 check_stats $SINGLEMDS "mknod" 2
14962         }
14963         rm -f ${testdir}/${tfile}-pipe || error "pipe remove failed"
14964         check_stats $SINGLEMDS "unlink" 1
14965         rm -f ${testdir}/${tfile} || error "file remove failed"
14966         check_stats $SINGLEMDS "unlink" 2
14967
14968         # remove working dir and check mdt stats again.
14969         rmdir ${testdir} || error "rmdir failed"
14970         check_stats $SINGLEMDS "rmdir" 1
14971
14972         local testdir1=$DIR/${tdir}/stats_testdir1
14973         mkdir_on_mdt0 -p ${testdir}
14974         mkdir_on_mdt0 -p ${testdir1}
14975         touch ${testdir1}/test1
14976         mv ${testdir1}/test1 ${testdir} || error "file crossdir rename"
14977         check_stats $SINGLEMDS "crossdir_rename" 1
14978
14979         mv ${testdir}/test1 ${testdir}/test0 || error "file samedir rename"
14980         check_stats $SINGLEMDS "samedir_rename" 1
14981
14982         rm -rf $DIR/${tdir}
14983 }
14984 run_test 133a "Verifying MDT stats ========================================"
14985
14986 test_133b() {
14987         local res
14988
14989         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14990         remote_ost_nodsh && skip "remote OST with nodsh"
14991         remote_mds_nodsh && skip "remote MDS with nodsh"
14992
14993         local testdir=$DIR/${tdir}/stats_testdir
14994
14995         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
14996         mkdir_on_mdt0 ${testdir} || error "mkdir_on_mdt0 failed"
14997         touch ${testdir}/${tfile} || error "touch failed"
14998         cancel_lru_locks mdc
14999
15000         # clear stats.
15001         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15002         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
15003
15004         # extra mdt stats verification.
15005         chmod 444 ${testdir}/${tfile} || error "chmod failed"
15006         check_stats $SINGLEMDS "setattr" 1
15007         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15008         if [ $MDS1_VERSION -ne $(version_code 2.2.0) ]
15009         then            # LU-1740
15010                 ls -l ${testdir}/${tfile} > /dev/null|| error "ls failed"
15011                 check_stats $SINGLEMDS "getattr" 1
15012         fi
15013         rm -rf $DIR/${tdir}
15014
15015         # when DNE is enabled, MDT uses STATFS RPC to ping other targets
15016         # so the check below is not reliable
15017         [ $MDSCOUNT -eq 1 ] || return 0
15018
15019         # Sleep to avoid a cached response.
15020         #define OBD_STATFS_CACHE_SECONDS 1
15021         sleep 2
15022         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15023         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
15024         $LFS df || error "lfs failed"
15025         check_stats $SINGLEMDS "statfs" 1
15026
15027         # check aggregated statfs (LU-10018)
15028         [ $MDS1_VERSION -lt $(version_code 2.11.54) ] &&
15029                 return 0
15030         [ $CLIENT_VERSION -lt $(version_code 2.11.54) ] &&
15031                 return 0
15032         sleep 2
15033         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15034         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
15035         df $DIR
15036         check_stats $SINGLEMDS "statfs" 1
15037
15038         # We want to check that the client didn't send OST_STATFS to
15039         # ost1 but the MDT also uses OST_STATFS for precreate. So some
15040         # extra care is needed here.
15041         if remote_mds; then
15042                 local nid=$($LCTL list_nids | head -1 | sed  "s/\./\\\./g")
15043                 local param="obdfilter.$FSNAME-OST0000.exports.'$nid'.stats"
15044
15045                 res=$(do_facet ost1 $LCTL get_param $param | grep statfs)
15046                 [ "$res" ] && error "OST got STATFS"
15047         fi
15048
15049         return 0
15050 }
15051 run_test 133b "Verifying extra MDT stats =================================="
15052
15053 test_133c() {
15054         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15055         remote_ost_nodsh && skip "remote OST with nodsh"
15056         remote_mds_nodsh && skip "remote MDS with nodsh"
15057
15058         local testdir=$DIR/$tdir/stats_testdir
15059
15060         test_mkdir -p $testdir
15061
15062         # verify obdfilter stats.
15063         $LFS setstripe -c 1 -i 0 $testdir/$tfile
15064         sync
15065         cancel_lru_locks osc
15066         wait_delete_completed
15067
15068         # clear stats.
15069         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15070         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
15071
15072         dd if=/dev/zero of=$testdir/$tfile conv=notrunc bs=512k count=1 ||
15073                 error "dd failed"
15074         sync
15075         cancel_lru_locks osc
15076         check_stats ost1 "write" 1
15077
15078         dd if=$testdir/$tfile of=/dev/null bs=1k count=1 || error "dd failed"
15079         check_stats ost1 "read" 1
15080
15081         > $testdir/$tfile || error "truncate failed"
15082         check_stats ost1 "punch" 1
15083
15084         rm -f $testdir/$tfile || error "file remove failed"
15085         wait_delete_completed
15086         check_stats ost1 "destroy" 1
15087
15088         rm -rf $DIR/$tdir
15089 }
15090 run_test 133c "Verifying OST stats ========================================"
15091
15092 order_2() {
15093         local value=$1
15094         local orig=$value
15095         local order=1
15096
15097         while [ $value -ge 2 ]; do
15098                 order=$((order*2))
15099                 value=$((value/2))
15100         done
15101
15102         if [ $orig -gt $order ]; then
15103                 order=$((order*2))
15104         fi
15105         echo $order
15106 }
15107
15108 size_in_KMGT() {
15109     local value=$1
15110     local size=('K' 'M' 'G' 'T');
15111     local i=0
15112     local size_string=$value
15113
15114     while [ $value -ge 1024 ]; do
15115         if [ $i -gt 3 ]; then
15116             #T is the biggest unit we get here, if that is bigger,
15117             #just return XXXT
15118             size_string=${value}T
15119             break
15120         fi
15121         value=$((value >> 10))
15122         if [ $value -lt 1024 ]; then
15123             size_string=${value}${size[$i]}
15124             break
15125         fi
15126         i=$((i + 1))
15127     done
15128
15129     echo $size_string
15130 }
15131
15132 get_rename_size() {
15133         local size=$1
15134         local context=${2:-.}
15135         local sample=$(do_facet $SINGLEMDS $LCTL \
15136                 get_param mdt.$FSNAME-MDT0000.rename_stats |
15137                 grep -A1 $context |
15138                 awk '/ '${size}'/ {print $4}' | sed -e "s/,//g")
15139         echo $sample
15140 }
15141
15142 test_133d() {
15143         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15144         remote_ost_nodsh && skip "remote OST with nodsh"
15145         remote_mds_nodsh && skip "remote MDS with nodsh"
15146         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
15147                 skip_env "MDS doesn't support rename stats"
15148
15149         local testdir1=$DIR/${tdir}/stats_testdir1
15150         local testdir2=$DIR/${tdir}/stats_testdir2
15151         mkdir -p $DIR/${tdir} || error "mkdir $tdir failed"
15152
15153         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
15154
15155         mkdir_on_mdt0 ${testdir1} || error "mkdir $testdir1 failed"
15156         mkdir_on_mdt0 ${testdir2} || error "mkdir $testdir2 failed"
15157
15158         createmany -o $testdir1/test 512 || error "createmany failed"
15159
15160         # check samedir rename size
15161         mv ${testdir1}/test0 ${testdir1}/test_0
15162
15163         local testdir1_size=$(ls -l $DIR/${tdir} |
15164                 awk '/stats_testdir1/ {print $5}')
15165         local testdir2_size=$(ls -l $DIR/${tdir} |
15166                 awk '/stats_testdir2/ {print $5}')
15167
15168         testdir1_size=$(order_2 $testdir1_size)
15169         testdir2_size=$(order_2 $testdir2_size)
15170
15171         testdir1_size=$(size_in_KMGT $testdir1_size)
15172         testdir2_size=$(size_in_KMGT $testdir2_size)
15173
15174         echo "source rename dir size: ${testdir1_size}"
15175         echo "target rename dir size: ${testdir2_size}"
15176
15177         local cmd="do_facet $SINGLEMDS $LCTL "
15178         cmd+="get_param mdt.$FSNAME-MDT0000.rename_stats"
15179
15180         eval $cmd || error "$cmd failed"
15181         local samedir=$($cmd | grep 'same_dir')
15182         local same_sample=$(get_rename_size $testdir1_size)
15183         [ -z "$samedir" ] && error "samedir_rename_size count error"
15184         [[ $same_sample -eq 1 ]] ||
15185                 error "samedir_rename_size error $same_sample"
15186         echo "Check same dir rename stats success"
15187
15188         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
15189
15190         # check crossdir rename size
15191         mv ${testdir1}/test_0 ${testdir2}/test_0
15192
15193         testdir1_size=$(ls -l $DIR/${tdir} |
15194                 awk '/stats_testdir1/ {print $5}')
15195         testdir2_size=$(ls -l $DIR/${tdir} |
15196                 awk '/stats_testdir2/ {print $5}')
15197
15198         testdir1_size=$(order_2 $testdir1_size)
15199         testdir2_size=$(order_2 $testdir2_size)
15200
15201         testdir1_size=$(size_in_KMGT $testdir1_size)
15202         testdir2_size=$(size_in_KMGT $testdir2_size)
15203
15204         echo "source rename dir size: ${testdir1_size}"
15205         echo "target rename dir size: ${testdir2_size}"
15206
15207         eval $cmd || error "$cmd failed"
15208         local crossdir=$($cmd | grep 'crossdir')
15209         local src_sample=$(get_rename_size $testdir1_size crossdir_src)
15210         local tgt_sample=$(get_rename_size $testdir2_size crossdir_tgt)
15211         [ -z "$crossdir" ] && error "crossdir_rename_size count error"
15212         [[ $src_sample -eq 1 ]] ||
15213                 error "crossdir_rename_size error $src_sample"
15214         [[ $tgt_sample -eq 1 ]] ||
15215                 error "crossdir_rename_size error $tgt_sample"
15216         echo "Check cross dir rename stats success"
15217         rm -rf $DIR/${tdir}
15218 }
15219 run_test 133d "Verifying rename_stats ========================================"
15220
15221 test_133e() {
15222         remote_mds_nodsh && skip "remote MDS with nodsh"
15223         remote_ost_nodsh && skip "remote OST with nodsh"
15224         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15225
15226         local testdir=$DIR/${tdir}/stats_testdir
15227         local ctr f0 f1 bs=32768 count=42 sum
15228
15229         mkdir -p ${testdir} || error "mkdir failed"
15230
15231         $LFS setstripe -c 1 -i 0 ${testdir}/${tfile}
15232
15233         for ctr in {write,read}_bytes; do
15234                 sync
15235                 cancel_lru_locks osc
15236
15237                 do_facet ost1 $LCTL set_param -n \
15238                         "obdfilter.*.exports.clear=clear"
15239
15240                 if [ $ctr = write_bytes ]; then
15241                         f0=/dev/zero
15242                         f1=${testdir}/${tfile}
15243                 else
15244                         f0=${testdir}/${tfile}
15245                         f1=/dev/null
15246                 fi
15247
15248                 dd if=$f0 of=$f1 conv=notrunc bs=$bs count=$count || \
15249                         error "dd failed"
15250                 sync
15251                 cancel_lru_locks osc
15252
15253                 sum=$(do_facet ost1 $LCTL get_param \
15254                         "obdfilter.*.exports.*.stats" |
15255                         awk -v ctr=$ctr 'BEGIN { sum = 0 }
15256                                 $1 == ctr { sum += $7 }
15257                                 END { printf("%0.0f", sum) }')
15258
15259                 if ((sum != bs * count)); then
15260                         error "Bad $ctr sum, expected $((bs * count)), got $sum"
15261                 fi
15262         done
15263
15264         rm -rf $DIR/${tdir}
15265 }
15266 run_test 133e "Verifying OST {read,write}_bytes nid stats ================="
15267
15268 test_133f() {
15269         [[ $(lustre_version_code $facet) -ge $(version_code 2.7.65) ]] ||
15270                 skip "too old lustre for get_param -R ($facet_ver)"
15271
15272         # verifying readability.
15273         $LCTL get_param -R '*' &> /dev/null
15274
15275         # Verifing writability with badarea_io.
15276         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
15277         local skipped_params='force_lbug|changelog_mask|daemon_file'
15278         $LCTL list_param -FR '*' | grep '=' | tr -d = |
15279                 egrep -v "$skipped_params" |
15280                 xargs -n 1 find $proc_dirs -name |
15281                 xargs -n 1 badarea_io ||
15282                 error "client badarea_io failed"
15283
15284         # remount the FS in case writes/reads /proc break the FS
15285         cleanup || error "failed to unmount"
15286         setup || error "failed to setup"
15287 }
15288 run_test 133f "Check reads/writes of client lustre proc files with bad area io"
15289
15290 test_133g() {
15291         remote_mds_nodsh && skip "remote MDS with nodsh"
15292         remote_ost_nodsh && skip "remote OST with nodsh"
15293
15294         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
15295         local proc_dirs_str=$(eval echo $proc_dirs)
15296         local skipped_params="'force_lbug|changelog_mask|daemon_file'"
15297         local facet
15298         for facet in mds1 ost1; do
15299                 local facet_ver=$(lustre_version_code $facet)
15300                 if [ $facet_ver -ge $(version_code 2.7.65) ]; then
15301                         do_facet $facet "$LCTL get_param -R '*'" &> /dev/null
15302                 else
15303                         log "$facet: too old lustre for get_param -R"
15304                 fi
15305                 if [ $facet_ver -ge $(version_code 2.5.54) ]; then
15306                         do_facet $facet "$LCTL list_param -FR '*' | grep '=' |
15307                                 tr -d = | egrep -v $skipped_params |
15308                                 xargs -n 1 find $proc_dirs_str -name |
15309                                 xargs -n 1 badarea_io" ||
15310                                         error "$facet badarea_io failed"
15311                 else
15312                         skip_noexit "$facet: too old lustre for get_param -R"
15313                 fi
15314         done
15315
15316         # remount the FS in case writes/reads /proc break the FS
15317         cleanup || error "failed to unmount"
15318         setup || error "failed to setup"
15319 }
15320 run_test 133g "Check reads/writes of server lustre proc files with bad area io"
15321
15322 test_133h() {
15323         remote_mds_nodsh && skip "remote MDS with nodsh"
15324         remote_ost_nodsh && skip "remote OST with nodsh"
15325         [[ $MDS1_VERSION -lt $(version_code 2.9.54) ]] &&
15326                 skip "Need MDS version at least 2.9.54"
15327
15328         local facet
15329         for facet in client mds1 ost1; do
15330                 # Get the list of files that are missing the terminating newline
15331                 local plist=$(do_facet $facet
15332                         $LCTL list_param -FR '*' | grep '=' | tr -d =)
15333                 local ent
15334                 for ent in $plist; do
15335                         local missing=$(do_facet $facet $LCTL get_param $ent \|\
15336                                 awk -v FS='\v' -v RS='\v\v' \
15337                                 "'END { if(NR>0 && \\\$NF !~ /.*\\\n\$/) \
15338                                         print FILENAME}'" 2>/dev/null)
15339                         [ -z $missing ] || {
15340                                 do_facet $facet $LCTL get_param $ent | od -An -tx1
15341                                 error "file does not end with newline: $facet-$ent"
15342                         }
15343                 done
15344         done
15345 }
15346 run_test 133h "Proc files should end with newlines"
15347
15348 test_134a() {
15349         remote_mds_nodsh && skip "remote MDS with nodsh"
15350         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
15351                 skip "Need MDS version at least 2.7.54"
15352
15353         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
15354         cancel_lru_locks mdc
15355
15356         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
15357         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
15358         [ $unused -eq 0 ] || error "$unused locks are not cleared"
15359
15360         local nr=1000
15361         createmany -o $DIR/$tdir/f $nr ||
15362                 error "failed to create $nr files in $DIR/$tdir"
15363         unused=$($LCTL get_param -n $nsdir.lock_unused_count)
15364
15365         #define OBD_FAIL_LDLM_WATERMARK_LOW     0x327
15366         do_facet mds1 $LCTL set_param fail_loc=0x327
15367         do_facet mds1 $LCTL set_param fail_val=500
15368         touch $DIR/$tdir/m
15369
15370         echo "sleep 10 seconds ..."
15371         sleep 10
15372         local lck_cnt=$($LCTL get_param -n $nsdir.lock_unused_count)
15373
15374         do_facet mds1 $LCTL set_param fail_loc=0
15375         do_facet mds1 $LCTL set_param fail_val=0
15376         [ $lck_cnt -lt $unused ] ||
15377                 error "No locks reclaimed, before:$unused, after:$lck_cnt"
15378
15379         rm $DIR/$tdir/m
15380         unlinkmany $DIR/$tdir/f $nr
15381 }
15382 run_test 134a "Server reclaims locks when reaching lock_reclaim_threshold"
15383
15384 test_134b() {
15385         remote_mds_nodsh && skip "remote MDS with nodsh"
15386         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
15387                 skip "Need MDS version at least 2.7.54"
15388
15389         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
15390         cancel_lru_locks mdc
15391
15392         local low_wm=$(do_facet mds1 $LCTL get_param -n \
15393                         ldlm.lock_reclaim_threshold_mb)
15394         # disable reclaim temporarily
15395         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=0
15396
15397         #define OBD_FAIL_LDLM_WATERMARK_HIGH     0x328
15398         do_facet mds1 $LCTL set_param fail_loc=0x328
15399         do_facet mds1 $LCTL set_param fail_val=500
15400
15401         $LCTL set_param debug=+trace
15402
15403         local nr=600
15404         createmany -o $DIR/$tdir/f $nr &
15405         local create_pid=$!
15406
15407         echo "Sleep $TIMEOUT seconds ..."
15408         sleep $TIMEOUT
15409         if ! ps -p $create_pid  > /dev/null 2>&1; then
15410                 do_facet mds1 $LCTL set_param fail_loc=0
15411                 do_facet mds1 $LCTL set_param fail_val=0
15412                 do_facet mds1 $LCTL set_param \
15413                         ldlm.lock_reclaim_threshold_mb=${low_wm}m
15414                 error "createmany finished incorrectly!"
15415         fi
15416         do_facet mds1 $LCTL set_param fail_loc=0
15417         do_facet mds1 $LCTL set_param fail_val=0
15418         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=${low_wm}m
15419         wait $create_pid || return 1
15420
15421         unlinkmany $DIR/$tdir/f $nr
15422 }
15423 run_test 134b "Server rejects lock request when reaching lock_limit_mb"
15424
15425 test_135() {
15426         remote_mds_nodsh && skip "remote MDS with nodsh"
15427         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
15428                 skip "Need MDS version at least 2.13.50"
15429         local fname
15430
15431         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
15432
15433 #define OBD_FAIL_PLAIN_RECORDS 0x1319
15434         #set only one record at plain llog
15435         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1319 fail_val=1
15436
15437         ost_set_temp_seq_width_all $DATA_SEQ_MAX_WIDTH
15438
15439         #fill already existed plain llog each 64767
15440         #wrapping whole catalog
15441         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
15442
15443         createmany -o $DIR/$tdir/$tfile_ 64700
15444         for (( i = 0; i < 64700; i = i + 2 ))
15445         do
15446                 rm $DIR/$tdir/$tfile_$i &
15447                 rm $DIR/$tdir/$tfile_$((i + 1)) &
15448                 local pid=$!
15449                 wait $pid
15450         done
15451
15452         #waiting osp synchronization
15453         wait_delete_completed
15454 }
15455 run_test 135 "Race catalog processing"
15456
15457 test_136() {
15458         remote_mds_nodsh && skip "remote MDS with nodsh"
15459         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
15460                 skip "Need MDS version at least 2.13.50"
15461         local fname
15462
15463         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
15464         $LFS setstripe -c 1 -i 0 $DIR/$tdir || error "failed to set striping"
15465         #set only one record at plain llog
15466 #define OBD_FAIL_CATALOG_FULL_CHECK                0x131a
15467         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x131a fail_val=1
15468
15469         ost_set_temp_seq_width_all $DATA_SEQ_MAX_WIDTH
15470
15471         #fill already existed 2 plain llogs each 64767
15472         #wrapping whole catalog
15473         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
15474         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 3 / 2))
15475         wait_delete_completed
15476
15477         createmany -o $DIR/$tdir/$tfile_ 10
15478         sleep 25
15479
15480         do_facet $SINGLEMDS $LCTL set_param fail_val=3
15481         for (( i = 0; i < 10; i = i + 3 ))
15482         do
15483                 rm $DIR/$tdir/$tfile_$i &
15484                 rm $DIR/$tdir/$tfile_$((i + 1)) &
15485                 local pid=$!
15486                 wait $pid
15487                 sleep 7
15488                 rm $DIR/$tdir/$tfile_$((i + 2)) &
15489         done
15490
15491         #waiting osp synchronization
15492         wait_delete_completed
15493 }
15494 run_test 136 "Race catalog processing 2"
15495
15496 test_140() { #bug-17379
15497         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15498
15499         test_mkdir $DIR/$tdir
15500         cd $DIR/$tdir || error "Changing to $DIR/$tdir"
15501         cp $(which stat) . || error "Copying stat to $DIR/$tdir"
15502
15503         # VFS limits max symlink depth to 5(4KSTACK) or 7(8KSTACK) or 8
15504         # For kernel > 3.5, bellow only tests consecutive symlink (MAX 40)
15505         local i=0
15506         while i=$((i + 1)); do
15507                 test_mkdir $i
15508                 cd $i || error "Changing to $i"
15509                 ln -s ../stat stat || error "Creating stat symlink"
15510                 # Read the symlink until ELOOP present,
15511                 # not LBUGing the system is considered success,
15512                 # we didn't overrun the stack.
15513                 $OPENFILE -f O_RDONLY stat >/dev/null 2>&1; ret=$?
15514                 if [ $ret -ne 0 ]; then
15515                         if [ $ret -eq 40 ]; then
15516                                 break  # -ELOOP
15517                         else
15518                                 error "Open stat symlink"
15519                                         return
15520                         fi
15521                 fi
15522         done
15523         i=$((i - 1))
15524         echo "The symlink depth = $i"
15525         [ $i -eq 5 ] || [ $i -eq 7 ] || [ $i -eq 8 ] || [ $i -eq 40 ] ||
15526                 error "Invalid symlink depth"
15527
15528         # Test recursive symlink
15529         ln -s symlink_self symlink_self
15530         $OPENFILE -f O_RDONLY symlink_self >/dev/null 2>&1; ret=$?
15531         echo "open symlink_self returns $ret"
15532         [ $ret -eq 40 ] || error "recursive symlink doesn't return -ELOOP"
15533 }
15534 run_test 140 "Check reasonable stack depth (shouldn't LBUG) ===="
15535
15536 test_150a() {
15537         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15538
15539         local TF="$TMP/$tfile"
15540
15541         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15542         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
15543         cp $TF $DIR/$tfile
15544         cancel_lru_locks $OSC
15545         cmp $TF $DIR/$tfile || error "$TMP/$tfile $DIR/$tfile differ"
15546         remount_client $MOUNT
15547         df -P $MOUNT
15548         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (remount)"
15549
15550         $TRUNCATE $TF 6000
15551         $TRUNCATE $DIR/$tfile 6000
15552         cancel_lru_locks $OSC
15553         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (truncate1)"
15554
15555         echo "12345" >>$TF
15556         echo "12345" >>$DIR/$tfile
15557         cancel_lru_locks $OSC
15558         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append1)"
15559
15560         echo "12345" >>$TF
15561         echo "12345" >>$DIR/$tfile
15562         cancel_lru_locks $OSC
15563         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append2)"
15564 }
15565 run_test 150a "truncate/append tests"
15566
15567 test_150b() {
15568         check_set_fallocate_or_skip
15569         local out
15570
15571         touch $DIR/$tfile
15572         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15573         out=$(check_fallocate $DIR/$tfile 2>&1) ||
15574                 skip_eopnotsupp "$out|check_fallocate failed"
15575 }
15576 run_test 150b "Verify fallocate (prealloc) functionality"
15577
15578 test_150bb() {
15579         check_set_fallocate_or_skip
15580
15581         touch $DIR/$tfile
15582         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15583         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=20 || error "dd failed"
15584         > $DIR/$tfile
15585         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
15586         # precomputed md5sum for 20MB of zeroes
15587         local expect="8f4e33f3dc3e414ff94e5fb6905cba8c"
15588         local sum=($(md5sum $DIR/$tfile))
15589
15590         [[ "${sum[0]}" == "$expect" ]] || error "fallocate unwritten is not zero"
15591
15592         check_set_fallocate 1
15593
15594         > $DIR/$tfile
15595         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
15596         sum=($(md5sum $DIR/$tfile))
15597
15598         [[ "${sum[0]}" == "$expect" ]] || error "fallocate zero is not zero"
15599 }
15600 run_test 150bb "Verify fallocate modes both zero space"
15601
15602 test_150c() {
15603         check_set_fallocate_or_skip
15604         local striping="-c2"
15605
15606         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15607         $LFS setstripe -c $OSTCOUNT -S1M $DIR/$tfile || error "setstripe failed"
15608         fallocate -l ${OSTCOUNT}m $DIR/$tfile || error "fallocate failed"
15609         local bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
15610         local want=$((OSTCOUNT * 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         rm -f $DIR/$tfile
15617
15618         echo "verify fallocate on PFL file"
15619
15620         [[ "x$DOM" == "xyes" ]] && striping="-L mdt"
15621
15622         $LFS setstripe -E1M $striping -E16M -c3 -Eeof -c 4 $DIR/$tfile ||
15623                 error "Create $DIR/$tfile failed"
15624         fallocate -l $((1048576 * 512)) $DIR/$tfile || error "fallocate failed"
15625         bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
15626         want=$((512 * 1048576))
15627
15628         # Must allocate all requested space, not more than 5% extra
15629         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
15630                 error "bytes $bytes is not $want"
15631 }
15632 run_test 150c "Verify fallocate Size and Blocks"
15633
15634 test_150d() {
15635         check_set_fallocate_or_skip
15636         local striping="-c2"
15637
15638         [[ "x$DOM" == "xyes" ]] && striping="-L mdt"
15639
15640         stack_trap "rm -f $DIR/$tdir; wait_delete_completed"
15641         $LFS setstripe -E1M $striping -E eof -c $OSTCOUNT -S1M $DIR/$tdir ||
15642                 error "setstripe failed"
15643         fallocate -o 1G -l ${OSTCOUNT}m $DIR/$tdir || error "fallocate failed"
15644         local bytes=$(($(stat -c '%b * %B' $DIR/$tdir)))
15645         local want=$((OSTCOUNT * 1048576))
15646
15647         # Must allocate all requested space, not more than 5% extra
15648         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
15649                 error "bytes $bytes is not $want"
15650 }
15651 run_test 150d "Verify fallocate Size and Blocks - Non zero start"
15652
15653 test_150e() {
15654         check_set_fallocate_or_skip
15655
15656         echo "df before:"
15657         $LFS df
15658         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15659         $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
15660                 error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
15661
15662         # Find OST with Minimum Size
15663         min_size_ost=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
15664                        sort -un | head -1)
15665
15666         # Get 100MB per OST of the available space to reduce run time
15667         # else 60% of the available space if we are running SLOW tests
15668         if [ $SLOW == "no" ]; then
15669                 local space=$((1024 * 100 * OSTCOUNT))
15670         else
15671                 local space=$(((min_size_ost * 60)/100 * OSTCOUNT))
15672         fi
15673
15674         fallocate -l${space}k $DIR/$tfile ||
15675                 error "fallocate ${space}k $DIR/$tfile failed"
15676         echo "'fallocate -l ${space}k $DIR/$tfile' succeeded"
15677
15678         # get size immediately after fallocate. This should be correctly
15679         # updated
15680         local size=$(stat -c '%s' $DIR/$tfile)
15681         local used=$(( $(stat -c '%b * %B' $DIR/$tfile) / 1024))
15682
15683         # Sleep for a while for statfs to get updated. And not pull from cache.
15684         sleep 2
15685
15686         echo "df after fallocate:"
15687         $LFS df
15688
15689         (( size / 1024 == space )) || error "size $size != requested $space"
15690         [ "$ost1_FSTYPE" != ldiskfs ] || (( used >= space )) ||
15691                 error "used $used < space $space"
15692
15693         rm $DIR/$tfile || error "rm failed"
15694         sync
15695         wait_delete_completed
15696
15697         echo "df after unlink:"
15698         $LFS df
15699 }
15700 run_test 150e "Verify 60% of available OST space consumed by fallocate"
15701
15702 test_150f() {
15703         local size
15704         local blocks
15705         local want_size_before=20480 # in bytes
15706         local want_blocks_before=40 # 512 sized blocks
15707         local want_blocks_after=24  # 512 sized blocks
15708         local length=$(((want_blocks_before - want_blocks_after) * 512))
15709
15710         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
15711                 skip "need at least 2.14.0 for fallocate punch"
15712
15713         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
15714                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
15715         fi
15716
15717         check_set_fallocate_or_skip
15718         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15719
15720         [[ "x$DOM" == "xyes" ]] &&
15721                 $LFS setstripe -E1M -L mdt -E eof $DIR/$tfile
15722
15723         echo "Verify fallocate punch: Range within the file range"
15724         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
15725                 error "dd failed for bs 4096 and count 5"
15726
15727         # Call fallocate with punch range which is within the file range
15728         out=$(fallocate -p --offset 4096 -l $length $DIR/$tfile 2>&1) ||
15729                 skip_eopnotsupp "$out|fallocate: offset 4096 and length $length"
15730         # client must see changes immediately after fallocate
15731         size=$(stat -c '%s' $DIR/$tfile)
15732         blocks=$(stat -c '%b' $DIR/$tfile)
15733
15734         # Verify punch worked.
15735         (( blocks == want_blocks_after )) ||
15736                 error "punch failed: blocks $blocks != $want_blocks_after"
15737
15738         (( size == want_size_before )) ||
15739                 error "punch failed: size $size != $want_size_before"
15740
15741         # Verify there is hole in file
15742         local data_off=$(lseek_test -d 4096 $DIR/$tfile)
15743         # precomputed md5sum
15744         local expect="4a9a834a2db02452929c0a348273b4aa"
15745
15746         cksum=($(md5sum $DIR/$tfile))
15747         [[ "${cksum[0]}" == "$expect" ]] ||
15748                 error "unexpected MD5SUM after punch: ${cksum[0]}"
15749
15750         # Start second sub-case for fallocate punch.
15751         echo "Verify fallocate punch: Range overlapping and less than blocksize"
15752         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
15753                 error "dd failed for bs 4096 and count 5"
15754
15755         # Punch range less than block size will have no change in block count
15756         want_blocks_after=40  # 512 sized blocks
15757
15758         # Punch overlaps two blocks and less than blocksize
15759         out=$(fallocate -p --offset 4000 -l 3000 $DIR/$tfile 2>&1) ||
15760                 skip_eopnotsupp "$out|fallocate: offset 4000 length 3000"
15761         size=$(stat -c '%s' $DIR/$tfile)
15762         blocks=$(stat -c '%b' $DIR/$tfile)
15763
15764         # Verify punch worked.
15765         (( blocks == want_blocks_after )) ||
15766                 error "punch failed: blocks $blocks != $want_blocks_after"
15767
15768         (( size == want_size_before )) ||
15769                 error "punch failed: size $size != $want_size_before"
15770
15771         # Verify if range is really zero'ed out. We expect Zeros.
15772         # precomputed md5sum
15773         expect="c57ec5d769c3dbe3426edc3f7d7e11d3"
15774         cksum=($(md5sum $DIR/$tfile))
15775         [[ "${cksum[0]}" == "$expect" ]] ||
15776                 error "unexpected MD5SUM after punch: ${cksum[0]}"
15777 }
15778 run_test 150f "Verify fallocate punch functionality"
15779
15780 test_150g() {
15781         local space
15782         local size
15783         local blocks
15784         local blocks_after
15785         local size_after
15786         local BS=4096 # Block size in bytes
15787
15788         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
15789                 skip "need at least 2.14.0 for fallocate punch"
15790
15791         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
15792                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
15793         fi
15794
15795         check_set_fallocate_or_skip
15796         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15797
15798         if [[ "x$DOM" == "xyes" ]]; then
15799                 $LFS setstripe -E2M -L mdt -E eof -c${OSTCOUNT} $DIR/$tfile ||
15800                         error "$LFS setstripe DoM + ${OSTCOUNT} OST failed"
15801         else
15802                 $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
15803                         error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
15804         fi
15805
15806         # Get 100MB per OST of the available space to reduce run time
15807         # else 60% of the available space if we are running SLOW tests
15808         if [ $SLOW == "no" ]; then
15809                 space=$((1024 * 100 * OSTCOUNT))
15810         else
15811                 # Find OST with Minimum Size
15812                 space=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
15813                         sort -un | head -1)
15814                 echo "min size OST: $space"
15815                 space=$(((space * 60)/100 * OSTCOUNT))
15816         fi
15817         # space in 1k units, round to 4k blocks
15818         local blkcount=$((space * 1024 / $BS))
15819
15820         echo "Verify fallocate punch: Very large Range"
15821         fallocate -l${space}k $DIR/$tfile ||
15822                 error "fallocate ${space}k $DIR/$tfile failed"
15823         # write 1M at the end, start and in the middle
15824         yes 'A' | dd of=$DIR/$tfile bs=$BS count=256 ||
15825                 error "dd failed: bs $BS count 256"
15826         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount - 256)) count=256 ||
15827                 error "dd failed: bs $BS count 256 seek $((blkcount - 256))"
15828         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount / 2)) count=1024 ||
15829                 error "dd failed: bs $BS count 256 seek $((blkcount / 2))"
15830
15831         # Gather stats.
15832         size=$(stat -c '%s' $DIR/$tfile)
15833
15834         # gather punch length.
15835         local punch_size=$((size - (BS * 2)))
15836
15837         echo "punch_size = $punch_size"
15838         echo "size - punch_size: $((size - punch_size))"
15839         echo "size - punch_size in blocks: $(((size - punch_size)/BS))"
15840
15841         # Call fallocate to punch all except 2 blocks. We leave the
15842         # first and the last block
15843         echo "fallocate -p --offset $BS -l $punch_size $DIR/$tfile"
15844         out=$(fallocate -p --offset $BS -l $punch_size $DIR/$tfile 2>&1) ||
15845                 skip_eopnotsupp "$out|fallocate: offset $BS length $punch_size"
15846
15847         size_after=$(stat -c '%s' $DIR/$tfile)
15848         blocks_after=$(stat -c '%b' $DIR/$tfile)
15849
15850         # Verify punch worked.
15851         # Size should be kept
15852         (( size == size_after )) ||
15853                 error "punch failed: size $size != $size_after"
15854
15855         # two 4k data blocks to remain plus possible 1 extra extent block
15856         (( blocks_after <= ((BS / 512) * 3) )) ||
15857                 error "too many blocks remains: $blocks_after"
15858
15859         # Verify that file has hole between the first and the last blocks
15860         local hole_start=$(lseek_test -l 0 $DIR/$tfile)
15861         local hole_end=$(lseek_test -d $BS $DIR/$tfile)
15862
15863         echo "Hole at [$hole_start, $hole_end)"
15864         (( hole_start == BS )) ||
15865                 error "no hole at offset $BS after punch"
15866
15867         (( hole_end == BS + punch_size )) ||
15868                 error "data at offset $hole_end < $((BS + punch_size))"
15869 }
15870 run_test 150g "Verify fallocate punch on large range"
15871
15872 test_150h() {
15873         local file=$DIR/$tfile
15874         local size
15875
15876         check_set_fallocate_or_skip
15877         statx_supported || skip_env "Test must be statx() syscall supported"
15878
15879         # fallocate() does not update the size information on the MDT
15880         fallocate -l 16K $file || error "failed to fallocate $file"
15881         cancel_lru_locks $OSC
15882         # STATX with cached-always mode will not send glimpse RPCs to OST,
15883         # it uses the caching attrs on the client side as much as possible.
15884         size=$($STATX --cached=always -c %s $file)
15885         [ $size == 16384 ] ||
15886                 error "size after fallocate() is $size, expected 16384"
15887 }
15888 run_test 150h "Verify extend fallocate updates the file size"
15889
15890 #LU-2902 roc_hit was not able to read all values from lproc
15891 function roc_hit_init() {
15892         local list=$(comma_list $(osts_nodes))
15893         local dir=$DIR/$tdir-check
15894         local file=$dir/$tfile
15895         local BEFORE
15896         local AFTER
15897         local idx
15898
15899         test_mkdir $dir
15900         #use setstripe to do a write to every ost
15901         for i in $(seq 0 $((OSTCOUNT-1))); do
15902                 $LFS setstripe -c 1 -i $i $dir || error "$LFS setstripe $file failed"
15903                 dd if=/dev/urandom of=$file bs=4k count=4 2>&1 > /dev/null
15904                 idx=$(printf %04x $i)
15905                 BEFORE=$(get_osd_param $list *OST*$idx stats |
15906                         awk '$1 == "cache_access" {sum += $7}
15907                                 END { printf("%0.0f", sum) }')
15908
15909                 cancel_lru_locks osc
15910                 cat $file >/dev/null
15911
15912                 AFTER=$(get_osd_param $list *OST*$idx stats |
15913                         awk '$1 == "cache_access" {sum += $7}
15914                                 END { printf("%0.0f", sum) }')
15915
15916                 echo BEFORE:$BEFORE AFTER:$AFTER
15917                 if ! let "AFTER - BEFORE == 4"; then
15918                         rm -rf $dir
15919                         error "roc_hit is not safe to use"
15920                 fi
15921                 rm $file
15922         done
15923
15924         rm -rf $dir
15925 }
15926
15927 function roc_hit() {
15928         local list=$(comma_list $(osts_nodes))
15929         echo $(get_osd_param $list '' stats |
15930                 awk '$1 == "cache_hit" {sum += $7}
15931                         END { printf("%0.0f", sum) }')
15932 }
15933
15934 function set_cache() {
15935         local on=1
15936
15937         if [ "$2" == "off" ]; then
15938                 on=0;
15939         fi
15940         local list=$(comma_list $(osts_nodes))
15941         set_osd_param $list '' $1_cache_enable $on
15942
15943         cancel_lru_locks osc
15944 }
15945
15946 test_151() {
15947         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15948         remote_ost_nodsh && skip "remote OST with nodsh"
15949         (( CLIENT_VERSION == OST1_VERSION )) ||
15950                 skip "LU-13081: no interop testing for OSS cache"
15951
15952         local CPAGES=3
15953         local list=$(comma_list $(osts_nodes))
15954
15955         # check whether obdfilter is cache capable at all
15956         if ! get_osd_param $list '' read_cache_enable >/dev/null; then
15957                 skip "not cache-capable obdfilter"
15958         fi
15959
15960         # check cache is enabled on all obdfilters
15961         if get_osd_param $list '' read_cache_enable | grep 0; then
15962                 skip "oss cache is disabled"
15963         fi
15964
15965         set_osd_param $list '' writethrough_cache_enable 1
15966
15967         # check write cache is enabled on all obdfilters
15968         if get_osd_param $list '' writethrough_cache_enable | grep 0; then
15969                 skip "oss write cache is NOT enabled"
15970         fi
15971
15972         roc_hit_init
15973
15974         #define OBD_FAIL_OBD_NO_LRU  0x609
15975         do_nodes $list $LCTL set_param fail_loc=0x609
15976
15977         # pages should be in the case right after write
15978         dd if=/dev/urandom of=$DIR/$tfile bs=4k count=$CPAGES ||
15979                 error "dd failed"
15980
15981         local BEFORE=$(roc_hit)
15982         cancel_lru_locks osc
15983         cat $DIR/$tfile >/dev/null
15984         local AFTER=$(roc_hit)
15985
15986         do_nodes $list $LCTL set_param fail_loc=0
15987
15988         if ! let "AFTER - BEFORE == CPAGES"; then
15989                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
15990         fi
15991
15992         cancel_lru_locks osc
15993         # invalidates OST cache
15994         do_nodes $list "echo 1 > /proc/sys/vm/drop_caches"
15995         set_osd_param $list '' read_cache_enable 0
15996         cat $DIR/$tfile >/dev/null
15997
15998         # now data shouldn't be found in the cache
15999         BEFORE=$(roc_hit)
16000         cancel_lru_locks osc
16001         cat $DIR/$tfile >/dev/null
16002         AFTER=$(roc_hit)
16003         if let "AFTER - BEFORE != 0"; then
16004                 error "IN CACHE: before: $BEFORE, after: $AFTER"
16005         fi
16006
16007         set_osd_param $list '' read_cache_enable 1
16008         rm -f $DIR/$tfile
16009 }
16010 run_test 151 "test cache on oss and controls ==============================="
16011
16012 test_152() {
16013         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16014
16015         local TF="$TMP/$tfile"
16016
16017         # simulate ENOMEM during write
16018 #define OBD_FAIL_OST_NOMEM      0x226
16019         lctl set_param fail_loc=0x80000226
16020         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
16021         cp $TF $DIR/$tfile
16022         sync || error "sync failed"
16023         lctl set_param fail_loc=0
16024
16025         # discard client's cache
16026         cancel_lru_locks osc
16027
16028         # simulate ENOMEM during read
16029         lctl set_param fail_loc=0x80000226
16030         cmp $TF $DIR/$tfile || error "cmp failed"
16031         lctl set_param fail_loc=0
16032
16033         rm -f $TF
16034 }
16035 run_test 152 "test read/write with enomem ============================"
16036
16037 test_153() {
16038         $MULTIOP $DIR/$tfile Ow4096Ycu || error "multiop failed"
16039 }
16040 run_test 153 "test if fdatasync does not crash ======================="
16041
16042 dot_lustre_fid_permission_check() {
16043         local fid=$1
16044         local ffid=$MOUNT/.lustre/fid/$fid
16045         local test_dir=$2
16046
16047         echo "stat fid $fid"
16048         stat $ffid || error "stat $ffid failed."
16049         echo "touch fid $fid"
16050         touch $ffid || error "touch $ffid failed."
16051         echo "write to fid $fid"
16052         cat /etc/hosts > $ffid || error "write $ffid failed."
16053         echo "read fid $fid"
16054         diff /etc/hosts $ffid || error "read $ffid failed."
16055         echo "append write to fid $fid"
16056         cat /etc/hosts >> $ffid || error "append write $ffid failed."
16057         echo "rename fid $fid"
16058         mv $ffid $test_dir/$tfile.1 &&
16059                 error "rename $ffid to $tfile.1 should fail."
16060         touch $test_dir/$tfile.1
16061         mv $test_dir/$tfile.1 $ffid &&
16062                 error "rename $tfile.1 to $ffid should fail."
16063         rm -f $test_dir/$tfile.1
16064         echo "truncate fid $fid"
16065         $TRUNCATE $ffid 777 || error "truncate $ffid failed."
16066         echo "link fid $fid"
16067         ln -f $ffid $test_dir/tfile.lnk || error "link $ffid failed."
16068         if [[ $($LCTL get_param -n mdc.*-mdc-*.connect_flags) =~ acl ]]; then
16069                 echo "setfacl fid $fid"
16070                 setfacl -R -m u:$USER0:rwx $ffid ||
16071                         error "setfacl $ffid failed"
16072                 echo "getfacl fid $fid"
16073                 getfacl $ffid || error "getfacl $ffid failed."
16074         fi
16075         echo "unlink fid $fid"
16076         unlink $MOUNT/.lustre/fid/$fid && error "unlink $ffid should fail."
16077         echo "mknod fid $fid"
16078         mknod $ffid c 1 3 && error "mknod $ffid should fail."
16079
16080         fid=[0xf00000400:0x1:0x0]
16081         ffid=$MOUNT/.lustre/fid/$fid
16082
16083         echo "stat non-exist fid $fid"
16084         stat $ffid > /dev/null && error "stat non-exist $ffid should fail."
16085         echo "write to non-exist fid $fid"
16086         cat /etc/hosts > $ffid && error "write non-exist $ffid should fail."
16087         echo "link new fid $fid"
16088         ln $test_dir/$tfile $ffid && error "link $ffid should fail."
16089
16090         mkdir -p $test_dir/$tdir
16091         touch $test_dir/$tdir/$tfile
16092         fid=$($LFS path2fid $test_dir/$tdir)
16093         rc=$?
16094         [ $rc -ne 0 ] &&
16095                 error "error: could not get fid for $test_dir/$dir/$tfile."
16096
16097         ffid=$MOUNT/.lustre/fid/$fid
16098
16099         echo "ls $fid"
16100         ls $ffid || error "ls $ffid failed."
16101         echo "touch $fid/$tfile.1"
16102         touch $ffid/$tfile.1 || error "touch $ffid/$tfile.1 failed."
16103
16104         echo "touch $MOUNT/.lustre/fid/$tfile"
16105         touch $MOUNT/.lustre/fid/$tfile && \
16106                 error "touch $MOUNT/.lustre/fid/$tfile should fail."
16107
16108         echo "setxattr to $MOUNT/.lustre/fid"
16109         setfattr -n trusted.name1 -v value1 $MOUNT/.lustre/fid
16110
16111         echo "listxattr for $MOUNT/.lustre/fid"
16112         getfattr -d -m "^trusted" $MOUNT/.lustre/fid
16113
16114         echo "delxattr from $MOUNT/.lustre/fid"
16115         setfattr -x trusted.name1 $MOUNT/.lustre/fid
16116
16117         echo "touch invalid fid: $MOUNT/.lustre/fid/[0x200000400:0x2:0x3]"
16118         touch $MOUNT/.lustre/fid/[0x200000400:0x2:0x3] &&
16119                 error "touch invalid fid should fail."
16120
16121         echo "touch non-normal fid: $MOUNT/.lustre/fid/[0x1:0x2:0x0]"
16122         touch $MOUNT/.lustre/fid/[0x1:0x2:0x0] &&
16123                 error "touch non-normal fid should fail."
16124
16125         echo "rename $tdir to $MOUNT/.lustre/fid"
16126         mrename $test_dir/$tdir $MOUNT/.lustre/fid &&
16127                 error "rename to $MOUNT/.lustre/fid should fail."
16128
16129         if [ $MDS1_VERSION -ge $(version_code 2.3.51) ]
16130         then            # LU-3547
16131                 local old_obf_mode=$(stat --format="%a" $DIR/.lustre/fid)
16132                 local new_obf_mode=777
16133
16134                 echo "change mode of $DIR/.lustre/fid to $new_obf_mode"
16135                 chmod $new_obf_mode $DIR/.lustre/fid ||
16136                         error "chmod $new_obf_mode $DIR/.lustre/fid failed"
16137
16138                 local obf_mode=$(stat --format=%a $DIR/.lustre/fid)
16139                 [ $obf_mode -eq $new_obf_mode ] ||
16140                         error "stat $DIR/.lustre/fid returned wrong mode $obf_mode"
16141
16142                 echo "restore mode of $DIR/.lustre/fid to $old_obf_mode"
16143                 chmod $old_obf_mode $DIR/.lustre/fid ||
16144                         error "chmod $old_obf_mode $DIR/.lustre/fid failed"
16145         fi
16146
16147         $OPENFILE -f O_LOV_DELAY_CREATE:O_CREAT $test_dir/$tfile-2
16148         fid=$($LFS path2fid $test_dir/$tfile-2)
16149
16150         if [ $MDS1_VERSION -ge $(version_code 2.6.50) ]
16151         then # LU-5424
16152                 echo "cp /etc/passwd $MOUNT/.lustre/fid/$fid"
16153                 cp /etc/passwd $MOUNT/.lustre/fid/$fid ||
16154                         error "create lov data thru .lustre failed"
16155         fi
16156         echo "cp /etc/passwd $test_dir/$tfile-2"
16157         cp /etc/passwd $test_dir/$tfile-2 ||
16158                 error "copy to $test_dir/$tfile-2 failed."
16159         echo "diff /etc/passwd $MOUNT/.lustre/fid/$fid"
16160         diff /etc/passwd $MOUNT/.lustre/fid/$fid ||
16161                 error "diff /etc/passwd $MOUNT/.lustre/fid/$fid failed."
16162
16163         rm -rf $test_dir/tfile.lnk
16164         rm -rf $test_dir/$tfile-2
16165 }
16166
16167 test_154A() {
16168         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
16169                 skip "Need MDS version at least 2.4.1"
16170
16171         local tf=$DIR/$tfile
16172         touch $tf
16173
16174         local fid=$($LFS path2fid $tf)
16175         [ -z "$fid" ] && error "path2fid unable to get $tf FID"
16176
16177         # check that we get the same pathname back
16178         local rootpath
16179         local found
16180         for rootpath in "$MOUNT" "$MOUNT///" "$MOUNT/$tfile"; do
16181                 echo "$rootpath $fid"
16182                 found=$($LFS fid2path $rootpath "$fid")
16183                 [ -z "$found" ] && error "fid2path unable to get '$fid' path"
16184                 [ "$found" == "$tf" ] || error "fid2path $found != $tf"
16185         done
16186
16187         # check wrong root path format
16188         rootpath=$MOUNT"_wrong"
16189         found=$($LFS fid2path $rootpath "$fid")
16190         [ -z "$found" ] || error "should fail ($rootpath != $MOUNT)"
16191 }
16192 run_test 154A "lfs path2fid and fid2path basic checks"
16193
16194 test_154B() {
16195         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
16196                 skip "Need MDS version at least 2.4.1"
16197
16198         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
16199         touch $DIR/$tdir/$tfile || error "touch $DIR/$tdir/$tfile failed"
16200         local linkea=$($LL_DECODE_LINKEA $DIR/$tdir/$tfile | grep 'pfid')
16201         [ -z "$linkea" ] && error "decode linkea $DIR/$tdir/$tfile failed"
16202
16203         local name=$(echo $linkea | awk '/pfid/ {print $5}' | sed -e "s/'//g")
16204         local PFID=$(echo $linkea | awk '/pfid/ {print $3}' | sed -e "s/,//g")
16205
16206         # check that we get the same pathname
16207         echo "PFID: $PFID, name: $name"
16208         local FOUND=$($LFS fid2path $MOUNT "$PFID")
16209         [ -z "$FOUND" ] && error "fid2path unable to get $PFID path"
16210         [ "$FOUND/$name" != "$DIR/$tdir/$tfile" ] &&
16211                 error "ll_decode_linkea has $FOUND/$name != $DIR/$tdir/$tfile"
16212
16213         rm -rf $DIR/$tdir || error "Can not delete directory $DIR/$tdir"
16214 }
16215 run_test 154B "verify the ll_decode_linkea tool"
16216
16217 test_154a() {
16218         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16219         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
16220         (( $MDS1_VERSION >= $(version_code 2.2.51) )) ||
16221                 skip "Need MDS version at least 2.2.51"
16222         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
16223
16224         cp /etc/hosts $DIR/$tfile
16225
16226         fid=$($LFS path2fid $DIR/$tfile)
16227         rc=$?
16228         [ $rc -ne 0 ] && error "error: could not get fid for $DIR/$tfile."
16229
16230         dot_lustre_fid_permission_check "$fid" $DIR ||
16231                 error "dot lustre permission check $fid failed"
16232
16233         ls -a $MOUNT | grep "\.lustre" && error ".lustre should not be listed"
16234
16235         rm -rf $MOUNT/.lustre && error ".lustre is not allowed to be unlinked"
16236
16237         touch $MOUNT/.lustre/file &&
16238                 error "creation is not allowed under .lustre"
16239
16240         mkdir $MOUNT/.lustre/dir &&
16241                 error "mkdir is not allowed under .lustre"
16242
16243         rm -rf $DIR/$tfile
16244 }
16245 run_test 154a "Open-by-FID"
16246
16247 test_154b() {
16248         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16249         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
16250         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16251         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
16252                 skip "Need MDS version at least 2.2.51"
16253
16254         local remote_dir=$DIR/$tdir/remote_dir
16255         local MDTIDX=1
16256         local rc=0
16257
16258         mkdir -p $DIR/$tdir
16259         $LFS mkdir -i $MDTIDX $remote_dir ||
16260                 error "create remote directory failed"
16261
16262         cp /etc/hosts $remote_dir/$tfile
16263
16264         fid=$($LFS path2fid $remote_dir/$tfile)
16265         rc=$?
16266         [ $rc -ne 0 ] && error "error: could not get fid for $remote_dir/$tfile"
16267
16268         dot_lustre_fid_permission_check "$fid" $remote_dir ||
16269                 error "dot lustre permission check $fid failed"
16270         rm -rf $DIR/$tdir
16271 }
16272 run_test 154b "Open-by-FID for remote directory"
16273
16274 test_154c() {
16275         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
16276                 skip "Need MDS version at least 2.4.1"
16277
16278         touch $DIR/$tfile.1 $DIR/$tfile.2 $DIR/$tfile.3
16279         local FID1=$($LFS path2fid $DIR/$tfile.1)
16280         local FID2=$($LFS path2fid $DIR/$tfile.2)
16281         local FID3=$($LFS path2fid $DIR/$tfile.3)
16282
16283         local N=1
16284         $LFS path2fid $DIR/$tfile.[123] | while read PATHNAME FID; do
16285                 [ "$PATHNAME" = "$DIR/$tfile.$N:" ] ||
16286                         error "path2fid pathname $PATHNAME != $DIR/$tfile.$N:"
16287                 local want=FID$N
16288                 [ "$FID" = "${!want}" ] ||
16289                         error "path2fid $PATHNAME FID $FID != FID$N ${!want}"
16290                 N=$((N + 1))
16291         done
16292
16293         $LFS fid2path $MOUNT "$FID1" "$FID2" "$FID3" | while read PATHNAME;
16294         do
16295                 [ "$PATHNAME" = "$DIR/$tfile.$N" ] ||
16296                         error "fid2path pathname $PATHNAME != $DIR/$tfile.$N:"
16297                 N=$((N + 1))
16298         done
16299 }
16300 run_test 154c "lfs path2fid and fid2path multiple arguments"
16301
16302 test_154d() {
16303         remote_mds_nodsh && skip "remote MDS with nodsh"
16304         [[ $MDS1_VERSION -lt $(version_code 2.5.53) ]] &&
16305                 skip "Need MDS version at least 2.5.53"
16306
16307         if remote_mds; then
16308                 nid=$($LCTL list_nids | sed  "s/\./\\\./g")
16309         else
16310                 nid="0@lo"
16311         fi
16312         local proc_ofile="mdt.*.exports.'$nid'.open_files"
16313         local fd
16314         local cmd
16315
16316         rm -f $DIR/$tfile
16317         touch $DIR/$tfile
16318
16319         local fid=$($LFS path2fid $DIR/$tfile)
16320         # Open the file
16321         fd=$(free_fd)
16322         cmd="exec $fd<$DIR/$tfile"
16323         eval $cmd
16324         local fid_list=$(do_facet $SINGLEMDS $LCTL get_param $proc_ofile)
16325         echo "$fid_list" | grep "$fid"
16326         rc=$?
16327
16328         cmd="exec $fd>/dev/null"
16329         eval $cmd
16330         if [ $rc -ne 0 ]; then
16331                 error "FID $fid not found in open files list $fid_list"
16332         fi
16333 }
16334 run_test 154d "Verify open file fid"
16335
16336 test_154e()
16337 {
16338         [[ $MDS1_VERSION -lt $(version_code 2.6.50) ]] &&
16339                 skip "Need MDS version at least 2.6.50"
16340
16341         if ls -a $MOUNT | grep -q '^\.lustre$'; then
16342                 error ".lustre returned by readdir"
16343         fi
16344 }
16345 run_test 154e ".lustre is not returned by readdir"
16346
16347 test_154f() {
16348         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
16349
16350         # create parent directory on a single MDT to avoid cross-MDT hardlinks
16351         mkdir_on_mdt0 $DIR/$tdir
16352         # test dirs inherit from its stripe
16353         mkdir -p $DIR/$tdir/foo1 || error "mkdir error"
16354         mkdir -p $DIR/$tdir/foo2 || error "mkdir error"
16355         cp /etc/hosts $DIR/$tdir/foo1/$tfile
16356         ln $DIR/$tdir/foo1/$tfile $DIR/$tdir/foo2/link
16357         touch $DIR/f
16358
16359         # get fid of parents
16360         local FID0=$($LFS path2fid $DIR/$tdir)
16361         local FID1=$($LFS path2fid $DIR/$tdir/foo1)
16362         local FID2=$($LFS path2fid $DIR/$tdir/foo2)
16363         local FID3=$($LFS path2fid $DIR)
16364
16365         # check that path2fid --parents returns expected <parent_fid>/name
16366         # 1) test for a directory (single parent)
16367         local parent=$($LFS path2fid --parents $DIR/$tdir/foo1)
16368         [ "$parent" == "$FID0/foo1" ] ||
16369                 error "expected parent: $FID0/foo1, got: $parent"
16370
16371         # 2) test for a file with nlink > 1 (multiple parents)
16372         parent=$($LFS path2fid --parents $DIR/$tdir/foo1/$tfile)
16373         echo "$parent" | grep -F "$FID1/$tfile" ||
16374                 error "$FID1/$tfile not returned in parent list"
16375         echo "$parent" | grep -F "$FID2/link" ||
16376                 error "$FID2/link not returned in parent list"
16377
16378         # 3) get parent by fid
16379         local file_fid=$($LFS path2fid $DIR/$tdir/foo1/$tfile)
16380         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
16381         echo "$parent" | grep -F "$FID1/$tfile" ||
16382                 error "$FID1/$tfile not returned in parent list (by fid)"
16383         echo "$parent" | grep -F "$FID2/link" ||
16384                 error "$FID2/link not returned in parent list (by fid)"
16385
16386         # 4) test for entry in root directory
16387         parent=$($LFS path2fid --parents $DIR/f)
16388         echo "$parent" | grep -F "$FID3/f" ||
16389                 error "$FID3/f not returned in parent list"
16390
16391         # 5) test it on root directory
16392         [ -z "$($LFS path2fid --parents $MOUNT 2>/dev/null)" ] ||
16393                 error "$MOUNT should not have parents"
16394
16395         # enable xattr caching and check that linkea is correctly updated
16396         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
16397         save_lustre_params client "llite.*.xattr_cache" > $save
16398         lctl set_param llite.*.xattr_cache 1
16399
16400         # 6.1) linkea update on rename
16401         mv $DIR/$tdir/foo1/$tfile $DIR/$tdir/foo2/$tfile.moved
16402
16403         # get parents by fid
16404         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
16405         # foo1 should no longer be returned in parent list
16406         echo "$parent" | grep -F "$FID1" &&
16407                 error "$FID1 should no longer be in parent list"
16408         # the new path should appear
16409         echo "$parent" | grep -F "$FID2/$tfile.moved" ||
16410                 error "$FID2/$tfile.moved is not in parent list"
16411
16412         # 6.2) linkea update on unlink
16413         rm -f $DIR/$tdir/foo2/link
16414         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
16415         # foo2/link should no longer be returned in parent list
16416         echo "$parent" | grep -F "$FID2/link" &&
16417                 error "$FID2/link should no longer be in parent list"
16418         true
16419
16420         rm -f $DIR/f
16421         restore_lustre_params < $save
16422         rm -f $save
16423 }
16424 run_test 154f "get parent fids by reading link ea"
16425
16426 test_154g()
16427 {
16428         [[ $MDS1_VERSION -ge $(version_code 2.6.92) &&
16429            $CLIENT_VERSION -gt $(version_code 2.6.99) ]] ||
16430                 skip "Need MDS version at least 2.6.92"
16431
16432         mkdir_on_mdt0 $DIR/$tdir
16433         llapi_fid_test -d $DIR/$tdir
16434 }
16435 run_test 154g "various llapi FID tests"
16436
16437 test_154h()
16438 {
16439         (( $CLIENT_VERSION >= $(version_code 2.15.55.1) )) ||
16440                 skip "Need client at least version 2.15.55.1"
16441
16442         # Create an empty file
16443         touch $DIR/$tfile
16444
16445         # Get FID (interactive mode) and save under $TMP/$tfile.log
16446         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
16447                 path2fid $DIR/$tfile
16448         EOF
16449
16450         fid=$(cat $TMP/$tfile.log)
16451         # $fid should not be empty
16452         [[ ! -z $fid ]] || error "FID is empty"
16453         $LFS rmfid $DIR "$fid" || error "rmfid failed for $fid"
16454 }
16455 run_test 154h "Verify interactive path2fid"
16456
16457 test_155_small_load() {
16458     local temp=$TMP/$tfile
16459     local file=$DIR/$tfile
16460
16461     dd if=/dev/urandom of=$temp bs=6096 count=1 || \
16462         error "dd of=$temp bs=6096 count=1 failed"
16463     cp $temp $file
16464     cancel_lru_locks $OSC
16465     cmp $temp $file || error "$temp $file differ"
16466
16467     $TRUNCATE $temp 6000
16468     $TRUNCATE $file 6000
16469     cmp $temp $file || error "$temp $file differ (truncate1)"
16470
16471     echo "12345" >>$temp
16472     echo "12345" >>$file
16473     cmp $temp $file || error "$temp $file differ (append1)"
16474
16475     echo "12345" >>$temp
16476     echo "12345" >>$file
16477     cmp $temp $file || error "$temp $file differ (append2)"
16478
16479     rm -f $temp $file
16480     true
16481 }
16482
16483 test_155_big_load() {
16484         remote_ost_nodsh && skip "remote OST with nodsh"
16485
16486         local temp=$TMP/$tfile
16487         local file=$DIR/$tfile
16488
16489         free_min_max
16490         local cache_size=$(do_facet ost$((MAXI+1)) \
16491                 "awk '/cache/ {sum+=\\\$4} END {print sum}' /proc/cpuinfo")
16492
16493         # LU-16042: can not get the cache size on Arm64 VM here, fallback to a
16494         # pre-set value
16495         if [ -z "$cache_size" ]; then
16496                 cache_size=256
16497         fi
16498         local large_file_size=$((cache_size * 2))
16499
16500         echo "OSS cache size: $cache_size KB"
16501         echo "Large file size: $large_file_size KB"
16502
16503         [ $MAXV -le $large_file_size ] &&
16504                 skip_env "max available OST size needs > $large_file_size KB"
16505
16506         $LFS setstripe $file -c 1 -i $MAXI || error "$LFS setstripe $file failed"
16507
16508         dd if=/dev/urandom of=$temp bs=$large_file_size count=1k ||
16509                 error "dd of=$temp bs=$large_file_size count=1k failed"
16510         cp $temp $file
16511         ls -lh $temp $file
16512         cancel_lru_locks osc
16513         cmp $temp $file || error "$temp $file differ"
16514
16515         rm -f $temp $file
16516         true
16517 }
16518
16519 save_writethrough() {
16520         local facets=$(get_facets OST)
16521
16522         save_lustre_params $facets "osd-*.*.writethrough_cache_enable" > $1
16523 }
16524
16525 test_155a() {
16526         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16527
16528         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16529
16530         save_writethrough $p
16531
16532         set_cache read on
16533         set_cache writethrough on
16534         test_155_small_load
16535         restore_lustre_params < $p
16536         rm -f $p
16537 }
16538 run_test 155a "Verify small file correctness: read cache:on write_cache:on"
16539
16540 test_155b() {
16541         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16542
16543         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16544
16545         save_writethrough $p
16546
16547         set_cache read on
16548         set_cache writethrough off
16549         test_155_small_load
16550         restore_lustre_params < $p
16551         rm -f $p
16552 }
16553 run_test 155b "Verify small file correctness: read cache:on write_cache:off"
16554
16555 test_155c() {
16556         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16557
16558         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16559
16560         save_writethrough $p
16561
16562         set_cache read off
16563         set_cache writethrough on
16564         test_155_small_load
16565         restore_lustre_params < $p
16566         rm -f $p
16567 }
16568 run_test 155c "Verify small file correctness: read cache:off write_cache:on"
16569
16570 test_155d() {
16571         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16572
16573         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16574
16575         save_writethrough $p
16576
16577         set_cache read off
16578         set_cache writethrough off
16579         test_155_small_load
16580         restore_lustre_params < $p
16581         rm -f $p
16582 }
16583 run_test 155d "Verify small file correctness: read cache:off write_cache:off"
16584
16585 test_155e() {
16586         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16587
16588         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16589
16590         save_writethrough $p
16591
16592         set_cache read on
16593         set_cache writethrough on
16594         test_155_big_load
16595         restore_lustre_params < $p
16596         rm -f $p
16597 }
16598 run_test 155e "Verify big file correctness: read cache:on write_cache:on"
16599
16600 test_155f() {
16601         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16602
16603         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16604
16605         save_writethrough $p
16606
16607         set_cache read on
16608         set_cache writethrough off
16609         test_155_big_load
16610         restore_lustre_params < $p
16611         rm -f $p
16612 }
16613 run_test 155f "Verify big file correctness: read cache:on write_cache:off"
16614
16615 test_155g() {
16616         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16617
16618         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16619
16620         save_writethrough $p
16621
16622         set_cache read off
16623         set_cache writethrough on
16624         test_155_big_load
16625         restore_lustre_params < $p
16626         rm -f $p
16627 }
16628 run_test 155g "Verify big file correctness: read cache:off write_cache:on"
16629
16630 test_155h() {
16631         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16632
16633         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16634
16635         save_writethrough $p
16636
16637         set_cache read off
16638         set_cache writethrough off
16639         test_155_big_load
16640         restore_lustre_params < $p
16641         rm -f $p
16642 }
16643 run_test 155h "Verify big file correctness: read cache:off write_cache:off"
16644
16645 test_156() {
16646         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16647         remote_ost_nodsh && skip "remote OST with nodsh"
16648         [ $OST1_VERSION -lt $(version_code 2.6.93) ] &&
16649                 skip "stats not implemented on old servers"
16650         [ "$ost1_FSTYPE" = "zfs" ] &&
16651                 skip "LU-1956/LU-2261: stats not implemented on OSD ZFS"
16652         (( CLIENT_VERSION == OST1_VERSION )) ||
16653                 skip "LU-13081: no interop testing for OSS cache"
16654
16655         local CPAGES=3
16656         local BEFORE
16657         local AFTER
16658         local file="$DIR/$tfile"
16659         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16660
16661         save_writethrough $p
16662         roc_hit_init
16663
16664         log "Turn on read and write cache"
16665         set_cache read on
16666         set_cache writethrough on
16667
16668         log "Write data and read it back."
16669         log "Read should be satisfied from the cache."
16670         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
16671         BEFORE=$(roc_hit)
16672         cancel_lru_locks osc
16673         cat $file >/dev/null
16674         AFTER=$(roc_hit)
16675         if ! let "AFTER - BEFORE == CPAGES"; then
16676                 error "NOT IN CACHE (2): before: $BEFORE, after: $AFTER"
16677         else
16678                 log "cache hits: before: $BEFORE, after: $AFTER"
16679         fi
16680
16681         log "Read again; it should be satisfied from the cache."
16682         BEFORE=$AFTER
16683         cancel_lru_locks osc
16684         cat $file >/dev/null
16685         AFTER=$(roc_hit)
16686         if ! let "AFTER - BEFORE == CPAGES"; then
16687                 error "NOT IN CACHE (3): before: $BEFORE, after: $AFTER"
16688         else
16689                 log "cache hits:: before: $BEFORE, after: $AFTER"
16690         fi
16691
16692         log "Turn off the read cache and turn on the write cache"
16693         set_cache read off
16694         set_cache writethrough on
16695
16696         log "Read again; it should be satisfied from the cache."
16697         BEFORE=$(roc_hit)
16698         cancel_lru_locks osc
16699         cat $file >/dev/null
16700         AFTER=$(roc_hit)
16701         if ! let "AFTER - BEFORE == CPAGES"; then
16702                 error "NOT IN CACHE (4): before: $BEFORE, after: $AFTER"
16703         else
16704                 log "cache hits:: before: $BEFORE, after: $AFTER"
16705         fi
16706
16707         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
16708                 # > 2.12.56 uses pagecache if cached
16709                 log "Read again; it should not be satisfied from the cache."
16710                 BEFORE=$AFTER
16711                 cancel_lru_locks osc
16712                 cat $file >/dev/null
16713                 AFTER=$(roc_hit)
16714                 if ! let "AFTER - BEFORE == 0"; then
16715                         error "IN CACHE (5): before: $BEFORE, after: $AFTER"
16716                 else
16717                         log "cache hits:: before: $BEFORE, after: $AFTER"
16718                 fi
16719         fi
16720
16721         log "Write data and read it back."
16722         log "Read should be satisfied from the cache."
16723         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
16724         BEFORE=$(roc_hit)
16725         cancel_lru_locks osc
16726         cat $file >/dev/null
16727         AFTER=$(roc_hit)
16728         if ! let "AFTER - BEFORE == CPAGES"; then
16729                 error "NOT IN CACHE (6): before: $BEFORE, after: $AFTER"
16730         else
16731                 log "cache hits:: before: $BEFORE, after: $AFTER"
16732         fi
16733
16734         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
16735                 # > 2.12.56 uses pagecache if cached
16736                 log "Read again; it should not be satisfied from the cache."
16737                 BEFORE=$AFTER
16738                 cancel_lru_locks osc
16739                 cat $file >/dev/null
16740                 AFTER=$(roc_hit)
16741                 if ! let "AFTER - BEFORE == 0"; then
16742                         error "IN CACHE (7): before: $BEFORE, after: $AFTER"
16743                 else
16744                         log "cache hits:: before: $BEFORE, after: $AFTER"
16745                 fi
16746         fi
16747
16748         log "Turn off read and write cache"
16749         set_cache read off
16750         set_cache writethrough off
16751
16752         log "Write data and read it back"
16753         log "It should not be satisfied from the cache."
16754         rm -f $file
16755         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
16756         cancel_lru_locks osc
16757         BEFORE=$(roc_hit)
16758         cat $file >/dev/null
16759         AFTER=$(roc_hit)
16760         if ! let "AFTER - BEFORE == 0"; then
16761                 error_ignore bz20762 "IN CACHE (8):before:$BEFORE,after:$AFTER"
16762         else
16763                 log "cache hits:: before: $BEFORE, after: $AFTER"
16764         fi
16765
16766         log "Turn on the read cache and turn off the write cache"
16767         set_cache read on
16768         set_cache writethrough off
16769
16770         log "Write data and read it back"
16771         log "It should not be satisfied from the cache."
16772         rm -f $file
16773         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
16774         BEFORE=$(roc_hit)
16775         cancel_lru_locks osc
16776         cat $file >/dev/null
16777         AFTER=$(roc_hit)
16778         if ! let "AFTER - BEFORE == 0"; then
16779                 error_ignore bz20762 "IN CACHE (9):before:$BEFORE,after:$AFTER"
16780         else
16781                 log "cache hits:: before: $BEFORE, after: $AFTER"
16782         fi
16783
16784         log "Read again; it should be satisfied from the cache."
16785         BEFORE=$(roc_hit)
16786         cancel_lru_locks osc
16787         cat $file >/dev/null
16788         AFTER=$(roc_hit)
16789         if ! let "AFTER - BEFORE == CPAGES"; then
16790                 error "NOT IN CACHE (1): before: $BEFORE, after: $AFTER"
16791         else
16792                 log "cache hits:: before: $BEFORE, after: $AFTER"
16793         fi
16794
16795         restore_lustre_params < $p
16796         rm -f $p $file
16797 }
16798 run_test 156 "Verification of tunables"
16799
16800 test_160a() {
16801         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16802         remote_mds_nodsh && skip "remote MDS with nodsh"
16803         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
16804                 skip "Need MDS version at least 2.2.0"
16805
16806         changelog_register || error "changelog_register failed"
16807         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16808         changelog_users $SINGLEMDS | grep -q $cl_user ||
16809                 error "User $cl_user not found in changelog_users"
16810
16811         mkdir_on_mdt0 $DIR/$tdir
16812
16813         # change something
16814         test_mkdir -p $DIR/$tdir/pics/2008/zachy
16815         changelog_clear 0 || error "changelog_clear failed"
16816         touch $DIR/$tdir/pics/2008/zachy/$tfile                 # open 1
16817         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg       # open 2
16818         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
16819         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
16820         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
16821         rm $DIR/$tdir/pics/desktop.jpg
16822
16823         echo "verifying changelog mask"
16824         changelog_chmask "-MKDIR"
16825         changelog_chmask "-CLOSE"
16826
16827         test_mkdir -p $DIR/$tdir/pics/zach/sofia                # not logged
16828         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # not logged
16829
16830         changelog_chmask "+MKDIR"
16831         changelog_chmask "+CLOSE"
16832
16833         test_mkdir -p $DIR/$tdir/pics/2008/sofia                # mkdir 1
16834         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # open 3
16835
16836         MKDIRS=$(changelog_dump | grep -c "MKDIR")
16837         CLOSES=$(changelog_dump | grep -c "CLOSE")
16838         [ $MKDIRS -eq 1 ] || error "MKDIR changelog mask count $MKDIRS != 1"
16839         [ $CLOSES -eq 3 ] || error "CLOSE changelog mask count $CLOSES != 3"
16840
16841         # verify contents
16842         echo "verifying target fid"
16843         local fidc=$(changelog_extract_field "CREAT" "$tfile" "t=")
16844         local fidf=$($LFS path2fid $DIR/$tdir/pics/zach/$tfile)
16845         [ "$fidc" == "$fidf" ] ||
16846                 error "changelog '$tfile' fid $fidc != file fid $fidf"
16847         echo "verifying parent fid"
16848         # The FID returned from the Changelog may be the directory shard on
16849         # a different MDT, and not the FID returned by path2fid on the parent.
16850         # Instead of comparing FIDs, verify that fid2path(fidp) is correct,
16851         # since this is what will matter when recreating this file in the tree.
16852         local fidp=$(changelog_extract_field "CREAT" "$tfile" "p=")
16853         local pathp=$($LFS fid2path $MOUNT "$fidp")
16854         [ "${pathp%/}" == "$DIR/$tdir/pics/zach" ] ||
16855                 error "changelog fid2path($fidc) $pathp != $DIR/$tdir/pics/zach"
16856
16857         echo "getting records for $cl_user"
16858         changelog_users $SINGLEMDS
16859         local user_rec1=$(changelog_user_rec $SINGLEMDS $cl_user)
16860         local nclr=3
16861         __changelog_clear $SINGLEMDS $cl_user +$nclr ||
16862                 error "changelog_clear failed"
16863         local user_rec2=$(changelog_user_rec $SINGLEMDS $cl_user)
16864         echo "verifying user clear: $user_rec1 + $nclr == $user_rec2"
16865         [ $user_rec2 == $((user_rec1 + nclr)) ] ||
16866                 error "user index expect $user_rec1 + $nclr != $user_rec2"
16867
16868         local min0_rec=$(changelog_users $SINGLEMDS |
16869                 awk 'min == "" || $2 < min { min = $2 }; END { print min }')
16870         local first_rec=$($LFS changelog $(facet_svc $SINGLEMDS) |
16871                           awk '{ print $1; exit; }')
16872
16873         changelog_dump | tail -n 5
16874         echo "verifying user min purge: $min0_rec + 1 == $first_rec"
16875         [ $first_rec == $((min0_rec + 1)) ] ||
16876                 error "first index should be $min0_rec + 1 not $first_rec"
16877
16878         # LU-3446 changelog index reset on MDT restart
16879         local cur_rec1=$(changelog_users $SINGLEMDS |
16880                          awk '/^current.index:/ { print $NF }')
16881         changelog_clear 0 ||
16882                 error "clear all changelog records for $cl_user failed"
16883         stop $SINGLEMDS || error "Fail to stop $SINGLEMDS"
16884         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
16885                 error "Fail to start $SINGLEMDS"
16886         local cur_rec2=$(changelog_users $SINGLEMDS |
16887                          awk '/^current.index:/ { print $NF }')
16888         echo "verifying index survives MDT restart: $cur_rec1 == $cur_rec2"
16889         [ $cur_rec1 == $cur_rec2 ] ||
16890                 error "current index should be $cur_rec1 not $cur_rec2"
16891
16892         echo "verifying users from this test are deregistered"
16893         changelog_deregister || error "changelog_deregister failed"
16894         changelog_users $SINGLEMDS | grep -q $cl_user &&
16895                 error "User '$cl_user' still in changelog_users"
16896
16897         # lctl get_param -n mdd.*.changelog_users
16898         # current_index: 144
16899         # ID    index (idle seconds)
16900         # cl3   144   (2) mask=<list>
16901         if [ -z "$(changelog_users $SINGLEMDS | grep -v current.index)" ]; then
16902                 # this is the normal case where all users were deregistered
16903                 # make sure no new records are added when no users are present
16904                 local last_rec1=$(changelog_users $SINGLEMDS |
16905                                   awk '/^current.index:/ { print $NF }')
16906                 touch $DIR/$tdir/chloe
16907                 local last_rec2=$(changelog_users $SINGLEMDS |
16908                                   awk '/^current.index:/ { print $NF }')
16909                 echo "verify changelogs are off: $last_rec1 == $last_rec2"
16910                 [ $last_rec1 == $last_rec2 ] || error "changelogs not off"
16911         else
16912                 # any changelog users must be leftovers from a previous test
16913                 changelog_users $SINGLEMDS
16914                 echo "other changelog users; can't verify off"
16915         fi
16916 }
16917 run_test 160a "changelog sanity"
16918
16919 test_160b() { # LU-3587
16920         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16921         remote_mds_nodsh && skip "remote MDS with nodsh"
16922         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
16923                 skip "Need MDS version at least 2.2.0"
16924
16925         changelog_register || error "changelog_register failed"
16926         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16927         changelog_users $SINGLEMDS | grep -q $cl_user ||
16928                 error "User '$cl_user' not found in changelog_users"
16929
16930         local longname1=$(str_repeat a 255)
16931         local longname2=$(str_repeat b 255)
16932
16933         cd $DIR
16934         echo "creating very long named file"
16935         touch $longname1 || error "create of '$longname1' failed"
16936         echo "renaming very long named file"
16937         mv $longname1 $longname2
16938
16939         changelog_dump | grep RENME | tail -n 5
16940         rm -f $longname2
16941 }
16942 run_test 160b "Verify that very long rename doesn't crash in changelog"
16943
16944 test_160c() {
16945         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16946         remote_mds_nodsh && skip "remote MDS with nodsh"
16947
16948         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
16949                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
16950                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
16951                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
16952
16953         local rc=0
16954
16955         # Registration step
16956         changelog_register || error "changelog_register failed"
16957
16958         rm -rf $DIR/$tdir
16959         mkdir -p $DIR/$tdir
16960         $MCREATE $DIR/$tdir/foo_160c
16961         changelog_chmask "-TRUNC"
16962         $TRUNCATE $DIR/$tdir/foo_160c 200
16963         changelog_chmask "+TRUNC"
16964         $TRUNCATE $DIR/$tdir/foo_160c 199
16965         changelog_dump | tail -n 5
16966         local truncs=$(changelog_dump | tail -n 5 | grep -c TRUNC)
16967         [ $truncs -eq 1 ] || error "TRUNC changelog mask count $truncs != 1"
16968 }
16969 run_test 160c "verify that changelog log catch the truncate event"
16970
16971 test_160d() {
16972         remote_mds_nodsh && skip "remote MDS with nodsh"
16973         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16974         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16975         [[ $MDS1_VERSION -ge $(version_code 2.7.60) ]] ||
16976                 skip "Need MDS version at least 2.7.60"
16977
16978         # Registration step
16979         changelog_register || error "changelog_register failed"
16980
16981         mkdir -p $DIR/$tdir/migrate_dir
16982         changelog_clear 0 || error "changelog_clear failed"
16983
16984         $LFS migrate -m 1 $DIR/$tdir/migrate_dir || error "migrate fails"
16985         changelog_dump | tail -n 5
16986         local migrates=$(changelog_dump | grep -c "MIGRT")
16987         [ $migrates -eq 1 ] || error "MIGRATE changelog count $migrates != 1"
16988 }
16989 run_test 160d "verify that changelog log catch the migrate event"
16990
16991 test_160e() {
16992         remote_mds_nodsh && skip "remote MDS with nodsh"
16993
16994         # Create a user
16995         changelog_register || error "changelog_register failed"
16996
16997         local MDT0=$(facet_svc $SINGLEMDS)
16998         local rc
16999
17000         # No user (expect fail)
17001         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister
17002         rc=$?
17003         if [ $rc -eq 0 ]; then
17004                 error "Should fail without user"
17005         elif [ $rc -ne 4 ]; then
17006                 error "changelog_deregister failed with $rc, expect 4(CMD_HELP)"
17007         fi
17008
17009         # Delete a future user (expect fail)
17010         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister "cl77"
17011         rc=$?
17012         if [ $rc -eq 0 ]; then
17013                 error "Deleted non-existant user cl77"
17014         elif [ $rc -ne 2 ]; then
17015                 error "changelog_deregister failed with $rc, expect 2 (ENOENT)"
17016         fi
17017
17018         # Clear to a bad index (1 billion should be safe)
17019         $LFS changelog_clear $MDT0 "${CL_USERS[$SINGLEMDS]%% *}" 1000000000
17020         rc=$?
17021
17022         if [ $rc -eq 0 ]; then
17023                 error "Successfully cleared to invalid CL index"
17024         elif [ $rc -ne 22 ]; then
17025                 error "changelog_clear failed with $rc, expected 22 (EINVAL)"
17026         fi
17027 }
17028 run_test 160e "changelog negative testing (should return errors)"
17029
17030 test_160f() {
17031         remote_mds_nodsh && skip "remote MDS with nodsh" && return
17032         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
17033                 skip "Need MDS version at least 2.10.56"
17034
17035         local mdts=$(comma_list $(mdts_nodes))
17036
17037         # Create a user
17038         changelog_register || error "first changelog_register failed"
17039         changelog_register || error "second changelog_register failed"
17040         local cl_users
17041         declare -A cl_user1
17042         declare -A cl_user2
17043         local user_rec1
17044         local user_rec2
17045         local i
17046
17047         # generate some changelog records to accumulate on each MDT
17048         # use all_char because created files should be evenly distributed
17049         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
17050                 error "test_mkdir $tdir failed"
17051         log "$(date +%s): creating first files"
17052         for ((i = 0; i < MDSCOUNT * 2; i++)); do
17053                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT)) ||
17054                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT)) failed"
17055         done
17056
17057         # check changelogs have been generated
17058         local start=$SECONDS
17059         local idle_time=$((MDSCOUNT * 5 + 5))
17060         local nbcl=$(changelog_dump | wc -l)
17061         [[ $nbcl -eq 0 ]] && error "no changelogs found"
17062
17063         for param in "changelog_max_idle_time=$idle_time" \
17064                      "changelog_gc=1" \
17065                      "changelog_min_gc_interval=2" \
17066                      "changelog_min_free_cat_entries=3"; do
17067                 local MDT0=$(facet_svc $SINGLEMDS)
17068                 local var="${param%=*}"
17069                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
17070
17071                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
17072                 do_nodes $mdts $LCTL set_param mdd.*.$param
17073         done
17074
17075         # force cl_user2 to be idle (1st part), but also cancel the
17076         # cl_user1 records so that it is not evicted later in the test.
17077         local sleep1=$((idle_time / 2))
17078         echo "$(date +%s): sleep1 $sleep1/${idle_time}s"
17079         sleep $sleep1
17080
17081         # simulate changelog catalog almost full
17082         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
17083         do_nodes $mdts "$LCTL set_param fail_loc=0x1313 fail_val=3"
17084
17085         for i in $(seq $MDSCOUNT); do
17086                 cl_users=(${CL_USERS[mds$i]})
17087                 cl_user1[mds$i]="${cl_users[0]}"
17088                 cl_user2[mds$i]="${cl_users[1]}"
17089
17090                 [ -n "${cl_user1[mds$i]}" ] ||
17091                         error "mds$i: no user registered"
17092                 [ -n "${cl_user2[mds$i]}" ] ||
17093                         error "mds$i: only ${cl_user2[mds$i]} is registered"
17094
17095                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17096                 [ -n "$user_rec1" ] ||
17097                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17098                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
17099                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17100                 [ -n "$user_rec2" ] ||
17101                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17102                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
17103                      "$user_rec1 + 2 == $user_rec2"
17104                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
17105                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
17106                               "$user_rec1 + 2, but is $user_rec2"
17107                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
17108                 [ -n "$user_rec2" ] ||
17109                         error "mds$i: User ${cl_user2[mds$i]} not registered"
17110                 [ $user_rec1 == $user_rec2 ] ||
17111                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
17112                               "$user_rec1, but is $user_rec2"
17113         done
17114
17115         # force cl_user2 idle (2nd part) to just exceed changelog_max_idle_time
17116         local sleep2=$((idle_time - (SECONDS - start) + 1))
17117         echo "$(date +%s): sleep2 $sleep2/${idle_time}s"
17118         sleep $sleep2
17119
17120         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
17121         # cl_user1 should be OK because it recently processed records.
17122         echo "$(date +%s): creating $((MDSCOUNT * 2)) files"
17123         for ((i = 0; i < MDSCOUNT * 2; i++)); do
17124                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT+2))||
17125                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT+2)) failed"
17126         done
17127
17128         # ensure gc thread is done
17129         for i in $(mdts_nodes); do
17130                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
17131                         error "$i: GC-thread not done"
17132         done
17133
17134         local first_rec
17135         for (( i = 1; i <= MDSCOUNT; i++ )); do
17136                 # check cl_user1 still registered
17137                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
17138                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17139                 # check cl_user2 unregistered
17140                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
17141                         error "mds$i: User ${cl_user2[mds$i]} still registered"
17142
17143                 # check changelogs are present and starting at $user_rec1 + 1
17144                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17145                 [ -n "$user_rec1" ] ||
17146                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17147                 first_rec=$($LFS changelog $(facet_svc mds$i) |
17148                             awk '{ print $1; exit; }')
17149
17150                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
17151                 [ $((user_rec1 + 1)) == $first_rec ] ||
17152                         error "mds$i: rec $first_rec != $user_rec1 + 1"
17153         done
17154 }
17155 run_test 160f "changelog garbage collect (timestamped users)"
17156
17157 test_160g() {
17158         remote_mds_nodsh && skip "remote MDS with nodsh"
17159         [[ $MDS1_VERSION -ge $(version_code 2.14.55) ]] ||
17160                 skip "Need MDS version at least 2.14.55"
17161
17162         local mdts=$(comma_list $(mdts_nodes))
17163
17164         # Create a user
17165         changelog_register || error "first changelog_register failed"
17166         changelog_register || error "second changelog_register failed"
17167         local cl_users
17168         declare -A cl_user1
17169         declare -A cl_user2
17170         local user_rec1
17171         local user_rec2
17172         local i
17173
17174         # generate some changelog records to accumulate on each MDT
17175         # use all_char because created files should be evenly distributed
17176         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
17177                 error "test_mkdir $tdir failed"
17178         for ((i = 0; i < MDSCOUNT; i++)); do
17179                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
17180                         error "create $DIR/$tdir/d$i.1 failed"
17181         done
17182
17183         # check changelogs have been generated
17184         local nbcl=$(changelog_dump | wc -l)
17185         (( $nbcl > 0 )) || error "no changelogs found"
17186
17187         # reduce the max_idle_indexes value to make sure we exceed it
17188         for param in "changelog_max_idle_indexes=2" \
17189                      "changelog_gc=1" \
17190                      "changelog_min_gc_interval=2"; do
17191                 local MDT0=$(facet_svc $SINGLEMDS)
17192                 local var="${param%=*}"
17193                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
17194
17195                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
17196                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
17197                         error "unable to set mdd.*.$param"
17198         done
17199
17200         local start=$SECONDS
17201         for i in $(seq $MDSCOUNT); do
17202                 cl_users=(${CL_USERS[mds$i]})
17203                 cl_user1[mds$i]="${cl_users[0]}"
17204                 cl_user2[mds$i]="${cl_users[1]}"
17205
17206                 [ -n "${cl_user1[mds$i]}" ] ||
17207                         error "mds$i: user1 is not registered"
17208                 [ -n "${cl_user2[mds$i]}" ] ||
17209                         error "mds$i: only ${cl_user1[mds$i]} is registered"
17210
17211                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17212                 [ -n "$user_rec1" ] ||
17213                         error "mds$i: user1 ${cl_user1[mds$i]} not found"
17214                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
17215                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17216                 [ -n "$user_rec2" ] ||
17217                         error "mds$i: user1 ${cl_user1[mds$i]} not found (2)"
17218                 echo "mds$i: verifying user1 ${cl_user1[mds$i]} clear: " \
17219                      "$user_rec1 + 2 == $user_rec2"
17220                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
17221                         error "mds$i: user1 ${cl_user1[mds$i]} index " \
17222                               "expected $user_rec1 + 2, but is $user_rec2"
17223                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
17224                 [ -n "$user_rec2" ] ||
17225                         error "mds$i: user2 ${cl_user2[mds$i]} not found"
17226                 [ $user_rec1 == $user_rec2 ] ||
17227                         error "mds$i: user2 ${cl_user2[mds$i]} index " \
17228                               "expected $user_rec1, but is $user_rec2"
17229         done
17230
17231         # ensure we are past the previous changelog_min_gc_interval set above
17232         local sleep2=$((start + 2 - SECONDS))
17233         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
17234         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
17235         # cl_user1 should be OK because it recently processed records.
17236         for ((i = 0; i < MDSCOUNT; i++)); do
17237                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 ||
17238                         error "create $DIR/$tdir/d$i.3 failed"
17239         done
17240
17241         # ensure gc thread is done
17242         for i in $(mdts_nodes); do
17243                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
17244                         error "$i: GC-thread not done"
17245         done
17246
17247         local first_rec
17248         for (( i = 1; i <= MDSCOUNT; i++ )); do
17249                 # check cl_user1 still registered
17250                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
17251                         error "mds$i: user1 ${cl_user1[mds$i]} not found (3)"
17252                 # check cl_user2 unregistered
17253                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
17254                         error "mds$i: user2 ${cl_user2[mds$i]} is registered"
17255
17256                 # check changelogs are present and starting at $user_rec1 + 1
17257                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17258                 [ -n "$user_rec1" ] ||
17259                         error "mds$i: user1 ${cl_user1[mds$i]} not found (4)"
17260                 first_rec=$($LFS changelog $(facet_svc mds$i) |
17261                             awk '{ print $1; exit; }')
17262
17263                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
17264                 [ $((user_rec1 + 1)) == $first_rec ] ||
17265                         error "mds$i: rec $first_rec != $user_rec1 + 1"
17266         done
17267 }
17268 run_test 160g "changelog garbage collect on idle records"
17269
17270 test_160h() {
17271         remote_mds_nodsh && skip "remote MDS with nodsh" && return
17272         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
17273                 skip "Need MDS version at least 2.10.56"
17274
17275         local mdts=$(comma_list $(mdts_nodes))
17276
17277         # Create a user
17278         changelog_register || error "first changelog_register failed"
17279         changelog_register || error "second changelog_register failed"
17280         local cl_users
17281         declare -A cl_user1
17282         declare -A cl_user2
17283         local user_rec1
17284         local user_rec2
17285         local i
17286
17287         # generate some changelog records to accumulate on each MDT
17288         # use all_char because created files should be evenly distributed
17289         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
17290                 error "test_mkdir $tdir failed"
17291         for ((i = 0; i < MDSCOUNT; i++)); do
17292                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
17293                         error "create $DIR/$tdir/d$i.1 failed"
17294         done
17295
17296         # check changelogs have been generated
17297         local nbcl=$(changelog_dump | wc -l)
17298         [[ $nbcl -eq 0 ]] && error "no changelogs found"
17299
17300         for param in "changelog_max_idle_time=10" \
17301                      "changelog_gc=1" \
17302                      "changelog_min_gc_interval=2"; do
17303                 local MDT0=$(facet_svc $SINGLEMDS)
17304                 local var="${param%=*}"
17305                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
17306
17307                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
17308                 do_nodes $mdts $LCTL set_param mdd.*.$param
17309         done
17310
17311         # force cl_user2 to be idle (1st part)
17312         sleep 9
17313
17314         for i in $(seq $MDSCOUNT); do
17315                 cl_users=(${CL_USERS[mds$i]})
17316                 cl_user1[mds$i]="${cl_users[0]}"
17317                 cl_user2[mds$i]="${cl_users[1]}"
17318
17319                 [ -n "${cl_user1[mds$i]}" ] ||
17320                         error "mds$i: no user registered"
17321                 [ -n "${cl_user2[mds$i]}" ] ||
17322                         error "mds$i: only ${cl_user2[mds$i]} is registered"
17323
17324                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17325                 [ -n "$user_rec1" ] ||
17326                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17327                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
17328                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17329                 [ -n "$user_rec2" ] ||
17330                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17331                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
17332                      "$user_rec1 + 2 == $user_rec2"
17333                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
17334                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
17335                               "$user_rec1 + 2, but is $user_rec2"
17336                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
17337                 [ -n "$user_rec2" ] ||
17338                         error "mds$i: User ${cl_user2[mds$i]} not registered"
17339                 [ $user_rec1 == $user_rec2 ] ||
17340                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
17341                               "$user_rec1, but is $user_rec2"
17342         done
17343
17344         # force cl_user2 to be idle (2nd part) and to reach
17345         # changelog_max_idle_time
17346         sleep 2
17347
17348         # force each GC-thread start and block then
17349         # one per MDT/MDD, set fail_val accordingly
17350         #define OBD_FAIL_FORCE_GC_THREAD 0x1316
17351         do_nodes $mdts $LCTL set_param fail_loc=0x1316
17352
17353         # generate more changelogs to trigger fail_loc
17354         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
17355                 error "create $DIR/$tdir/${tfile}bis failed"
17356
17357         # stop MDT to stop GC-thread, should be done in back-ground as it will
17358         # block waiting for the thread to be released and exit
17359         declare -A stop_pids
17360         for i in $(seq $MDSCOUNT); do
17361                 stop mds$i &
17362                 stop_pids[mds$i]=$!
17363         done
17364
17365         for i in $(mdts_nodes); do
17366                 local facet
17367                 local nb=0
17368                 local facets=$(facets_up_on_host $i)
17369
17370                 for facet in ${facets//,/ }; do
17371                         if [[ $facet == mds* ]]; then
17372                                 nb=$((nb + 1))
17373                         fi
17374                 done
17375                 # ensure each MDS's gc threads are still present and all in "R"
17376                 # state (OBD_FAIL_FORCE_GC_THREAD effect!)
17377                 [[ $(do_node $i pgrep chlg_gc_thread | wc -l) -eq $nb ]] ||
17378                         error "$i: expected $nb GC-thread"
17379                 wait_update $i \
17380                         "ps -C chlg_gc_thread -o state --no-headers | uniq" \
17381                         "R" 20 ||
17382                         error "$i: GC-thread not found in R-state"
17383                 # check umounts of each MDT on MDS have reached kthread_stop()
17384                 [[ $(do_node $i pgrep umount | wc -l) -eq $nb ]] ||
17385                         error "$i: expected $nb umount"
17386                 wait_update $i \
17387                         "ps -C umount -o state --no-headers | uniq" "D" 20 ||
17388                         error "$i: umount not found in D-state"
17389         done
17390
17391         # release all GC-threads
17392         do_nodes $mdts $LCTL set_param fail_loc=0
17393
17394         # wait for MDT stop to complete
17395         for i in $(seq $MDSCOUNT); do
17396                 wait ${stop_pids[mds$i]} || error "mds$i: stop failed"
17397         done
17398
17399         # XXX
17400         # may try to check if any orphan changelog records are present
17401         # via ldiskfs/zfs and llog_reader...
17402
17403         # re-start/mount MDTs
17404         for i in $(seq $MDSCOUNT); do
17405                 start mds$i $(mdsdevname $i) $MDS_MOUNT_OPTS ||
17406                         error "Fail to start mds$i"
17407         done
17408
17409         local first_rec
17410         for i in $(seq $MDSCOUNT); do
17411                 # check cl_user1 still registered
17412                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
17413                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17414                 # check cl_user2 unregistered
17415                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
17416                         error "mds$i: User ${cl_user2[mds$i]} still registered"
17417
17418                 # check changelogs are present and starting at $user_rec1 + 1
17419                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17420                 [ -n "$user_rec1" ] ||
17421                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17422                 first_rec=$($LFS changelog $(facet_svc mds$i) |
17423                             awk '{ print $1; exit; }')
17424
17425                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
17426                 [ $((user_rec1 + 1)) == $first_rec ] ||
17427                         error "mds$i: first index should be $user_rec1 + 1, " \
17428                               "but is $first_rec"
17429         done
17430 }
17431 run_test 160h "changelog gc thread stop upon umount, orphan records delete " \
17432               "during mount"
17433
17434 test_160i() {
17435
17436         local mdts=$(comma_list $(mdts_nodes))
17437
17438         changelog_register || error "first changelog_register failed"
17439
17440         # generate some changelog records to accumulate on each MDT
17441         # use all_char because created files should be evenly distributed
17442         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
17443                 error "test_mkdir $tdir failed"
17444         for ((i = 0; i < MDSCOUNT; i++)); do
17445                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
17446                         error "create $DIR/$tdir/d$i.1 failed"
17447         done
17448
17449         # check changelogs have been generated
17450         local nbcl=$(changelog_dump | wc -l)
17451         [[ $nbcl -eq 0 ]] && error "no changelogs found"
17452
17453         # simulate race between register and unregister
17454         # XXX as fail_loc is set per-MDS, with DNE configs the race
17455         # simulation will only occur for one MDT per MDS and for the
17456         # others the normal race scenario will take place
17457         #define CFS_FAIL_CHLOG_USER_REG_UNREG_RACE          0x1315
17458         do_nodes $mdts $LCTL set_param fail_loc=0x10001315
17459         do_nodes $mdts $LCTL set_param fail_val=1
17460
17461         # unregister 1st user
17462         changelog_deregister &
17463         local pid1=$!
17464         # wait some time for deregister work to reach race rdv
17465         sleep 2
17466         # register 2nd user
17467         changelog_register || error "2nd user register failed"
17468
17469         wait $pid1 || error "1st user deregister failed"
17470
17471         local i
17472         local last_rec
17473         declare -A LAST_REC
17474         for i in $(seq $MDSCOUNT); do
17475                 if changelog_users mds$i | grep "^cl"; then
17476                         # make sure new records are added with one user present
17477                         LAST_REC[mds$i]=$(changelog_users $SINGLEMDS |
17478                                           awk '/^current.index:/ { print $NF }')
17479                 else
17480                         error "mds$i has no user registered"
17481                 fi
17482         done
17483
17484         # generate more changelog records to accumulate on each MDT
17485         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
17486                 error "create $DIR/$tdir/${tfile}bis failed"
17487
17488         for i in $(seq $MDSCOUNT); do
17489                 last_rec=$(changelog_users $SINGLEMDS |
17490                            awk '/^current.index:/ { print $NF }')
17491                 echo "verify changelogs are on: $last_rec != ${LAST_REC[mds$i]}"
17492                 [ $last_rec != ${LAST_REC[mds$i]} ] ||
17493                         error "changelogs are off on mds$i"
17494         done
17495 }
17496 run_test 160i "changelog user register/unregister race"
17497
17498 test_160j() {
17499         remote_mds_nodsh && skip "remote MDS with nodsh"
17500         [[ $MDS1_VERSION -lt $(version_code 2.12.56) ]] &&
17501                 skip "Need MDS version at least 2.12.56"
17502
17503         mount_client $MOUNT2 || error "mount_client on $MOUNT2 failed"
17504         stack_trap "umount $MOUNT2" EXIT
17505
17506         changelog_register || error "first changelog_register failed"
17507         stack_trap "changelog_deregister" EXIT
17508
17509         # generate some changelog
17510         # use all_char because created files should be evenly distributed
17511         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
17512                 error "mkdir $tdir failed"
17513         for ((i = 0; i < MDSCOUNT; i++)); do
17514                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
17515                         error "create $DIR/$tdir/d$i.1 failed"
17516         done
17517
17518         # open the changelog device
17519         exec 3>/dev/changelog-$FSNAME-MDT0000
17520         stack_trap "exec 3>&-" EXIT
17521         exec 4</dev/changelog-$FSNAME-MDT0000
17522         stack_trap "exec 4<&-" EXIT
17523
17524         # umount the first lustre mount
17525         umount $MOUNT
17526         stack_trap "mount_client $MOUNT" EXIT
17527
17528         # read changelog, which may or may not fail, but should not crash
17529         cat <&4 >/dev/null
17530
17531         # clear changelog
17532         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
17533         changelog_users $SINGLEMDS | grep -q $cl_user ||
17534                 error "User $cl_user not found in changelog_users"
17535
17536         printf 'clear:'$cl_user':0' >&3
17537 }
17538 run_test 160j "client can be umounted while its chanangelog is being used"
17539
17540 test_160k() {
17541         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17542         remote_mds_nodsh && skip "remote MDS with nodsh"
17543
17544         mkdir -p $DIR/$tdir/1/1
17545
17546         changelog_register || error "changelog_register failed"
17547         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
17548
17549         changelog_users $SINGLEMDS | grep -q $cl_user ||
17550                 error "User '$cl_user' not found in changelog_users"
17551 #define OBD_FAIL_MDS_CHANGELOG_REORDER 0x15d
17552         do_facet mds1 $LCTL set_param fail_loc=0x8000015d fail_val=3
17553         rmdir $DIR/$tdir/1/1 & sleep 1
17554         mkdir $DIR/$tdir/2
17555         touch $DIR/$tdir/2/2
17556         rm -rf $DIR/$tdir/2
17557
17558         wait
17559         sleep 4
17560
17561         changelog_dump | grep rmdir || error "rmdir not recorded"
17562 }
17563 run_test 160k "Verify that changelog records are not lost"
17564
17565 # Verifies that a file passed as a parameter has recently had an operation
17566 # performed on it that has generated an MTIME changelog which contains the
17567 # correct parent FID. As files might reside on a different MDT from the
17568 # parent directory in DNE configurations, the FIDs are translated to paths
17569 # before being compared, which should be identical
17570 compare_mtime_changelog() {
17571         local file="${1}"
17572         local mdtidx
17573         local mtime
17574         local cl_fid
17575         local pdir
17576         local dir
17577
17578         mdtidx=$($LFS getstripe --mdt-index $file)
17579         mdtidx=$(printf "%04x" $mdtidx)
17580
17581         # Obtain the parent FID from the MTIME changelog
17582         mtime=$($LFS changelog $FSNAME-MDT$mdtidx | tail -n 1 | grep MTIME)
17583         [ -z "$mtime" ] && error "MTIME changelog not recorded"
17584
17585         cl_fid=$(sed -e 's/.* p=//' -e 's/ .*//' <<<$mtime)
17586         [ -z "$cl_fid" ] && error "parent FID not present"
17587
17588         # Verify that the path for the parent FID is the same as the path for
17589         # the test directory
17590         pdir=$($LFS fid2path $MOUNT "$cl_fid")
17591
17592         dir=$(dirname $1)
17593
17594         [[ "${pdir%/}" == "$dir" ]] ||
17595                 error "MTIME changelog parent FID is wrong, expected $dir, got $pdir"
17596 }
17597
17598 test_160l() {
17599         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17600
17601         remote_mds_nodsh && skip "remote MDS with nodsh"
17602         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
17603                 skip "Need MDS version at least 2.13.55"
17604
17605         local cl_user
17606
17607         changelog_register || error "changelog_register failed"
17608         cl_user="${CL_USERS[$SINGLEMDS]%% *}"
17609
17610         changelog_users $SINGLEMDS | grep -q $cl_user ||
17611                 error "User '$cl_user' not found in changelog_users"
17612
17613         # Clear some types so that MTIME changelogs are generated
17614         changelog_chmask "-CREAT"
17615         changelog_chmask "-CLOSE"
17616
17617         test_mkdir $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
17618
17619         # Test CL_MTIME during setattr
17620         touch $DIR/$tdir/$tfile
17621         compare_mtime_changelog $DIR/$tdir/$tfile
17622
17623         # Test CL_MTIME during close
17624         $MULTIOP $DIR/$tdir/${tfile}_2 O_2w4096c || error "multiop failed"
17625         compare_mtime_changelog $DIR/$tdir/${tfile}_2
17626 }
17627 run_test 160l "Verify that MTIME changelog records contain the parent FID"
17628
17629 test_160m() {
17630         remote_mds_nodsh && skip "remote MDS with nodsh" && return
17631         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
17632                 skip "Need MDS version at least 2.14.51"
17633         local cl_users
17634         local cl_user1
17635         local cl_user2
17636         local pid1
17637
17638         # Create a user
17639         changelog_register || error "first changelog_register failed"
17640         changelog_register || error "second changelog_register failed"
17641
17642         cl_users=(${CL_USERS[mds1]})
17643         cl_user1="${cl_users[0]}"
17644         cl_user2="${cl_users[1]}"
17645         # generate some changelog records to accumulate on MDT0
17646         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
17647         createmany -m $DIR/$tdir/$tfile 50 ||
17648                 error "create $DIR/$tdir/$tfile failed"
17649         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
17650         rm -f $DIR/$tdir
17651
17652         # check changelogs have been generated
17653         local nbcl=$(changelog_dump | wc -l)
17654         [[ $nbcl -eq 0 ]] && error "no changelogs found"
17655
17656 #define OBD_FAIL_MDS_CHANGELOG_RACE      0x15f
17657         do_facet mds1 $LCTL set_param fail_loc=0x8000015f fail_val=0
17658
17659         __changelog_clear mds1 $cl_user1 +10
17660         __changelog_clear mds1 $cl_user2 0 &
17661         pid1=$!
17662         sleep 2
17663         __changelog_clear mds1 $cl_user1 0 ||
17664                 error "fail to cancel record for $cl_user1"
17665         wait $pid1
17666         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
17667 }
17668 run_test 160m "Changelog clear race"
17669
17670 test_160n() {
17671         remote_mds_nodsh && skip "remote MDS with nodsh" && return
17672         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
17673                 skip "Need MDS version at least 2.14.51"
17674         local cl_users
17675         local cl_user1
17676         local cl_user2
17677         local pid1
17678         local first_rec
17679         local last_rec=0
17680
17681         # Create a user
17682         changelog_register || error "first changelog_register failed"
17683
17684         cl_users=(${CL_USERS[mds1]})
17685         cl_user1="${cl_users[0]}"
17686
17687         # generate some changelog records to accumulate on MDT0
17688         test_mkdir -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
17689         first_rec=$(changelog_users $SINGLEMDS |
17690                         awk '/^current.index:/ { print $NF }')
17691         while (( last_rec < (( first_rec + 65000)) )); do
17692                 createmany -m $DIR/$tdir/$tfile 10000 ||
17693                         error "create $DIR/$tdir/$tfile failed"
17694
17695                 for i in $(seq 0 10000); do
17696                         mrename $DIR/$tdir/$tfile$i $DIR/$tdir/$tfile-new$i \
17697                                 > /dev/null
17698                 done
17699
17700                 unlinkmany $DIR/$tdir/$tfile-new 10000 ||
17701                         error "unlinkmany failed unlink"
17702                 last_rec=$(changelog_users $SINGLEMDS |
17703                         awk '/^current.index:/ { print $NF }')
17704                 echo last record $last_rec
17705                 (( last_rec == 0 )) && error "no changelog found"
17706         done
17707
17708 #define OBD_FAIL_MDS_CHANGELOG_DEL       0x16c
17709         do_facet mds1 $LCTL set_param fail_loc=0x8000016c fail_val=0
17710
17711         __changelog_clear mds1 $cl_user1 0 &
17712         pid1=$!
17713         sleep 2
17714         __changelog_clear mds1 $cl_user1 0 ||
17715                 error "fail to cancel record for $cl_user1"
17716         wait $pid1
17717         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
17718 }
17719 run_test 160n "Changelog destroy race"
17720
17721 test_160o() {
17722         local mdt="$(facet_svc $SINGLEMDS)"
17723
17724         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
17725         remote_mds_nodsh && skip "remote MDS with nodsh"
17726         [ $MDS1_VERSION -ge $(version_code 2.14.52) ] ||
17727                 skip "Need MDS version at least 2.14.52"
17728
17729         changelog_register --user test_160o -m unlnk+close+open ||
17730                 error "changelog_register failed"
17731
17732         do_facet $SINGLEMDS $LCTL --device $mdt \
17733                                 changelog_register -u "Tt3_-#" &&
17734                 error "bad symbols in name should fail"
17735
17736         do_facet $SINGLEMDS $LCTL --device $mdt \
17737                                 changelog_register -u test_160o &&
17738                 error "the same name registration should fail"
17739
17740         do_facet $SINGLEMDS $LCTL --device $mdt \
17741                         changelog_register -u test_160toolongname &&
17742                 error "too long name registration should fail"
17743
17744         changelog_chmask "MARK+HSM"
17745         lctl get_param mdd.*.changelog*mask
17746         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
17747         changelog_users $SINGLEMDS | grep -q $cl_user ||
17748                 error "User $cl_user not found in changelog_users"
17749         #verify username
17750         echo $cl_user | grep -q test_160o ||
17751                 error "User $cl_user has no specific name 'test160o'"
17752
17753         # change something
17754         changelog_clear 0 || error "changelog_clear failed"
17755         # generate some changelog records to accumulate on MDT0
17756         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
17757         touch $DIR/$tdir/$tfile                 # open 1
17758
17759         OPENS=$(changelog_dump | grep -c "OPEN")
17760         [[ $OPENS -eq 1 ]] || error "OPEN changelog mask count $OPENS != 1"
17761
17762         # must be no MKDIR it wasn't set as user mask
17763         MKDIR=$(changelog_dump | grep -c "MKDIR")
17764         [[ $MKDIR -eq 0 ]] || error "MKDIR changelog mask found $MKDIR > 0"
17765
17766         oldmask=$(do_facet $SINGLEMDS $LCTL get_param \
17767                                 mdd.$mdt.changelog_current_mask -n)
17768         # register maskless user
17769         changelog_register || error "changelog_register failed"
17770         # effective mask should be not changed because it is not minimal
17771         mask=$(do_facet $SINGLEMDS $LCTL get_param \
17772                                 mdd.$mdt.changelog_current_mask -n)
17773         [[ $mask == $oldmask ]] || error "mask was changed: $mask vs $oldmask"
17774         # set server mask to minimal value
17775         changelog_chmask "MARK"
17776         # check effective mask again, should be treated as DEFMASK now
17777         mask=$(do_facet $SINGLEMDS $LCTL get_param \
17778                                 mdd.$mdt.changelog_current_mask -n)
17779         [[ $mask == *"HLINK"* ]] || error "mask is not DEFMASK as expected"
17780
17781         if (( $MDS1_VERSION >= $(version_code 2.15.52) )) ; then
17782                 # set server mask back to some value
17783                 changelog_chmask "CLOSE,UNLNK"
17784                 # check effective mask again, should not remain as DEFMASK
17785                 mask=$(do_facet $SINGLEMDS $LCTL get_param \
17786                                 mdd.$mdt.changelog_current_mask -n)
17787                 [[ $mask != *"HLINK"* ]] || error "mask is still DEFMASK"
17788         fi
17789
17790         do_facet $SINGLEMDS $LCTL --device $mdt \
17791                                 changelog_deregister -u test_160o ||
17792                 error "cannot deregister by name"
17793 }
17794 run_test 160o "changelog user name and mask"
17795
17796 test_160p() {
17797         remote_mds_nodsh && skip "remote MDS with nodsh" && return
17798         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
17799                 skip "Need MDS version at least 2.14.51"
17800         [[ "$mds1_FSTYPE" == "ldiskfs" ]] || skip "ldiskfs only test"
17801         local cl_users
17802         local cl_user1
17803         local entry_count
17804
17805         # Create a user
17806         changelog_register || error "first changelog_register failed"
17807
17808         cl_users=(${CL_USERS[mds1]})
17809         cl_user1="${cl_users[0]}"
17810
17811         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
17812         createmany -m $DIR/$tdir/$tfile 50 ||
17813                 error "create $DIR/$tdir/$tfile failed"
17814         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
17815         rm -rf $DIR/$tdir
17816
17817         # check changelogs have been generated
17818         entry_count=$(changelog_dump | wc -l)
17819         ((entry_count != 0)) || error "no changelog entries found"
17820
17821         # remove changelog_users and check that orphan entries are removed
17822         stop mds1
17823         local dev=$(mdsdevname 1)
17824         do_facet mds1 "$DEBUGFS -w -R 'rm changelog_users' $dev"
17825         start mds1 $dev $MDS_MOUNT_OPTS || error "cannot start mds1"
17826         entry_count=$(changelog_dump | wc -l)
17827         ((entry_count == 0)) ||
17828                 error "found $entry_count changelog entries, expected none"
17829 }
17830 run_test 160p "Changelog orphan cleanup with no users"
17831
17832 test_160q() {
17833         local mdt="$(facet_svc $SINGLEMDS)"
17834         local clu
17835
17836         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
17837         remote_mds_nodsh && skip "remote MDS with nodsh"
17838         [ $MDS1_VERSION -ge $(version_code 2.14.54) ] ||
17839                 skip "Need MDS version at least 2.14.54"
17840
17841         # set server mask to minimal value like server init does
17842         changelog_chmask "MARK"
17843         clu=$(do_facet $SINGLEMDS $LCTL --device $mdt changelog_register -n) ||
17844                 error "changelog_register failed"
17845         # check effective mask again, should be treated as DEFMASK now
17846         mask=$(do_facet $SINGLEMDS $LCTL get_param \
17847                                 mdd.$mdt.changelog_current_mask -n)
17848         do_facet $SINGLEMDS $LCTL --device $mdt changelog_deregister $clu ||
17849                 error "changelog_deregister failed"
17850         [[ $mask == *"HLINK"* ]] || error "mask is not DEFMASK as expected"
17851 }
17852 run_test 160q "changelog effective mask is DEFMASK if not set"
17853
17854 test_160s() {
17855         remote_mds_nodsh && skip "remote MDS with nodsh"
17856         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
17857                 skip "Need MDS version at least 2.14.55"
17858
17859         local mdts=$(comma_list $(mdts_nodes))
17860
17861         #define OBD_FAIL_TIME_IN_CHLOG_USER     0x1314
17862         do_nodes $mdts $LCTL set_param fail_loc=0x1314 \
17863                                        fail_val=$((24 * 3600 * 10))
17864
17865         # Create a user which is 10 days old
17866         changelog_register || error "first changelog_register failed"
17867         local cl_users
17868         declare -A cl_user1
17869         local i
17870
17871         # generate some changelog records to accumulate on each MDT
17872         # use all_char because created files should be evenly distributed
17873         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
17874                 error "test_mkdir $tdir failed"
17875         for ((i = 0; i < MDSCOUNT; i++)); do
17876                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
17877                         error "create $DIR/$tdir/d$i.1 failed"
17878         done
17879
17880         # check changelogs have been generated
17881         local nbcl=$(changelog_dump | wc -l)
17882         (( nbcl > 0 )) || error "no changelogs found"
17883
17884         # reduce the max_idle_indexes value to make sure we exceed it
17885         for param in "changelog_max_idle_indexes=2097446912" \
17886                      "changelog_max_idle_time=2592000" \
17887                      "changelog_gc=1" \
17888                      "changelog_min_gc_interval=2"; do
17889                 local MDT0=$(facet_svc $SINGLEMDS)
17890                 local var="${param%=*}"
17891                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
17892
17893                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
17894                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
17895                         error "unable to set mdd.*.$param"
17896         done
17897
17898         local start=$SECONDS
17899         for i in $(seq $MDSCOUNT); do
17900                 cl_users=(${CL_USERS[mds$i]})
17901                 cl_user1[mds$i]="${cl_users[0]}"
17902
17903                 [[ -n "${cl_user1[mds$i]}" ]] ||
17904                         error "mds$i: no user registered"
17905         done
17906
17907         #define OBD_FAIL_MDS_CHANGELOG_IDX_PUMP   0x16d
17908         do_nodes $mdts $LCTL set_param fail_loc=0x16d fail_val=500000000
17909
17910         # ensure we are past the previous changelog_min_gc_interval set above
17911         local sleep2=$((start + 2 - SECONDS))
17912         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
17913
17914         # Generate one more changelog to trigger GC
17915         for ((i = 0; i < MDSCOUNT; i++)); do
17916                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 $DIR/$tdir/d$i.4 ||
17917                         error "create $DIR/$tdir/d$i.3 failed"
17918         done
17919
17920         # ensure gc thread is done
17921         for node in $(mdts_nodes); do
17922                 wait_update $node "pgrep chlg_gc_thread" "" 20 ||
17923                         error "$node: GC-thread not done"
17924         done
17925
17926         do_nodes $mdts $LCTL set_param fail_loc=0
17927
17928         for (( i = 1; i <= MDSCOUNT; i++ )); do
17929                 # check cl_user1 is purged
17930                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" &&
17931                         error "mds$i: User ${cl_user1[mds$i]} is registered"
17932         done
17933         return 0
17934 }
17935 run_test 160s "changelog garbage collect on idle records * time"
17936
17937 test_160t() {
17938         remote_mds_nodsh && skip "remote MDS with nodsh"
17939         (( $MDS1_VERSION >= $(version_code 2.15.50) )) ||
17940                 skip "Need MDS version at least 2.15.50"
17941
17942         local MDT0=$(facet_svc $SINGLEMDS)
17943         local cl_users
17944         local cl_user1
17945         local cl_user2
17946         local start
17947
17948         changelog_register --user user1 -m all ||
17949                 error "user1 failed to register"
17950
17951         mkdir_on_mdt0 $DIR/$tdir
17952         # create default overstripe to maximize changelog size
17953         $LFS setstripe  -C 8 $DIR/$tdir || error "setstripe failed"
17954         createmany -o $DIR/$tdir/u1_ 2000 || error "createmany for user1 failed"
17955         llog_size1=$(do_facet mds1 $LCTL get_param -n mdd.$MDT0.changelog_size)
17956
17957         # user2 consumes less records so less space
17958         changelog_register --user user2 || error "user2 failed to register"
17959         createmany -o $DIR/$tdir/u2_ 500 || error "createmany for user2 failed"
17960         llog_size2=$(do_facet mds1 $LCTL get_param -n mdd.$MDT0.changelog_size)
17961
17962         # check changelogs have been generated
17963         local nbcl=$(changelog_dump | wc -l)
17964         (( nbcl > 0 )) || error "no changelogs found"
17965
17966         # reduce the changelog_min_gc_interval to force check
17967         for param in "changelog_gc=1" "changelog_min_gc_interval=2"; do
17968                 local var="${param%=*}"
17969                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
17970
17971                 stack_trap "do_facet mds1 $LCTL set_param mdd.$MDT0.$var=$old"
17972                 do_facet mds1 $LCTL set_param mdd.$MDT0.$param ||
17973                         error "unable to set mdd.*.$param"
17974         done
17975
17976         start=$SECONDS
17977         cl_users=(${CL_USERS[mds1]})
17978         cl_user1="${cl_users[0]}"
17979         cl_user2="${cl_users[1]}"
17980
17981         [[ -n $cl_user1 ]] ||
17982                 error "mds1: user #1 isn't registered"
17983         [[ -n $cl_user2 ]] ||
17984                 error "mds1: user #2 isn't registered"
17985
17986         # ensure we are past the previous changelog_min_gc_interval set above
17987         local sleep2=$((start + 2 - SECONDS))
17988         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
17989
17990         #define OBD_FAIL_MDS_CHANGELOG_ENOSPC 0x018c
17991         do_facet mds1 $LCTL set_param fail_loc=0x018c \
17992                         fail_val=$(((llog_size1 + llog_size2) / 2))
17993
17994         # Generate more changelog to trigger GC
17995         createmany -o $DIR/$tdir/u3_ 4 ||
17996                 error "create failed for more files"
17997
17998         # ensure gc thread is done
17999         wait_update_facet mds1 "pgrep chlg_gc_thread" "" 20 ||
18000                 error "mds1: GC-thread not done"
18001
18002         do_facet mds1 $LCTL set_param fail_loc=0
18003
18004         # check cl_user1 is purged
18005         changelog_users mds1 | grep -q "$cl_user1" &&
18006                 error "User $cl_user1 is registered"
18007         # check cl_user2 is not purged
18008         changelog_users mds1 | grep -q "$cl_user2" ||
18009                 error "User $cl_user2 is not registered"
18010 }
18011 run_test 160t "changelog garbage collect on lack of space"
18012
18013 test_161a() {
18014         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18015
18016         test_mkdir -c1 $DIR/$tdir
18017         cp /etc/hosts $DIR/$tdir/$tfile
18018         test_mkdir -c1 $DIR/$tdir/foo1
18019         test_mkdir -c1 $DIR/$tdir/foo2
18020         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/sofia
18021         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/zachary
18022         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/luna
18023         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/thor
18024         local FID=$($LFS path2fid $DIR/$tdir/$tfile | tr -d '[]')
18025         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
18026                 $LFS fid2path $DIR $FID
18027                 error "bad link ea"
18028         fi
18029         # middle
18030         rm $DIR/$tdir/foo2/zachary
18031         # last
18032         rm $DIR/$tdir/foo2/thor
18033         # first
18034         rm $DIR/$tdir/$tfile
18035         # rename
18036         mv $DIR/$tdir/foo1/sofia $DIR/$tdir/foo2/maggie
18037         [ "$($LFS fid2path $FSNAME --link 1 $FID)" != "$tdir/foo2/maggie" ] &&
18038                 { $LFS fid2path $DIR $FID; error "bad link rename"; }
18039         rm $DIR/$tdir/foo2/maggie
18040
18041         # overflow the EA
18042         local longname=$tfile.avg_len_is_thirty_two_
18043         stack_trap "unlinkmany $DIR/$tdir/foo2/$longname 1000 || \
18044                 error_noexit 'failed to unlink many hardlinks'" EXIT
18045         createmany -l$DIR/$tdir/foo1/luna $DIR/$tdir/foo2/$longname 1000 ||
18046                 error "failed to hardlink many files"
18047         links=$($LFS fid2path $DIR $FID | wc -l)
18048         echo -n "${links}/1000 links in link EA"
18049         [[ $links -gt 60 ]] || error "expected at least 60 links in link EA"
18050 }
18051 run_test 161a "link ea sanity"
18052
18053 test_161b() {
18054         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18055         [ $MDSCOUNT -lt 2 ] && skip_env "skipping remote directory test"
18056
18057         local MDTIDX=1
18058         local remote_dir=$DIR/$tdir/remote_dir
18059
18060         mkdir -p $DIR/$tdir
18061         $LFS mkdir -i $MDTIDX $remote_dir ||
18062                 error "create remote directory failed"
18063
18064         cp /etc/hosts $remote_dir/$tfile
18065         mkdir -p $remote_dir/foo1
18066         mkdir -p $remote_dir/foo2
18067         ln $remote_dir/$tfile $remote_dir/foo1/sofia
18068         ln $remote_dir/$tfile $remote_dir/foo2/zachary
18069         ln $remote_dir/$tfile $remote_dir/foo1/luna
18070         ln $remote_dir/$tfile $remote_dir/foo2/thor
18071
18072         local FID=$($LFS path2fid $remote_dir/$tfile | tr -d '[' |
18073                      tr -d ']')
18074         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
18075                 $LFS fid2path $DIR $FID
18076                 error "bad link ea"
18077         fi
18078         # middle
18079         rm $remote_dir/foo2/zachary
18080         # last
18081         rm $remote_dir/foo2/thor
18082         # first
18083         rm $remote_dir/$tfile
18084         # rename
18085         mv $remote_dir/foo1/sofia $remote_dir/foo2/maggie
18086         local link_path=$($LFS fid2path $FSNAME --link 1 $FID)
18087         if [ "$DIR/$link_path" != "$remote_dir/foo2/maggie" ]; then
18088                 $LFS fid2path $DIR $FID
18089                 error "bad link rename"
18090         fi
18091         rm $remote_dir/foo2/maggie
18092
18093         # overflow the EA
18094         local longname=filename_avg_len_is_thirty_two_
18095         createmany -l$remote_dir/foo1/luna $remote_dir/foo2/$longname 1000 ||
18096                 error "failed to hardlink many files"
18097         links=$($LFS fid2path $DIR $FID | wc -l)
18098         echo -n "${links}/1000 links in link EA"
18099         [[ ${links} -gt 60 ]] ||
18100                 error "expected at least 60 links in link EA"
18101         unlinkmany $remote_dir/foo2/$longname 1000 ||
18102         error "failed to unlink many hardlinks"
18103 }
18104 run_test 161b "link ea sanity under remote directory"
18105
18106 test_161c() {
18107         remote_mds_nodsh && skip "remote MDS with nodsh"
18108         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18109         [[ $MDS1_VERSION -lt $(version_code 2.1.5) ]] &&
18110                 skip "Need MDS version at least 2.1.5"
18111
18112         # define CLF_RENAME_LAST 0x0001
18113         # rename overwrite a target having nlink = 1 (changelog flag 0x1)
18114         changelog_register || error "changelog_register failed"
18115
18116         rm -rf $DIR/$tdir
18117         test_mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir
18118         touch $DIR/$tdir/foo_161c
18119         touch $DIR/$tdir/bar_161c
18120         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
18121         changelog_dump | grep RENME | tail -n 5
18122         local flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
18123         changelog_clear 0 || error "changelog_clear failed"
18124         if [ x$flags != "x0x1" ]; then
18125                 error "flag $flags is not 0x1"
18126         fi
18127
18128         echo "rename overwrite target with nlink = 1, changelog flags=$flags"
18129         # rename overwrite a target having nlink > 1 (changelog flag 0x0)
18130         touch $DIR/$tdir/foo_161c
18131         touch $DIR/$tdir/bar_161c
18132         ln $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
18133         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
18134         changelog_dump | grep RENME | tail -n 5
18135         flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
18136         changelog_clear 0 || error "changelog_clear failed"
18137         if [ x$flags != "x0x0" ]; then
18138                 error "flag $flags is not 0x0"
18139         fi
18140         echo "rename overwrite a target having nlink > 1," \
18141                 "changelog record has flags of $flags"
18142
18143         # rename doesn't overwrite a target (changelog flag 0x0)
18144         touch $DIR/$tdir/foo_161c
18145         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/foo2_161c
18146         changelog_dump | grep RENME | tail -n 5
18147         flags=$(changelog_dump | grep RENME | tail -1 | cut -f5 -d' ')
18148         changelog_clear 0 || error "changelog_clear failed"
18149         if [ x$flags != "x0x0" ]; then
18150                 error "flag $flags is not 0x0"
18151         fi
18152         echo "rename doesn't overwrite a target," \
18153                 "changelog record has flags of $flags"
18154
18155         # define CLF_UNLINK_LAST 0x0001
18156         # unlink a file having nlink = 1 (changelog flag 0x1)
18157         rm -f $DIR/$tdir/foo2_161c
18158         changelog_dump | grep UNLNK | tail -n 5
18159         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
18160         changelog_clear 0 || error "changelog_clear failed"
18161         if [ x$flags != "x0x1" ]; then
18162                 error "flag $flags is not 0x1"
18163         fi
18164         echo "unlink a file having nlink = 1," \
18165                 "changelog record has flags of $flags"
18166
18167         # unlink a file having nlink > 1 (changelog flag 0x0)
18168         ln -f $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
18169         rm -f $DIR/$tdir/foobar_161c
18170         changelog_dump | grep UNLNK | tail -n 5
18171         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
18172         changelog_clear 0 || error "changelog_clear failed"
18173         if [ x$flags != "x0x0" ]; then
18174                 error "flag $flags is not 0x0"
18175         fi
18176         echo "unlink a file having nlink > 1, changelog record flags '$flags'"
18177 }
18178 run_test 161c "check CL_RENME[UNLINK] changelog record flags"
18179
18180 test_161d() {
18181         remote_mds_nodsh && skip "remote MDS with nodsh"
18182         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
18183
18184         local pid
18185         local fid
18186
18187         changelog_register || error "changelog_register failed"
18188
18189         # work in a standalone dir to avoid locking on $DIR/$MOUNT to
18190         # interfer with $MOUNT/.lustre/fid/ access
18191         mkdir $DIR/$tdir
18192         [[ $? -eq 0 ]] || error "mkdir failed"
18193
18194         #define OBD_FAIL_LLITE_CREATE_NODE_PAUSE 0x140c | CFS_FAIL_ONCE
18195         $LCTL set_param fail_loc=0x8000140c
18196         # 5s pause
18197         $LCTL set_param fail_val=5
18198
18199         # create file
18200         echo foofoo > $DIR/$tdir/$tfile &
18201         pid=$!
18202
18203         # wait for create to be delayed
18204         sleep 2
18205
18206         ps -p $pid
18207         [[ $? -eq 0 ]] || error "create should be blocked"
18208
18209         local tempfile="$(mktemp --tmpdir $tfile.XXXXXX)"
18210         stack_trap "rm -f $tempfile"
18211         fid=$(changelog_extract_field "CREAT" "$tfile" "t=")
18212         cat $MOUNT/.lustre/fid/$fid 2>/dev/null >$tempfile || error "cat failed"
18213         # some delay may occur during ChangeLog publishing and file read just
18214         # above, that could allow file write to happen finally
18215         [[ -s $tempfile ]] && echo "file should be empty"
18216
18217         $LCTL set_param fail_loc=0
18218
18219         wait $pid
18220         [[ $? -eq 0 ]] || error "create failed"
18221 }
18222 run_test 161d "create with concurrent .lustre/fid access"
18223
18224 check_path() {
18225         local expected="$1"
18226         shift
18227         local fid="$2"
18228
18229         local path
18230         path=$($LFS fid2path "$@")
18231         local rc=$?
18232
18233         if [ $rc -ne 0 ]; then
18234                 error "path looked up of '$expected' failed: rc=$rc"
18235         elif [ "$path" != "$expected" ]; then
18236                 error "path looked up '$path' instead of '$expected'"
18237         else
18238                 echo "FID '$fid' resolves to path '$path' as expected"
18239         fi
18240 }
18241
18242 test_162a() { # was test_162
18243         test_mkdir -p -c1 $DIR/$tdir/d2
18244         touch $DIR/$tdir/d2/$tfile
18245         touch $DIR/$tdir/d2/x1
18246         touch $DIR/$tdir/d2/x2
18247         test_mkdir -p -c1 $DIR/$tdir/d2/a/b/c
18248         test_mkdir -p -c1 $DIR/$tdir/d2/p/q/r
18249         # regular file
18250         local fid=$($LFS path2fid $DIR/$tdir/d2/$tfile | tr -d '[]')
18251         check_path "$tdir/d2/$tfile" $FSNAME "$fid" --link 0
18252
18253         # softlink
18254         ln -s $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/slink
18255         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink | tr -d '[]')
18256         check_path "$tdir/d2/p/q/r/slink" $FSNAME "$fid" --link 0
18257
18258         # softlink to wrong file
18259         ln -s /this/is/garbage $DIR/$tdir/d2/p/q/r/slink.wrong
18260         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink.wrong | tr -d '[]')
18261         check_path "$tdir/d2/p/q/r/slink.wrong" $FSNAME "$fid" --link 0
18262
18263         # hardlink
18264         ln $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/hlink
18265         mv $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/a/b/c/new_file
18266         fid=$($LFS path2fid $DIR/$tdir/d2/a/b/c/new_file | tr -d '[]')
18267         # fid2path dir/fsname should both work
18268         check_path "$tdir/d2/a/b/c/new_file" $FSNAME "$fid" --link 1
18269         check_path "$DIR/$tdir/d2/p/q/r/hlink" $DIR "$fid" --link 0
18270
18271         # hardlink count: check that there are 2 links
18272         local nlinks=$($LFS fid2path $DIR "$fid" | wc -l)
18273         [ $nlinks -eq 2 ] || error "expect 2 links, found $nlinks"
18274
18275         # hardlink indexing: remove the first link
18276         rm $DIR/$tdir/d2/p/q/r/hlink
18277         check_path "$tdir/d2/a/b/c/new_file" $FSNAME $fid --link 0
18278 }
18279 run_test 162a "path lookup sanity"
18280
18281 test_162b() {
18282         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18283         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18284
18285         mkdir $DIR/$tdir
18286         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
18287                                 error "create striped dir failed"
18288
18289         local FID=$($LFS getdirstripe $DIR/$tdir/striped_dir |
18290                                         tail -n 1 | awk '{print $2}')
18291         stat $MOUNT/.lustre/fid/$FID && error "sub_stripe can be accessed"
18292
18293         touch $DIR/$tdir/striped_dir/f{0..4} || error "touch f0..4 failed"
18294         mkdir $DIR/$tdir/striped_dir/d{0..4} || error "mkdir d0..4 failed"
18295
18296         # regular file
18297         for ((i=0;i<5;i++)); do
18298                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/f$i | tr -d '[]') ||
18299                         error "get fid for f$i failed"
18300                 check_path "$tdir/striped_dir/f$i" $FSNAME $FID --link 0
18301
18302                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/d$i | tr -d '[]') ||
18303                         error "get fid for d$i failed"
18304                 check_path "$tdir/striped_dir/d$i" $FSNAME $FID --link 0
18305         done
18306
18307         return 0
18308 }
18309 run_test 162b "striped directory path lookup sanity"
18310
18311 # LU-4239: Verify fid2path works with paths 100 or more directories deep
18312 test_162c() {
18313         [[ $MDS1_VERSION -lt $(version_code 2.7.51) ]] &&
18314                 skip "Need MDS version at least 2.7.51"
18315
18316         local lpath=$tdir.local
18317         local rpath=$tdir.remote
18318
18319         test_mkdir $DIR/$lpath
18320         test_mkdir $DIR/$rpath
18321
18322         for ((i = 0; i <= 101; i++)); do
18323                 lpath="$lpath/$i"
18324                 mkdir $DIR/$lpath
18325                 FID=$($LFS path2fid $DIR/$lpath | tr -d '[]') ||
18326                         error "get fid for local directory $DIR/$lpath failed"
18327                 check_path "$DIR/$lpath" $MOUNT $FID --link 0
18328
18329                 rpath="$rpath/$i"
18330                 test_mkdir $DIR/$rpath
18331                 FID=$($LFS path2fid $DIR/$rpath | tr -d '[]') ||
18332                         error "get fid for remote directory $DIR/$rpath failed"
18333                 check_path "$DIR/$rpath" $MOUNT $FID --link 0
18334         done
18335
18336         return 0
18337 }
18338 run_test 162c "fid2path works with paths 100 or more directories deep"
18339
18340 oalr_event_count() {
18341         local event="${1}"
18342         local trace="${2}"
18343
18344         awk -v name="${FSNAME}-OST0000" \
18345             -v event="${event}" \
18346             '$1 == "TRACE" && $2 == event && $3 == name' \
18347             "${trace}" |
18348         wc -l
18349 }
18350
18351 oalr_expect_event_count() {
18352         local event="${1}"
18353         local trace="${2}"
18354         local expect="${3}"
18355         local count
18356
18357         count=$(oalr_event_count "${event}" "${trace}")
18358         if ((count == expect)); then
18359                 return 0
18360         fi
18361
18362         error_noexit "${event} event count was '${count}', expected ${expect}"
18363         cat "${trace}" >&2
18364         exit 1
18365 }
18366
18367 cleanup_165() {
18368         do_facet ost1 killall --quiet -KILL ofd_access_log_reader || true
18369         stop ost1
18370         start ost1 "$(ostdevname 1)" $OST_MOUNT_OPTS
18371 }
18372
18373 setup_165() {
18374         sync # Flush previous IOs so we can count log entries.
18375         do_facet ost1 $LCTL set_param "obdfilter.${FSNAME}-OST0000.access_log_size=4096"
18376         stack_trap cleanup_165 EXIT
18377 }
18378
18379 test_165a() {
18380         local trace="/tmp/${tfile}.trace"
18381         local rc
18382         local count
18383
18384         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
18385                 skip "OFD access log unsupported"
18386
18387         setup_165
18388         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
18389         sleep 5
18390
18391         do_facet ost1 ofd_access_log_reader --list
18392         stop ost1
18393
18394         do_facet ost1 killall -TERM ofd_access_log_reader
18395         wait
18396         rc=$?
18397
18398         if ((rc != 0)); then
18399                 error "ofd_access_log_reader exited with rc = '${rc}'"
18400         fi
18401
18402         # Parse trace file for discovery events:
18403         oalr_expect_event_count alr_log_add "${trace}" 1
18404         oalr_expect_event_count alr_log_eof "${trace}" 1
18405         oalr_expect_event_count alr_log_free "${trace}" 1
18406 }
18407 run_test 165a "ofd access log discovery"
18408
18409 test_165b() {
18410         local trace="/tmp/${tfile}.trace"
18411         local file="${DIR}/${tfile}"
18412         local pfid1
18413         local pfid2
18414         local -a entry
18415         local rc
18416         local count
18417         local size
18418         local flags
18419
18420         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
18421                 skip "OFD access log unsupported"
18422
18423         setup_165
18424         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
18425         sleep 5
18426
18427         do_facet ost1 ofd_access_log_reader --list
18428
18429         lfs setstripe -c 1 -i 0 "${file}"
18430         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
18431                 error "cannot create '${file}'"
18432
18433         sleep 5
18434         do_facet ost1 killall -TERM ofd_access_log_reader
18435         wait
18436         rc=$?
18437
18438         if ((rc != 0)); then
18439                 error "ofd_access_log_reader exited with rc = '${rc}'"
18440         fi
18441
18442         oalr_expect_event_count alr_log_entry "${trace}" 1
18443
18444         pfid1=$($LFS path2fid "${file}")
18445
18446         # 1     2             3   4    5     6   7    8    9     10
18447         # TRACE alr_log_entry OST PFID BEGIN END TIME SIZE COUNT FLAGS
18448         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
18449
18450         echo "entry = '${entry[*]}'" >&2
18451
18452         pfid2=${entry[4]}
18453         if [[ "${pfid1}" != "${pfid2}" ]]; then
18454                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
18455         fi
18456
18457         size=${entry[8]}
18458         if ((size != 1048576)); then
18459                 error "entry '${entry[*]}' has invalid io size '${size}', expected 1048576"
18460         fi
18461
18462         flags=${entry[10]}
18463         if [[ "${flags}" != "w" ]]; then
18464                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'w'"
18465         fi
18466
18467         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
18468         sleep 5
18469
18470         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r524288c ||
18471                 error "cannot read '${file}'"
18472         sleep 5
18473
18474         do_facet ost1 killall -TERM ofd_access_log_reader
18475         wait
18476         rc=$?
18477
18478         if ((rc != 0)); then
18479                 error "ofd_access_log_reader exited with rc = '${rc}'"
18480         fi
18481
18482         oalr_expect_event_count alr_log_entry "${trace}" 1
18483
18484         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
18485         echo "entry = '${entry[*]}'" >&2
18486
18487         pfid2=${entry[4]}
18488         if [[ "${pfid1}" != "${pfid2}" ]]; then
18489                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
18490         fi
18491
18492         size=${entry[8]}
18493         if ((size != 524288)); then
18494                 error "entry '${entry[*]}' has invalid io size '${size}', 524288"
18495         fi
18496
18497         flags=${entry[10]}
18498         if [[ "${flags}" != "r" ]]; then
18499                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'r'"
18500         fi
18501 }
18502 run_test 165b "ofd access log entries are produced and consumed"
18503
18504 test_165c() {
18505         local trace="/tmp/${tfile}.trace"
18506         local file="${DIR}/${tdir}/${tfile}"
18507
18508         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
18509                 skip "OFD access log unsupported"
18510
18511         test_mkdir "${DIR}/${tdir}"
18512
18513         setup_165
18514         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
18515         sleep 5
18516
18517         lfs setstripe -c 1 -i 0 "${DIR}/${tdir}"
18518
18519         # 4096 / 64 = 64. Create twice as many entries.
18520         for ((i = 0; i < 128; i++)); do
18521                 $MULTIOP "${file}-${i}" oO_CREAT:O_WRONLY:w512c ||
18522                         error "cannot create file"
18523         done
18524
18525         sync
18526
18527         do_facet ost1 killall -TERM ofd_access_log_reader
18528         wait
18529         rc=$?
18530         if ((rc != 0)); then
18531                 error "ofd_access_log_reader exited with rc = '${rc}'"
18532         fi
18533
18534         unlinkmany  "${file}-%d" 128
18535 }
18536 run_test 165c "full ofd access logs do not block IOs"
18537
18538 oal_get_read_count() {
18539         local stats="$1"
18540
18541         # STATS lustre-OST0001 alr_read_count 1
18542
18543         do_facet ost1 cat "${stats}" |
18544         awk '$1 == "STATS" && $3 == "alr_read_count" { count = $4; }
18545              END { print count; }'
18546 }
18547
18548 oal_expect_read_count() {
18549         local stats="$1"
18550         local count
18551         local expect="$2"
18552
18553         # Ask ofd_access_log_reader to write stats.
18554         do_facet ost1 killall -USR1 ofd_access_log_reader
18555
18556         # Allow some time for things to happen.
18557         sleep 1
18558
18559         count=$(oal_get_read_count "${stats}")
18560         if ((count == expect)); then
18561                 return 0
18562         fi
18563
18564         error_noexit "bad read count, got ${count}, expected ${expect}"
18565         do_facet ost1 cat "${stats}" >&2
18566         exit 1
18567 }
18568
18569 test_165d() {
18570         local stats="/tmp/${tfile}.stats"
18571         local file="${DIR}/${tdir}/${tfile}"
18572         local param="obdfilter.${FSNAME}-OST0000.access_log_mask"
18573
18574         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
18575                 skip "OFD access log unsupported"
18576
18577         test_mkdir "${DIR}/${tdir}"
18578
18579         setup_165
18580         do_facet ost1 ofd_access_log_reader --stats="${stats}" &
18581         sleep 5
18582
18583         lfs setstripe -c 1 -i 0 "${file}"
18584
18585         do_facet ost1 lctl set_param "${param}=rw"
18586         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
18587                 error "cannot create '${file}'"
18588         oal_expect_read_count "${stats}" 1
18589
18590         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
18591                 error "cannot read '${file}'"
18592         oal_expect_read_count "${stats}" 2
18593
18594         do_facet ost1 lctl set_param "${param}=r"
18595         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
18596                 error "cannot create '${file}'"
18597         oal_expect_read_count "${stats}" 2
18598
18599         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
18600                 error "cannot read '${file}'"
18601         oal_expect_read_count "${stats}" 3
18602
18603         do_facet ost1 lctl set_param "${param}=w"
18604         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
18605                 error "cannot create '${file}'"
18606         oal_expect_read_count "${stats}" 4
18607
18608         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
18609                 error "cannot read '${file}'"
18610         oal_expect_read_count "${stats}" 4
18611
18612         do_facet ost1 lctl set_param "${param}=0"
18613         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
18614                 error "cannot create '${file}'"
18615         oal_expect_read_count "${stats}" 4
18616
18617         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
18618                 error "cannot read '${file}'"
18619         oal_expect_read_count "${stats}" 4
18620
18621         do_facet ost1 killall -TERM ofd_access_log_reader
18622         wait
18623         rc=$?
18624         if ((rc != 0)); then
18625                 error "ofd_access_log_reader exited with rc = '${rc}'"
18626         fi
18627 }
18628 run_test 165d "ofd_access_log mask works"
18629
18630 test_165e() {
18631         local stats="/tmp/${tfile}.stats"
18632         local file0="${DIR}/${tdir}-0/${tfile}"
18633         local file1="${DIR}/${tdir}-1/${tfile}"
18634
18635         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
18636                 skip "OFD access log unsupported"
18637
18638         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
18639
18640         test_mkdir -c 1 -i 0 "${DIR}/${tdir}-0"
18641         test_mkdir -c 1 -i 1 "${DIR}/${tdir}-1"
18642
18643         lfs setstripe -c 1 -i 0 "${file0}"
18644         lfs setstripe -c 1 -i 0 "${file1}"
18645
18646         setup_165
18647         do_facet ost1 ofd_access_log_reader -I 1 --stats="${stats}" &
18648         sleep 5
18649
18650         $MULTIOP "${file0}" oO_CREAT:O_WRONLY:w512c ||
18651                 error "cannot create '${file0}'"
18652         sync
18653         oal_expect_read_count "${stats}" 0
18654
18655         $MULTIOP "${file1}" oO_CREAT:O_WRONLY:w512c ||
18656                 error "cannot create '${file1}'"
18657         sync
18658         oal_expect_read_count "${stats}" 1
18659
18660         do_facet ost1 killall -TERM ofd_access_log_reader
18661         wait
18662         rc=$?
18663         if ((rc != 0)); then
18664                 error "ofd_access_log_reader exited with rc = '${rc}'"
18665         fi
18666 }
18667 run_test 165e "ofd_access_log MDT index filter works"
18668
18669 test_165f() {
18670         local trace="/tmp/${tfile}.trace"
18671         local rc
18672         local count
18673
18674         setup_165
18675         do_facet ost1 timeout 60 ofd_access_log_reader \
18676                 --exit-on-close --debug=- --trace=- > "${trace}" &
18677         sleep 5
18678         stop ost1
18679
18680         wait
18681         rc=$?
18682
18683         if ((rc != 0)); then
18684                 error_noexit "ofd_access_log_reader exited with rc = '${rc}'"
18685                 cat "${trace}"
18686                 exit 1
18687         fi
18688 }
18689 run_test 165f "ofd_access_log_reader --exit-on-close works"
18690
18691 test_169() {
18692         # do directio so as not to populate the page cache
18693         log "creating a 10 Mb file"
18694         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c ||
18695                 error "multiop failed while creating a file"
18696         log "starting reads"
18697         dd if=$DIR/$tfile of=/dev/null bs=4096 &
18698         log "truncating the file"
18699         $MULTIOP $DIR/$tfile oO_TRUNC:c ||
18700                 error "multiop failed while truncating the file"
18701         log "killing dd"
18702         kill %+ || true # reads might have finished
18703         echo "wait until dd is finished"
18704         wait
18705         log "removing the temporary file"
18706         rm -rf $DIR/$tfile || error "tmp file removal failed"
18707 }
18708 run_test 169 "parallel read and truncate should not deadlock"
18709
18710 test_170() {
18711         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18712
18713         $LCTL clear     # bug 18514
18714         $LCTL debug_daemon start $TMP/${tfile}_log_good
18715         touch $DIR/$tfile
18716         $LCTL debug_daemon stop
18717         sed -e "s/^...../a/g" $TMP/${tfile}_log_good > $TMP/${tfile}_log_bad ||
18718                 error "sed failed to read log_good"
18719
18720         $LCTL debug_daemon start $TMP/${tfile}_log_good
18721         rm -rf $DIR/$tfile
18722         $LCTL debug_daemon stop
18723
18724         $LCTL df $TMP/${tfile}_log_bad > $TMP/${tfile}_log_bad.out 2>&1 ||
18725                error "lctl df log_bad failed"
18726
18727         local bad_line=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
18728         local good_line1=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
18729
18730         $LCTL df $TMP/${tfile}_log_good > $TMP/${tfile}_log_good.out 2>&1
18731         local good_line2=$(tail -n 1 $TMP/${tfile}_log_good.out | awk '{print $5}')
18732
18733         [ "$bad_line" ] && [ "$good_line1" ] && [ "$good_line2" ] ||
18734                 error "bad_line good_line1 good_line2 are empty"
18735
18736         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
18737         cat $TMP/${tfile}_log_bad >> $TMP/${tfile}_logs_corrupt
18738         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
18739
18740         $LCTL df $TMP/${tfile}_logs_corrupt > $TMP/${tfile}_log_bad.out 2>&1
18741         local bad_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
18742         local good_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
18743
18744         [ "$bad_line_new" ] && [ "$good_line_new" ] ||
18745                 error "bad_line_new good_line_new are empty"
18746
18747         local expected_good=$((good_line1 + good_line2*2))
18748
18749         rm -f $TMP/${tfile}*
18750         # LU-231, short malformed line may not be counted into bad lines
18751         if [ $bad_line -ne $bad_line_new ] &&
18752                    [ $bad_line -ne $((bad_line_new - 1)) ]; then
18753                 error "expected $bad_line bad lines, but got $bad_line_new"
18754                 return 1
18755         fi
18756
18757         if [ $expected_good -ne $good_line_new ]; then
18758                 error "expected $expected_good good lines, but got $good_line_new"
18759                 return 2
18760         fi
18761         true
18762 }
18763 run_test 170 "test lctl df to handle corrupted log ====================="
18764
18765 test_171() { # bug20592
18766         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18767
18768         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
18769         $LCTL set_param fail_loc=0x50e
18770         $LCTL set_param fail_val=3000
18771         multiop_bg_pause $DIR/$tfile O_s || true
18772         local MULTIPID=$!
18773         kill -USR1 $MULTIPID
18774         # cause log dump
18775         sleep 3
18776         wait $MULTIPID
18777         if dmesg | grep "recursive fault"; then
18778                 error "caught a recursive fault"
18779         fi
18780         $LCTL set_param fail_loc=0
18781         true
18782 }
18783 run_test 171 "test libcfs_debug_dumplog_thread stuck in do_exit() ======"
18784
18785 test_172() {
18786
18787         #define OBD_FAIL_OBD_CLEANUP  0x60e
18788         $LCTL set_param fail_loc=0x60e
18789         umount $MOUNT || error "umount $MOUNT failed"
18790         stack_trap "mount_client $MOUNT"
18791
18792         (( $($LCTL dl | egrep -c " osc | lov | lmv | mdc ") > 0 )) ||
18793                 error "no client OBDs are remained"
18794
18795         $LCTL dl | while read devno state type name foo; do
18796                 case $type in
18797                 lov|osc|lmv|mdc)
18798                         $LCTL --device $name cleanup
18799                         $LCTL --device $name detach
18800                         ;;
18801                 *)
18802                         # skip server devices
18803                         ;;
18804                 esac
18805         done
18806
18807         if (( $($LCTL dl | egrep -c " osc | lov | lmv | mdc ") > 0 )); then
18808                 $LCTL dl | egrep " osc | lov | lmv | mdc "
18809                 error "some client OBDs are still remained"
18810         fi
18811
18812 }
18813 run_test 172 "manual device removal with lctl cleanup/detach ======"
18814
18815 # it would be good to share it with obdfilter-survey/iokit-libecho code
18816 setup_obdecho_osc () {
18817         local rc=0
18818         local ost_nid=$1
18819         local obdfilter_name=$2
18820         echo "Creating new osc for $obdfilter_name on $ost_nid"
18821         # make sure we can find loopback nid
18822         $LCTL add_uuid $ost_nid $ost_nid >/dev/null 2>&1
18823
18824         [ $rc -eq 0 ] && { $LCTL attach osc ${obdfilter_name}_osc     \
18825                            ${obdfilter_name}_osc_UUID || rc=2; }
18826         [ $rc -eq 0 ] && { $LCTL --device ${obdfilter_name}_osc setup \
18827                            ${obdfilter_name}_UUID  $ost_nid || rc=3; }
18828         return $rc
18829 }
18830
18831 cleanup_obdecho_osc () {
18832         local obdfilter_name=$1
18833         $LCTL --device ${obdfilter_name}_osc cleanup >/dev/null
18834         $LCTL --device ${obdfilter_name}_osc detach  >/dev/null
18835         return 0
18836 }
18837
18838 obdecho_test() {
18839         local OBD=$1
18840         local node=$2
18841         local pages=${3:-64}
18842         local rc=0
18843         local id
18844
18845         local count=10
18846         local obd_size=$(get_obd_size $node $OBD)
18847         local page_size=$(get_page_size $node)
18848         if [[ -n "$obd_size" ]]; then
18849                 local new_count=$((obd_size / (pages * page_size / 1024)))
18850                 [[ $new_count -ge $count ]] || count=$new_count
18851         fi
18852
18853         do_facet $node "$LCTL attach echo_client ec ec_uuid" || rc=1
18854         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec setup $OBD" ||
18855                            rc=2; }
18856         if [ $rc -eq 0 ]; then
18857             id=$(do_facet $node "$LCTL --device ec create 1"  | awk '/object id/ {print $6}')
18858             [ ${PIPESTATUS[0]} -eq 0 -a -n "$id" ] || rc=3
18859         fi
18860         echo "New object id is $id"
18861         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec getattr $id" ||
18862                            rc=4; }
18863         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec "                 \
18864                            "test_brw $count w v $pages $id" || rc=4; }
18865         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec destroy $id 1" ||
18866                            rc=4; }
18867         [ $rc -eq 0 ] || [ $rc -gt 2 ] &&
18868                 { do_facet $node "$LCTL --device ec cleanup" || rc=5; }
18869         [ $rc -eq 0 ] || [ $rc -gt 1 ] &&
18870                 { do_facet $node "$LCTL --device ec detach" || rc=6; }
18871         [ $rc -ne 0 ] && echo "obecho_create_test failed: $rc"
18872         return $rc
18873 }
18874
18875 test_180a() {
18876         skip "obdecho on osc is no longer supported"
18877 }
18878 run_test 180a "test obdecho on osc"
18879
18880 test_180b() {
18881         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18882         remote_ost_nodsh && skip "remote OST with nodsh"
18883
18884         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
18885                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
18886                 error "failed to load module obdecho"
18887
18888         local target=$(do_facet ost1 $LCTL dl |
18889                        awk '/obdfilter/ { print $4; exit; }')
18890
18891         if [ -n "$target" ]; then
18892                 obdecho_test $target ost1 || error "obdecho_test failed with $?"
18893         else
18894                 do_facet ost1 $LCTL dl
18895                 error "there is no obdfilter target on ost1"
18896         fi
18897 }
18898 run_test 180b "test obdecho directly on obdfilter"
18899
18900 test_180c() { # LU-2598
18901         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18902         remote_ost_nodsh && skip "remote OST with nodsh"
18903         [[ $MDS1_VERSION -lt $(version_code 2.4.0) ]] &&
18904                 skip "Need MDS version at least 2.4.0"
18905
18906         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
18907                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
18908                 error "failed to load module obdecho"
18909
18910         local target=$(do_facet ost1 $LCTL dl |
18911                        awk '/obdfilter/ { print $4; exit; }')
18912
18913         if [ -n "$target" ]; then
18914                 local pages=16384 # 64MB bulk I/O RPC size
18915
18916                 obdecho_test "$target" ost1 "$pages" ||
18917                         error "obdecho_test with pages=$pages failed with $?"
18918         else
18919                 do_facet ost1 $LCTL dl
18920                 error "there is no obdfilter target on ost1"
18921         fi
18922 }
18923 run_test 180c "test huge bulk I/O size on obdfilter, don't LASSERT"
18924
18925 test_181() { # bug 22177
18926         test_mkdir $DIR/$tdir
18927         # create enough files to index the directory
18928         createmany -o $DIR/$tdir/foobar 4000
18929         # print attributes for debug purpose
18930         lsattr -d .
18931         # open dir
18932         multiop_bg_pause $DIR/$tdir D_Sc || return 1
18933         MULTIPID=$!
18934         # remove the files & current working dir
18935         unlinkmany $DIR/$tdir/foobar 4000
18936         rmdir $DIR/$tdir
18937         kill -USR1 $MULTIPID
18938         wait $MULTIPID
18939         stat $DIR/$tdir && error "open-unlinked dir was not removed!"
18940         return 0
18941 }
18942 run_test 181 "Test open-unlinked dir ========================"
18943
18944 test_182a() {
18945         local fcount=1000
18946         local tcount=10
18947
18948         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
18949
18950         $LCTL set_param mdc.*.rpc_stats=clear
18951
18952         for (( i = 0; i < $tcount; i++ )) ; do
18953                 mkdir $DIR/$tdir/$i
18954         done
18955
18956         for (( i = 0; i < $tcount; i++ )) ; do
18957                 createmany -o $DIR/$tdir/$i/f- $fcount &
18958         done
18959         wait
18960
18961         for (( i = 0; i < $tcount; i++ )) ; do
18962                 unlinkmany $DIR/$tdir/$i/f- $fcount &
18963         done
18964         wait
18965
18966         $LCTL get_param mdc.*.rpc_stats
18967
18968         rm -rf $DIR/$tdir
18969 }
18970 run_test 182a "Test parallel modify metadata operations from mdc"
18971
18972 test_182b() {
18973         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
18974         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
18975         local dcount=1000
18976         local tcount=10
18977         local stime
18978         local etime
18979         local delta
18980
18981         do_facet mds1 $LCTL list_param \
18982                 osp.$FSNAME-MDT*-osp-MDT*.rpc_stats ||
18983                 skip "MDS lacks parallel RPC handling"
18984
18985         $LFS mkdir -i 0 $DIR/$tdir || error "creating dir $DIR/$tdir"
18986
18987         rpc_count=$(do_facet mds1 $LCTL get_param -n \
18988                     osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight)
18989
18990         stime=$(date +%s)
18991         createmany -i 0 -d $DIR/$tdir/t- $tcount
18992
18993         for (( i = 0; i < $tcount; i++ )) ; do
18994                 createmany -i 0 -d $DIR/$tdir/t-$i/d- 0 $dcount &
18995         done
18996         wait
18997         etime=$(date +%s)
18998         delta=$((etime - stime))
18999         echo "Time for file creation $delta sec for $rpc_count parallel RPCs"
19000
19001         stime=$(date +%s)
19002         for (( i = 0; i < $tcount; i++ )) ; do
19003                 unlinkmany -d $DIR/$tdir/$i/d- $dcount &
19004         done
19005         wait
19006         etime=$(date +%s)
19007         delta=$((etime - stime))
19008         echo "Time for file removal $delta sec for $rpc_count parallel RPCs"
19009
19010         rm -rf $DIR/$tdir
19011
19012         $LFS mkdir -i 0 $DIR/$tdir || error "creating dir $DIR/$tdir"
19013
19014         do_facet mds1 $LCTL set_param osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight=1
19015
19016         stime=$(date +%s)
19017         createmany -i 0 -d $DIR/$tdir/t- $tcount
19018
19019         for (( i = 0; i < $tcount; i++ )) ; do
19020                 createmany -i 0 -d $DIR/$tdir/t-$i/d- 0 $dcount &
19021         done
19022         wait
19023         etime=$(date +%s)
19024         delta=$((etime - stime))
19025         echo "Time for file creation $delta sec for 1 RPC sent at a time"
19026
19027         stime=$(date +%s)
19028         for (( i = 0; i < $tcount; i++ )) ; do
19029                 unlinkmany -d $DIR/$tdir/t-$i/d- $dcount &
19030         done
19031         wait
19032         etime=$(date +%s)
19033         delta=$((etime - stime))
19034         echo "Time for file removal $delta sec for 1 RPC sent at a time"
19035
19036         do_facet mds1 $LCTL set_param osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight=$rpc_count
19037 }
19038 run_test 182b "Test parallel modify metadata operations from osp"
19039
19040 test_183() { # LU-2275
19041         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19042         remote_mds_nodsh && skip "remote MDS with nodsh"
19043         [[ $MDS1_VERSION -lt $(version_code 2.3.56) ]] &&
19044                 skip "Need MDS version at least 2.3.56"
19045
19046         mkdir_on_mdt0 $DIR/$tdir || error "creating dir $DIR/$tdir"
19047         echo aaa > $DIR/$tdir/$tfile
19048
19049 #define OBD_FAIL_MDS_NEGATIVE_POSITIVE  0x148
19050         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x148
19051
19052         ls -l $DIR/$tdir && error "ls succeeded, should have failed"
19053         cat $DIR/$tdir/$tfile && error "cat succeeded, should have failed"
19054
19055         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
19056
19057         # Flush negative dentry cache
19058         touch $DIR/$tdir/$tfile
19059
19060         # We are not checking for any leaked references here, they'll
19061         # become evident next time we do cleanup with module unload.
19062         rm -rf $DIR/$tdir
19063 }
19064 run_test 183 "No crash or request leak in case of strange dispositions ========"
19065
19066 # test suite 184 is for LU-2016, LU-2017
19067 test_184a() {
19068         check_swap_layouts_support
19069
19070         dir0=$DIR/$tdir/$testnum
19071         test_mkdir -p -c1 $dir0
19072         ref1=/etc/passwd
19073         ref2=/etc/group
19074         file1=$dir0/f1
19075         file2=$dir0/f2
19076         $LFS setstripe -c1 $file1
19077         cp $ref1 $file1
19078         $LFS setstripe -c2 $file2
19079         cp $ref2 $file2
19080         gen1=$($LFS getstripe -g $file1)
19081         gen2=$($LFS getstripe -g $file2)
19082
19083         $LFS swap_layouts $file1 $file2 || error "swap of file layout failed"
19084         gen=$($LFS getstripe -g $file1)
19085         [[ $gen1 != $gen ]] ||
19086                 error "Layout generation on $file1 does not change"
19087         gen=$($LFS getstripe -g $file2)
19088         [[ $gen2 != $gen ]] ||
19089                 error "Layout generation on $file2 does not change"
19090
19091         cmp $ref1 $file2 || error "content compare failed ($ref1 != $file2)"
19092         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
19093
19094         lfsck_verify_pfid $file1 $file2 || error "PFID are not transferred"
19095 }
19096 run_test 184a "Basic layout swap"
19097
19098 test_184b() {
19099         check_swap_layouts_support
19100
19101         dir0=$DIR/$tdir/$testnum
19102         mkdir -p $dir0 || error "creating dir $dir0"
19103         file1=$dir0/f1
19104         file2=$dir0/f2
19105         file3=$dir0/f3
19106         dir1=$dir0/d1
19107         dir2=$dir0/d2
19108         mkdir $dir1 $dir2
19109         $LFS setstripe -c1 $file1
19110         $LFS setstripe -c2 $file2
19111         $LFS setstripe -c1 $file3
19112         chown $RUNAS_ID $file3
19113         gen1=$($LFS getstripe -g $file1)
19114         gen2=$($LFS getstripe -g $file2)
19115
19116         $LFS swap_layouts $dir1 $dir2 &&
19117                 error "swap of directories layouts should fail"
19118         $LFS swap_layouts $dir1 $file1 &&
19119                 error "swap of directory and file layouts should fail"
19120         $RUNAS $LFS swap_layouts $file1 $file2 &&
19121                 error "swap of file we cannot write should fail"
19122         $LFS swap_layouts $file1 $file3 &&
19123                 error "swap of file with different owner should fail"
19124         /bin/true # to clear error code
19125 }
19126 run_test 184b "Forbidden layout swap (will generate errors)"
19127
19128 test_184c() {
19129         local cmpn_arg=$(cmp -n 2>&1 | grep "invalid option")
19130         [ -n "$cmpn_arg" ] && skip_env "cmp does not support -n"
19131         check_swap_layouts_support
19132         check_swap_layout_no_dom $DIR
19133
19134         local dir0=$DIR/$tdir/$testnum
19135         mkdir -p $dir0 || error "creating dir $dir0"
19136
19137         local ref1=$dir0/ref1
19138         local ref2=$dir0/ref2
19139         local file1=$dir0/file1
19140         local file2=$dir0/file2
19141         # create a file large enough for the concurrent test
19142         dd if=/dev/urandom of=$ref1 bs=1M count=$((RANDOM % 50 + 20))
19143         dd if=/dev/urandom of=$ref2 bs=1M count=$((RANDOM % 50 + 20))
19144         echo "ref file size: ref1($(stat -c %s $ref1))," \
19145              "ref2($(stat -c %s $ref2))"
19146
19147         cp $ref2 $file2
19148         dd if=$ref1 of=$file1 bs=16k &
19149         local DD_PID=$!
19150
19151         # Make sure dd starts to copy file, but wait at most 5 seconds
19152         local loops=0
19153         while [ ! -s $file1 -a $((loops++)) -lt 50 ]; do sleep 0.1; done
19154
19155         $LFS swap_layouts $file1 $file2
19156         local rc=$?
19157         wait $DD_PID
19158         [[ $? == 0 ]] || error "concurrent write on $file1 failed"
19159         [[ $rc == 0 ]] || error "swap of $file1 and $file2 failed"
19160
19161         # how many bytes copied before swapping layout
19162         local copied=$(stat -c %s $file2)
19163         local remaining=$(stat -c %s $ref1)
19164         remaining=$((remaining - copied))
19165         echo "Copied $copied bytes before swapping layout..."
19166
19167         cmp -n $copied $file1 $ref2 | grep differ &&
19168                 error "Content mismatch [0, $copied) of ref2 and file1"
19169         cmp -n $copied $file2 $ref1 ||
19170                 error "Content mismatch [0, $copied) of ref1 and file2"
19171         cmp -i $copied:$copied -n $remaining $file1 $ref1 ||
19172                 error "Content mismatch [$copied, EOF) of ref1 and file1"
19173
19174         # clean up
19175         rm -f $ref1 $ref2 $file1 $file2
19176 }
19177 run_test 184c "Concurrent write and layout swap"
19178
19179 test_184d() {
19180         check_swap_layouts_support
19181         check_swap_layout_no_dom $DIR
19182         [ -z "$(which getfattr 2>/dev/null)" ] &&
19183                 skip_env "no getfattr command"
19184
19185         local file1=$DIR/$tdir/$tfile-1
19186         local file2=$DIR/$tdir/$tfile-2
19187         local file3=$DIR/$tdir/$tfile-3
19188         local lovea1
19189         local lovea2
19190
19191         mkdir -p $DIR/$tdir
19192         touch $file1 || error "create $file1 failed"
19193         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
19194                 error "create $file2 failed"
19195         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
19196                 error "create $file3 failed"
19197         lovea1=$(get_layout_param $file1)
19198
19199         $LFS swap_layouts $file2 $file3 ||
19200                 error "swap $file2 $file3 layouts failed"
19201         $LFS swap_layouts $file1 $file2 ||
19202                 error "swap $file1 $file2 layouts failed"
19203
19204         lovea2=$(get_layout_param $file2)
19205         echo "$lovea1"
19206         echo "$lovea2"
19207         [ "$lovea1" == "$lovea2" ] || error "lovea $lovea1 != $lovea2"
19208
19209         lovea1=$(getfattr -n trusted.lov $file1 | grep ^trusted)
19210         [[ -z "$lovea1" ]] || error "$file1 shouldn't have lovea"
19211 }
19212 run_test 184d "allow stripeless layouts swap"
19213
19214 test_184e() {
19215         [[ $MDS1_VERSION -ge $(version_code 2.6.94) ]] ||
19216                 skip "Need MDS version at least 2.6.94"
19217         check_swap_layouts_support
19218         check_swap_layout_no_dom $DIR
19219         [ -z "$(which getfattr 2>/dev/null)" ] &&
19220                 skip_env "no getfattr command"
19221
19222         local file1=$DIR/$tdir/$tfile-1
19223         local file2=$DIR/$tdir/$tfile-2
19224         local file3=$DIR/$tdir/$tfile-3
19225         local lovea
19226
19227         mkdir -p $DIR/$tdir
19228         touch $file1 || error "create $file1 failed"
19229         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
19230                 error "create $file2 failed"
19231         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
19232                 error "create $file3 failed"
19233
19234         $LFS swap_layouts $file1 $file2 ||
19235                 error "swap $file1 $file2 layouts failed"
19236
19237         lovea=$(getfattr -n trusted.lov $file1 | grep ^trusted)
19238         [[ -z "$lovea" ]] || error "$file1 shouldn't have lovea"
19239
19240         echo 123 > $file1 || error "Should be able to write into $file1"
19241
19242         $LFS swap_layouts $file1 $file3 ||
19243                 error "swap $file1 $file3 layouts failed"
19244
19245         echo 123 > $file1 || error "Should be able to write into $file1"
19246
19247         rm -rf $file1 $file2 $file3
19248 }
19249 run_test 184e "Recreate layout after stripeless layout swaps"
19250
19251 test_184f() {
19252         # Create a file with name longer than sizeof(struct stat) ==
19253         # 144 to see if we can get chars from the file name to appear
19254         # in the returned striping. Note that 'f' == 0x66.
19255         local file=$(for ((i = 0; i < 200; i++)); do echo -n f; done)
19256
19257         mkdir -p $DIR/$tdir
19258         mcreate $DIR/$tdir/$file
19259         if lfs find --stripe-count 0x6666 $DIR/$tdir | grep $file; then
19260                 error "IOC_MDC_GETFILEINFO returned garbage striping"
19261         fi
19262 }
19263 run_test 184f "IOC_MDC_GETFILEINFO for files with long names but no striping"
19264
19265 test_185() { # LU-2441
19266         # LU-3553 - no volatile file support in old servers
19267         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
19268                 skip "Need MDS version at least 2.3.60"
19269
19270         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
19271         touch $DIR/$tdir/spoo
19272         local mtime1=$(stat -c "%Y" $DIR/$tdir)
19273         local fid=$($MULTIOP $DIR/$tdir VFw4096c) ||
19274                 error "cannot create/write a volatile file"
19275         [ "$FILESET" == "" ] &&
19276         $CHECKSTAT -t file $MOUNT/.lustre/fid/$fid 2>/dev/null &&
19277                 error "FID is still valid after close"
19278
19279         multiop_bg_pause $DIR/$tdir vVw4096_c
19280         local multi_pid=$!
19281
19282         local OLD_IFS=$IFS
19283         IFS=":"
19284         local fidv=($fid)
19285         IFS=$OLD_IFS
19286         # assume that the next FID for this client is sequential, since stdout
19287         # is unfortunately eaten by multiop_bg_pause
19288         local n=$((${fidv[1]} + 1))
19289         local next_fid="${fidv[0]}:$(printf "0x%x" $n):${fidv[2]}"
19290         if [ "$FILESET" == "" ]; then
19291                 $CHECKSTAT -t file $MOUNT/.lustre/fid/$next_fid ||
19292                         error "FID is missing before close"
19293         fi
19294         kill -USR1 $multi_pid
19295         # 1 second delay, so if mtime change we will see it
19296         sleep 1
19297         local mtime2=$(stat -c "%Y" $DIR/$tdir)
19298         [[ $mtime1 == $mtime2 ]] || error "mtime has changed"
19299 }
19300 run_test 185 "Volatile file support"
19301
19302 function create_check_volatile() {
19303         local idx=$1
19304         local tgt
19305
19306         $MULTIOP $MOUNT/.lustre/fid V${idx}Fw4096_c >&/tmp/${tfile}.fid &
19307         local PID=$!
19308         sleep 1
19309         local FID=$(cat /tmp/${tfile}.fid)
19310         [ "$FID" == "" ] && error "can't get FID for volatile"
19311         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID || error "can't stat $FID"
19312         tgt=$($LFS getstripe -m $MOUNT/.lustre/fid/$FID)
19313         [ "$tgt" != "$idx" ] && error "wrong MDS $tgt, expected $idx"
19314         kill -USR1 $PID
19315         wait
19316         sleep 1
19317         cancel_lru_locks mdc # flush opencache
19318         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID && error "can stat $FID"
19319         return 0
19320 }
19321
19322 test_185a(){
19323         # LU-12516 - volatile creation via .lustre
19324         [[ $MDS1_VERSION -ge $(version_code 2.12.55) ]] ||
19325                 skip "Need MDS version at least 2.3.55"
19326
19327         create_check_volatile 0
19328         [ $MDSCOUNT -lt 2 ] && return 0
19329
19330         # DNE case
19331         create_check_volatile 1
19332
19333         return 0
19334 }
19335 run_test 185a "Volatile file creation in .lustre/fid/"
19336
19337 test_187a() {
19338         remote_mds_nodsh && skip "remote MDS with nodsh"
19339         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
19340                 skip "Need MDS version at least 2.3.0"
19341
19342         local dir0=$DIR/$tdir/$testnum
19343         mkdir -p $dir0 || error "creating dir $dir0"
19344
19345         local file=$dir0/file1
19346         dd if=/dev/urandom of=$file count=10 bs=1M conv=fsync
19347         stack_trap "rm -f $file"
19348         local dv1=$($LFS data_version $file)
19349         dd if=/dev/urandom of=$file seek=10 count=1 bs=1M conv=fsync
19350         local dv2=$($LFS data_version $file)
19351         [[ $dv1 != $dv2 ]] ||
19352                 error "data version did not change on write $dv1 == $dv2"
19353 }
19354 run_test 187a "Test data version change"
19355
19356 test_187b() {
19357         remote_mds_nodsh && skip "remote MDS with nodsh"
19358         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
19359                 skip "Need MDS version at least 2.3.0"
19360
19361         local dir0=$DIR/$tdir/$testnum
19362         mkdir -p $dir0 || error "creating dir $dir0"
19363
19364         declare -a DV=$($MULTIOP $dir0 Vw1000xYw1000xY | cut -f3 -d" ")
19365         [[ ${DV[0]} != ${DV[1]} ]] ||
19366                 error "data version did not change on write"\
19367                       " ${DV[0]} == ${DV[1]}"
19368
19369         # clean up
19370         rm -f $file1
19371 }
19372 run_test 187b "Test data version change on volatile file"
19373
19374 test_200() {
19375         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19376         remote_mgs_nodsh && skip "remote MGS with nodsh"
19377         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
19378
19379         local POOL=${POOL:-cea1}
19380         local POOL_ROOT=${POOL_ROOT:-$DIR/d200.pools}
19381         local POOL_DIR_NAME=${POOL_DIR_NAME:-dir_tst}
19382         # Pool OST targets
19383         local first_ost=0
19384         local last_ost=$(($OSTCOUNT - 1))
19385         local ost_step=2
19386         local ost_list=$(seq $first_ost $ost_step $last_ost)
19387         local ost_range="$first_ost $last_ost $ost_step"
19388         local test_path=$POOL_ROOT/$POOL_DIR_NAME
19389         local file_dir=$POOL_ROOT/file_tst
19390         local subdir=$test_path/subdir
19391         local rc=0
19392
19393         while : ; do
19394                 # former test_200a test_200b
19395                 pool_add $POOL                          || { rc=$? ; break; }
19396                 pool_add_targets  $POOL $ost_range      || { rc=$? ; break; }
19397                 # former test_200c test_200d
19398                 mkdir -p $test_path
19399                 pool_set_dir      $POOL $test_path      || { rc=$? ; break; }
19400                 pool_check_dir    $POOL $test_path      || { rc=$? ; break; }
19401                 mkdir -p $subdir
19402                 pool_check_dir    $POOL $subdir         || { rc=$? ; break; }
19403                 pool_dir_rel_path $POOL $POOL_DIR_NAME $POOL_ROOT \
19404                                                         || { rc=$? ; break; }
19405                 # former test_200e test_200f
19406                 local files=$((OSTCOUNT*3))
19407                 pool_alloc_files  $POOL $test_path $files "$ost_list" \
19408                                                         || { rc=$? ; break; }
19409                 pool_create_files $POOL $file_dir $files "$ost_list" \
19410                                                         || { rc=$? ; break; }
19411                 # former test_200g test_200h
19412                 pool_lfs_df $POOL                       || { rc=$? ; break; }
19413                 pool_file_rel_path $POOL $test_path     || { rc=$? ; break; }
19414
19415                 # former test_201a test_201b test_201c
19416                 pool_remove_first_target $POOL          || { rc=$? ; break; }
19417
19418                 local f=$test_path/$tfile
19419                 pool_remove_all_targets $POOL $f        || { rc=$? ; break; }
19420                 pool_remove $POOL $f                    || { rc=$? ; break; }
19421                 break
19422         done
19423
19424         destroy_test_pools
19425
19426         return $rc
19427 }
19428 run_test 200 "OST pools"
19429
19430 # usage: default_attr <count | size | offset>
19431 default_attr() {
19432         $LCTL get_param -n lov.$FSNAME-clilov-\*.stripe${1}
19433 }
19434
19435 # usage: check_default_stripe_attr
19436 check_default_stripe_attr() {
19437         ACTUAL=$($LFS getstripe $* $DIR/$tdir)
19438         case $1 in
19439         --stripe-count|-c)
19440                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr count);;
19441         --stripe-size|-S)
19442                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr size);;
19443         --stripe-index|-i)
19444                 EXPECTED=-1;;
19445         *)
19446                 error "unknown getstripe attr '$1'"
19447         esac
19448
19449         [ $ACTUAL == $EXPECTED ] ||
19450                 error "$DIR/$tdir has $1 '$ACTUAL', not '$EXPECTED'"
19451 }
19452
19453 test_204a() {
19454         test_mkdir $DIR/$tdir
19455         $LFS setstripe --stripe-count 0 --stripe-size 0 --stripe-index -1 $DIR/$tdir
19456
19457         check_default_stripe_attr --stripe-count
19458         check_default_stripe_attr --stripe-size
19459         check_default_stripe_attr --stripe-index
19460 }
19461 run_test 204a "Print default stripe attributes"
19462
19463 test_204b() {
19464         test_mkdir $DIR/$tdir
19465         $LFS setstripe --stripe-count 1 $DIR/$tdir
19466
19467         check_default_stripe_attr --stripe-size
19468         check_default_stripe_attr --stripe-index
19469 }
19470 run_test 204b "Print default stripe size and offset"
19471
19472 test_204c() {
19473         test_mkdir $DIR/$tdir
19474         $LFS setstripe --stripe-size 65536 $DIR/$tdir
19475
19476         check_default_stripe_attr --stripe-count
19477         check_default_stripe_attr --stripe-index
19478 }
19479 run_test 204c "Print default stripe count and offset"
19480
19481 test_204d() {
19482         test_mkdir $DIR/$tdir
19483         $LFS setstripe --stripe-index 0 $DIR/$tdir
19484
19485         check_default_stripe_attr --stripe-count
19486         check_default_stripe_attr --stripe-size
19487 }
19488 run_test 204d "Print default stripe count and size"
19489
19490 test_204e() {
19491         test_mkdir $DIR/$tdir
19492         $LFS setstripe -d $DIR/$tdir
19493
19494         check_default_stripe_attr --stripe-count --raw
19495         check_default_stripe_attr --stripe-size --raw
19496         check_default_stripe_attr --stripe-index --raw
19497 }
19498 run_test 204e "Print raw stripe attributes"
19499
19500 test_204f() {
19501         test_mkdir $DIR/$tdir
19502         $LFS setstripe --stripe-count 1 $DIR/$tdir
19503
19504         check_default_stripe_attr --stripe-size --raw
19505         check_default_stripe_attr --stripe-index --raw
19506 }
19507 run_test 204f "Print raw stripe size and offset"
19508
19509 test_204g() {
19510         test_mkdir $DIR/$tdir
19511         $LFS setstripe --stripe-size 65536 $DIR/$tdir
19512
19513         check_default_stripe_attr --stripe-count --raw
19514         check_default_stripe_attr --stripe-index --raw
19515 }
19516 run_test 204g "Print raw stripe count and offset"
19517
19518 test_204h() {
19519         test_mkdir $DIR/$tdir
19520         $LFS setstripe --stripe-index 0 $DIR/$tdir
19521
19522         check_default_stripe_attr --stripe-count --raw
19523         check_default_stripe_attr --stripe-size --raw
19524 }
19525 run_test 204h "Print raw stripe count and size"
19526
19527 # Figure out which job scheduler is being used, if any,
19528 # or use a fake one
19529 if [ -n "$SLURM_JOB_ID" ]; then # SLURM
19530         JOBENV=SLURM_JOB_ID
19531 elif [ -n "$LSB_JOBID" ]; then # Load Sharing Facility
19532         JOBENV=LSB_JOBID
19533 elif [ -n "$PBS_JOBID" ]; then # PBS/Maui/Moab
19534         JOBENV=PBS_JOBID
19535 elif [ -n "$LOADL_STEPID" ]; then # LoadLeveller
19536         JOBENV=LOADL_STEP_ID
19537 elif [ -n "$JOB_ID" ]; then # Sun Grid Engine
19538         JOBENV=JOB_ID
19539 else
19540         $LCTL list_param jobid_name > /dev/null 2>&1
19541         if [ $? -eq 0 ]; then
19542                 JOBENV=nodelocal
19543         else
19544                 JOBENV=FAKE_JOBID
19545         fi
19546 fi
19547 LUSTRE_JOBID_SIZE=31 # plus NUL terminator
19548
19549 verify_jobstats() {
19550         local cmd=($1)
19551         shift
19552         local facets="$@"
19553
19554 # we don't really need to clear the stats for this test to work, since each
19555 # command has a unique jobid, but it makes debugging easier if needed.
19556 #       for facet in $facets; do
19557 #               local dev=$(convert_facet2label $facet)
19558 #               # clear old jobstats
19559 #               do_facet $facet lctl set_param *.$dev.job_stats="clear"
19560 #       done
19561
19562         # use a new JobID for each test, or we might see an old one
19563         [ "$JOBENV" = "FAKE_JOBID" ] &&
19564                 FAKE_JOBID=id.$testnum.$(basename ${cmd[0]}).$RANDOM
19565
19566         JOBVAL=${!JOBENV:0:$LUSTRE_JOBID_SIZE}
19567
19568         [ "$JOBENV" = "nodelocal" ] && {
19569                 FAKE_JOBID=id.$testnum.%e.$RANDOM
19570                 $LCTL set_param jobid_name=$FAKE_JOBID
19571                 JOBVAL=${FAKE_JOBID/\%e/$(basename ${cmd[0]})}
19572         }
19573
19574         log "Test: ${cmd[*]}"
19575         log "Using JobID environment $($LCTL get_param -n jobid_var)=$JOBVAL"
19576
19577         if [ $JOBENV = "FAKE_JOBID" ]; then
19578                 FAKE_JOBID=$JOBVAL ${cmd[*]}
19579         else
19580                 ${cmd[*]}
19581         fi
19582
19583         # all files are created on OST0000
19584         for facet in $facets; do
19585                 local stats="*.$(convert_facet2label $facet).job_stats"
19586
19587                 # strip out libtool wrappers for in-tree executables
19588                 if (( $(do_facet $facet lctl get_param $stats |
19589                         sed -e 's/\.lt-/./' | grep -cw $JOBVAL) != 1 )); then
19590                         do_facet $facet lctl get_param $stats
19591                         error "No jobstats for $JOBVAL found on $facet::$stats"
19592                 fi
19593         done
19594 }
19595
19596 jobstats_set() {
19597         local new_jobenv=$1
19598
19599         set_persistent_param_and_check client "jobid_var" \
19600                 "$FSNAME.sys.jobid_var" $new_jobenv
19601 }
19602
19603 test_205a() { # Job stats
19604         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19605         [[ $MDS1_VERSION -ge $(version_code 2.7.1) ]] ||
19606                 skip "Need MDS version with at least 2.7.1"
19607         remote_mgs_nodsh && skip "remote MGS with nodsh"
19608         remote_mds_nodsh && skip "remote MDS with nodsh"
19609         remote_ost_nodsh && skip "remote OST with nodsh"
19610         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep jobstats)" ] &&
19611                 skip "Server doesn't support jobstats"
19612         [[ $JOBID_VAR = disable ]] && skip_env "jobstats is disabled"
19613
19614         local old_jobenv=$($LCTL get_param -n jobid_var)
19615         [ $old_jobenv != $JOBENV ] && jobstats_set $JOBENV
19616         stack_trap "jobstats_set $old_jobenv" EXIT
19617
19618         changelog_register
19619
19620         local old_jobid_name=$($LCTL get_param jobid_name)
19621         stack_trap "$LCTL set_param $old_jobid_name" EXIT
19622
19623         local old_interval=$(do_facet $SINGLEMDS lctl get_param -n \
19624                                 mdt.*.job_cleanup_interval | head -n 1)
19625         local new_interval=5
19626         do_facet $SINGLEMDS \
19627                 $LCTL set_param mdt.*.job_cleanup_interval=$new_interval
19628         stack_trap "do_facet $SINGLEMDS \
19629                 $LCTL set_param mdt.*.job_cleanup_interval=$old_interval" EXIT
19630         local start=$SECONDS
19631
19632         local cmd
19633         # mkdir
19634         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir"
19635         verify_jobstats "$cmd" "$SINGLEMDS"
19636         # rmdir
19637         cmd="rmdir $DIR/$tdir"
19638         verify_jobstats "$cmd" "$SINGLEMDS"
19639         # mkdir on secondary MDT
19640         if [ $MDSCOUNT -gt 1 ]; then
19641                 cmd="lfs mkdir -i 1 $DIR/$tdir.remote"
19642                 verify_jobstats "$cmd" "mds2"
19643         fi
19644         # mknod
19645         cmd="mknod $DIR/$tfile c 1 3"
19646         verify_jobstats "$cmd" "$SINGLEMDS"
19647         # unlink
19648         cmd="rm -f $DIR/$tfile"
19649         verify_jobstats "$cmd" "$SINGLEMDS"
19650         # create all files on OST0000 so verify_jobstats can find OST stats
19651         # open & close
19652         cmd="$LFS setstripe -i 0 -c 1 $DIR/$tfile"
19653         verify_jobstats "$cmd" "$SINGLEMDS"
19654         # setattr
19655         cmd="touch $DIR/$tfile"
19656         verify_jobstats "$cmd" "$SINGLEMDS ost1"
19657         # write
19658         cmd="dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=sync"
19659         verify_jobstats "$cmd" "ost1"
19660         # read
19661         cancel_lru_locks osc
19662         cmd="dd if=$DIR/$tfile of=/dev/null bs=1M count=1 iflag=direct"
19663         verify_jobstats "$cmd" "ost1"
19664         # truncate
19665         cmd="$TRUNCATE $DIR/$tfile 0"
19666         verify_jobstats "$cmd" "$SINGLEMDS ost1"
19667         # rename
19668         cmd="mv -f $DIR/$tfile $DIR/$tdir.rename"
19669         verify_jobstats "$cmd" "$SINGLEMDS"
19670         # jobstats expiry - sleep until old stats should be expired
19671         local left=$((new_interval + 5 - (SECONDS - start)))
19672         [ $left -ge 0 ] && wait_update_facet $SINGLEMDS \
19673                 "lctl get_param *.*.job_stats | grep -c 'job_id.*mkdir'" \
19674                         "0" $left
19675         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir.expire"
19676         verify_jobstats "$cmd" "$SINGLEMDS"
19677         [ $(do_facet $SINGLEMDS lctl get_param *.*.job_stats |
19678             grep -c "job_id.*mkdir") -gt 1 ] && error "old jobstats not expired"
19679
19680         # Ensure that jobid are present in changelog (if supported by MDS)
19681         if [ $MDS1_VERSION -ge $(version_code 2.6.52) ];then
19682                 changelog_dump | tail -10
19683                 jobids=$(changelog_dump | tail -9 | grep -c "j=")
19684                 [ $jobids -eq 9 ] ||
19685                         error "Wrong changelog jobid count $jobids != 9"
19686
19687                 # LU-5862
19688                 JOBENV="disable"
19689                 jobstats_set $JOBENV
19690                 touch $DIR/$tfile
19691                 changelog_dump | grep $tfile
19692                 jobids=$(changelog_dump | grep $tfile | tail -1 | grep -c "j=")
19693                 [ $jobids -eq 0 ] ||
19694                         error "Unexpected jobids when jobid_var=$JOBENV"
19695         fi
19696
19697         # test '%j' access to environment variable - if supported
19698         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%h.E"; then
19699                 JOBENV="JOBCOMPLEX"
19700                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
19701
19702                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
19703         fi
19704
19705         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%H.E"; then
19706                 JOBENV="JOBCOMPLEX"
19707                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname -s).E"
19708
19709                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
19710         fi
19711
19712         # test '%j' access to per-session jobid - if supported
19713         if lctl list_param jobid_this_session > /dev/null 2>&1
19714         then
19715                 lctl set_param jobid_var=session jobid_name="S.%j.%e.%u.%h.E"
19716                 lctl set_param jobid_this_session=$USER
19717
19718                 JOBENV="JOBCOMPLEX"
19719                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
19720
19721                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
19722         fi
19723 }
19724 run_test 205a "Verify job stats"
19725
19726 # LU-13117, LU-13597, LU-16599
19727 test_205b() {
19728         (( $MDS1_VERSION >= $(version_code 2.13.54.91) )) ||
19729                 skip "Need MDS version at least 2.13.54.91"
19730
19731         local job_stats="mdt.*.job_stats"
19732         local old_jobid=$(do_facet mds1 $LCTL get_param jobid_var)
19733
19734         do_facet mds1 $LCTL set_param $job_stats=clear
19735
19736         # Setting jobid_var to USER might not be supported
19737         [[ -n "$old_jobid" ]] && stack_trap "$LCTL set_param $old_jobid"
19738         $LCTL set_param jobid_var=USER || true
19739         stack_trap "$LCTL set_param $($LCTL get_param jobid_name)"
19740         $LCTL set_param jobid_name="%j.%e.%u"
19741
19742         env -i USERTESTJOBSTATS=foolish touch $DIR/$tfile.1
19743         do_facet mds1 $LCTL get_param $job_stats | grep "job_id:.*foolish" &&
19744                 { do_facet mds1 $LCTL get_param $job_stats;
19745                   error "Unexpected jobid found"; }
19746         do_facet mds1 $LCTL get_param $job_stats | grep "open:.*min.*max.*sum"||
19747                 { do_facet mds1 $LCTL get_param $job_stats;
19748                   error "wrong job_stats format found"; }
19749
19750         (( $MDS1_VERSION <= $(version_code 2.15.0) )) &&
19751                 echo "MDS does not yet escape jobid" && return 0
19752
19753         mkdir_on_mdt0 $DIR/$tdir
19754         $LCTL set_param jobid_var=TEST205b
19755         env -i TEST205b="has sp" touch $DIR/$tdir/$tfile.2
19756         local jobid=$(do_facet mds1 $LCTL get_param $job_stats |
19757                       awk '/has\\x20sp/ {print $3}')
19758         [[ -n "$jobid" ]] || { do_facet mds1 $LCTL get_param $job_stats;
19759                   error "jobid not escaped"; }
19760
19761         if (( $MDS1_VERSION >= $(version_code 2.15.53.139) )); then
19762                 # need to run such a command on mds1:
19763                 # lctl set_param mdt.$FSNAME-MDT0000.job_stats='"has\x20sp.touch.0"'
19764                 #
19765                 # there might be multiple MDTs on single mds server, so need to
19766                 # specifiy MDT0000. Or the command will fail due to other MDTs
19767                 do_facet_vp mds1 $LCTL set_param mdt.$FSNAME-MDT0000.job_stats=$jobid ||
19768                         error "cannot clear escaped jobid in job_stats";
19769         else
19770                 echo "MDS does not support clearing escaped jobid"
19771         fi
19772 }
19773 run_test 205b "Verify job stats jobid and output format"
19774
19775 # LU-13733
19776 test_205c() {
19777         $LCTL set_param llite.*.stats=0
19778         dd if=/dev/zero of=$DIR/$tfile.1 bs=4k count=1
19779         $LCTL get_param llite.*.stats
19780         $LCTL get_param llite.*.stats | grep \
19781                 "write_bytes *1 samples \[bytes\] 4096 4096 4096 16777216" ||
19782                         error "wrong client stats format found"
19783 }
19784 run_test 205c "Verify client stats format"
19785
19786 test_205d() {
19787         local file=$DIR/$tdir/$tfile
19788
19789         (( $MDS1_VERSION >= $(version_code 2.15.53) )) ||
19790                 skip "need lustre >= 2.15.53 for lljobstat"
19791         (( $OST1_VERSION >= $(version_code 2.15.53) )) ||
19792                 skip "need lustre >= 2.15.53 for lljobstat"
19793         verify_yaml_available || skip_env "YAML verification not installed"
19794
19795         test_mkdir -i 0 $DIR/$tdir
19796         $LFS setstripe -E 1M -L mdt -E -1 $file || error "create file failed"
19797         stack_trap "rm -rf $DIR/$tdir"
19798
19799         dd if=/dev/zero of=$file bs=1M count=10 conv=sync ||
19800                 error "failed to write data to $file"
19801         mv $file $file.2
19802
19803         do_facet mds1 "$LCTL get_param -n mdt.$FSNAME-MDT0000.rename_stats"
19804         echo -n 'verify rename_stats...'
19805         do_facet mds1 "$LCTL get_param -n mdt.$FSNAME-MDT0000.rename_stats" |
19806                 verify_yaml || error "rename_stats is not valid YAML"
19807         echo " OK"
19808
19809         echo -n 'verify mdt job_stats...'
19810         do_facet mds1 "$LCTL get_param -n mdt.$FSNAME-MDT0000.job_stats" |
19811                 verify_yaml || error "job_stats on mds1 is not valid YAML"
19812         echo " OK"
19813
19814         echo -n 'verify ost job_stats...'
19815         do_facet ost1 "$LCTL get_param -n obdfilter.$FSNAME-OST0000.job_stats" |
19816                 verify_yaml || error "job_stats on ost1 is not valid YAML"
19817         echo " OK"
19818 }
19819 run_test 205d "verify the format of some stats files"
19820
19821 test_205e() {
19822         local ops_comma
19823         local file=$DIR/$tdir/$tfile
19824         local -a cli_params
19825
19826         (( $MDS1_VERSION >= $(version_code 2.15.53) )) ||
19827                 skip "need lustre >= 2.15.53 for lljobstat"
19828         (( $OST1_VERSION >= $(version_code 2.15.53) )) ||
19829                 skip "need lustre >= 2.15.53 for lljobstat"
19830         verify_yaml_available || skip_env "YAML verification not installed"
19831
19832         cli_params=( $($LCTL get_param jobid_name jobid_var) )
19833         $LCTL set_param jobid_var=nodelocal jobid_name=205e.%e.%u
19834         stack_trap "$LCTL set_param ${cli_params[*]}" EXIT
19835
19836         mkdir_on_mdt0 $DIR/$tdir || error "failed to create dir"
19837         stack_trap "rm -rf $DIR/$tdir"
19838
19839         $LFS setstripe -E EOF -i 0 -c 1 $file ||
19840                 error "failed to create $file on ost1"
19841         dd if=/dev/zero of=$file bs=1M count=10 oflag=sync ||
19842                 error "failed to write data to $file"
19843
19844         do_facet mds1 "$LCTL get_param *.*.job_stats"
19845         do_facet ost1 "$LCTL get_param *.*.job_stats"
19846
19847         do_facet ost1 "lljobstat -n 1 -i 0 -c 1000"
19848         do_facet ost1 "lljobstat -n 1 -i 0 -c 1000" | verify_yaml ||
19849                 error "The output of lljobstat is not an valid YAML"
19850
19851         # verify that job dd.0 does exist and has some ops on ost1
19852         # typically this line is like:
19853         # - 205e.dd.0:            {ops: 20, ...}
19854         ops_comma=$(do_facet ost1 "lljobstat -n 1 -i 0 -c 1000" |
19855                     awk '$2=="205e.dd.0:" {print $4}')
19856
19857         (( ${ops_comma%,} >= 10 )) ||
19858                 error "cannot find job 205e.dd.0 with ops >= 10"
19859 }
19860 run_test 205e "verify the output of lljobstat"
19861
19862 test_205f() {
19863         verify_yaml_available || skip_env "YAML verification not installed"
19864
19865         # check both qos_ost_weights and qos_mdt_weights
19866         do_facet mds1 $LCTL get_param -n lod.*.qos*weights
19867         do_facet mds1 $LCTL get_param -n lod.*.qos*weights | verify_yaml ||
19868                 error "qos_ost_weights is not valid YAML"
19869 }
19870 run_test 205f "verify qos_ost_weights YAML format "
19871
19872 __test_205_jobstats_dump() {
19873         local -a pids
19874         local nbr_instance=$1
19875
19876         while true; do
19877                 if (( ${#pids[@]} >= nbr_instance )); then
19878                         wait ${pids[@]}
19879                         pids=()
19880                 fi
19881
19882                 do_facet mds1 "$LCTL get_param mdt.*.job_stats > /dev/null" &
19883                 pids+=( $! )
19884         done
19885 }
19886
19887 __test_205_cleanup() {
19888         kill $@
19889         # Clear all job entries
19890         do_facet mds1 "$LCTL set_param mdt.*.job_stats=clear"
19891 }
19892
19893 test_205g() {
19894         local -a mds1_params
19895         local -a cli_params
19896         local pids
19897         local interval=5
19898
19899         mds1_params=( $(do_facet mds1 $LCTL get_param mdt.*.job_cleanup_interval) )
19900         do_facet mds1 $LCTL set_param mdt.*.job_cleanup_interval=$interval
19901         stack_trap "do_facet mds1 $LCTL set_param ${mds1_params[*]}" EXIT
19902
19903         cli_params=( $($LCTL get_param jobid_name jobid_var) )
19904         $LCTL set_param jobid_var=TEST205G_ID jobid_name=%j.%p
19905         stack_trap "$LCTL set_param ${cli_params[*]}" EXIT
19906
19907         # start jobs loop
19908         export TEST205G_ID=205g
19909         stack_trap "unset TEST205G_ID" EXIT
19910         while true; do
19911                 printf $DIR/$tfile.{0001..1000} | xargs -P10 -n1 touch
19912         done & pids="$! "
19913
19914         __test_205_jobstats_dump 4 & pids+="$! "
19915         stack_trap "__test_205_cleanup $pids" EXIT INT
19916
19917         [[ $SLOW == "no" ]] && sleep 90 || sleep 240
19918 }
19919 run_test 205g "stress test for job_stats procfile"
19920
19921 # LU-1480, LU-1773 and LU-1657
19922 test_206() {
19923         mkdir -p $DIR/$tdir
19924         $LFS setstripe -c -1 $DIR/$tdir
19925 #define OBD_FAIL_LOV_INIT 0x1403
19926         $LCTL set_param fail_loc=0xa0001403
19927         $LCTL set_param fail_val=1
19928         touch $DIR/$tdir/$tfile || true
19929 }
19930 run_test 206 "fail lov_init_raid0() doesn't lbug"
19931
19932 test_207a() {
19933         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
19934         local fsz=`stat -c %s $DIR/$tfile`
19935         cancel_lru_locks mdc
19936
19937         # do not return layout in getattr intent
19938 #define OBD_FAIL_MDS_NO_LL_GETATTR 0x170
19939         $LCTL set_param fail_loc=0x170
19940         local sz=`stat -c %s $DIR/$tfile`
19941
19942         [ $fsz -eq $sz ] || error "file size expected $fsz, actual $sz"
19943
19944         rm -rf $DIR/$tfile
19945 }
19946 run_test 207a "can refresh layout at glimpse"
19947
19948 test_207b() {
19949         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
19950         local cksum=`md5sum $DIR/$tfile`
19951         local fsz=`stat -c %s $DIR/$tfile`
19952         cancel_lru_locks mdc
19953         cancel_lru_locks osc
19954
19955         # do not return layout in getattr intent
19956 #define OBD_FAIL_MDS_NO_LL_OPEN 0x171
19957         $LCTL set_param fail_loc=0x171
19958
19959         # it will refresh layout after the file is opened but before read issues
19960         echo checksum is "$cksum"
19961         echo "$cksum" |md5sum -c --quiet || error "file differs"
19962
19963         rm -rf $DIR/$tfile
19964 }
19965 run_test 207b "can refresh layout at open"
19966
19967 test_208() {
19968         # FIXME: in this test suite, only RD lease is used. This is okay
19969         # for now as only exclusive open is supported. After generic lease
19970         # is done, this test suite should be revised. - Jinshan
19971
19972         remote_mds_nodsh && skip "remote MDS with nodsh"
19973         [[ $MDS1_VERSION -ge $(version_code 2.4.52) ]] ||
19974                 skip "Need MDS version at least 2.4.52"
19975
19976         echo "==== test 1: verify get lease work"
19977         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eRE+eU || error "get lease error"
19978
19979         echo "==== test 2: verify lease can be broken by upcoming open"
19980         $MULTIOP $DIR/$tfile oO_RDWR:eR_E-eUc &
19981         local PID=$!
19982         sleep 2
19983
19984         $MULTIOP $DIR/$tfile oO_RDWR:c
19985         kill -USR1 $PID && wait $PID || error "break lease error"
19986
19987         echo "==== test 3: verify lease can't be granted if an open already exists"
19988         $MULTIOP $DIR/$tfile oO_RDWR:_c &
19989         local PID=$!
19990         sleep 2
19991
19992         $MULTIOP $DIR/$tfile oO_RDWR:eReUc && error "apply lease should fail"
19993         kill -USR1 $PID && wait $PID || error "open file error"
19994
19995         echo "==== test 4: lease can sustain over recovery"
19996         $MULTIOP $DIR/$tfile oO_RDWR:eR_E+eUc &
19997         PID=$!
19998         sleep 2
19999
20000         fail mds1
20001
20002         kill -USR1 $PID && wait $PID || error "lease broken over recovery"
20003
20004         echo "==== test 5: lease broken can't be regained by replay"
20005         $MULTIOP $DIR/$tfile oO_RDWR:eR_E-eUc &
20006         PID=$!
20007         sleep 2
20008
20009         # open file to break lease and then recovery
20010         $MULTIOP $DIR/$tfile oO_RDWR:c || error "open file error"
20011         fail mds1
20012
20013         kill -USR1 $PID && wait $PID || error "lease not broken over recovery"
20014
20015         rm -f $DIR/$tfile
20016 }
20017 run_test 208 "Exclusive open"
20018
20019 test_209() {
20020         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep disp_stripe)" ] &&
20021                 skip_env "must have disp_stripe"
20022
20023         touch $DIR/$tfile
20024         sync; sleep 5; sync;
20025
20026         echo 3 > /proc/sys/vm/drop_caches
20027         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
20028                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
20029         req_before=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
20030
20031         # open/close 500 times
20032         for i in $(seq 500); do
20033                 cat $DIR/$tfile
20034         done
20035
20036         echo 3 > /proc/sys/vm/drop_caches
20037         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
20038                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
20039         req_after=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
20040
20041         echo "before: $req_before, after: $req_after"
20042         [ $((req_after - req_before)) -ge 300 ] &&
20043                 error "open/close requests are not freed"
20044         return 0
20045 }
20046 run_test 209 "read-only open/close requests should be freed promptly"
20047
20048 test_210() {
20049         local pid
20050
20051         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eW_E+eUc &
20052         pid=$!
20053         sleep 1
20054
20055         $LFS getstripe $DIR/$tfile
20056         kill -USR1 $pid
20057         wait $pid || error "multiop failed"
20058
20059         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
20060         pid=$!
20061         sleep 1
20062
20063         $LFS getstripe $DIR/$tfile
20064         kill -USR1 $pid
20065         wait $pid || error "multiop failed"
20066 }
20067 run_test 210 "lfs getstripe does not break leases"
20068
20069 test_212() {
20070         size=`date +%s`
20071         size=$((size % 8192 + 1))
20072         dd if=/dev/urandom of=$DIR/f212 bs=1k count=$size
20073         sendfile $DIR/f212 $DIR/f212.xyz || error "sendfile wrong"
20074         rm -f $DIR/f212 $DIR/f212.xyz
20075 }
20076 run_test 212 "Sendfile test ============================================"
20077
20078 test_213() {
20079         dd if=/dev/zero of=$DIR/$tfile bs=4k count=4
20080         cancel_lru_locks osc
20081         lctl set_param fail_loc=0x8000040f
20082         # generate a read lock
20083         cat $DIR/$tfile > /dev/null
20084         # write to the file, it will try to cancel the above read lock.
20085         cat /etc/hosts >> $DIR/$tfile
20086 }
20087 run_test 213 "OSC lock completion and cancel race don't crash - bug 18829"
20088
20089 test_214() { # for bug 20133
20090         mkdir -p $DIR/$tdir/d214c || error "mkdir $DIR/$tdir/d214c failed"
20091         for (( i=0; i < 340; i++ )) ; do
20092                 touch $DIR/$tdir/d214c/a$i
20093         done
20094
20095         ls -l $DIR/$tdir || error "ls -l $DIR/d214p failed"
20096         mv $DIR/$tdir/d214c $DIR/ || error "mv $DIR/d214p/d214c $DIR/ failed"
20097         ls $DIR/d214c || error "ls $DIR/d214c failed"
20098         rm -rf $DIR/$tdir || error "rm -rf $DIR/d214* failed"
20099         rm -rf $DIR/d214* || error "rm -rf $DIR/d214* failed"
20100 }
20101 run_test 214 "hash-indexed directory test - bug 20133"
20102
20103 # having "abc" as 1st arg, creates $TMP/lnet_abc.out and $TMP/lnet_abc.sys
20104 create_lnet_proc_files() {
20105         lctl get_param -n $1 >$TMP/lnet_$1.sys || error "cannot read lnet.$1"
20106 }
20107
20108 # counterpart of create_lnet_proc_files
20109 remove_lnet_proc_files() {
20110         rm -f $TMP/lnet_$1.sys
20111 }
20112
20113 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
20114 # 3rd arg as regexp for body
20115 check_lnet_proc_stats() {
20116         local l=$(cat "$TMP/lnet_$1" |wc -l)
20117         [ $l = 1 ] || (cat "$TMP/lnet_$1" && error "$2 is not of 1 line: $l")
20118
20119         grep -E "$3" "$TMP/lnet_$1" || (cat "$TMP/lnet_$1" && error "$2 misformatted")
20120 }
20121
20122 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
20123 # 3rd arg as regexp for body, 4th arg as regexp for 1st line, 5th arg is
20124 # optional and can be regexp for 2nd line (lnet.routes case)
20125 check_lnet_proc_entry() {
20126         local blp=2          # blp stands for 'position of 1st line of body'
20127         [ -z "$5" ] || blp=3 # lnet.routes case
20128
20129         local l=$(cat "$TMP/lnet_$1" |wc -l)
20130         # subtracting one from $blp because the body can be empty
20131         [ "$l" -ge "$(($blp - 1))" ] || (cat "$TMP/lnet_$1" && error "$2 is too short: $l")
20132
20133         sed -n '1 p' "$TMP/lnet_$1" |grep -E "$4" >/dev/null ||
20134                 (cat "$TMP/lnet_$1" && error "1st line of $2 misformatted")
20135
20136         [ "$5" = "" ] || sed -n '2 p' "$TMP/lnet_$1" |grep -E "$5" >/dev/null ||
20137                 (cat "$TMP/lnet_$1" && error "2nd line of $2 misformatted")
20138
20139         # bail out if any unexpected line happened
20140         sed -n "$blp p" "$TMP/lnet_$1" | grep -Ev "$3"
20141         [ "$?" != 0 ] || error "$2 misformatted"
20142 }
20143
20144 test_215() { # for bugs 18102, 21079, 21517
20145         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20146
20147         local N='(0|[1-9][0-9]*)'       # non-negative numeric
20148         local P='[1-9][0-9]*'           # positive numeric
20149         local I='(0|-?[1-9][0-9]*|NA)'  # any numeric (0 | >0 | <0) or NA if no value
20150         local NET='[a-z][a-z0-9]*'      # LNET net like o2ib2
20151         local ADDR='[0-9.]+'            # LNET addr like 10.0.0.1
20152         local NID="$ADDR@$NET"          # LNET nid like 10.0.0.1@o2ib2
20153
20154         local L1 # regexp for 1st line
20155         local L2 # regexp for 2nd line (optional)
20156         local BR # regexp for the rest (body)
20157
20158         # lnet.stats should look as 11 space-separated non-negative numerics
20159         BR="^$N $N $N $N $N $N $N $N $N $N $N$"
20160         create_lnet_proc_files "stats"
20161         check_lnet_proc_stats "stats.sys" "lnet.stats" "$BR"
20162         remove_lnet_proc_files "stats"
20163
20164         # lnet.routes should look like this:
20165         # Routing disabled/enabled
20166         # net hops priority state router
20167         # where net is a string like tcp0, hops > 0, priority >= 0,
20168         # state is up/down,
20169         # router is a string like 192.168.1.1@tcp2
20170         L1="^Routing (disabled|enabled)$"
20171         L2="^net +hops +priority +state +router$"
20172         BR="^$NET +$N +(0|1) +(up|down) +$NID$"
20173         create_lnet_proc_files "routes"
20174         check_lnet_proc_entry "routes.sys" "lnet.routes" "$BR" "$L1" "$L2"
20175         remove_lnet_proc_files "routes"
20176
20177         # lnet.routers should look like this:
20178         # ref rtr_ref alive_cnt state last_ping ping_sent deadline down_ni router
20179         # where ref > 0, rtr_ref > 0, alive_cnt >= 0, state is up/down,
20180         # last_ping >= 0, ping_sent is boolean (0/1), deadline and down_ni are
20181         # numeric (0 or >0 or <0), router is a string like 192.168.1.1@tcp2
20182         L1="^ref +rtr_ref +alive +router$"
20183         BR="^$P +$P +(up|down) +$NID$"
20184         create_lnet_proc_files "routers"
20185         check_lnet_proc_entry "routers.sys" "lnet.routers" "$BR" "$L1"
20186         remove_lnet_proc_files "routers"
20187
20188         # lnet.peers should look like this:
20189         # nid refs state last max rtr min tx min queue
20190         # where nid is a string like 192.168.1.1@tcp2, refs > 0,
20191         # state is up/down/NA, max >= 0. last, rtr, min, tx, min are
20192         # numeric (0 or >0 or <0), queue >= 0.
20193         L1="^nid +refs +state +last +max +rtr +min +tx +min +queue$"
20194         BR="^$NID +$P +(up|down|NA) +$I +$N +$I +$I +$I +$I +$N$"
20195         create_lnet_proc_files "peers"
20196         check_lnet_proc_entry "peers.sys" "lnet.peers" "$BR" "$L1"
20197         remove_lnet_proc_files "peers"
20198
20199         # lnet.buffers  should look like this:
20200         # pages count credits min
20201         # where pages >=0, count >=0, credits and min are numeric (0 or >0 or <0)
20202         L1="^pages +count +credits +min$"
20203         BR="^ +$N +$N +$I +$I$"
20204         create_lnet_proc_files "buffers"
20205         check_lnet_proc_entry "buffers.sys" "lnet.buffers" "$BR" "$L1"
20206         remove_lnet_proc_files "buffers"
20207
20208         # lnet.nis should look like this:
20209         # nid status alive refs peer rtr max tx min
20210         # where nid is a string like 192.168.1.1@tcp2, status is up/down,
20211         # alive is numeric (0 or >0 or <0), refs >= 0, peer >= 0,
20212         # rtr >= 0, max >=0, tx and min are numeric (0 or >0 or <0).
20213         L1="^nid +status +alive +refs +peer +rtr +max +tx +min$"
20214         BR="^$NID +(up|down) +$I +$N +$N +$N +$N +$I +$I$"
20215         create_lnet_proc_files "nis"
20216         check_lnet_proc_entry "nis.sys" "lnet.nis" "$BR" "$L1"
20217         remove_lnet_proc_files "nis"
20218
20219         # can we successfully write to lnet.stats?
20220         lctl set_param -n stats=0 || error "cannot write to lnet.stats"
20221 }
20222 run_test 215 "lnet exists and has proper content - bugs 18102, 21079, 21517"
20223
20224 test_216() { # bug 20317
20225         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20226         remote_ost_nodsh && skip "remote OST with nodsh"
20227
20228         local node
20229         local facets=$(get_facets OST)
20230         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
20231
20232         save_lustre_params client "osc.*.contention_seconds" > $p
20233         save_lustre_params $facets \
20234                 "ldlm.namespaces.filter-*.max_nolock_bytes" >> $p
20235         save_lustre_params $facets \
20236                 "ldlm.namespaces.filter-*.contended_locks" >> $p
20237         save_lustre_params $facets \
20238                 "ldlm.namespaces.filter-*.contention_seconds" >> $p
20239         clear_stats osc.*.osc_stats
20240
20241         # agressive lockless i/o settings
20242         do_nodes $(comma_list $(osts_nodes)) \
20243                 "lctl set_param -n ldlm.namespaces.*.max_nolock_bytes=2000000 \
20244                         ldlm.namespaces.filter-*.contended_locks=0 \
20245                         ldlm.namespaces.filter-*.contention_seconds=60"
20246         lctl set_param -n osc.*.contention_seconds=60
20247
20248         $DIRECTIO write $DIR/$tfile 0 10 4096
20249         $CHECKSTAT -s 40960 $DIR/$tfile
20250
20251         # disable lockless i/o
20252         do_nodes $(comma_list $(osts_nodes)) \
20253                 "lctl set_param -n ldlm.namespaces.filter-*.max_nolock_bytes=0 \
20254                         ldlm.namespaces.filter-*.contended_locks=32 \
20255                         ldlm.namespaces.filter-*.contention_seconds=0"
20256         lctl set_param -n osc.*.contention_seconds=0
20257         clear_stats osc.*.osc_stats
20258
20259         dd if=/dev/zero of=$DIR/$tfile count=0
20260         $CHECKSTAT -s 0 $DIR/$tfile
20261
20262         restore_lustre_params <$p
20263         rm -f $p
20264         rm $DIR/$tfile
20265 }
20266 run_test 216 "check lockless direct write updates file size and kms correctly"
20267
20268 test_217() { # bug 22430
20269         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20270
20271         local node
20272
20273         for node in $(nodes_list); do
20274                 local nid=$(host_nids_address $node $NETTYPE)
20275                 local node_ip=$(do_node $node getent ahostsv4 $node |
20276                                 awk '{ print $1; exit; }')
20277
20278                 echo "node: '$node', nid: '$nid', node_ip='$node_ip'"
20279                 # if hostname matches any NID, use hostname for better testing
20280                 if [[ -z "$nid" || "$nid" =~ "$node_ip" ]]; then
20281                         echo "lctl ping node $node@$NETTYPE"
20282                         lctl ping $node@$NETTYPE
20283                 else # otherwise, at least test 'lctl ping' is working
20284                         echo "lctl ping nid $(h2nettype $nid)"
20285                         lctl ping $(h2nettype $nid)
20286                         echo "skipping $node (no hyphen detected)"
20287                 fi
20288         done
20289 }
20290 run_test 217 "check lctl ping for hostnames with embedded hyphen ('-')"
20291
20292 test_218() {
20293         # do directio so as not to populate the page cache
20294         log "creating a 10 Mb file"
20295         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c ||
20296                 error "multiop failed while creating a file"
20297         log "starting reads"
20298         dd if=$DIR/$tfile of=/dev/null bs=4096 &
20299         log "truncating the file"
20300         $MULTIOP $DIR/$tfile oO_TRUNC:c ||
20301                 error "multiop failed while truncating the file"
20302         log "killing dd"
20303         kill %+ || true # reads might have finished
20304         echo "wait until dd is finished"
20305         wait
20306         log "removing the temporary file"
20307         rm -rf $DIR/$tfile || error "tmp file removal failed"
20308 }
20309 run_test 218 "parallel read and truncate should not deadlock"
20310
20311 test_219() {
20312         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20313
20314         # write one partial page
20315         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1
20316         # set no grant so vvp_io_commit_write will do sync write
20317         $LCTL set_param fail_loc=0x411
20318         # write a full page at the end of file
20319         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=1 conv=notrunc
20320
20321         $LCTL set_param fail_loc=0
20322         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=3
20323         $LCTL set_param fail_loc=0x411
20324         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1 seek=2 conv=notrunc
20325
20326         # LU-4201
20327         dd if=/dev/zero of=$DIR/$tfile-2 bs=1024 count=1
20328         $CHECKSTAT -s 1024 $DIR/$tfile-2 || error "checkstat wrong size"
20329 }
20330 run_test 219 "LU-394: Write partial won't cause uncontiguous pages vec at LND"
20331
20332 test_220() { #LU-325
20333         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20334         remote_ost_nodsh && skip "remote OST with nodsh"
20335         remote_mds_nodsh && skip "remote MDS with nodsh"
20336         remote_mgs_nodsh && skip "remote MGS with nodsh"
20337
20338         local OSTIDX=0
20339
20340         # create on MDT0000 so the last_id and next_id are correct
20341         mkdir_on_mdt0 $DIR/$tdir
20342         local OST=$($LFS df $DIR | awk '/OST:'$OSTIDX'/ { print $1 }')
20343         OST=${OST%_UUID}
20344
20345         # on the mdt's osc
20346         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $OST)
20347         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
20348                         osp.$mdtosc_proc1.prealloc_last_id)
20349         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
20350                         osp.$mdtosc_proc1.prealloc_next_id)
20351
20352         $LFS df -i
20353
20354         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=-1
20355         #define OBD_FAIL_OST_ENOINO              0x229
20356         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0x229
20357         create_pool $FSNAME.$TESTNAME || return 1
20358         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $OST || return 2
20359
20360         $LFS setstripe $DIR/$tdir -i $OSTIDX -c 1 -p $FSNAME.$TESTNAME
20361
20362         MDSOBJS=$((last_id - next_id))
20363         echo "preallocated objects on MDS is $MDSOBJS" "($last_id - $next_id)"
20364
20365         blocks=$($LFS df $MOUNT | awk '($1 == '$OSTIDX') { print $4 }')
20366         echo "OST still has $count kbytes free"
20367
20368         echo "create $MDSOBJS files @next_id..."
20369         createmany -o $DIR/$tdir/f $MDSOBJS || return 3
20370
20371         local last_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
20372                         osp.$mdtosc_proc1.prealloc_last_id)
20373         local next_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
20374                         osp.$mdtosc_proc1.prealloc_next_id)
20375
20376         echo "after creation, last_id=$last_id2, next_id=$next_id2"
20377         $LFS df -i
20378
20379         echo "cleanup..."
20380
20381         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=0
20382         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0
20383
20384         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $OST ||
20385                 error "$LCTL pool_remove $FSNAME.$TESTNAME $OST failed"
20386         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
20387                 error "$LCTL pool_destroy $FSNAME.$TESTNAME failed"
20388         echo "unlink $MDSOBJS files @$next_id..."
20389         unlinkmany $DIR/$tdir/f $MDSOBJS || error "unlinkmany failed"
20390 }
20391 run_test 220 "preallocated MDS objects still used if ENOSPC from OST"
20392
20393 test_221() {
20394         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20395
20396         dd if=`which date` of=$MOUNT/date oflag=sync
20397         chmod +x $MOUNT/date
20398
20399         #define OBD_FAIL_LLITE_FAULT_TRUNC_RACE  0x1401
20400         $LCTL set_param fail_loc=0x80001401
20401
20402         $MOUNT/date > /dev/null
20403         rm -f $MOUNT/date
20404 }
20405 run_test 221 "make sure fault and truncate race to not cause OOM"
20406
20407 test_222a () {
20408         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20409
20410         rm -rf $DIR/$tdir
20411         test_mkdir $DIR/$tdir
20412         $LFS setstripe -c 1 -i 0 $DIR/$tdir
20413         createmany -o $DIR/$tdir/$tfile 10
20414         cancel_lru_locks mdc
20415         cancel_lru_locks osc
20416         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
20417         $LCTL set_param fail_loc=0x31a
20418         ls -l $DIR/$tdir > /dev/null || error "AGL for ls failed"
20419         $LCTL set_param fail_loc=0
20420         rm -r $DIR/$tdir
20421 }
20422 run_test 222a "AGL for ls should not trigger CLIO lock failure"
20423
20424 test_222b () {
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_DELAY           0x31a
20434         $LCTL set_param fail_loc=0x31a
20435         rm -r $DIR/$tdir || error "AGL for rmdir failed"
20436         $LCTL set_param fail_loc=0
20437 }
20438 run_test 222b "AGL for rmdir should not trigger CLIO lock failure"
20439
20440 test_223 () {
20441         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20442
20443         rm -rf $DIR/$tdir
20444         test_mkdir $DIR/$tdir
20445         $LFS setstripe -c 1 -i 0 $DIR/$tdir
20446         createmany -o $DIR/$tdir/$tfile 10
20447         cancel_lru_locks mdc
20448         cancel_lru_locks osc
20449         #define OBD_FAIL_LDLM_AGL_NOLOCK          0x31b
20450         $LCTL set_param fail_loc=0x31b
20451         ls -l $DIR/$tdir > /dev/null || error "reenqueue failed"
20452         $LCTL set_param fail_loc=0
20453         rm -r $DIR/$tdir
20454 }
20455 run_test 223 "osc reenqueue if without AGL lock granted ======================="
20456
20457 test_224a() { # LU-1039, MRP-303
20458         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20459         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB   0x508
20460         $LCTL set_param fail_loc=0x508
20461         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 conv=fsync
20462         $LCTL set_param fail_loc=0
20463         df $DIR
20464 }
20465 run_test 224a "Don't panic on bulk IO failure"
20466
20467 test_224bd_sub() { # LU-1039, MRP-303
20468         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20469         local timeout=$1
20470
20471         shift
20472         dd if=/dev/urandom of=$TMP/$tfile bs=1M count=1
20473
20474         $LFS setstripe -c 1 -i 0 $DIR/$tfile
20475
20476         dd if=$TMP/$tfile of=$DIR/$tfile bs=1M count=1
20477         cancel_lru_locks osc
20478         set_checksums 0
20479         stack_trap "set_checksums $ORIG_CSUM" EXIT
20480         local at_max_saved=0
20481
20482         # adaptive timeouts may prevent seeing the issue
20483         if at_is_enabled; then
20484                 at_max_saved=$(at_max_get mds)
20485                 at_max_set 0 mds client
20486                 stack_trap "at_max_set $at_max_saved mds client" EXIT
20487         fi
20488
20489         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB2   0x515
20490         do_facet ost1 $LCTL set_param fail_val=$timeout fail_loc=0x80000515
20491         dd of=$TMP/$tfile.new if=$DIR/$tfile bs=1M count=1 || "$@"
20492
20493         do_facet ost1 $LCTL set_param fail_loc=0
20494         cmp $TMP/$tfile $TMP/$tfile.new || error "file contents wrong"
20495         df $DIR
20496 }
20497
20498 test_224b() {
20499         test_224bd_sub 3 error "dd failed"
20500 }
20501 run_test 224b "Don't panic on bulk IO failure"
20502
20503 test_224c() { # LU-6441
20504         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20505         remote_mds_nodsh && skip "remote MDS with nodsh"
20506
20507         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
20508         save_writethrough $p
20509         set_cache writethrough on
20510
20511         local pages_per_rpc=$($LCTL get_param osc.*.max_pages_per_rpc)
20512         local at_max=$($LCTL get_param -n at_max)
20513         local timeout=$($LCTL get_param -n timeout)
20514         local test_at="at_max"
20515         local param_at="$FSNAME.sys.at_max"
20516         local test_timeout="timeout"
20517         local param_timeout="$FSNAME.sys.timeout"
20518
20519         $LCTL set_param -n osc.*.max_pages_per_rpc=1024
20520
20521         set_persistent_param_and_check client "$test_at" "$param_at" 0
20522         set_persistent_param_and_check client "$test_timeout" "$param_timeout" 5
20523
20524         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB3 0x520
20525         do_facet ost1 "$LCTL set_param fail_loc=0x520"
20526         $LFS setstripe -c 1 -i 0 $DIR/$tfile
20527         stack_trap "rm -f $DIR/$tfile"
20528         dd if=/dev/zero of=$DIR/$tfile bs=8MB count=1
20529         sync
20530         do_facet ost1 "$LCTL set_param fail_loc=0"
20531
20532         set_persistent_param_and_check client "$test_at" "$param_at" $at_max
20533         set_persistent_param_and_check client "$test_timeout" "$param_timeout" \
20534                 $timeout
20535
20536         $LCTL set_param -n $pages_per_rpc
20537         restore_lustre_params < $p
20538         rm -f $p
20539 }
20540 run_test 224c "Don't hang if one of md lost during large bulk RPC"
20541
20542 test_224d() { # LU-11169
20543         test_224bd_sub $((TIMEOUT + 2)) error "dd failed"
20544 }
20545 run_test 224d "Don't corrupt data on bulk IO timeout"
20546
20547 MDSSURVEY=${MDSSURVEY:-$(which mds-survey 2>/dev/null || true)}
20548 test_225a () {
20549         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20550         if [ -z ${MDSSURVEY} ]; then
20551                 skip_env "mds-survey not found"
20552         fi
20553         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
20554                 skip "Need MDS version at least 2.2.51"
20555
20556         local mds=$(facet_host $SINGLEMDS)
20557         local target=$(do_nodes $mds 'lctl dl' |
20558                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
20559
20560         local cmd1="file_count=1000 thrhi=4"
20561         local cmd2="dir_count=2 layer=mdd stripe_count=0"
20562         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
20563         local cmd="$cmd1 $cmd2 $cmd3"
20564
20565         rm -f ${TMP}/mds_survey*
20566         echo + $cmd
20567         eval $cmd || error "mds-survey with zero-stripe failed"
20568         cat ${TMP}/mds_survey*
20569         rm -f ${TMP}/mds_survey*
20570 }
20571 run_test 225a "Metadata survey sanity with zero-stripe"
20572
20573 test_225b () {
20574         if [ -z ${MDSSURVEY} ]; then
20575                 skip_env "mds-survey not found"
20576         fi
20577         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
20578                 skip "Need MDS version at least 2.2.51"
20579         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20580         remote_mds_nodsh && skip "remote MDS with nodsh"
20581         if [ $($LCTL dl | grep -c osc) -eq 0 ]; then
20582                 skip_env "Need to mount OST to test"
20583         fi
20584
20585         local mds=$(facet_host $SINGLEMDS)
20586         local target=$(do_nodes $mds 'lctl dl' |
20587                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
20588
20589         local cmd1="file_count=1000 thrhi=4"
20590         local cmd2="dir_count=2 layer=mdd stripe_count=1"
20591         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
20592         local cmd="$cmd1 $cmd2 $cmd3"
20593
20594         rm -f ${TMP}/mds_survey*
20595         echo + $cmd
20596         eval $cmd || error "mds-survey with stripe_count failed"
20597         cat ${TMP}/mds_survey*
20598         rm -f ${TMP}/mds_survey*
20599 }
20600 run_test 225b "Metadata survey sanity with stripe_count = 1"
20601
20602 mcreate_path2fid () {
20603         local mode=$1
20604         local major=$2
20605         local minor=$3
20606         local name=$4
20607         local desc=$5
20608         local path=$DIR/$tdir/$name
20609         local fid
20610         local rc
20611         local fid_path
20612
20613         $MCREATE --mode=$1 --major=$2 --minor=$3 $path ||
20614                 error "cannot create $desc"
20615
20616         fid=$($LFS path2fid $path | tr -d '[' | tr -d ']')
20617         rc=$?
20618         [ $rc -ne 0 ] && error "cannot get fid of a $desc"
20619
20620         fid_path=$($LFS fid2path $MOUNT $fid)
20621         rc=$?
20622         [ $rc -ne 0 ] && error "cannot get path of $desc by $DIR $path $fid"
20623
20624         [ "$path" == "$fid_path" ] ||
20625                 error "fid2path returned $fid_path, expected $path"
20626
20627         echo "pass with $path and $fid"
20628 }
20629
20630 test_226a () {
20631         rm -rf $DIR/$tdir
20632         mkdir -p $DIR/$tdir
20633
20634         mcreate_path2fid 0010666 0 0 fifo "FIFO"
20635         mcreate_path2fid 0020666 1 3 null "character special file (null)"
20636         mcreate_path2fid 0020666 1 255 none "character special file (no device)"
20637         mcreate_path2fid 0040666 0 0 dir "directory"
20638         mcreate_path2fid 0060666 7 0 loop0 "block special file (loop)"
20639         mcreate_path2fid 0100666 0 0 file "regular file"
20640         mcreate_path2fid 0120666 0 0 link "symbolic link"
20641         mcreate_path2fid 0140666 0 0 sock "socket"
20642 }
20643 run_test 226a "call path2fid and fid2path on files of all type"
20644
20645 test_226b () {
20646         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20647
20648         local MDTIDX=1
20649
20650         rm -rf $DIR/$tdir
20651         mkdir -p $DIR/$tdir
20652         $LFS setdirstripe -i $MDTIDX $DIR/$tdir/remote_dir ||
20653                 error "create remote directory failed"
20654         mcreate_path2fid 0010666 0 0 "remote_dir/fifo" "FIFO"
20655         mcreate_path2fid 0020666 1 3 "remote_dir/null" \
20656                                 "character special file (null)"
20657         mcreate_path2fid 0020666 1 255 "remote_dir/none" \
20658                                 "character special file (no device)"
20659         mcreate_path2fid 0040666 0 0 "remote_dir/dir" "directory"
20660         mcreate_path2fid 0060666 7 0 "remote_dir/loop0" \
20661                                 "block special file (loop)"
20662         mcreate_path2fid 0100666 0 0 "remote_dir/file" "regular file"
20663         mcreate_path2fid 0120666 0 0 "remote_dir/link" "symbolic link"
20664         mcreate_path2fid 0140666 0 0 "remote_dir/sock" "socket"
20665 }
20666 run_test 226b "call path2fid and fid2path on files of all type under remote dir"
20667
20668 test_226c () {
20669         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20670         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
20671                 skip "Need MDS version at least 2.13.55"
20672
20673         local submnt=/mnt/submnt
20674         local srcfile=/etc/passwd
20675         local dstfile=$submnt/passwd
20676         local path
20677         local fid
20678
20679         rm -rf $DIR/$tdir
20680         rm -rf $submnt
20681         $LFS setdirstripe -c -1 -i 1 $DIR/$tdir ||
20682                 error "create remote directory failed"
20683         mkdir -p $submnt || error "create $submnt failed"
20684         $MOUNT_CMD $MGSNID:/$FSNAME/$tdir $submnt ||
20685                 error "mount $submnt failed"
20686         stack_trap "umount $submnt" EXIT
20687
20688         cp $srcfile $dstfile
20689         fid=$($LFS path2fid $dstfile)
20690         path=$($LFS fid2path $submnt "$fid")
20691         [ "$path" = "$dstfile" ] ||
20692                 error "fid2path $submnt $fid failed ($path != $dstfile)"
20693 }
20694 run_test 226c "call path2fid and fid2path under remote dir with subdir mount"
20695
20696 # LU-1299 Executing or running ldd on a truncated executable does not
20697 # cause an out-of-memory condition.
20698 test_227() {
20699         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20700         [ -z "$(which ldd)" ] && skip_env "should have ldd tool"
20701
20702         dd if=$(which date) of=$MOUNT/date bs=1k count=1
20703         chmod +x $MOUNT/date
20704
20705         $MOUNT/date > /dev/null
20706         ldd $MOUNT/date > /dev/null
20707         rm -f $MOUNT/date
20708 }
20709 run_test 227 "running truncated executable does not cause OOM"
20710
20711 # LU-1512 try to reuse idle OI blocks
20712 test_228a() {
20713         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20714         remote_mds_nodsh && skip "remote MDS with nodsh"
20715         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
20716
20717         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
20718         local myDIR=$DIR/$tdir
20719
20720         mkdir -p $myDIR
20721         #define OBD_FAIL_SEQ_EXHAUST             0x1002
20722         $LCTL set_param fail_loc=0x80001002
20723         createmany -o $myDIR/t- 10000
20724         $LCTL set_param fail_loc=0
20725         # The guard is current the largest FID holder
20726         touch $myDIR/guard
20727         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
20728                     tr -d '[')
20729         local IDX=$(($SEQ % 64))
20730
20731         do_facet $SINGLEMDS sync
20732         # Make sure journal flushed.
20733         sleep 6
20734         local blk1=$(do_facet $SINGLEMDS \
20735                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
20736                      grep Blockcount | awk '{print $4}')
20737
20738         # Remove old files, some OI blocks will become idle.
20739         unlinkmany $myDIR/t- 10000
20740         # Create new files, idle OI blocks should be reused.
20741         createmany -o $myDIR/t- 2000
20742         do_facet $SINGLEMDS sync
20743         # Make sure journal flushed.
20744         sleep 6
20745         local blk2=$(do_facet $SINGLEMDS \
20746                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
20747                      grep Blockcount | awk '{print $4}')
20748
20749         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
20750 }
20751 run_test 228a "try to reuse idle OI blocks"
20752
20753 test_228b() {
20754         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20755         remote_mds_nodsh && skip "remote MDS with nodsh"
20756         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
20757
20758         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
20759         local myDIR=$DIR/$tdir
20760
20761         mkdir -p $myDIR
20762         #define OBD_FAIL_SEQ_EXHAUST             0x1002
20763         $LCTL set_param fail_loc=0x80001002
20764         createmany -o $myDIR/t- 10000
20765         $LCTL set_param fail_loc=0
20766         # The guard is current the largest FID holder
20767         touch $myDIR/guard
20768         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
20769                     tr -d '[')
20770         local IDX=$(($SEQ % 64))
20771
20772         do_facet $SINGLEMDS sync
20773         # Make sure journal flushed.
20774         sleep 6
20775         local blk1=$(do_facet $SINGLEMDS \
20776                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
20777                      grep Blockcount | awk '{print $4}')
20778
20779         # Remove old files, some OI blocks will become idle.
20780         unlinkmany $myDIR/t- 10000
20781
20782         # stop the MDT
20783         stop $SINGLEMDS || error "Fail to stop MDT."
20784         # remount the MDT
20785         start $SINGLEMDS $(facet_device $SINGLEMDS) $MDS_MOUNT_OPTS ||
20786                 error "Fail to start MDT."
20787
20788         client_up || error "Fail to df."
20789         # Create new files, idle OI blocks should be reused.
20790         createmany -o $myDIR/t- 2000
20791         do_facet $SINGLEMDS sync
20792         # Make sure journal flushed.
20793         sleep 6
20794         local blk2=$(do_facet $SINGLEMDS \
20795                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
20796                      grep Blockcount | awk '{print $4}')
20797
20798         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
20799 }
20800 run_test 228b "idle OI blocks can be reused after MDT restart"
20801
20802 #LU-1881
20803 test_228c() {
20804         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20805         remote_mds_nodsh && skip "remote MDS with nodsh"
20806         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
20807
20808         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
20809         local myDIR=$DIR/$tdir
20810
20811         mkdir -p $myDIR
20812         #define OBD_FAIL_SEQ_EXHAUST             0x1002
20813         $LCTL set_param fail_loc=0x80001002
20814         # 20000 files can guarantee there are index nodes in the OI file
20815         createmany -o $myDIR/t- 20000
20816         $LCTL set_param fail_loc=0
20817         # The guard is current the largest FID holder
20818         touch $myDIR/guard
20819         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
20820                     tr -d '[')
20821         local IDX=$(($SEQ % 64))
20822
20823         do_facet $SINGLEMDS sync
20824         # Make sure journal flushed.
20825         sleep 6
20826         local blk1=$(do_facet $SINGLEMDS \
20827                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
20828                      grep Blockcount | awk '{print $4}')
20829
20830         # Remove old files, some OI blocks will become idle.
20831         unlinkmany $myDIR/t- 20000
20832         rm -f $myDIR/guard
20833         # The OI file should become empty now
20834
20835         # Create new files, idle OI blocks should be reused.
20836         createmany -o $myDIR/t- 2000
20837         do_facet $SINGLEMDS sync
20838         # Make sure journal flushed.
20839         sleep 6
20840         local blk2=$(do_facet $SINGLEMDS \
20841                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
20842                      grep Blockcount | awk '{print $4}')
20843
20844         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
20845 }
20846 run_test 228c "NOT shrink the last entry in OI index node to recycle idle leaf"
20847
20848 test_229() { # LU-2482, LU-3448
20849         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20850         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
20851         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
20852                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
20853
20854         rm -f $DIR/$tfile
20855
20856         # Create a file with a released layout and stripe count 2.
20857         $MULTIOP $DIR/$tfile H2c ||
20858                 error "failed to create file with released layout"
20859
20860         $LFS getstripe -v $DIR/$tfile
20861
20862         local pattern=$($LFS getstripe -L $DIR/$tfile)
20863         [ X"$pattern" = X"released" ] || error "pattern error ($pattern)"
20864
20865         local stripe_count=$($LFS getstripe -c $DIR/$tfile) ||
20866                 error "getstripe"
20867         [ $stripe_count -eq 2 ] || error "stripe count not 2 ($stripe_count)"
20868         stat $DIR/$tfile || error "failed to stat released file"
20869
20870         chown $RUNAS_ID $DIR/$tfile ||
20871                 error "chown $RUNAS_ID $DIR/$tfile failed"
20872
20873         chgrp $RUNAS_ID $DIR/$tfile ||
20874                 error "chgrp $RUNAS_ID $DIR/$tfile failed"
20875
20876         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
20877         rm $DIR/$tfile || error "failed to remove released file"
20878 }
20879 run_test 229 "getstripe/stat/rm/attr changes work on released files"
20880
20881 test_230a() {
20882         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20883         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20884         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20885                 skip "Need MDS version at least 2.11.52"
20886
20887         local MDTIDX=1
20888
20889         test_mkdir $DIR/$tdir
20890         test_mkdir -i0 -c1 $DIR/$tdir/test_230_local
20891         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230_local)
20892         [ $mdt_idx -ne 0 ] &&
20893                 error "create local directory on wrong MDT $mdt_idx"
20894
20895         $LFS mkdir -i $MDTIDX $DIR/$tdir/test_230 ||
20896                         error "create remote directory failed"
20897         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230)
20898         [ $mdt_idx -ne $MDTIDX ] &&
20899                 error "create remote directory on wrong MDT $mdt_idx"
20900
20901         createmany -o $DIR/$tdir/test_230/t- 10 ||
20902                 error "create files on remote directory failed"
20903         mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230/t-0)
20904         [ $mdt_idx -ne $MDTIDX ] && error "create files on wrong MDT $mdt_idx"
20905         rm -r $DIR/$tdir || error "unlink remote directory failed"
20906 }
20907 run_test 230a "Create remote directory and files under the remote directory"
20908
20909 test_230b() {
20910         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20911         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20912         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20913                 skip "Need MDS version at least 2.11.52"
20914
20915         local MDTIDX=1
20916         local mdt_index
20917         local i
20918         local file
20919         local pid
20920         local stripe_count
20921         local migrate_dir=$DIR/$tdir/migrate_dir
20922         local other_dir=$DIR/$tdir/other_dir
20923
20924         test_mkdir $DIR/$tdir
20925         test_mkdir -i0 -c1 $migrate_dir
20926         test_mkdir -i0 -c1 $other_dir
20927         for ((i=0; i<10; i++)); do
20928                 mkdir -p $migrate_dir/dir_${i}
20929                 createmany -o $migrate_dir/dir_${i}/f 10 ||
20930                         error "create files under remote dir failed $i"
20931         done
20932
20933         cp /etc/passwd $migrate_dir/$tfile
20934         cp /etc/passwd $other_dir/$tfile
20935         chattr +SAD $migrate_dir
20936         chattr +SAD $migrate_dir/$tfile
20937
20938         local old_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
20939         local old_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
20940         local old_dir_mode=$(stat -c%f $migrate_dir)
20941         local old_file_mode=$(stat -c%f $migrate_dir/$tfile)
20942
20943         mkdir -p $migrate_dir/dir_default_stripe2
20944         $LFS setstripe -c 2 $migrate_dir/dir_default_stripe2
20945         $LFS setstripe -c 2 $migrate_dir/${tfile}_stripe2
20946
20947         mkdir -p $other_dir
20948         ln $migrate_dir/$tfile $other_dir/luna
20949         ln $migrate_dir/$tfile $migrate_dir/sofia
20950         ln $other_dir/$tfile $migrate_dir/david
20951         ln -s $migrate_dir/$tfile $other_dir/zachary
20952         ln -s $migrate_dir/$tfile $migrate_dir/${tfile}_ln
20953         ln -s $other_dir/$tfile $migrate_dir/${tfile}_ln_other
20954
20955         local len
20956         local lnktgt
20957
20958         # inline symlink
20959         for len in 58 59 60; do
20960                 lnktgt=$(str_repeat 'l' $len)
20961                 touch $migrate_dir/$lnktgt
20962                 ln -s $lnktgt $migrate_dir/${len}char_ln
20963         done
20964
20965         # PATH_MAX
20966         for len in 4094 4095; do
20967                 lnktgt=$(str_repeat 'l' $len)
20968                 ln -s $lnktgt $migrate_dir/${len}char_ln
20969         done
20970
20971         # NAME_MAX
20972         for len in 254 255; do
20973                 touch $migrate_dir/$(str_repeat 'l' $len)
20974         done
20975
20976         $LFS migrate -m $MDTIDX $migrate_dir ||
20977                 error "fails on migrating remote dir to MDT1"
20978
20979         echo "migratate to MDT1, then checking.."
20980         for ((i = 0; i < 10; i++)); do
20981                 for file in $(find $migrate_dir/dir_${i}); do
20982                         mdt_index=$($LFS getstripe -m $file)
20983                         # broken symlink getstripe will fail
20984                         [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
20985                                 error "$file is not on MDT${MDTIDX}"
20986                 done
20987         done
20988
20989         # the multiple link file should still in MDT0
20990         mdt_index=$($LFS getstripe -m $migrate_dir/$tfile)
20991         [ $mdt_index == 0 ] ||
20992                 error "$file is not on MDT${MDTIDX}"
20993
20994         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
20995         [ "$old_dir_flag" = "$new_dir_flag" ] ||
20996                 error " expect $old_dir_flag get $new_dir_flag"
20997
20998         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
20999         [ "$old_file_flag" = "$new_file_flag" ] ||
21000                 error " expect $old_file_flag get $new_file_flag"
21001
21002         local new_dir_mode=$(stat -c%f $migrate_dir)
21003         [ "$old_dir_mode" = "$new_dir_mode" ] ||
21004                 error "expect mode $old_dir_mode get $new_dir_mode"
21005
21006         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
21007         [ "$old_file_mode" = "$new_file_mode" ] ||
21008                 error "expect mode $old_file_mode get $new_file_mode"
21009
21010         diff /etc/passwd $migrate_dir/$tfile ||
21011                 error "$tfile different after migration"
21012
21013         diff /etc/passwd $other_dir/luna ||
21014                 error "luna different after migration"
21015
21016         diff /etc/passwd $migrate_dir/sofia ||
21017                 error "sofia different after migration"
21018
21019         diff /etc/passwd $migrate_dir/david ||
21020                 error "david different after migration"
21021
21022         diff /etc/passwd $other_dir/zachary ||
21023                 error "zachary different after migration"
21024
21025         diff /etc/passwd $migrate_dir/${tfile}_ln ||
21026                 error "${tfile}_ln different after migration"
21027
21028         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
21029                 error "${tfile}_ln_other different after migration"
21030
21031         stripe_count=$($LFS getstripe -c $migrate_dir/dir_default_stripe2)
21032         [ $stripe_count = 2 ] ||
21033                 error "dir strpe_count $d != 2 after migration."
21034
21035         stripe_count=$($LFS getstripe -c $migrate_dir/${tfile}_stripe2)
21036         [ $stripe_count = 2 ] ||
21037                 error "file strpe_count $d != 2 after migration."
21038
21039         #migrate back to MDT0
21040         MDTIDX=0
21041
21042         $LFS migrate -m $MDTIDX $migrate_dir ||
21043                 error "fails on migrating remote dir to MDT0"
21044
21045         echo "migrate back to MDT0, checking.."
21046         for file in $(find $migrate_dir); do
21047                 mdt_index=$($LFS getstripe -m $file)
21048                 [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
21049                         error "$file is not on MDT${MDTIDX}"
21050         done
21051
21052         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
21053         [ "$old_dir_flag" = "$new_dir_flag" ] ||
21054                 error " expect $old_dir_flag get $new_dir_flag"
21055
21056         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
21057         [ "$old_file_flag" = "$new_file_flag" ] ||
21058                 error " expect $old_file_flag get $new_file_flag"
21059
21060         local new_dir_mode=$(stat -c%f $migrate_dir)
21061         [ "$old_dir_mode" = "$new_dir_mode" ] ||
21062                 error "expect mode $old_dir_mode get $new_dir_mode"
21063
21064         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
21065         [ "$old_file_mode" = "$new_file_mode" ] ||
21066                 error "expect mode $old_file_mode get $new_file_mode"
21067
21068         diff /etc/passwd ${migrate_dir}/$tfile ||
21069                 error "$tfile different after migration"
21070
21071         diff /etc/passwd ${other_dir}/luna ||
21072                 error "luna different after migration"
21073
21074         diff /etc/passwd ${migrate_dir}/sofia ||
21075                 error "sofia different after migration"
21076
21077         diff /etc/passwd ${other_dir}/zachary ||
21078                 error "zachary different after migration"
21079
21080         diff /etc/passwd $migrate_dir/${tfile}_ln ||
21081                 error "${tfile}_ln different after migration"
21082
21083         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
21084                 error "${tfile}_ln_other different after migration"
21085
21086         stripe_count=$($LFS getstripe -c ${migrate_dir}/dir_default_stripe2)
21087         [ $stripe_count = 2 ] ||
21088                 error "dir strpe_count $d != 2 after migration."
21089
21090         stripe_count=$($LFS getstripe -c ${migrate_dir}/${tfile}_stripe2)
21091         [ $stripe_count = 2 ] ||
21092                 error "file strpe_count $d != 2 after migration."
21093
21094         rm -rf $DIR/$tdir || error "rm dir failed after migration"
21095 }
21096 run_test 230b "migrate directory"
21097
21098 test_230c() {
21099         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21100         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21101         remote_mds_nodsh && skip "remote MDS with nodsh"
21102         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21103                 skip "Need MDS version at least 2.11.52"
21104
21105         local MDTIDX=1
21106         local total=3
21107         local mdt_index
21108         local file
21109         local migrate_dir=$DIR/$tdir/migrate_dir
21110
21111         #If migrating directory fails in the middle, all entries of
21112         #the directory is still accessiable.
21113         test_mkdir $DIR/$tdir
21114         test_mkdir -i0 -c1 $migrate_dir
21115         test_mkdir -i1 -c1 $DIR/$tdir/remote_dir
21116         stat $migrate_dir
21117         createmany -o $migrate_dir/f $total ||
21118                 error "create files under ${migrate_dir} failed"
21119
21120         # fail after migrating top dir, and this will fail only once, so the
21121         # first sub file migration will fail (currently f3), others succeed.
21122         #OBD_FAIL_MIGRATE_ENTRIES       0x1801
21123         do_facet mds1 lctl set_param fail_loc=0x1801
21124         local t=$(ls $migrate_dir | wc -l)
21125         $LFS migrate --mdt-index $MDTIDX $migrate_dir &&
21126                 error "migrate should fail"
21127         local u=$(ls $migrate_dir | wc -l)
21128         [ "$u" == "$t" ] || error "$u != $t during migration"
21129
21130         # add new dir/file should succeed
21131         mkdir $migrate_dir/dir ||
21132                 error "mkdir failed under migrating directory"
21133         touch $migrate_dir/file ||
21134                 error "create file failed under migrating directory"
21135
21136         # add file with existing name should fail
21137         for file in $migrate_dir/f*; do
21138                 stat $file > /dev/null || error "stat $file failed"
21139                 $OPENFILE -f O_CREAT:O_EXCL $file &&
21140                         error "open(O_CREAT|O_EXCL) $file should fail"
21141                 $MULTIOP $file m && error "create $file should fail"
21142                 touch $DIR/$tdir/remote_dir/$tfile ||
21143                         error "touch $tfile failed"
21144                 ln $DIR/$tdir/remote_dir/$tfile $file &&
21145                         error "link $file should fail"
21146                 mdt_index=$($LFS getstripe -m $file)
21147                 if [ $mdt_index == 0 ]; then
21148                         # file failed to migrate is not allowed to rename to
21149                         mv $DIR/$tdir/remote_dir/$tfile $file &&
21150                                 error "rename to $file should fail"
21151                 else
21152                         mv $DIR/$tdir/remote_dir/$tfile $file ||
21153                                 error "rename to $file failed"
21154                 fi
21155                 echo hello >> $file || error "write $file failed"
21156         done
21157
21158         # resume migration with different options should fail
21159         $LFS migrate -m 0 $migrate_dir &&
21160                 error "migrate -m 0 $migrate_dir should fail"
21161
21162         $LFS migrate -m $MDTIDX -c 2 $migrate_dir &&
21163                 error "migrate -c 2 $migrate_dir should fail"
21164
21165         # resume migration should succeed
21166         $LFS migrate -m $MDTIDX $migrate_dir ||
21167                 error "migrate $migrate_dir failed"
21168
21169         echo "Finish migration, then checking.."
21170         for file in $(find $migrate_dir); do
21171                 mdt_index=$($LFS getstripe -m $file)
21172                 [ $mdt_index == $MDTIDX ] ||
21173                         error "$file is not on MDT${MDTIDX}"
21174         done
21175
21176         rm -rf $DIR/$tdir || error "rm dir failed after migration"
21177 }
21178 run_test 230c "check directory accessiblity if migration failed"
21179
21180 test_230d() {
21181         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21182         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21183         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21184                 skip "Need MDS version at least 2.11.52"
21185         # LU-11235
21186         [ "$mds1_FSTYPE" == "zfs" ] && skip "skip ZFS backend"
21187
21188         local migrate_dir=$DIR/$tdir/migrate_dir
21189         local old_index
21190         local new_index
21191         local old_count
21192         local new_count
21193         local new_hash
21194         local mdt_index
21195         local i
21196         local j
21197
21198         old_index=$((RANDOM % MDSCOUNT))
21199         old_count=$((MDSCOUNT - old_index))
21200         new_index=$((RANDOM % MDSCOUNT))
21201         new_count=$((MDSCOUNT - new_index))
21202         new_hash=1 # for all_char
21203
21204         [ $old_count -gt 1 ] && old_count=$((old_count - RANDOM % old_count))
21205         [ $new_count -gt 1 ] && new_count=$((new_count - RANDOM % new_count))
21206
21207         test_mkdir $DIR/$tdir
21208         test_mkdir -i $old_index -c $old_count $migrate_dir
21209
21210         for ((i=0; i<100; i++)); do
21211                 test_mkdir -i0 -c1 $migrate_dir/dir_${i}
21212                 createmany -o $migrate_dir/dir_${i}/f 100 ||
21213                         error "create files under remote dir failed $i"
21214         done
21215
21216         echo -n "Migrate from MDT$old_index "
21217         [ $old_count -gt 1 ] && echo -n "... MDT$((old_index + old_count - 1)) "
21218         echo -n "to MDT$new_index"
21219         [ $new_count -gt 1 ] && echo -n " ... MDT$((new_index + new_count - 1))"
21220         echo
21221
21222         echo "$LFS migrate -m$new_index -c$new_count -H $new_hash $migrate_dir"
21223         $LFS migrate -m $new_index -c $new_count -H $new_hash $migrate_dir ||
21224                 error "migrate remote dir error"
21225
21226         echo "Finish migration, then checking.."
21227         for file in $(find $migrate_dir -maxdepth 1); do
21228                 mdt_index=$($LFS getstripe -m $file)
21229                 if [ $mdt_index -lt $new_index ] ||
21230                    [ $mdt_index -gt $((new_index + new_count - 1)) ]; then
21231                         error "$file is on MDT$mdt_index"
21232                 fi
21233         done
21234
21235         rm -rf $DIR/$tdir || error "rm dir failed after migration"
21236 }
21237 run_test 230d "check migrate big directory"
21238
21239 test_230e() {
21240         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21241         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21242         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21243                 skip "Need MDS version at least 2.11.52"
21244
21245         local i
21246         local j
21247         local a_fid
21248         local b_fid
21249
21250         mkdir_on_mdt0 $DIR/$tdir
21251         mkdir $DIR/$tdir/migrate_dir
21252         mkdir $DIR/$tdir/other_dir
21253         touch $DIR/$tdir/migrate_dir/a
21254         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/b
21255         ls $DIR/$tdir/other_dir
21256
21257         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
21258                 error "migrate dir fails"
21259
21260         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
21261         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
21262
21263         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
21264         [ $mdt_index == 0 ] || error "a is not on MDT0"
21265
21266         $LFS migrate -m 1 $DIR/$tdir/other_dir ||
21267                 error "migrate dir fails"
21268
21269         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir)
21270         [ $mdt_index == 1 ] || error "other_dir is not on MDT1"
21271
21272         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
21273         [ $mdt_index == 1 ] || error "a is not on MDT1"
21274
21275         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir/b)
21276         [ $mdt_index == 1 ] || error "b is not on MDT1"
21277
21278         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
21279         b_fid=$($LFS path2fid $DIR/$tdir/other_dir/b)
21280
21281         [ "$a_fid" = "$b_fid" ] || error "different fid after migration"
21282
21283         rm -rf $DIR/$tdir || error "rm dir failed after migration"
21284 }
21285 run_test 230e "migrate mulitple local link files"
21286
21287 test_230f() {
21288         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21289         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21290         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21291                 skip "Need MDS version at least 2.11.52"
21292
21293         local a_fid
21294         local ln_fid
21295
21296         mkdir -p $DIR/$tdir
21297         mkdir $DIR/$tdir/migrate_dir
21298         $LFS mkdir -i1 $DIR/$tdir/other_dir
21299         touch $DIR/$tdir/migrate_dir/a
21300         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln1
21301         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln2
21302         ls $DIR/$tdir/other_dir
21303
21304         # a should be migrated to MDT1, since no other links on MDT0
21305         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
21306                 error "#1 migrate dir fails"
21307         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
21308         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
21309         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
21310         [ $mdt_index == 1 ] || error "a is not on MDT1"
21311
21312         # a should stay on MDT1, because it is a mulitple link file
21313         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
21314                 error "#2 migrate dir fails"
21315         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
21316         [ $mdt_index == 1 ] || error "a is not on MDT1"
21317
21318         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
21319                 error "#3 migrate dir fails"
21320
21321         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
21322         ln_fid=$($LFS path2fid $DIR/$tdir/other_dir/ln1)
21323         [ "$a_fid" = "$ln_fid" ] || error "different fid after migrate to MDT1"
21324
21325         rm -rf $DIR/$tdir/other_dir/ln1 || error "unlink ln1 fails"
21326         rm -rf $DIR/$tdir/other_dir/ln2 || error "unlink ln2 fails"
21327
21328         # a should be migrated to MDT0, since no other links on MDT1
21329         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
21330                 error "#4 migrate dir fails"
21331         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
21332         [ $mdt_index == 0 ] || error "a is not on MDT0"
21333
21334         rm -rf $DIR/$tdir || error "rm dir failed after migration"
21335 }
21336 run_test 230f "migrate mulitple remote link files"
21337
21338 test_230g() {
21339         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21340         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21341         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21342                 skip "Need MDS version at least 2.11.52"
21343
21344         mkdir -p $DIR/$tdir/migrate_dir
21345
21346         $LFS migrate -m 1000 $DIR/$tdir/migrate_dir &&
21347                 error "migrating dir to non-exist MDT succeeds"
21348         true
21349 }
21350 run_test 230g "migrate dir to non-exist MDT"
21351
21352 test_230h() {
21353         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21354         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21355         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21356                 skip "Need MDS version at least 2.11.52"
21357
21358         local mdt_index
21359
21360         mkdir -p $DIR/$tdir/migrate_dir
21361
21362         $LFS migrate -m1 $DIR &&
21363                 error "migrating mountpoint1 should fail"
21364
21365         $LFS migrate -m1 $DIR/$tdir/.. &&
21366                 error "migrating mountpoint2 should fail"
21367
21368         # same as mv
21369         $LFS migrate -m1 $DIR/$tdir/migrate_dir/.. &&
21370                 error "migrating $tdir/migrate_dir/.. should fail"
21371
21372         true
21373 }
21374 run_test 230h "migrate .. and root"
21375
21376 test_230i() {
21377         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21378         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21379         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21380                 skip "Need MDS version at least 2.11.52"
21381
21382         mkdir -p $DIR/$tdir/migrate_dir
21383
21384         $LFS migrate -m 1 $DIR/$tdir/migrate_dir/ ||
21385                 error "migration fails with a tailing slash"
21386
21387         $LFS migrate -m 0 $DIR/$tdir/migrate_dir// ||
21388                 error "migration fails with two tailing slashes"
21389 }
21390 run_test 230i "lfs migrate -m tolerates trailing slashes"
21391
21392 test_230j() {
21393         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
21394         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
21395                 skip "Need MDS version at least 2.11.52"
21396
21397         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
21398         $LFS setstripe -E 1M -L mdt $DIR/$tdir/$tfile ||
21399                 error "create $tfile failed"
21400         cat /etc/passwd > $DIR/$tdir/$tfile
21401
21402         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
21403
21404         cmp /etc/passwd $DIR/$tdir/$tfile ||
21405                 error "DoM file mismatch after migration"
21406 }
21407 run_test 230j "DoM file data not changed after dir migration"
21408
21409 test_230k() {
21410         [ $MDSCOUNT -lt 4 ] && skip "needs >= 4 MDTs"
21411         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
21412                 skip "Need MDS version at least 2.11.56"
21413
21414         local total=20
21415         local files_on_starting_mdt=0
21416
21417         $LFS mkdir -i -1 -c 2 $DIR/$tdir || error "mkdir failed"
21418         $LFS getdirstripe $DIR/$tdir
21419         for i in $(seq $total); do
21420                 echo $((i*i - i)) > $DIR/$tdir/$tfile.$i || error "write failed"
21421                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
21422                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
21423         done
21424
21425         echo "$files_on_starting_mdt files on MDT0"
21426
21427         $LFS migrate -m 1,3 $DIR/$tdir || error "migrate -m 1,3 failed"
21428         $LFS getdirstripe $DIR/$tdir
21429
21430         files_on_starting_mdt=0
21431         for i in $(seq $total); do
21432                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
21433                         error "file $tfile.$i mismatch after migration"
21434                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 1 ]] &&
21435                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
21436         done
21437
21438         echo "$files_on_starting_mdt files on MDT1 after migration"
21439         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT1"
21440
21441         $LFS migrate -m 0 -c 2 $DIR/$tdir || error "migrate -m 0 -c 2 failed"
21442         $LFS getdirstripe $DIR/$tdir
21443
21444         files_on_starting_mdt=0
21445         for i in $(seq $total); do
21446                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
21447                         error "file $tfile.$i mismatch after 2nd migration"
21448                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
21449                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
21450         done
21451
21452         echo "$files_on_starting_mdt files on MDT0 after 2nd migration"
21453         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT0"
21454
21455         true
21456 }
21457 run_test 230k "file data not changed after dir migration"
21458
21459 test_230l() {
21460         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
21461         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
21462                 skip "Need MDS version at least 2.11.56"
21463
21464         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir failed"
21465         createmany -o $DIR/$tdir/f___________________________________ 1000 ||
21466                 error "create files under remote dir failed $i"
21467         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
21468 }
21469 run_test 230l "readdir between MDTs won't crash"
21470
21471 test_230m() {
21472         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
21473         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
21474                 skip "Need MDS version at least 2.11.56"
21475
21476         local MDTIDX=1
21477         local mig_dir=$DIR/$tdir/migrate_dir
21478         local longstr="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
21479         local shortstr="b"
21480         local val
21481
21482         echo "Creating files and dirs with xattrs"
21483         test_mkdir $DIR/$tdir
21484         test_mkdir -i0 -c1 $mig_dir
21485         mkdir $mig_dir/dir
21486         setfattr -n user.attr1 -v $longstr $mig_dir/dir ||
21487                 error "cannot set xattr attr1 on dir"
21488         setfattr -n user.attr2 -v $shortstr $mig_dir/dir ||
21489                 error "cannot set xattr attr2 on dir"
21490         touch $mig_dir/dir/f0
21491         setfattr -n user.attr1 -v $longstr $mig_dir/dir/f0 ||
21492                 error "cannot set xattr attr1 on file"
21493         setfattr -n user.attr2 -v $shortstr $mig_dir/dir/f0 ||
21494                 error "cannot set xattr attr2 on file"
21495         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
21496         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
21497         [ "$val" = $longstr ] || error "xattr attr1 not set properly on dir"
21498         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
21499         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on dir"
21500         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
21501         [ "$val" = $longstr ] || error "xattr attr1 not set properly on file"
21502         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
21503         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on file"
21504
21505         echo "Migrating to MDT1"
21506         $LFS migrate -m $MDTIDX $mig_dir ||
21507                 error "fails on migrating dir to MDT1"
21508
21509         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
21510         echo "Checking xattrs"
21511         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
21512         [ "$val" = $longstr ] ||
21513                 error "expecting xattr1 $longstr on dir, found $val"
21514         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
21515         [ "$val" = $shortstr ] ||
21516                 error "expecting xattr2 $shortstr on dir, found $val"
21517         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
21518         [ "$val" = $longstr ] ||
21519                 error "expecting xattr1 $longstr on file, found $val"
21520         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
21521         [ "$val" = $shortstr ] ||
21522                 error "expecting xattr2 $shortstr on file, found $val"
21523 }
21524 run_test 230m "xattrs not changed after dir migration"
21525
21526 test_230n() {
21527         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
21528         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
21529                 skip "Need MDS version at least 2.13.53"
21530
21531         $LFS mkdir -i 0 $DIR/$tdir || error "mkdir $tdir failed"
21532         cat /etc/hosts > $DIR/$tdir/$tfile
21533         $LFS mirror extend -N1 $DIR/$tdir/$tfile || error "Mirroring failed"
21534         $LFS migrate -m 1 $DIR/$tdir || error "Migration failed"
21535
21536         cmp /etc/hosts $DIR/$tdir/$tfile ||
21537                 error "File data mismatch after migration"
21538 }
21539 run_test 230n "Dir migration with mirrored file"
21540
21541 test_230o() {
21542         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
21543         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
21544                 skip "Need MDS version at least 2.13.52"
21545
21546         local mdts=$(comma_list $(mdts_nodes))
21547         local timeout=100
21548         local restripe_status
21549         local delta
21550         local i
21551
21552         [[ $mds1_FSTYPE == zfs ]] && timeout=300
21553
21554         # in case "crush" hash type is not set
21555         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
21556
21557         restripe_status=$(do_facet mds1 $LCTL get_param -n \
21558                            mdt.*MDT0000.enable_dir_restripe)
21559         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
21560         stack_trap "do_nodes $mdts $LCTL set_param \
21561                     mdt.*.enable_dir_restripe=$restripe_status"
21562
21563         mkdir $DIR/$tdir
21564         createmany -m $DIR/$tdir/f 100 ||
21565                 error "create files under remote dir failed $i"
21566         createmany -d $DIR/$tdir/d 100 ||
21567                 error "create dirs under remote dir failed $i"
21568
21569         for i in $(seq 2 $MDSCOUNT); do
21570                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
21571                 $LFS setdirstripe -c $i $DIR/$tdir ||
21572                         error "split -c $i $tdir failed"
21573                 wait_update $HOSTNAME \
21574                         "$LFS getdirstripe -H $DIR/$tdir" "crush" $timeout ||
21575                         error "dir split not finished"
21576                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
21577                         awk '/migrate/ {sum += $2} END { print sum }')
21578                 echo "$delta migrated when dir split $((i - 1)) to $i stripes"
21579                 # delta is around total_files/stripe_count
21580                 (( $delta < 200 / (i - 1) + 4 )) ||
21581                         error "$delta files migrated >= $((200 / (i - 1) + 4))"
21582         done
21583 }
21584 run_test 230o "dir split"
21585
21586 test_230p() {
21587         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
21588         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
21589                 skip "Need MDS version at least 2.13.52"
21590
21591         local mdts=$(comma_list $(mdts_nodes))
21592         local timeout=100
21593         local restripe_status
21594         local delta
21595         local c
21596
21597         [[ $mds1_FSTYPE == zfs ]] && timeout=300
21598
21599         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
21600
21601         restripe_status=$(do_facet mds1 $LCTL get_param -n \
21602                            mdt.*MDT0000.enable_dir_restripe)
21603         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
21604         stack_trap "do_nodes $mdts $LCTL set_param \
21605                     mdt.*.enable_dir_restripe=$restripe_status"
21606
21607         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir
21608         createmany -m $DIR/$tdir/f 100 ||
21609                 error "create files under remote dir failed"
21610         createmany -d $DIR/$tdir/d 100 ||
21611                 error "create dirs under remote dir failed"
21612
21613         for c in $(seq $((MDSCOUNT - 1)) -1 1); do
21614                 local mdt_hash="crush"
21615
21616                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
21617                 $LFS setdirstripe -c $c $DIR/$tdir ||
21618                         error "split -c $c $tdir failed"
21619                 if (( MDS1_VERSION >= $(version_code 2.14.51) )); then
21620                         mdt_hash="$mdt_hash,fixed"
21621                 elif [ $c -eq 1 ]; then
21622                         mdt_hash="none"
21623                 fi
21624                 wait_update $HOSTNAME \
21625                         "$LFS getdirstripe -H $DIR/$tdir" $mdt_hash $timeout ||
21626                         error "dir merge not finished"
21627                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
21628                         awk '/migrate/ {sum += $2} END { print sum }')
21629                 echo "$delta migrated when dir merge $((c + 1)) to $c stripes"
21630                 # delta is around total_files/stripe_count
21631                 (( delta < 200 / c + 4 )) ||
21632                         error "$delta files migrated >= $((200 / c + 4))"
21633         done
21634 }
21635 run_test 230p "dir merge"
21636
21637 test_230q() {
21638         (( MDSCOUNT > 1)) || skip "needs >= 2 MDTs"
21639         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
21640                 skip "Need MDS version at least 2.13.52"
21641
21642         local mdts=$(comma_list $(mdts_nodes))
21643         local saved_threshold=$(do_facet mds1 \
21644                         $LCTL get_param -n mdt.*-MDT0000.dir_split_count)
21645         local saved_delta=$(do_facet mds1 \
21646                         $LCTL get_param -n mdt.*-MDT0000.dir_split_delta)
21647         local threshold=100
21648         local delta=2
21649         local total=0
21650         local stripe_count=0
21651         local stripe_index
21652         local nr_files
21653         local create
21654
21655         # test with fewer files on ZFS
21656         [ "$mds1_FSTYPE" == "zfs" ] && threshold=40
21657
21658         stack_trap "do_nodes $mdts $LCTL set_param \
21659                     mdt.*.dir_split_count=$saved_threshold"
21660         stack_trap "do_nodes $mdts $LCTL set_param \
21661                     mdt.*.dir_split_delta=$saved_delta"
21662         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.dir_restripe_nsonly=1"
21663         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_auto_split=1"
21664         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_count=$threshold"
21665         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_delta=$delta"
21666         do_nodes $mdts "$LCTL set_param mdt.*.dir_restripe_nsonly=0"
21667         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
21668
21669         $LFS mkdir -i -1 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
21670         stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
21671
21672         create=$((threshold * 3 / 2))
21673         while [ $stripe_count -lt $MDSCOUNT ]; do
21674                 createmany -m $DIR/$tdir/f $total $create ||
21675                         error "create sub files failed"
21676                 stat $DIR/$tdir > /dev/null
21677                 total=$((total + create))
21678                 stripe_count=$((stripe_count + delta))
21679                 [ $stripe_count -gt $MDSCOUNT ] && stripe_count=$MDSCOUNT
21680
21681                 wait_update $HOSTNAME \
21682                         "$LFS getdirstripe -c $DIR/$tdir" "$stripe_count" 40 ||
21683                         error "stripe count $($LFS getdirstripe -c $DIR/$tdir) != $stripe_count"
21684
21685                 wait_update $HOSTNAME \
21686                         "$LFS getdirstripe -H $DIR/$tdir" "crush" 200 ||
21687                         error "stripe hash $($LFS getdirstripe -H $DIR/$tdir) != crush"
21688
21689                 nr_files=$($LFS find -m 1 $DIR/$tdir | grep -c -w $stripe_index)
21690                 echo "$nr_files/$total files on MDT$stripe_index after split"
21691                 # allow 10% margin of imbalance with crush hash
21692                 (( $nr_files <= $total / $stripe_count + $create / 10)) ||
21693                         error "$nr_files files on MDT$stripe_index after split"
21694
21695                 nr_files=$($LFS find -type f $DIR/$tdir | wc -l)
21696                 [ $nr_files -eq $total ] ||
21697                         error "total sub files $nr_files != $total"
21698         done
21699
21700         (( MDS1_VERSION >= $(version_code 2.14.51) )) || return 0
21701
21702         echo "fixed layout directory won't auto split"
21703         $LFS migrate -m 0 $DIR/$tdir || error "migrate $tdir failed"
21704         wait_update $HOSTNAME "$LFS getdirstripe -H $DIR/$tdir" "crush,fixed" \
21705                 10 || error "stripe hash $($LFS getdirstripe -H $DIR/$tdir)"
21706         wait_update $HOSTNAME "$LFS getdirstripe -c $DIR/$tdir" 1 10 ||
21707                 error "stripe count $($LFS getdirstripe -c $DIR/$tdir)"
21708 }
21709 run_test 230q "dir auto split"
21710
21711 test_230r() {
21712         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
21713         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
21714         [[ $MDS1_VERSION -ge $(version_code 2.13.54) ]] ||
21715                 skip "Need MDS version at least 2.13.54"
21716
21717         # maximum amount of local locks:
21718         # parent striped dir - 2 locks
21719         # new stripe in parent to migrate to - 1 lock
21720         # source and target - 2 locks
21721         # Total 5 locks for regular file
21722         mkdir -p $DIR/$tdir
21723         $LFS mkdir -i1 -c2 $DIR/$tdir/dir1
21724         touch $DIR/$tdir/dir1/eee
21725
21726         # create 4 hardlink for 4 more locks
21727         # Total: 9 locks > RS_MAX_LOCKS (8)
21728         $LFS mkdir -i1 -c1 $DIR/$tdir/dir2
21729         $LFS mkdir -i1 -c1 $DIR/$tdir/dir3
21730         $LFS mkdir -i1 -c1 $DIR/$tdir/dir4
21731         $LFS mkdir -i1 -c1 $DIR/$tdir/dir5
21732         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir2/eee
21733         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir3/eee
21734         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir4/eee
21735         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir5/eee
21736
21737         cancel_lru_locks mdc
21738
21739         $LFS migrate -m1 -c1 $DIR/$tdir/dir1 ||
21740                 error "migrate dir fails"
21741
21742         rm -rf $DIR/$tdir || error "rm dir failed after migration"
21743 }
21744 run_test 230r "migrate with too many local locks"
21745
21746 test_230s() {
21747         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
21748                 skip "Need MDS version at least 2.14.52"
21749
21750         local mdts=$(comma_list $(mdts_nodes))
21751         local restripe_status=$(do_facet mds1 $LCTL get_param -n \
21752                                 mdt.*MDT0000.enable_dir_restripe)
21753
21754         stack_trap "do_nodes $mdts $LCTL set_param \
21755                     mdt.*.enable_dir_restripe=$restripe_status"
21756
21757         local st
21758         for st in 0 1; do
21759                 do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=$st"
21760                 test_mkdir $DIR/$tdir
21761                 $LFS mkdir $DIR/$tdir |& grep "File exists" ||
21762                         error "$LFS mkdir should return EEXIST if target exists"
21763                 rmdir $DIR/$tdir
21764         done
21765 }
21766 run_test 230s "lfs mkdir should return -EEXIST if target exists"
21767
21768 test_230t()
21769 {
21770         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
21771         [[ $MDS1_VERSION -ge $(version_code 2.14.50) ]] ||
21772                 skip "Need MDS version at least 2.14.50"
21773
21774         test_mkdir $DIR/$tdir || error "mkdir $tdir failed"
21775         test_mkdir $DIR/$tdir/subdir || error "mkdir subdir failed"
21776         $LFS project -p 1 -s $DIR/$tdir ||
21777                 error "set $tdir project id failed"
21778         $LFS project -p 2 -s $DIR/$tdir/subdir ||
21779                 error "set subdir project id failed"
21780         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir || error "migrate failed"
21781 }
21782 run_test 230t "migrate directory with project ID set"
21783
21784 test_230u()
21785 {
21786         (( MDSCOUNT > 3 )) || skip_env "needs >= 4 MDTs"
21787         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
21788                 skip "Need MDS version at least 2.14.53"
21789
21790         local count
21791
21792         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
21793         mkdir $DIR/$tdir/sub{0..99} || error "mkdir sub failed"
21794         $LFS migrate -m -1 $DIR/$tdir/sub{0..99} || error "migrate sub failed"
21795         for i in $(seq 0 $((MDSCOUNT - 1))); do
21796                 count=$($LFS getstripe -m $DIR/$tdir/sub* | grep -c ^$i)
21797                 echo "$count dirs migrated to MDT$i"
21798         done
21799         count=$($LFS getstripe -m $DIR/$tdir/sub* | sort -u | wc -l)
21800         (( count >= MDSCOUNT - 1 )) || error "dirs migrated to $count MDTs"
21801 }
21802 run_test 230u "migrate directory by QOS"
21803
21804 test_230v()
21805 {
21806         (( MDSCOUNT > 3 )) || skip_env "needs >= 4 MDTs"
21807         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
21808                 skip "Need MDS version at least 2.14.53"
21809
21810         local count
21811
21812         mkdir $DIR/$tdir || error "mkdir $tdir failed"
21813         mkdir $DIR/$tdir/sub{0..99} || error "mkdir sub failed"
21814         $LFS migrate -m 0,2,1 $DIR/$tdir || error "migrate $tdir failed"
21815         for i in $(seq 0 $((MDSCOUNT - 1))); do
21816                 count=$($LFS getstripe -m $DIR/$tdir/sub* | grep -c ^$i)
21817                 echo "$count subdirs migrated to MDT$i"
21818                 (( i == 3 )) && (( count > 0 )) &&
21819                         error "subdir shouldn't be migrated to MDT3"
21820         done
21821         count=$($LFS getstripe -m $DIR/$tdir/sub* | sort -u | wc -l)
21822         (( count == 3 )) || error "dirs migrated to $count MDTs"
21823 }
21824 run_test 230v "subdir migrated to the MDT where its parent is located"
21825
21826 test_230w() {
21827         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
21828         (( MDS1_VERSION >= $(version_code 2.15.0) )) ||
21829                 skip "Need MDS version at least 2.15.0"
21830
21831         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
21832         createmany -o $DIR/$tdir/f 10 || error "create files failed"
21833         createmany -d $DIR/$tdir/d 10 || error "create dirs failed"
21834
21835         $LFS migrate -m 1 -c $MDSCOUNT -d $DIR/$tdir ||
21836                 error "migrate failed"
21837
21838         (( $($LFS getdirstripe -c $DIR/$tdir) == MDSCOUNT )) ||
21839                 error "$tdir stripe count mismatch"
21840
21841         for i in $(seq 0 9); do
21842                 (( $($LFS getdirstripe -c $DIR/$tdir/d$i) == 0 )) ||
21843                         error "d$i is striped"
21844         done
21845 }
21846 run_test 230w "non-recursive mode dir migration"
21847
21848 test_230x() {
21849         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
21850         (( MDS1_VERSION >= $(version_code 2.15.0) )) ||
21851                 skip "Need MDS version at least 2.15.0"
21852
21853         mkdir -p $DIR/$tdir || error "mkdir failed"
21854         createmany -d $DIR/$tdir/sub 100 || error "createmany failed"
21855
21856         local mdt_name=$(mdtname_from_index 0)
21857         local low=$(do_facet mds2 $LCTL get_param -n \
21858                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low)
21859         local high=$(do_facet mds2 $LCTL get_param -n \
21860                 osp.*$mdt_name-osp-MDT0001.reserved_ino_high)
21861         local ffree=$($LFS df -i $MOUNT | awk "/$mdt_name/ { print \$4 }")
21862         local maxage=$(do_facet mds2 $LCTL get_param -n \
21863                 osp.*$mdt_name-osp-MDT0001.maxage)
21864
21865         stack_trap "do_facet mds2 $LCTL set_param -n \
21866                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low=$low \
21867                 osp.*$mdt_name-osp-MDT0001.reserved_ino_high=$high" EXIT
21868         stack_trap "do_facet mds2 $LCTL set_param -n \
21869                 osp.*$mdt_name-osp-MDT0001.maxage=$maxage" EXIT
21870
21871         do_facet mds2 $LCTL set_param -n \
21872                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low=$((ffree + 1))
21873         do_facet mds2 $LCTL set_param -n osp.*$mdt_name-osp-MDT0001.maxage=1
21874         sleep 4
21875         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir &&
21876                 error "migrate $tdir should fail"
21877
21878         do_facet mds2 $LCTL set_param -n \
21879                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low=$low
21880         do_facet mds2 $LCTL set_param -n \
21881                 osp.*$mdt_name-osp-MDT0001.reserved_ino_high=$high
21882         sleep 4
21883         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir ||
21884                 error "migrate failed"
21885         (( $($LFS getdirstripe -c $DIR/$tdir) == $MDSCOUNT )) ||
21886                 error "$tdir stripe count mismatch"
21887 }
21888 run_test 230x "dir migration check space"
21889
21890 test_230y() {
21891         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
21892         (( MDS1_VERSION >= $(version_code 2.15.55.45) )) ||
21893                 skip "Need MDS version at least 2.15.55.45"
21894
21895         local pid
21896
21897         test_mkdir -c -1 $DIR/$tdir || error "mkdir $tdir failed"
21898         $LFS getdirstripe $DIR/$tdir
21899         createmany -d $DIR/$tdir/d 100 || error "createmany failed"
21900         $LFS migrate -m 1 -c 2 $DIR/$tdir &
21901         pid=$!
21902         sleep 1
21903
21904         #OBD_FAIL_MIGRATE_BAD_HASH      0x1802
21905         do_facet mds2 lctl set_param fail_loc=0x1802
21906
21907         wait $pid
21908         do_facet mds2 lctl set_param fail_loc=0
21909         $LFS getdirstripe $DIR/$tdir
21910         unlinkmany -d $DIR/$tdir/d 100 || error "unlinkmany failed"
21911         rmdir $DIR/$tdir || error "rmdir $tdir failed"
21912 }
21913 run_test 230y "unlink dir with bad hash type"
21914
21915 test_230z() {
21916         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
21917         (( MDS1_VERSION >= $(version_code 2.15.55.45) )) ||
21918                 skip "Need MDS version at least 2.15.55.45"
21919
21920         local pid
21921
21922         test_mkdir -c -1 $DIR/$tdir || error "mkdir $tdir failed"
21923         $LFS getdirstripe $DIR/$tdir
21924         createmany -d $DIR/$tdir/d 100 || error "createmany failed"
21925         $LFS migrate -m 1 -c 2 -H fnv_1a_64 $DIR/$tdir &
21926         pid=$!
21927         sleep 1
21928
21929         #OBD_FAIL_MIGRATE_BAD_HASH      0x1802
21930         do_facet mds2 lctl set_param fail_loc=0x1802
21931
21932         wait $pid
21933         do_facet mds2 lctl set_param fail_loc=0
21934         $LFS getdirstripe $DIR/$tdir
21935
21936         # resume migration
21937         $LFS migrate -m 1 -c 2 -H fnv_1a_64 $DIR/$tdir ||
21938                 error "resume migration failed"
21939         $LFS getdirstripe $DIR/$tdir
21940         [ $($LFS getdirstripe -H $DIR/$tdir) == "fnv_1a_64,fixed" ] ||
21941                 error "migration is not finished"
21942 }
21943 run_test 230z "resume dir migration with bad hash type"
21944
21945 test_231a()
21946 {
21947         # For simplicity this test assumes that max_pages_per_rpc
21948         # is the same across all OSCs
21949         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
21950         local bulk_size=$((max_pages * PAGE_SIZE))
21951         local brw_size=$(do_facet ost1 $LCTL get_param -n obdfilter.*.brw_size |
21952                                        head -n 1)
21953
21954         mkdir -p $DIR/$tdir
21955         $LFS setstripe -S ${brw_size}M $DIR/$tdir ||
21956                 error "failed to set stripe with -S ${brw_size}M option"
21957         stack_trap "rm -rf $DIR/$tdir"
21958
21959         # clear the OSC stats
21960         $LCTL set_param osc.*.stats=0 &>/dev/null
21961         stop_writeback
21962
21963         # Client writes $bulk_size - there must be 1 rpc for $max_pages.
21964         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=$bulk_size count=1 \
21965                 oflag=direct &>/dev/null || error "dd failed"
21966
21967         sync; sleep 1; sync # just to be safe
21968         local nrpcs=$($LCTL get_param osc.*.stats |awk '/ost_write/ {print $2}')
21969         if [ x$nrpcs != "x1" ]; then
21970                 $LCTL get_param osc.*.stats
21971                 error "found $nrpcs ost_write RPCs, not 1 as expected"
21972         fi
21973
21974         start_writeback
21975         # Drop the OSC cache, otherwise we will read from it
21976         cancel_lru_locks osc
21977
21978         # clear the OSC stats
21979         $LCTL set_param osc.*.stats=0 &>/dev/null
21980
21981         # Client reads $bulk_size.
21982         dd if=$DIR/$tdir/$tfile of=/dev/null bs=$bulk_size count=1 \
21983                 iflag=direct &>/dev/null || error "dd failed"
21984
21985         nrpcs=$($LCTL get_param osc.*.stats | awk '/ost_read/ { print $2 }')
21986         if [ x$nrpcs != "x1" ]; then
21987                 $LCTL get_param osc.*.stats
21988                 error "found $nrpcs ost_read RPCs, not 1 as expected"
21989         fi
21990 }
21991 run_test 231a "checking that reading/writing of BRW RPC size results in one RPC"
21992
21993 test_231b() {
21994         mkdir -p $DIR/$tdir
21995         stack_trap "rm -rf $DIR/$tdir"
21996         local i
21997         for i in {0..1023}; do
21998                 dd if=/dev/zero of=$DIR/$tdir/$tfile conv=notrunc \
21999                         seek=$((2 * i)) bs=4096 count=1 &>/dev/null ||
22000                         error "dd of=$DIR/$tdir/$tfile seek=$((2 * i)) failed"
22001         done
22002         sync
22003 }
22004 run_test 231b "must not assert on fully utilized OST request buffer"
22005
22006 test_232a() {
22007         mkdir -p $DIR/$tdir
22008         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
22009
22010         #define OBD_FAIL_LDLM_OST_LVB            0x31c
22011         do_facet ost1 $LCTL set_param fail_loc=0x31c
22012
22013         # ignore dd failure
22014         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1 || true
22015         stack_trap "rm -f $DIR/$tdir/$tfile"
22016
22017         do_facet ost1 $LCTL set_param fail_loc=0
22018         umount_client $MOUNT || error "umount failed"
22019         mount_client $MOUNT || error "mount failed"
22020         stop ost1 || error "cannot stop ost1"
22021         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
22022 }
22023 run_test 232a "failed lock should not block umount"
22024
22025 test_232b() {
22026         [ $MDS1_VERSION -ge $(version_code 2.10.58) ] ||
22027                 skip "Need MDS version at least 2.10.58"
22028
22029         mkdir -p $DIR/$tdir
22030         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
22031         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1
22032         stack_trap "rm -f $DIR/$tdir/$tfile"
22033         sync
22034         cancel_lru_locks osc
22035
22036         #define OBD_FAIL_LDLM_OST_LVB            0x31c
22037         do_facet ost1 $LCTL set_param fail_loc=0x31c
22038
22039         # ignore failure
22040         $LFS data_version $DIR/$tdir/$tfile || true
22041
22042         do_facet ost1 $LCTL set_param fail_loc=0
22043         umount_client $MOUNT || error "umount failed"
22044         mount_client $MOUNT || error "mount failed"
22045         stop ost1 || error "cannot stop ost1"
22046         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
22047 }
22048 run_test 232b "failed data version lock should not block umount"
22049
22050 test_233a() {
22051         [ $MDS1_VERSION -ge $(version_code 2.3.64) ] ||
22052                 skip "Need MDS version at least 2.3.64"
22053         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
22054
22055         local fid=$($LFS path2fid $MOUNT)
22056
22057         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
22058                 error "cannot access $MOUNT using its FID '$fid'"
22059 }
22060 run_test 233a "checking that OBF of the FS root succeeds"
22061
22062 test_233b() {
22063         [ $MDS1_VERSION -ge $(version_code 2.5.90) ] ||
22064                 skip "Need MDS version at least 2.5.90"
22065         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
22066
22067         local fid=$($LFS path2fid $MOUNT/.lustre)
22068
22069         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
22070                 error "cannot access $MOUNT/.lustre using its FID '$fid'"
22071
22072         fid=$($LFS path2fid $MOUNT/.lustre/fid)
22073         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
22074                 error "cannot access $MOUNT/.lustre/fid using its FID '$fid'"
22075 }
22076 run_test 233b "checking that OBF of the FS .lustre succeeds"
22077
22078 test_234() {
22079         local p="$TMP/sanityN-$TESTNAME.parameters"
22080         save_lustre_params client "llite.*.xattr_cache" > $p
22081         lctl set_param llite.*.xattr_cache 1 ||
22082                 skip_env "xattr cache is not supported"
22083
22084         mkdir -p $DIR/$tdir || error "mkdir failed"
22085         touch $DIR/$tdir/$tfile || error "touch failed"
22086         # OBD_FAIL_LLITE_XATTR_ENOMEM
22087         $LCTL set_param fail_loc=0x1405
22088         getfattr -n user.attr $DIR/$tdir/$tfile &&
22089                 error "getfattr should have failed with ENOMEM"
22090         $LCTL set_param fail_loc=0x0
22091         rm -rf $DIR/$tdir
22092
22093         restore_lustre_params < $p
22094         rm -f $p
22095 }
22096 run_test 234 "xattr cache should not crash on ENOMEM"
22097
22098 test_235() {
22099         [ $MDS1_VERSION -lt $(version_code 2.4.52) ] &&
22100                 skip "Need MDS version at least 2.4.52"
22101
22102         flock_deadlock $DIR/$tfile
22103         local RC=$?
22104         case $RC in
22105                 0)
22106                 ;;
22107                 124) error "process hangs on a deadlock"
22108                 ;;
22109                 *) error "error executing flock_deadlock $DIR/$tfile"
22110                 ;;
22111         esac
22112 }
22113 run_test 235 "LU-1715: flock deadlock detection does not work properly"
22114
22115 #LU-2935
22116 test_236() {
22117         check_swap_layouts_support
22118
22119         local ref1=/etc/passwd
22120         local ref2=/etc/group
22121         local file1=$DIR/$tdir/f1
22122         local file2=$DIR/$tdir/f2
22123
22124         test_mkdir -c1 $DIR/$tdir
22125         $LFS setstripe -c 1 $file1 || error "cannot setstripe on '$file1': rc = $?"
22126         cp $ref1 $file1 || error "cp $ref1 $file1 failed: rc = $?"
22127         $LFS setstripe -c 2 $file2 || error "cannot setstripe on '$file2': rc = $?"
22128         cp $ref2 $file2 || error "cp $ref2 $file2 failed: rc = $?"
22129         local fd=$(free_fd)
22130         local cmd="exec $fd<>$file2"
22131         eval $cmd
22132         rm $file2
22133         $LFS swap_layouts $file1 /proc/self/fd/${fd} ||
22134                 error "cannot swap layouts of '$file1' and /proc/self/fd/${fd}"
22135         cmd="exec $fd>&-"
22136         eval $cmd
22137         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
22138
22139         #cleanup
22140         rm -rf $DIR/$tdir
22141 }
22142 run_test 236 "Layout swap on open unlinked file"
22143
22144 # LU-4659 linkea consistency
22145 test_238() {
22146         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
22147                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
22148                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
22149                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
22150
22151         touch $DIR/$tfile
22152         ln $DIR/$tfile $DIR/$tfile.lnk
22153         touch $DIR/$tfile.new
22154         mv $DIR/$tfile.new $DIR/$tfile
22155         local fid1=$($LFS path2fid $DIR/$tfile)
22156         local fid2=$($LFS path2fid $DIR/$tfile.lnk)
22157         local path1=$($LFS fid2path $FSNAME "$fid1")
22158         [ $tfile == $path1 ] || error "linkea inconsistent: $tfile $fid1 $path1"
22159         local path2=$($LFS fid2path $FSNAME "$fid2")
22160         [ $tfile.lnk == $path2 ] ||
22161                 error "linkea inconsistent: $tfile.lnk $fid2 $path2!"
22162         rm -f $DIR/$tfile*
22163 }
22164 run_test 238 "Verify linkea consistency"
22165
22166 test_239A() { # was test_239
22167         [ $MDS1_VERSION -lt $(version_code 2.5.60) ] &&
22168                 skip "Need MDS version at least 2.5.60"
22169
22170         local list=$(comma_list $(mdts_nodes))
22171
22172         mkdir -p $DIR/$tdir
22173         createmany -o $DIR/$tdir/f- 5000
22174         unlinkmany $DIR/$tdir/f- 5000
22175         [ $MDS1_VERSION -gt $(version_code 2.10.4) ] &&
22176                 do_nodes $list "lctl set_param -n osp.*.force_sync=1"
22177         changes=$(do_nodes $list "lctl get_param -n osp.*MDT*.sync_changes \
22178                         osp.*MDT*.sync_in_flight" | calc_sum)
22179         [ "$changes" -eq 0 ] || error "$changes not synced"
22180 }
22181 run_test 239A "osp_sync test"
22182
22183 test_239a() { #LU-5297
22184         remote_mds_nodsh && skip "remote MDS with nodsh"
22185
22186         touch $DIR/$tfile
22187         #define OBD_FAIL_OSP_CHECK_INVALID_REC     0x2100
22188         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2100
22189         chgrp $RUNAS_GID $DIR/$tfile
22190         wait_delete_completed
22191 }
22192 run_test 239a "process invalid osp sync record correctly"
22193
22194 test_239b() { #LU-5297
22195         remote_mds_nodsh && skip "remote MDS with nodsh"
22196
22197         touch $DIR/$tfile1
22198         #define OBD_FAIL_OSP_CHECK_ENOMEM     0x2101
22199         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2101
22200         chgrp $RUNAS_GID $DIR/$tfile1
22201         wait_delete_completed
22202         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
22203         touch $DIR/$tfile2
22204         chgrp $RUNAS_GID $DIR/$tfile2
22205         wait_delete_completed
22206 }
22207 run_test 239b "process osp sync record with ENOMEM error correctly"
22208
22209 test_240() {
22210         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22211         remote_mds_nodsh && skip "remote MDS with nodsh"
22212
22213         mkdir -p $DIR/$tdir
22214
22215         $LFS mkdir -i 0 $DIR/$tdir/d0 ||
22216                 error "failed to mkdir $DIR/$tdir/d0 on MDT0"
22217         $LFS mkdir -i 1 $DIR/$tdir/d0/d1 ||
22218                 error "failed to mkdir $DIR/$tdir/d0/d1 on MDT1"
22219
22220         umount_client $MOUNT || error "umount failed"
22221         #define OBD_FAIL_TGT_DELAY_CONDITIONAL   0x713
22222         do_facet mds2 lctl set_param fail_loc=0x713 fail_val=1
22223         mount_client $MOUNT || error "failed to mount client"
22224
22225         echo "stat $DIR/$tdir/d0/d1, should not fail/ASSERT"
22226         stat $DIR/$tdir/d0/d1 || error "fail to stat $DIR/$tdir/d0/d1"
22227 }
22228 run_test 240 "race between ldlm enqueue and the connection RPC (no ASSERT)"
22229
22230 test_241_bio() {
22231         local count=$1
22232         local bsize=$2
22233
22234         for LOOP in $(seq $count); do
22235                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 2>/dev/null
22236                 cancel_lru_locks $OSC || true
22237         done
22238 }
22239
22240 test_241_dio() {
22241         local count=$1
22242         local bsize=$2
22243
22244         for LOOP in $(seq $1); do
22245                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 iflag=direct \
22246                         2>/dev/null
22247         done
22248 }
22249
22250 test_241a() { # was test_241
22251         local bsize=$PAGE_SIZE
22252
22253         (( bsize < 40960 )) && bsize=40960
22254         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
22255         ls -la $DIR/$tfile
22256         cancel_lru_locks $OSC
22257         test_241_bio 1000 $bsize &
22258         PID=$!
22259         test_241_dio 1000 $bsize
22260         wait $PID
22261 }
22262 run_test 241a "bio vs dio"
22263
22264 test_241b() {
22265         local bsize=$PAGE_SIZE
22266
22267         (( bsize < 40960 )) && bsize=40960
22268         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
22269         ls -la $DIR/$tfile
22270         test_241_dio 1000 $bsize &
22271         PID=$!
22272         test_241_dio 1000 $bsize
22273         wait $PID
22274 }
22275 run_test 241b "dio vs dio"
22276
22277 test_242() {
22278         remote_mds_nodsh && skip "remote MDS with nodsh"
22279
22280         mkdir_on_mdt0 $DIR/$tdir
22281         touch $DIR/$tdir/$tfile
22282
22283         #define OBD_FAIL_MDS_READPAGE_PACK      0x105
22284         do_facet mds1 lctl set_param fail_loc=0x105
22285         /bin/ls $DIR/$tdir && error "ls $DIR/$tdir should fail"
22286
22287         do_facet mds1 lctl set_param fail_loc=0
22288         /bin/ls $DIR/$tdir || error "ls $DIR/$tdir failed"
22289 }
22290 run_test 242 "mdt_readpage failure should not cause directory unreadable"
22291
22292 test_243()
22293 {
22294         test_mkdir $DIR/$tdir
22295         group_lock_test -d $DIR/$tdir || error "A group lock test failed"
22296 }
22297 run_test 243 "various group lock tests"
22298
22299 test_244a()
22300 {
22301         test_mkdir $DIR/$tdir
22302         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=35
22303         sendfile_grouplock $DIR/$tdir/$tfile || \
22304                 error "sendfile+grouplock failed"
22305         rm -rf $DIR/$tdir
22306 }
22307 run_test 244a "sendfile with group lock tests"
22308
22309 test_244b()
22310 {
22311         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
22312
22313         local threads=50
22314         local size=$((1024*1024))
22315
22316         test_mkdir $DIR/$tdir
22317         for i in $(seq 1 $threads); do
22318                 local file=$DIR/$tdir/file_$((i / 10))
22319                 $MULTIOP $file OG1234w$size_$((i % 3))w$size_$((i % 4))g1234c &
22320                 local pids[$i]=$!
22321         done
22322         for i in $(seq 1 $threads); do
22323                 wait ${pids[$i]}
22324         done
22325 }
22326 run_test 244b "multi-threaded write with group lock"
22327
22328 test_245a() {
22329         local flagname="multi_mod_rpcs"
22330         local connect_data_name="max_mod_rpcs"
22331         local out
22332
22333         # check if multiple modify RPCs flag is set
22334         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import |
22335                 grep "connect_flags:")
22336         echo "$out"
22337
22338         echo "$out" | grep -qw $flagname
22339         if [ $? -ne 0 ]; then
22340                 echo "connect flag $flagname is not set"
22341                 return
22342         fi
22343
22344         # check if multiple modify RPCs data is set
22345         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import)
22346         echo "$out"
22347
22348         echo "$out" | grep -qw $connect_data_name ||
22349                 error "import should have connect data $connect_data_name"
22350 }
22351 run_test 245a "check mdc connection flag/data: multiple modify RPCs"
22352
22353 test_245b() {
22354         local flagname="multi_mod_rpcs"
22355         local connect_data_name="max_mod_rpcs"
22356         local out
22357
22358         remote_mds_nodsh && skip "remote MDS with nodsh"
22359         [[ $MDSCOUNT -ge 2 ]] || skip "needs >= 2 MDTs"
22360
22361         # check if multiple modify RPCs flag is set
22362         out=$(do_facet mds1 \
22363               $LCTL get_param osp.$FSNAME-MDT0001-osp-MDT0000.import |
22364               grep "connect_flags:")
22365         echo "$out"
22366
22367         [[ "$out" =~ $flagname ]] || skip "connect flag $flagname is not set"
22368
22369         # check if multiple modify RPCs data is set
22370         out=$(do_facet mds1 \
22371               $LCTL get_param osp.$FSNAME-MDT0001-osp-MDT0000.import)
22372
22373         [[ "$out" =~ $connect_data_name ]] ||
22374                 {
22375                         echo "$out"
22376                         error "missing connect data $connect_data_name"
22377                 }
22378 }
22379 run_test 245b "check osp connection flag/data: multiple modify RPCs"
22380
22381 cleanup_247() {
22382         local submount=$1
22383
22384         trap 0
22385         umount_client $submount
22386         rmdir $submount
22387 }
22388
22389 test_247a() {
22390         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
22391                 grep -q subtree ||
22392                 skip_env "Fileset feature is not supported"
22393
22394         local submount=${MOUNT}_$tdir
22395
22396         mkdir $MOUNT/$tdir
22397         mkdir -p $submount || error "mkdir $submount failed"
22398         FILESET="$FILESET/$tdir" mount_client $submount ||
22399                 error "mount $submount failed"
22400         trap "cleanup_247 $submount" EXIT
22401         echo foo > $submount/$tfile || error "write $submount/$tfile failed"
22402         [ $(cat $MOUNT/$tdir/$tfile) = "foo" ] ||
22403                 error "read $MOUNT/$tdir/$tfile failed"
22404         cleanup_247 $submount
22405 }
22406 run_test 247a "mount subdir as fileset"
22407
22408 test_247b() {
22409         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
22410                 skip_env "Fileset feature is not supported"
22411
22412         local submount=${MOUNT}_$tdir
22413
22414         rm -rf $MOUNT/$tdir
22415         mkdir -p $submount || error "mkdir $submount failed"
22416         SKIP_FILESET=1
22417         FILESET="$FILESET/$tdir" mount_client $submount &&
22418                 error "mount $submount should fail"
22419         rmdir $submount
22420 }
22421 run_test 247b "mount subdir that dose not exist"
22422
22423 test_247c() {
22424         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
22425                 skip_env "Fileset feature is not supported"
22426
22427         local submount=${MOUNT}_$tdir
22428
22429         mkdir -p $MOUNT/$tdir/dir1
22430         mkdir -p $submount || error "mkdir $submount failed"
22431         trap "cleanup_247 $submount" EXIT
22432         FILESET="$FILESET/$tdir" mount_client $submount ||
22433                 error "mount $submount failed"
22434         local fid=$($LFS path2fid $MOUNT/)
22435         $LFS fid2path $submount $fid && error "fid2path should fail"
22436         cleanup_247 $submount
22437 }
22438 run_test 247c "running fid2path outside subdirectory root"
22439
22440 test_247d() {
22441         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
22442                 skip "Fileset feature is not supported"
22443
22444         local submount=${MOUNT}_$tdir
22445
22446         mkdir -p $MOUNT/$tdir/dir1
22447         mkdir -p $submount || error "mkdir $submount failed"
22448         FILESET="$FILESET/$tdir" mount_client $submount ||
22449                 error "mount $submount failed"
22450         trap "cleanup_247 $submount" EXIT
22451
22452         local td=$submount/dir1
22453         local fid=$($LFS path2fid $td)
22454         [ -z "$fid" ] && error "path2fid unable to get $td FID"
22455
22456         # check that we get the same pathname back
22457         local rootpath
22458         local found
22459         for rootpath in "$submount" "$submount///" "$submount/dir1"; do
22460                 echo "$rootpath $fid"
22461                 found=$($LFS fid2path $rootpath "$fid")
22462                 [ -n "$found" ] || error "fid2path should succeed"
22463                 [ "$found" == "$td" ] || error "fid2path $found != $td"
22464         done
22465         # check wrong root path format
22466         rootpath=$submount"_wrong"
22467         found=$($LFS fid2path $rootpath "$fid")
22468         [ -z "$found" ] || error "fid2path should fail ($rootpath != $submount)"
22469
22470         cleanup_247 $submount
22471 }
22472 run_test 247d "running fid2path inside subdirectory root"
22473
22474 # LU-8037
22475 test_247e() {
22476         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
22477                 grep -q subtree ||
22478                 skip "Fileset feature is not supported"
22479
22480         local submount=${MOUNT}_$tdir
22481
22482         mkdir $MOUNT/$tdir
22483         mkdir -p $submount || error "mkdir $submount failed"
22484         FILESET="$FILESET/.." mount_client $submount &&
22485                 error "mount $submount should fail"
22486         rmdir $submount
22487 }
22488 run_test 247e "mount .. as fileset"
22489
22490 test_247f() {
22491         (( $MDSCOUNT > 1 )) || skip_env "needs >= 2 MDTs"
22492         (( $MDS1_VERSION >= $(version_code 2.14.50.162) )) ||
22493                 skip "Need at least version 2.14.50.162"
22494         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
22495                 skip "Fileset feature is not supported"
22496
22497         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
22498         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote ||
22499                 error "mkdir remote failed"
22500         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote/subdir ||
22501                 error "mkdir remote/subdir failed"
22502         $LFS mkdir -i 0 -c $MDSCOUNT $DIR/$tdir/striped ||
22503                 error "mkdir striped failed"
22504         mkdir $DIR/$tdir/striped/subdir || error "mkdir striped/subdir failed"
22505
22506         local submount=${MOUNT}_$tdir
22507
22508         mkdir -p $submount || error "mkdir $submount failed"
22509         stack_trap "rmdir $submount"
22510
22511         local dir
22512         local fileset=$FILESET
22513         local mdts=$(comma_list $(mdts_nodes))
22514
22515         do_nodes $mdts "$LCTL set_param mdt.*.enable_remote_subdir_mount=1"
22516         for dir in $tdir/remote $tdir/remote/subdir $tdir/striped \
22517                 $tdir/striped/subdir $tdir/striped/.; do
22518                 FILESET="$fileset/$dir" mount_client $submount ||
22519                         error "mount $dir failed"
22520                 umount_client $submount
22521         done
22522 }
22523 run_test 247f "mount striped or remote directory as fileset"
22524
22525 test_subdir_mount_lock()
22526 {
22527         local testdir=$1
22528         local submount=${MOUNT}_$(basename $testdir)
22529
22530         touch $DIR/$testdir/$tfile || error "touch $tfile failed"
22531
22532         mkdir -p $submount || error "mkdir $submount failed"
22533         stack_trap "rmdir $submount"
22534
22535         FILESET="$fileset/$testdir" mount_client $submount ||
22536                 error "mount $FILESET failed"
22537         stack_trap "umount $submount"
22538
22539         local mdts=$(comma_list $(mdts_nodes))
22540
22541         local nrpcs
22542
22543         stat $submount > /dev/null || error "stat $submount failed"
22544         cancel_lru_locks $MDC
22545         stat $submount > /dev/null || error "stat $submount failed"
22546         stat $submount/$tfile > /dev/null || error "stat $tfile failed"
22547         do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear > /dev/null"
22548         stat $submount/$tfile > /dev/null || error "stat $tfile failed"
22549         nrpcs=$(do_nodes $mdts "lctl get_param -n mdt.*.md_stats" |
22550                 awk '/getattr/ {sum += $2} END {print sum}')
22551
22552         [ -z "$nrpcs" ] || error "$nrpcs extra getattr sent"
22553 }
22554
22555 test_247g() {
22556         (( $MDSCOUNT > 1 )) || skip_env "needs > 1 MDTs"
22557
22558         $LFS mkdir -i 0 -c 4 -H fnv_1a_64 $DIR/$tdir ||
22559                 error "mkdir $tdir failed"
22560         test_subdir_mount_lock $tdir
22561 }
22562 run_test 247g "striped directory submount revalidate ROOT from cache"
22563
22564 test_247h() {
22565         (( $MDSCOUNT > 1 )) || skip_env "needs > 1 MDTs"
22566         (( $MDS1_VERSION >= $(version_code 2.15.51) )) ||
22567                 skip "Need MDS version at least 2.15.51"
22568
22569         $LFS mkdir -i 1 -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
22570         test_subdir_mount_lock $tdir
22571         mkdir_on_mdt -i 0 $DIR/$tdir/$tdir.0 || error "mkdir $tdir.0 failed"
22572         mkdir_on_mdt -i 1 $DIR/$tdir/$tdir.0/$tdir.1 ||
22573                 error "mkdir $tdir.1 failed"
22574         test_subdir_mount_lock $tdir/$tdir.0/$tdir.1
22575 }
22576 run_test 247h "remote directory submount revalidate ROOT from cache"
22577
22578 test_248a() {
22579         local fast_read_sav=$($LCTL get_param -n llite.*.fast_read 2>/dev/null)
22580         [ -z "$fast_read_sav" ] && skip "no fast read support"
22581
22582         # create a large file for fast read verification
22583         dd if=/dev/zero of=$DIR/$tfile bs=1M count=128 > /dev/null 2>&1
22584
22585         # make sure the file is created correctly
22586         $CHECKSTAT -s $((128*1024*1024)) $DIR/$tfile ||
22587                 { rm -f $DIR/$tfile; skip "file creation error"; }
22588
22589         echo "Test 1: verify that fast read is 4 times faster on cache read"
22590
22591         # small read with fast read enabled
22592         $LCTL set_param -n llite.*.fast_read=1
22593         local t_fast=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
22594                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
22595                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
22596         # small read with fast read disabled
22597         $LCTL set_param -n llite.*.fast_read=0
22598         local t_slow=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
22599                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
22600                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
22601
22602         # verify that fast read is 4 times faster for cache read
22603         [ $(bc <<< "4 * $t_fast < $t_slow") -eq 1 ] ||
22604                 error_not_in_vm "fast read was not 4 times faster: " \
22605                            "$t_fast vs $t_slow"
22606
22607         echo "Test 2: verify the performance between big and small read"
22608         $LCTL set_param -n llite.*.fast_read=1
22609
22610         # 1k non-cache read
22611         cancel_lru_locks osc
22612         local t_1k=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
22613                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
22614                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
22615
22616         # 1M non-cache read
22617         cancel_lru_locks osc
22618         local t_1m=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
22619                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
22620                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
22621
22622         # verify that big IO is not 4 times faster than small IO
22623         [ $(bc <<< "4 * $t_1k >= $t_1m") -eq 1 ] ||
22624                 error_not_in_vm "bigger IO is way too fast: $t_1k vs $t_1m"
22625
22626         $LCTL set_param -n llite.*.fast_read=$fast_read_sav
22627         rm -f $DIR/$tfile
22628 }
22629 run_test 248a "fast read verification"
22630
22631 test_248b() {
22632         # Default short_io_bytes=16384, try both smaller and larger sizes.
22633         # Lustre O_DIRECT read and write needs to be a multiple of PAGE_SIZE.
22634         # 6017024 = 2^12*13*113 = 47008*128 = 11752*512 = 4096*1469 = 53248*113
22635         echo "bs=53248 count=113 normal buffered write"
22636         dd if=/dev/urandom of=$TMP/$tfile.0 bs=53248 count=113 ||
22637                 error "dd of initial data file failed"
22638         stack_trap "rm -f $DIR/$tfile.[0-3] $TMP/$tfile.[0-3]" EXIT
22639
22640         echo "bs=47008 count=128 oflag=dsync normal write $tfile.0"
22641         dd if=$TMP/$tfile.0 of=$DIR/$tfile.0 bs=47008 count=128 oflag=dsync ||
22642                 error "dd with sync normal writes failed"
22643         cmp $TMP/$tfile.0 $DIR/$tfile.0 || error "compare $DIR/$tfile.0 failed"
22644
22645         echo "bs=11752 count=512 oflag=dsync small write $tfile.1"
22646         dd if=$TMP/$tfile.0 of=$DIR/$tfile.1 bs=11752 count=512 oflag=dsync ||
22647                 error "dd with sync small writes failed"
22648         cmp $TMP/$tfile.0 $DIR/$tfile.1 || error "compare $DIR/$tfile.1 failed"
22649
22650         cancel_lru_locks osc
22651
22652         # calculate the small O_DIRECT size and count for the client PAGE_SIZE
22653         local num=$((13 * 113 / (PAGE_SIZE / 4096)))
22654         echo "bs=$PAGE_SIZE count=$num iflag=direct small read $tfile.1"
22655         dd if=$DIR/$tfile.1 of=$TMP/$tfile.1 bs=$PAGE_SIZE count=$num \
22656                 iflag=direct || error "dd with O_DIRECT small read failed"
22657         # adjust bytes checked to handle larger PAGE_SIZE for ARM/PPC
22658         cmp --bytes=$((PAGE_SIZE * num)) $TMP/$tfile.0 $TMP/$tfile.1 ||
22659                 error "compare $TMP/$tfile.1 failed"
22660
22661         local save=$($LCTL get_param -n osc.*OST000*.short_io_bytes | head -n 1)
22662         stack_trap "$LCTL set_param osc.$FSNAME-*.short_io_bytes=$save" EXIT
22663
22664         # just to see what the maximum tunable value is, and test parsing
22665         echo "test invalid parameter 2MB"
22666         $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=2M &&
22667                 error "too-large short_io_bytes allowed"
22668         echo "test maximum parameter 512KB"
22669         # if we can set a larger short_io_bytes, run test regardless of version
22670         if ! $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=512K; then
22671                 # older clients may not allow setting it this large, that's OK
22672                 [ $CLIENT_VERSION -ge $(version_code 2.13.50) ] ||
22673                         skip "Need at least client version 2.13.50"
22674                 error "medium short_io_bytes failed"
22675         fi
22676         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
22677         size=$($LCTL get_param -n osc.$FSNAME-OST0000*.short_io_bytes)
22678
22679         echo "test large parameter 64KB"
22680         $LCTL set_param osc.$FSNAME-*.short_io_bytes=65536
22681         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
22682
22683         echo "bs=47008 count=128 oflag=dsync large write $tfile.2"
22684         dd if=$TMP/$tfile.0 of=$DIR/$tfile.2 bs=47008 count=128 oflag=dsync ||
22685                 error "dd with sync large writes failed"
22686         cmp $TMP/$tfile.0 $DIR/$tfile.2 || error "compare $DIR/$tfile.2 failed"
22687
22688         # calculate the large O_DIRECT size and count for the client PAGE_SIZE
22689         local size=$(((4096 * 13 + PAGE_SIZE - 1) / PAGE_SIZE * PAGE_SIZE))
22690         num=$((113 * 4096 / PAGE_SIZE))
22691         echo "bs=$size count=$num oflag=direct large write $tfile.3"
22692         dd if=$TMP/$tfile.0 of=$DIR/$tfile.3 bs=$size count=$num oflag=direct ||
22693                 error "dd with O_DIRECT large writes failed"
22694         cmp --bytes=$((size * num)) $TMP/$tfile.0 $DIR/$tfile.3 ||
22695                 error "compare $DIR/$tfile.3 failed"
22696
22697         cancel_lru_locks osc
22698
22699         echo "bs=$size count=$num iflag=direct large read $tfile.2"
22700         dd if=$DIR/$tfile.2 of=$TMP/$tfile.2 bs=$size count=$num iflag=direct ||
22701                 error "dd with O_DIRECT large read failed"
22702         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.2 ||
22703                 error "compare $TMP/$tfile.2 failed"
22704
22705         echo "bs=$size count=$num iflag=direct large read $tfile.3"
22706         dd if=$DIR/$tfile.3 of=$TMP/$tfile.3 bs=$size count=$num iflag=direct ||
22707                 error "dd with O_DIRECT large read failed"
22708         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.3 ||
22709                 error "compare $TMP/$tfile.3 failed"
22710 }
22711 run_test 248b "test short_io read and write for both small and large sizes"
22712
22713 test_249() { # LU-7890
22714         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
22715                 skip "Need at least version 2.8.54"
22716
22717         rm -f $DIR/$tfile
22718         $LFS setstripe -c 1 $DIR/$tfile
22719         # Offset 2T == 4k * 512M
22720         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 seek=512M ||
22721                 error "dd to 2T offset failed"
22722 }
22723 run_test 249 "Write above 2T file size"
22724
22725 test_250() {
22726         [ "$(facet_fstype ost$(($($LFS getstripe -i $DIR/$tfile) + 1)))" = "zfs" ] \
22727          && skip "no 16TB file size limit on ZFS"
22728
22729         $LFS setstripe -c 1 $DIR/$tfile
22730         # ldiskfs extent file size limit is (16TB - 4KB - 1) bytes
22731         local size=$((16 * 1024 * 1024 * 1024 * 1024 - 4096 - 1))
22732         $TRUNCATE $DIR/$tfile $size || error "truncate $tfile to $size failed"
22733         dd if=/dev/zero of=$DIR/$tfile bs=10 count=1 oflag=append \
22734                 conv=notrunc,fsync && error "append succeeded"
22735         return 0
22736 }
22737 run_test 250 "Write above 16T limit"
22738
22739 test_251() {
22740         $LFS setstripe -c -1 -S 1048576 $DIR/$tfile
22741
22742         #define OBD_FAIL_LLITE_LOST_LAYOUT 0x1407
22743         #Skip once - writing the first stripe will succeed
22744         $LCTL set_param fail_loc=0xa0001407 fail_val=1
22745         $MULTIOP $DIR/$tfile o:O_RDWR:w2097152c 2>&1 | grep -q "short write" &&
22746                 error "short write happened"
22747
22748         $LCTL set_param fail_loc=0xa0001407 fail_val=1
22749         $MULTIOP $DIR/$tfile or2097152c 2>&1 | grep -q "short read" &&
22750                 error "short read happened"
22751
22752         rm -f $DIR/$tfile
22753 }
22754 run_test 251 "Handling short read and write correctly"
22755
22756 test_252() {
22757         remote_mds_nodsh && skip "remote MDS with nodsh"
22758         remote_ost_nodsh && skip "remote OST with nodsh"
22759         if [ "$ost1_FSTYPE" != ldiskfs ] || [ "$mds1_FSTYPE" != ldiskfs ]; then
22760                 skip_env "ldiskfs only test"
22761         fi
22762
22763         local tgt
22764         local dev
22765         local out
22766         local uuid
22767         local num
22768         local gen
22769
22770         # check lr_reader on OST0000
22771         tgt=ost1
22772         dev=$(facet_device $tgt)
22773         out=$(do_facet $tgt $LR_READER $dev)
22774         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
22775         echo "$out"
22776         uuid=$(echo "$out" | grep -i uuid | awk '{ print $2 }')
22777         [ "$uuid" == "$(ostuuid_from_index 0)" ] ||
22778                 error "Invalid uuid returned by $LR_READER on target $tgt"
22779         echo -e "uuid returned by $LR_READER is '$uuid'\n"
22780
22781         # check lr_reader -c on MDT0000
22782         tgt=mds1
22783         dev=$(facet_device $tgt)
22784         if ! do_facet $tgt $LR_READER -h | grep -q OPTIONS; then
22785                 skip "$LR_READER does not support additional options"
22786         fi
22787         out=$(do_facet $tgt $LR_READER -c $dev)
22788         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
22789         echo "$out"
22790         num=$(echo "$out" | grep -c "mdtlov")
22791         [ "$num" -eq $((MDSCOUNT - 1)) ] ||
22792                 error "Invalid number of mdtlov clients returned by $LR_READER"
22793         echo -e "Number of mdtlov clients returned by $LR_READER is '$num'\n"
22794
22795         # check lr_reader -cr on MDT0000
22796         out=$(do_facet $tgt $LR_READER -cr $dev)
22797         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
22798         echo "$out"
22799         echo "$out" | grep -q "^reply_data:$" ||
22800                 error "$LR_READER should have returned 'reply_data' section"
22801         num=$(echo "$out" | grep -c "client_generation")
22802         echo -e "Number of reply data returned by $LR_READER is '$num'\n"
22803 }
22804 run_test 252 "check lr_reader tool"
22805
22806 test_253() {
22807         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22808         remote_mds_nodsh && skip "remote MDS with nodsh"
22809         remote_mgs_nodsh && skip "remote MGS with nodsh"
22810
22811         local ostidx=0
22812         local rc=0
22813         local ost_name=$(ostname_from_index $ostidx)
22814
22815         # on the mdt's osc
22816         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $ost_name)
22817         do_facet $SINGLEMDS $LCTL get_param -n \
22818                 osp.$mdtosc_proc1.reserved_mb_high ||
22819                 skip  "remote MDS does not support reserved_mb_high"
22820
22821         rm -rf $DIR/$tdir
22822         wait_mds_ost_sync
22823         wait_delete_completed
22824         mkdir $DIR/$tdir
22825         stack_trap "rm -rf $DIR/$tdir"
22826
22827         pool_add $TESTNAME || error "Pool creation failed"
22828         pool_add_targets $TESTNAME 0 || error "Pool add targets failed"
22829
22830         $LFS setstripe $DIR/$tdir -i $ostidx -c 1 -p $FSNAME.$TESTNAME ||
22831                 error "Setstripe failed"
22832
22833         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M count=10
22834
22835         local wms=$(ost_watermarks_set_enospc $tfile $ostidx |
22836                     grep "watermarks")
22837         stack_trap "ost_watermarks_clear_enospc $tfile $ostidx $wms" EXIT
22838
22839         local oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
22840                         osp.$mdtosc_proc1.prealloc_status)
22841         echo "prealloc_status $oa_status"
22842
22843         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1M count=1 &&
22844                 error "File creation should fail"
22845
22846         #object allocation was stopped, but we still able to append files
22847         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M seek=6 count=5 \
22848                 oflag=append || error "Append failed"
22849
22850         rm -f $DIR/$tdir/$tfile.0
22851
22852         # For this test, we want to delete the files we created to go out of
22853         # space but leave the watermark, so we remain nearly out of space
22854         ost_watermarks_enospc_delete_files $tfile $ostidx
22855
22856         wait_delete_completed
22857
22858         sleep_maxage
22859
22860         for i in $(seq 10 12); do
22861                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$i bs=1M count=1 \
22862                         2>/dev/null || error "File creation failed after rm"
22863         done
22864
22865         oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
22866                         osp.$mdtosc_proc1.prealloc_status)
22867         echo "prealloc_status $oa_status"
22868
22869         if (( oa_status != 0 )); then
22870                 error "Object allocation still disable after rm"
22871         fi
22872 }
22873 run_test 253 "Check object allocation limit"
22874
22875 test_254() {
22876         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22877         remote_mds_nodsh && skip "remote MDS with nodsh"
22878
22879         local mdt=$(facet_svc $SINGLEMDS)
22880
22881         do_facet $SINGLEMDS $LCTL get_param -n mdd.$mdt.changelog_size ||
22882                 skip "MDS does not support changelog_size"
22883
22884         local cl_user
22885
22886         changelog_register || error "changelog_register failed"
22887
22888         changelog_clear 0 || error "changelog_clear failed"
22889
22890         local size1=$(do_facet $SINGLEMDS \
22891                       $LCTL get_param -n mdd.$mdt.changelog_size)
22892         echo "Changelog size $size1"
22893
22894         rm -rf $DIR/$tdir
22895         $LFS mkdir -i 0 $DIR/$tdir
22896         # change something
22897         mkdir -p $DIR/$tdir/pics/2008/zachy
22898         touch $DIR/$tdir/pics/2008/zachy/timestamp
22899         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg
22900         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
22901         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
22902         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
22903         rm $DIR/$tdir/pics/desktop.jpg
22904
22905         local size2=$(do_facet $SINGLEMDS \
22906                       $LCTL get_param -n mdd.$mdt.changelog_size)
22907         echo "Changelog size after work $size2"
22908
22909         (( $size2 > $size1 )) ||
22910                 error "new Changelog size=$size2 less than old size=$size1"
22911 }
22912 run_test 254 "Check changelog size"
22913
22914 ladvise_no_type()
22915 {
22916         local type=$1
22917         local file=$2
22918
22919         lfs ladvise -a invalid $file 2>&1 | grep "Valid types" |
22920                 awk -F: '{print $2}' | grep $type > /dev/null
22921         if [ $? -ne 0 ]; then
22922                 return 0
22923         fi
22924         return 1
22925 }
22926
22927 ladvise_no_ioctl()
22928 {
22929         local file=$1
22930
22931         lfs ladvise -a willread $file > /dev/null 2>&1
22932         if [ $? -eq 0 ]; then
22933                 return 1
22934         fi
22935
22936         lfs ladvise -a willread $file 2>&1 |
22937                 grep "Inappropriate ioctl for device" > /dev/null
22938         if [ $? -eq 0 ]; then
22939                 return 0
22940         fi
22941         return 1
22942 }
22943
22944 percent() {
22945         bc <<<"scale=2; ($1 - $2) * 100 / $2"
22946 }
22947
22948 # run a random read IO workload
22949 # usage: random_read_iops <filename> <filesize> <iosize>
22950 random_read_iops() {
22951         local file=$1
22952         local fsize=$2
22953         local iosize=${3:-4096}
22954
22955         $READS -f $file -s $fsize -b $iosize -n $((fsize / iosize)) -t 60 |
22956                 sed -e '/^$/d' -e 's#.*s, ##' -e 's#MB/s##'
22957 }
22958
22959 drop_file_oss_cache() {
22960         local file="$1"
22961         local nodes="$2"
22962
22963         $LFS ladvise -a dontneed $file 2>/dev/null ||
22964                 do_nodes $nodes "echo 3 > /proc/sys/vm/drop_caches"
22965 }
22966
22967 ladvise_willread_performance()
22968 {
22969         local repeat=10
22970         local average_origin=0
22971         local average_cache=0
22972         local average_ladvise=0
22973
22974         for ((i = 1; i <= $repeat; i++)); do
22975                 echo "Iter $i/$repeat: reading without willread hint"
22976                 cancel_lru_locks osc
22977                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
22978                 local speed_origin=$(random_read_iops $DIR/$tfile $size)
22979                 echo "Iter $i/$repeat: uncached speed: $speed_origin"
22980                 average_origin=$(bc <<<"$average_origin + $speed_origin")
22981
22982                 cancel_lru_locks osc
22983                 local speed_cache=$(random_read_iops $DIR/$tfile $size)
22984                 echo "Iter $i/$repeat: OSS cache speed: $speed_cache"
22985                 average_cache=$(bc <<<"$average_cache + $speed_cache")
22986
22987                 cancel_lru_locks osc
22988                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
22989                 $LFS ladvise -a willread $DIR/$tfile || error "ladvise failed"
22990                 local speed_ladvise=$(random_read_iops $DIR/$tfile $size)
22991                 echo "Iter $i/$repeat: ladvise speed: $speed_ladvise"
22992                 average_ladvise=$(bc <<<"$average_ladvise + $speed_ladvise")
22993         done
22994         average_origin=$(bc <<<"scale=2; $average_origin / $repeat")
22995         average_cache=$(bc <<<"scale=2; $average_cache / $repeat")
22996         average_ladvise=$(bc <<<"scale=2; $average_ladvise / $repeat")
22997
22998         speedup_cache=$(percent $average_cache $average_origin)
22999         speedup_ladvise=$(percent $average_ladvise $average_origin)
23000
23001         echo "Average uncached read: $average_origin"
23002         echo "Average speedup with OSS cached read: " \
23003                 "$average_cache = +$speedup_cache%"
23004         echo "Average speedup with ladvise willread: " \
23005                 "$average_ladvise = +$speedup_ladvise%"
23006
23007         local lowest_speedup=20
23008         if (( ${average_cache%.*} < $lowest_speedup )); then
23009                 echo "Speedup with OSS cached read less than $lowest_speedup%,"\
23010                      " got $average_cache%. Skipping ladvise willread check."
23011                 return 0
23012         fi
23013
23014         # the test won't work on ZFS until it supports 'ladvise dontneed', but
23015         # it is still good to run until then to exercise 'ladvise willread'
23016         ! $LFS ladvise -a dontneed $DIR/$tfile &&
23017                 [ "$ost1_FSTYPE" = "zfs" ] &&
23018                 echo "osd-zfs does not support dontneed or drop_caches" &&
23019                 return 0
23020
23021         lowest_speedup=$(bc <<<"scale=2; $average_cache / 2")
23022         (( ${average_ladvise%.*} > ${lowest_speedup%.*} )) ||
23023                 error_not_in_vm "Speedup with willread is less than " \
23024                         "$lowest_speedup%, got $average_ladvise%"
23025 }
23026
23027 test_255a() {
23028         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
23029                 skip "lustre < 2.8.54 does not support ladvise "
23030         remote_ost_nodsh && skip "remote OST with nodsh"
23031
23032         stack_trap "rm -f $DIR/$tfile"
23033         lfs setstripe -c -1 -i 0 $DIR/$tfile || error "$tfile failed"
23034
23035         ladvise_no_type willread $DIR/$tfile &&
23036                 skip "willread ladvise is not supported"
23037
23038         ladvise_no_ioctl $DIR/$tfile &&
23039                 skip "ladvise ioctl is not supported"
23040
23041         local size_mb=100
23042         local size=$((size_mb * 1048576))
23043         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
23044                 error "dd to $DIR/$tfile failed"
23045
23046         lfs ladvise -a willread $DIR/$tfile ||
23047                 error "Ladvise failed with no range argument"
23048
23049         lfs ladvise -a willread -s 0 $DIR/$tfile ||
23050                 error "Ladvise failed with no -l or -e argument"
23051
23052         lfs ladvise -a willread -e 1 $DIR/$tfile ||
23053                 error "Ladvise failed with only -e argument"
23054
23055         lfs ladvise -a willread -l 1 $DIR/$tfile ||
23056                 error "Ladvise failed with only -l argument"
23057
23058         lfs ladvise -a willread -s 2 -e 1 $DIR/$tfile &&
23059                 error "End offset should not be smaller than start offset"
23060
23061         lfs ladvise -a willread -s 2 -e 2 $DIR/$tfile &&
23062                 error "End offset should not be equal to start offset"
23063
23064         lfs ladvise -a willread -s $size -l 1 $DIR/$tfile ||
23065                 error "Ladvise failed with overflowing -s argument"
23066
23067         lfs ladvise -a willread -s 1 -e $((size + 1)) $DIR/$tfile ||
23068                 error "Ladvise failed with overflowing -e argument"
23069
23070         lfs ladvise -a willread -s 1 -l $size $DIR/$tfile ||
23071                 error "Ladvise failed with overflowing -l argument"
23072
23073         lfs ladvise -a willread -l 1 -e 2 $DIR/$tfile &&
23074                 error "Ladvise succeeded with conflicting -l and -e arguments"
23075
23076         echo "Synchronous ladvise should wait"
23077         local delay=4
23078 #define OBD_FAIL_OST_LADVISE_PAUSE       0x237
23079         do_nodes $(comma_list $(osts_nodes)) \
23080                 $LCTL set_param fail_val=$delay fail_loc=0x237
23081
23082         local start_ts=$SECONDS
23083         lfs ladvise -a willread $DIR/$tfile ||
23084                 error "Ladvise failed with no range argument"
23085         local end_ts=$SECONDS
23086         local inteval_ts=$((end_ts - start_ts))
23087
23088         if [ $inteval_ts -lt $(($delay - 1)) ]; then
23089                 error "Synchronous advice didn't wait reply"
23090         fi
23091
23092         echo "Asynchronous ladvise shouldn't wait"
23093         local start_ts=$SECONDS
23094         lfs ladvise -a willread -b $DIR/$tfile ||
23095                 error "Ladvise failed with no range argument"
23096         local end_ts=$SECONDS
23097         local inteval_ts=$((end_ts - start_ts))
23098
23099         if [ $inteval_ts -gt $(($delay / 2)) ]; then
23100                 error "Asynchronous advice blocked"
23101         fi
23102
23103         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param fail_loc=0
23104         ladvise_willread_performance
23105 }
23106 run_test 255a "check 'lfs ladvise -a willread'"
23107
23108 facet_meminfo() {
23109         local facet=$1
23110         local info=$2
23111
23112         do_facet $facet "cat /proc/meminfo | grep ^${info}:" | awk '{print $2}'
23113 }
23114
23115 test_255b() {
23116         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
23117                 skip "lustre < 2.8.54 does not support ladvise "
23118         remote_ost_nodsh && skip "remote OST with nodsh"
23119
23120         stack_trap "rm -f $DIR/$tfile"
23121         lfs setstripe -c 1 -i 0 $DIR/$tfile
23122
23123         ladvise_no_type dontneed $DIR/$tfile &&
23124                 skip "dontneed ladvise is not supported"
23125
23126         ladvise_no_ioctl $DIR/$tfile &&
23127                 skip "ladvise ioctl is not supported"
23128
23129         ! $LFS ladvise -a dontneed $DIR/$tfile &&
23130                 [ "$ost1_FSTYPE" = "zfs" ] &&
23131                 skip "zfs-osd does not support 'ladvise dontneed'"
23132
23133         local size_mb=100
23134         local size=$((size_mb * 1048576))
23135         # In order to prevent disturbance of other processes, only check 3/4
23136         # of the memory usage
23137         local kibibytes=$((size_mb * 1024 * 3 / 4))
23138
23139         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
23140                 error "dd to $DIR/$tfile failed"
23141
23142         #force write to complete before dropping OST cache & checking memory
23143         sync
23144
23145         local total=$(facet_meminfo ost1 MemTotal)
23146         echo "Total memory: $total KiB"
23147
23148         do_facet ost1 "sync && echo 3 > /proc/sys/vm/drop_caches"
23149         local before_read=$(facet_meminfo ost1 Cached)
23150         echo "Cache used before read: $before_read KiB"
23151
23152         lfs ladvise -a willread $DIR/$tfile ||
23153                 error "Ladvise willread failed"
23154         local after_read=$(facet_meminfo ost1 Cached)
23155         echo "Cache used after read: $after_read KiB"
23156
23157         lfs ladvise -a dontneed $DIR/$tfile ||
23158                 error "Ladvise dontneed again failed"
23159         local no_read=$(facet_meminfo ost1 Cached)
23160         echo "Cache used after dontneed ladvise: $no_read KiB"
23161
23162         if [ $total -lt $((before_read + kibibytes)) ]; then
23163                 echo "Memory is too small, abort checking"
23164                 return 0
23165         fi
23166
23167         if [ $((before_read + kibibytes)) -gt $after_read ]; then
23168                 error "Ladvise willread should use more memory" \
23169                         "than $kibibytes KiB"
23170         fi
23171
23172         if [ $((no_read + kibibytes)) -gt $after_read ]; then
23173                 error "Ladvise dontneed should release more memory" \
23174                         "than $kibibytes KiB"
23175         fi
23176 }
23177 run_test 255b "check 'lfs ladvise -a dontneed'"
23178
23179 test_255c() {
23180         [ $OST1_VERSION -lt $(version_code 2.10.50) ] &&
23181                 skip "lustre < 2.10.50 does not support lockahead"
23182
23183         local ost1_imp=$(get_osc_import_name client ost1)
23184         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
23185                          cut -d'.' -f2)
23186         local count
23187         local new_count
23188         local difference
23189         local i
23190         local rc
23191
23192         test_mkdir -p $DIR/$tdir
23193         $LFS setstripe -i 0 -c 1 $DIR/$tdir
23194
23195         #test 10 returns only success/failure
23196         i=10
23197         lockahead_test -d $DIR/$tdir -t $i -f $tfile
23198         rc=$?
23199         if [ $rc -eq 255 ]; then
23200                 error "Ladvise test${i} failed, ${rc}"
23201         fi
23202
23203         #test 11 counts lock enqueue requests, all others count new locks
23204         i=11
23205         count=$(do_facet ost1 \
23206                 $LCTL get_param -n ost.OSS.ost.stats)
23207         count=$(echo "$count" | grep ldlm_extent_enqueue | awk '{ print $2 }')
23208
23209         lockahead_test -d $DIR/$tdir -t $i -f $tfile
23210         rc=$?
23211         if [ $rc -eq 255 ]; then
23212                 error "Ladvise test${i} failed, ${rc}"
23213         fi
23214
23215         new_count=$(do_facet ost1 \
23216                 $LCTL get_param -n ost.OSS.ost.stats)
23217         new_count=$(echo "$new_count" | grep ldlm_extent_enqueue | \
23218                    awk '{ print $2 }')
23219
23220         difference="$((new_count - count))"
23221         if [ $difference -ne $rc ]; then
23222                 error "Ladvise test${i}, bad enqueue count, returned " \
23223                       "${rc}, actual ${difference}"
23224         fi
23225
23226         for i in $(seq 12 21); do
23227                 # If we do not do this, we run the risk of having too many
23228                 # locks and starting lock cancellation while we are checking
23229                 # lock counts.
23230                 cancel_lru_locks osc
23231
23232                 count=$($LCTL get_param -n \
23233                        ldlm.namespaces.$imp_name.lock_unused_count)
23234
23235                 lockahead_test -d $DIR/$tdir -t $i -f $tfile
23236                 rc=$?
23237                 if [ $rc -eq 255 ]; then
23238                         error "Ladvise test ${i} failed, ${rc}"
23239                 fi
23240
23241                 new_count=$($LCTL get_param -n \
23242                        ldlm.namespaces.$imp_name.lock_unused_count)
23243                 difference="$((new_count - count))"
23244
23245                 # Test 15 output is divided by 100 to map down to valid return
23246                 if [ $i -eq 15 ]; then
23247                         rc="$((rc * 100))"
23248                 fi
23249
23250                 if [ $difference -ne $rc ]; then
23251                         error "Ladvise test ${i}, bad lock count, returned " \
23252                               "${rc}, actual ${difference}"
23253                 fi
23254         done
23255
23256         #test 22 returns only success/failure
23257         i=22
23258         lockahead_test -d $DIR/$tdir -t $i -f $tfile
23259         rc=$?
23260         if [ $rc -eq 255 ]; then
23261                 error "Ladvise test${i} failed, ${rc}"
23262         fi
23263 }
23264 run_test 255c "suite of ladvise lockahead tests"
23265
23266 test_256() {
23267         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23268         remote_mds_nodsh && skip "remote MDS with nodsh"
23269         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
23270         changelog_users $SINGLEMDS | grep "^cl" &&
23271                 skip "active changelog user"
23272
23273         local cl_user
23274         local cat_sl
23275         local mdt_dev
23276
23277         mdt_dev=$(facet_device $SINGLEMDS)
23278         echo $mdt_dev
23279
23280         changelog_register || error "changelog_register failed"
23281
23282         rm -rf $DIR/$tdir
23283         mkdir_on_mdt -i$(($(facet_number $SINGLEMDS) - 1)) $DIR/$tdir
23284
23285         changelog_clear 0 || error "changelog_clear failed"
23286
23287         # change something
23288         touch $DIR/$tdir/{1..10}
23289
23290         # stop the MDT
23291         stop $SINGLEMDS || error "Fail to stop MDT"
23292
23293         # remount the MDT
23294         start $SINGLEMDS $(facet_device $SINGLEMDS) $MDS_MOUNT_OPTS ||
23295                 error "Fail to start MDT"
23296
23297         #after mount new plainllog is used
23298         touch $DIR/$tdir/{11..19}
23299         local tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
23300         stack_trap "rm -f $tmpfile"
23301         cat_sl=$(do_facet $SINGLEMDS "sync; \
23302                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
23303                  llog_reader $tmpfile | grep -c type=1064553b")
23304         do_facet $SINGLEMDS llog_reader $tmpfile
23305
23306         [ $cat_sl != 2 ] && error "Changelog catalog has $cat_sl != 2 slots"
23307
23308         changelog_clear 0 || error "changelog_clear failed"
23309
23310         cat_sl=$(do_facet $SINGLEMDS "sync; \
23311                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
23312                  llog_reader $tmpfile | grep -c type=1064553b")
23313
23314         if (( cat_sl == 2 )); then
23315                 error "Empty plain llog was not deleted from changelog catalog"
23316         elif (( cat_sl != 1 )); then
23317                 error "Active plain llog shouldn't be deleted from catalog"
23318         fi
23319 }
23320 run_test 256 "Check llog delete for empty and not full state"
23321
23322 test_257() {
23323         remote_mds_nodsh && skip "remote MDS with nodsh"
23324         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
23325                 skip "Need MDS version at least 2.8.55"
23326
23327         test_mkdir $DIR/$tdir
23328
23329         setfattr -n trusted.name1 -v value1 $DIR/$tdir ||
23330                 error "setfattr -n trusted.name1=value1 $DIR/$tdir failed"
23331         stat $DIR/$tdir
23332
23333 #define OBD_FAIL_MDS_XATTR_REP                  0x161
23334         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
23335         local facet=mds$((mdtidx + 1))
23336         set_nodes_failloc $(facet_active_host $facet) 0x80000161
23337         getfattr -n trusted.name1 $DIR/$tdir 2> /dev/null
23338
23339         stop $facet || error "stop MDS failed"
23340         start $facet $(mdsdevname $((mdtidx + 1))) $MDS_MOUNT_OPTS ||
23341                 error "start MDS fail"
23342         wait_recovery_complete $facet
23343 }
23344 run_test 257 "xattr locks are not lost"
23345
23346 # Verify we take the i_mutex when security requires it
23347 test_258a() {
23348 #define OBD_FAIL_IMUTEX_SEC 0x141c
23349         $LCTL set_param fail_loc=0x141c
23350         touch $DIR/$tfile
23351         chmod u+s $DIR/$tfile
23352         chmod a+rwx $DIR/$tfile
23353         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
23354         RC=$?
23355         if [ $RC -ne 0 ]; then
23356                 error "error, failed to take i_mutex, rc=$?"
23357         fi
23358         rm -f $DIR/$tfile
23359 }
23360 run_test 258a "verify i_mutex security behavior when suid attributes is set"
23361
23362 # Verify we do NOT take the i_mutex in the normal case
23363 test_258b() {
23364 #define OBD_FAIL_IMUTEX_NOSEC 0x141d
23365         $LCTL set_param fail_loc=0x141d
23366         touch $DIR/$tfile
23367         chmod a+rwx $DIR
23368         chmod a+rw $DIR/$tfile
23369         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
23370         RC=$?
23371         if [ $RC -ne 0 ]; then
23372                 error "error, took i_mutex unnecessarily, rc=$?"
23373         fi
23374         rm -f $DIR/$tfile
23375
23376 }
23377 run_test 258b "verify i_mutex security behavior"
23378
23379 test_259() {
23380         local file=$DIR/$tfile
23381         local before
23382         local after
23383
23384         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
23385
23386         stack_trap "rm -f $file" EXIT
23387
23388         wait_delete_completed
23389         before=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
23390         echo "before: $before"
23391
23392         $LFS setstripe -i 0 -c 1 $file
23393         dd if=/dev/zero of=$file bs=1M count=10 || error "couldn't write"
23394         sync_all_data
23395         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
23396         echo "after write: $after"
23397
23398 #define OBD_FAIL_OSD_FAIL_AT_TRUNCATE          0x2301
23399         do_facet ost1 $LCTL set_param fail_loc=0x2301
23400         $TRUNCATE $file 0
23401         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
23402         echo "after truncate: $after"
23403
23404         stop ost1
23405         do_facet ost1 $LCTL set_param fail_loc=0
23406         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
23407         sleep 2
23408         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
23409         echo "after restart: $after"
23410         [ $((after - before)) -ge $(fs_log_size ost1) ] &&
23411                 error "missing truncate?"
23412
23413         return 0
23414 }
23415 run_test 259 "crash at delayed truncate"
23416
23417 test_260() {
23418 #define OBD_FAIL_MDC_CLOSE               0x806
23419         $LCTL set_param fail_loc=0x80000806
23420         touch $DIR/$tfile
23421
23422 }
23423 run_test 260 "Check mdc_close fail"
23424
23425 ### Data-on-MDT sanity tests ###
23426 test_270a() {
23427         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23428                 skip "Need MDS version at least 2.10.55 for DoM"
23429
23430         # create DoM file
23431         local dom=$DIR/$tdir/dom_file
23432         local tmp=$DIR/$tdir/tmp_file
23433
23434         mkdir_on_mdt0 $DIR/$tdir
23435
23436         # basic checks for DoM component creation
23437         $LFS setstripe -E 1024K -E 2048K -L mdt $dom 2>/dev/null &&
23438                 error "Can set MDT layout to non-first entry"
23439
23440         $LFS setstripe -E 1024K -L mdt -E 2048K -L mdt $dom 2>/dev/null &&
23441                 error "Can define multiple entries as MDT layout"
23442
23443         $LFS setstripe -E 1M -L mdt $dom || error "Can't create DoM layout"
23444
23445         [ $($LFS getstripe -L $dom) == "mdt" ] || error "bad pattern"
23446         [ $($LFS getstripe -c $dom) == 0 ] || error "bad stripe count"
23447         [ $($LFS getstripe -S $dom) == 1048576 ] || error "bad stripe size"
23448
23449         local mdtidx=$($LFS getstripe -m $dom)
23450         local mdtname=MDT$(printf %04x $mdtidx)
23451         local facet=mds$((mdtidx + 1))
23452         local space_check=1
23453
23454         # Skip free space checks with ZFS
23455         [ "$(facet_fstype $facet)" == "zfs" ] && space_check=0
23456
23457         # write
23458         sync
23459         local size_tmp=$((65536 * 3))
23460         local mdtfree1=$(do_facet $facet \
23461                          lctl get_param -n osd*.*$mdtname.kbytesfree)
23462
23463         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
23464         # check also direct IO along write
23465         # IO size must be a multiple of PAGE_SIZE on all platforms (ARM=64KB)
23466         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
23467         sync
23468         cmp $tmp $dom || error "file data is different"
23469         [ $(stat -c%s $dom) == $size_tmp ] ||
23470                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
23471         if [ $space_check == 1 ]; then
23472                 local mdtfree2=$(do_facet $facet \
23473                                  lctl get_param -n osd*.*$mdtname.kbytesfree)
23474
23475                 # increase in usage from by $size_tmp
23476                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
23477                         error "MDT free space wrong after write: " \
23478                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
23479         fi
23480
23481         # truncate
23482         local size_dom=10000
23483
23484         $TRUNCATE $dom $size_dom
23485         [ $(stat -c%s $dom) == $size_dom ] ||
23486                 error "bad size after truncate: $(stat -c%s $dom) != $size_dom"
23487         if [ $space_check == 1 ]; then
23488                 mdtfree1=$(do_facet $facet \
23489                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23490                 # decrease in usage from $size_tmp to new $size_dom
23491                 [ $(($mdtfree1 - $mdtfree2)) -ge \
23492                   $(((size_tmp - size_dom) / 1024)) ] ||
23493                         error "MDT free space is wrong after truncate: " \
23494                               "$mdtfree1 >= $mdtfree2 + ($size_tmp - $size_dom) / 1024"
23495         fi
23496
23497         # append
23498         cat $tmp >> $dom
23499         sync
23500         size_dom=$((size_dom + size_tmp))
23501         [ $(stat -c%s $dom) == $size_dom ] ||
23502                 error "bad size after append: $(stat -c%s $dom) != $size_dom"
23503         if [ $space_check == 1 ]; then
23504                 mdtfree2=$(do_facet $facet \
23505                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23506                 # increase in usage by $size_tmp from previous
23507                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
23508                         error "MDT free space is wrong after append: " \
23509                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
23510         fi
23511
23512         # delete
23513         rm $dom
23514         if [ $space_check == 1 ]; then
23515                 mdtfree1=$(do_facet $facet \
23516                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23517                 # decrease in usage by $size_dom from previous
23518                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_dom / 1024)) ] ||
23519                         error "MDT free space is wrong after removal: " \
23520                               "$mdtfree1 >= $mdtfree2 + $size_dom/1024"
23521         fi
23522
23523         # combined striping
23524         $LFS setstripe -E 1024K -L mdt -E EOF $dom ||
23525                 error "Can't create DoM + OST striping"
23526
23527         size_tmp=2031616 # must be a multiple of PAGE_SIZE=65536 on ARM
23528         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
23529         # check also direct IO along write
23530         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
23531         sync
23532         cmp $tmp $dom || error "file data is different"
23533         [ $(stat -c%s $dom) == $size_tmp ] ||
23534                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
23535         rm $dom $tmp
23536
23537         return 0
23538 }
23539 run_test 270a "DoM: basic functionality tests"
23540
23541 test_270b() {
23542         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23543                 skip "Need MDS version at least 2.10.55"
23544
23545         local dom=$DIR/$tdir/dom_file
23546         local max_size=1048576
23547
23548         mkdir -p $DIR/$tdir
23549         $LFS setstripe -E $max_size -L mdt $dom
23550
23551         # truncate over the limit
23552         $TRUNCATE $dom $(($max_size + 1)) &&
23553                 error "successful truncate over the maximum size"
23554         # write over the limit
23555         dd if=/dev/zero of=$dom bs=$max_size seek=1 count=1 &&
23556                 error "successful write over the maximum size"
23557         # append over the limit
23558         dd if=/dev/zero of=$dom bs=$(($max_size - 3)) count=1
23559         echo "12345" >> $dom && error "successful append over the maximum size"
23560         rm $dom
23561
23562         return 0
23563 }
23564 run_test 270b "DoM: maximum size overflow checks for DoM-only file"
23565
23566 test_270c() {
23567         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23568                 skip "Need MDS version at least 2.10.55"
23569
23570         mkdir -p $DIR/$tdir
23571         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
23572
23573         # check files inherit DoM EA
23574         touch $DIR/$tdir/first
23575         [ $($LFS getstripe -L $DIR/$tdir/first) == "mdt" ] ||
23576                 error "bad pattern"
23577         [ $($LFS getstripe -c $DIR/$tdir/first) == 0 ] ||
23578                 error "bad stripe count"
23579         [ $($LFS getstripe -S $DIR/$tdir/first) == 1048576 ] ||
23580                 error "bad stripe size"
23581
23582         # check directory inherits DoM EA and uses it as default
23583         mkdir $DIR/$tdir/subdir
23584         touch $DIR/$tdir/subdir/second
23585         [ $($LFS getstripe -L $DIR/$tdir/subdir/second) == "mdt" ] ||
23586                 error "bad pattern in sub-directory"
23587         [ $($LFS getstripe -c $DIR/$tdir/subdir/second) == 0 ] ||
23588                 error "bad stripe count in sub-directory"
23589         [ $($LFS getstripe -S $DIR/$tdir/subdir/second) == 1048576 ] ||
23590                 error "bad stripe size in sub-directory"
23591         return 0
23592 }
23593 run_test 270c "DoM: DoM EA inheritance tests"
23594
23595 test_270d() {
23596         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23597                 skip "Need MDS version at least 2.10.55"
23598
23599         mkdir -p $DIR/$tdir
23600         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
23601
23602         # inherit default DoM striping
23603         mkdir $DIR/$tdir/subdir
23604         touch $DIR/$tdir/subdir/f1
23605
23606         # change default directory striping
23607         $LFS setstripe -c 1 $DIR/$tdir/subdir
23608         touch $DIR/$tdir/subdir/f2
23609         [ $($LFS getstripe -c $DIR/$tdir/subdir/f2) == 1 ] ||
23610                 error "wrong default striping in file 2"
23611         [ $($LFS getstripe -L $DIR/$tdir/subdir/f2) == "raid0" ] ||
23612                 error "bad pattern in file 2"
23613         return 0
23614 }
23615 run_test 270d "DoM: change striping from DoM to RAID0"
23616
23617 test_270e() {
23618         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23619                 skip "Need MDS version at least 2.10.55"
23620
23621         mkdir -p $DIR/$tdir/dom
23622         mkdir -p $DIR/$tdir/norm
23623         DOMFILES=20
23624         NORMFILES=10
23625         $LFS setstripe -E 1M -L mdt $DIR/$tdir/dom
23626         $LFS setstripe -i 0 -S 2M $DIR/$tdir/norm
23627
23628         createmany -o $DIR/$tdir/dom/dom- $DOMFILES
23629         createmany -o $DIR/$tdir/norm/norm- $NORMFILES
23630
23631         # find DoM files by layout
23632         NUM=$($LFS find -L mdt -type f $DIR/$tdir 2>/dev/null | wc -l)
23633         [ $NUM -eq  $DOMFILES ] ||
23634                 error "lfs find -L: found $NUM, expected $DOMFILES"
23635         echo "Test 1: lfs find 20 DOM files by layout: OK"
23636
23637         # there should be 1 dir with default DOM striping
23638         NUM=$($LFS find -L mdt -type d $DIR/$tdir 2>/dev/null | wc -l)
23639         [ $NUM -eq  1 ] ||
23640                 error "lfs find -L: found $NUM, expected 1 dir"
23641         echo "Test 2: lfs find 1 DOM dir by layout: OK"
23642
23643         # find DoM files by stripe size
23644         NUM=$($LFS find -S -1200K -type f $DIR/$tdir 2>/dev/null | wc -l)
23645         [ $NUM -eq  $DOMFILES ] ||
23646                 error "lfs find -S: found $NUM, expected $DOMFILES"
23647         echo "Test 4: lfs find 20 DOM files by stripe size: OK"
23648
23649         # find files by stripe offset except DoM files
23650         NUM=$($LFS find -i 0 -type f $DIR/$tdir 2>/dev/null | wc -l)
23651         [ $NUM -eq  $NORMFILES ] ||
23652                 error "lfs find -i: found $NUM, expected $NORMFILES"
23653         echo "Test 5: lfs find no DOM files by stripe index: OK"
23654         return 0
23655 }
23656 run_test 270e "DoM: lfs find with DoM files test"
23657
23658 test_270f() {
23659         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23660                 skip "Need MDS version at least 2.10.55"
23661
23662         local mdtname=${FSNAME}-MDT0000-mdtlov
23663         local dom=$DIR/$tdir/dom_file
23664         local dom_limit_saved=$(do_facet mds1 $LCTL get_param -n \
23665                                                 lod.$mdtname.dom_stripesize)
23666         local dom_limit=131072
23667
23668         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=$dom_limit
23669         local dom_current=$(do_facet mds1 $LCTL get_param -n \
23670                                                 lod.$mdtname.dom_stripesize)
23671         [ ${dom_limit} -eq ${dom_current} ] ||
23672                 error "Cannot change per-MDT DoM stripe limit to $dom_limit"
23673
23674         $LFS mkdir -i 0 -c 1 $DIR/$tdir
23675         $LFS setstripe -d $DIR/$tdir
23676         $LFS setstripe -E $dom_limit -L mdt $DIR/$tdir ||
23677                 error "Can't set directory default striping"
23678
23679         # exceed maximum stripe size
23680         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
23681                 error "Can't create file with $((dom_limit * 2)) DoM stripe"
23682         [ $($LFS getstripe -S $dom) -eq $((dom_limit * 2)) ] &&
23683                 error "Able to create DoM component size more than LOD limit"
23684
23685         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
23686         dom_current=$(do_facet mds1 $LCTL get_param -n \
23687                                                 lod.$mdtname.dom_stripesize)
23688         [ 0 -eq ${dom_current} ] ||
23689                 error "Can't set zero DoM stripe limit"
23690         rm $dom
23691
23692         # attempt to create DoM file on server with disabled DoM should
23693         # remove DoM entry from layout and be succeed
23694         $LFS setstripe -E $dom_limit -L mdt -E -1 $dom ||
23695                 error "Can't create DoM file (DoM is disabled)"
23696         [ $($LFS getstripe -L $dom) == "mdt" ] &&
23697                 error "File has DoM component while DoM is disabled"
23698         rm $dom
23699
23700         # attempt to create DoM file with only DoM stripe should return error
23701         $LFS setstripe -E $dom_limit -L mdt $dom &&
23702                 error "Able to create DoM-only file while DoM is disabled"
23703
23704         # too low values to be aligned with smallest stripe size 64K
23705         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=30000
23706         dom_current=$(do_facet mds1 $LCTL get_param -n \
23707                                                 lod.$mdtname.dom_stripesize)
23708         [ 30000 -eq ${dom_current} ] &&
23709                 error "Can set too small DoM stripe limit"
23710
23711         # 64K is a minimal stripe size in Lustre, expect limit of that size
23712         [ 65536 -eq ${dom_current} ] ||
23713                 error "Limit is not set to 64K but ${dom_current}"
23714
23715         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=2147483648
23716         dom_current=$(do_facet mds1 $LCTL get_param -n \
23717                                                 lod.$mdtname.dom_stripesize)
23718         echo $dom_current
23719         [ 2147483648 -eq ${dom_current} ] &&
23720                 error "Can set too large DoM stripe limit"
23721
23722         do_facet mds1 $LCTL set_param -n \
23723                                 lod.$mdtname.dom_stripesize=$((dom_limit * 2))
23724         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
23725                 error "Can't create DoM component size after limit change"
23726         do_facet mds1 $LCTL set_param -n \
23727                                 lod.$mdtname.dom_stripesize=$((dom_limit / 2))
23728         $LFS setstripe -E $dom_limit -L mdt ${dom}_big ||
23729                 error "Can't create DoM file after limit decrease"
23730         [ $($LFS getstripe -S ${dom}_big) -eq $((dom_limit / 2)) ] ||
23731                 error "Can create big DoM component after limit decrease"
23732         touch ${dom}_def ||
23733                 error "Can't create file with old default layout"
23734
23735         do_facet mds1 $LCTL set_param -n lod.*.dom_stripesize=$dom_limit_saved
23736         return 0
23737 }
23738 run_test 270f "DoM: maximum DoM stripe size checks"
23739
23740 test_270g() {
23741         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
23742                 skip "Need MDS version at least 2.13.52"
23743         local dom=$DIR/$tdir/$tfile
23744
23745         $LFS mkdir -i 0 -c 1 $DIR/$tdir
23746         local lodname=${FSNAME}-MDT0000-mdtlov
23747
23748         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
23749         save_lustre_params mds1 "lod.${lodname}.dom_stripesize_max_kb" > $save
23750         save_lustre_params mds1 "lod.${lodname}.dom_threshold_free_mb" >> $save
23751         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
23752
23753         local dom_limit=1024
23754         local dom_threshold="50%"
23755
23756         $LFS setstripe -d $DIR/$tdir
23757         $LFS setstripe -E ${dom_limit}K -L mdt $DIR/$tdir ||
23758                 error "Can't set directory default striping"
23759
23760         do_facet mds1 $LCTL set_param -n \
23761                                 lod.${lodname}.dom_stripesize_max_kb=$dom_limit
23762         # set 0 threshold and create DOM file to change tunable stripesize
23763         do_facet mds1 $LCTL set_param -n lod.${lodname}.dom_threshold_free_mb=0
23764         $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
23765                 error "Failed to create $dom file"
23766         # now tunable dom_cur_stripesize should reach maximum
23767         local dom_current=$(do_facet mds1 $LCTL get_param -n \
23768                                         lod.${lodname}.dom_stripesize_cur_kb)
23769         [[ $dom_current == $dom_limit ]] ||
23770                 error "Current DOM stripesize is not maximum"
23771         rm $dom
23772
23773         # set threshold for further tests
23774         do_facet mds1 $LCTL set_param -n \
23775                         lod.${lodname}.dom_threshold_free_mb=$dom_threshold
23776         echo "DOM threshold is $dom_threshold free space"
23777         local dom_def
23778         local dom_set
23779         # Spoof bfree to exceed threshold
23780         #define OBD_FAIL_MDS_STATFS_SPOOF   0x168
23781         do_facet mds1 $LCTL set_param -n fail_loc=0x0168
23782         for spfree in 40 20 0 15 30 55; do
23783                 do_facet mds1 $LCTL set_param -n fail_val=$spfree
23784                 $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
23785                         error "Failed to create $dom file"
23786                 dom_def=$(do_facet mds1 $LCTL get_param -n \
23787                                         lod.${lodname}.dom_stripesize_cur_kb)
23788                 echo "Free space: ${spfree}%, default DOM stripe: ${dom_def}K"
23789                 [[ $dom_def != $dom_current ]] ||
23790                         error "Default stripe size was not changed"
23791                 if (( spfree > 0 )) ; then
23792                         dom_set=$($LFS getstripe -S $dom)
23793                         (( dom_set == dom_def * 1024 )) ||
23794                                 error "DOM component size is still old"
23795                 else
23796                         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
23797                                 error "DoM component is set with no free space"
23798                 fi
23799                 rm $dom
23800                 dom_current=$dom_def
23801         done
23802 }
23803 run_test 270g "DoM: default DoM stripe size depends on free space"
23804
23805 test_270h() {
23806         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
23807                 skip "Need MDS version at least 2.13.53"
23808
23809         local mdtname=${FSNAME}-MDT0000-mdtlov
23810         local dom=$DIR/$tdir/$tfile
23811         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
23812
23813         save_lustre_params mds1 "lod.*.dom_stripesize" > $save
23814         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
23815
23816         $LFS mkdir -i 0 -c 1 $DIR/$tdir
23817         $LFS setstripe -E 1M -c1  -E -1 -c2 ${dom}_1 ||
23818                 error "can't create OST file"
23819         # mirrored file with DOM entry in the second mirror
23820         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 ${dom}_1 ||
23821                 error "can't create mirror with DoM component"
23822
23823         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
23824
23825         # DOM component in the middle and has other enries in the same mirror,
23826         # should succeed but lost DoM component
23827         $LFS setstripe --copy=${dom}_1 $dom ||
23828                 error "Can't create file from OST|DOM mirror layout"
23829         # check new file has no DoM layout after all
23830         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
23831                 error "File has DoM component while DoM is disabled"
23832 }
23833 run_test 270h "DoM: DoM stripe removal when disabled on server"
23834
23835 test_270i() {
23836         (( $MDS1_VERSION >= $(version_code 2.14.54) )) ||
23837                 skip "Need MDS version at least 2.14.54"
23838
23839         mkdir $DIR/$tdir
23840         # DoM with plain layout
23841         $LFS setstripe -L mdt -S 128k -c -1 $DIR/$tdir &&
23842                 error "default plain layout with DoM must fail"
23843         $LFS setstripe -L mdt -S 128k -c -1 $DIR/$tdir/$tfile &&
23844                 error "setstripe plain file layout with DoM must fail"
23845         $LFS setstripe -E 1M -L mdt -S 128k -c -1 -E eof $DIR/$tdir &&
23846                 error "default DoM layout with bad striping must fail"
23847         $LFS setstripe -E 1M -L mdt -S 128k -c -1 -E eof $DIR/$tdir/$tfile &&
23848                 error "setstripe to DoM layout with bad striping must fail"
23849         return 0
23850 }
23851 run_test 270i "DoM: setting invalid DoM striping should fail"
23852
23853 test_271a() {
23854         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23855                 skip "Need MDS version at least 2.10.55"
23856
23857         local dom=$DIR/$tdir/dom
23858
23859         mkdir -p $DIR/$tdir
23860
23861         $LFS setstripe -E 1024K -L mdt $dom
23862
23863         lctl set_param -n mdc.*.stats=clear
23864         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
23865         cat $dom > /dev/null
23866         local reads=$(lctl get_param -n mdc.*.stats | grep -c ost_read)
23867         [ $reads -eq 0 ] || error "Unexpected $reads READ RPCs"
23868         ls $dom
23869         rm -f $dom
23870 }
23871 run_test 271a "DoM: data is cached for read after write"
23872
23873 test_271b() {
23874         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23875                 skip "Need MDS version at least 2.10.55"
23876
23877         local dom=$DIR/$tdir/dom
23878
23879         mkdir -p $DIR/$tdir
23880
23881         $LFS setstripe -E 1024K -L mdt -E EOF $dom
23882
23883         lctl set_param -n mdc.*.stats=clear
23884         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
23885         cancel_lru_locks mdc
23886         $CHECKSTAT -t file -s 4096 $dom || error "stat #1 fails"
23887         # second stat to check size is cached on client
23888         $CHECKSTAT -t file -s 4096 $dom || error "stat #2 fails"
23889         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
23890         [ $gls -eq 0 ] || error "Unexpected $gls glimpse RPCs"
23891         rm -f $dom
23892 }
23893 run_test 271b "DoM: no glimpse RPC for stat (DoM only file)"
23894
23895 test_271ba() {
23896         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23897                 skip "Need MDS version at least 2.10.55"
23898
23899         local dom=$DIR/$tdir/dom
23900
23901         mkdir -p $DIR/$tdir
23902
23903         $LFS setstripe -E 1024K -L mdt -E EOF $dom
23904
23905         lctl set_param -n mdc.*.stats=clear
23906         lctl set_param -n osc.*.stats=clear
23907         dd if=/dev/zero of=$dom bs=2048K count=1 || return 1
23908         cancel_lru_locks mdc
23909         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
23910         # second stat to check size is cached on client
23911         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
23912         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
23913         [ $gls == 0 ] || error "Unexpected $gls glimpse RPCs"
23914         local gls=$(lctl get_param -n osc.*.stats | grep -c ldlm_glimpse)
23915         [ $gls == 0 ] || error "Unexpected $gls OSC glimpse RPCs"
23916         rm -f $dom
23917 }
23918 run_test 271ba "DoM: no glimpse RPC for stat (combined file)"
23919
23920
23921 get_mdc_stats() {
23922         local mdtidx=$1
23923         local param=$2
23924         local mdt=MDT$(printf %04x $mdtidx)
23925
23926         if [ -z $param ]; then
23927                 lctl get_param -n mdc.*$mdt*.stats
23928         else
23929                 lctl get_param -n mdc.*$mdt*.stats | awk "/$param/"'{print $2}'
23930         fi
23931 }
23932
23933 test_271c() {
23934         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23935                 skip "Need MDS version at least 2.10.55"
23936
23937         local dom=$DIR/$tdir/dom
23938
23939         mkdir -p $DIR/$tdir
23940
23941         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
23942
23943         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
23944         local facet=mds$((mdtidx + 1))
23945
23946         cancel_lru_locks mdc
23947         do_facet $facet lctl set_param -n mdt.*.dom_lock=0
23948         createmany -o $dom 1000
23949         lctl set_param -n mdc.*.stats=clear
23950         smalliomany -w $dom 1000 200
23951         get_mdc_stats $mdtidx
23952         local enq=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
23953         # Each file has 1 open, 1 IO enqueues, total 2000
23954         # but now we have also +1 getxattr for security.capability, total 3000
23955         [ $enq -ge 2000 ] || error "Too few enqueues $enq, expected > 2000"
23956         unlinkmany $dom 1000
23957
23958         cancel_lru_locks mdc
23959         do_facet $facet lctl set_param -n mdt.*.dom_lock=1
23960         createmany -o $dom 1000
23961         lctl set_param -n mdc.*.stats=clear
23962         smalliomany -w $dom 1000 200
23963         local enq_2=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
23964         # Expect to see reduced amount of RPCs by 1000 due to single enqueue
23965         # for OPEN and IO lock.
23966         [ $((enq - enq_2)) -ge 1000 ] ||
23967                 error "Too many enqueues $enq_2, expected about $((enq - 1000))"
23968         unlinkmany $dom 1000
23969         return 0
23970 }
23971 run_test 271c "DoM: IO lock at open saves enqueue RPCs"
23972
23973 cleanup_271def_tests() {
23974         trap 0
23975         rm -f $1
23976 }
23977
23978 test_271d() {
23979         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
23980                 skip "Need MDS version at least 2.10.57"
23981
23982         local dom=$DIR/$tdir/dom
23983         local tmp=$TMP/$tfile
23984         trap "cleanup_271def_tests $tmp" EXIT
23985
23986         mkdir -p $DIR/$tdir
23987
23988         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
23989
23990         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
23991
23992         cancel_lru_locks mdc
23993         dd if=/dev/urandom of=$tmp bs=1000 count=1
23994         dd if=$tmp of=$dom bs=1000 count=1
23995         cancel_lru_locks mdc
23996
23997         cat /etc/hosts >> $tmp
23998         lctl set_param -n mdc.*.stats=clear
23999
24000         # append data to the same file it should update local page
24001         echo "Append to the same page"
24002         cat /etc/hosts >> $dom
24003         local num=$(get_mdc_stats $mdtidx ost_read)
24004         local ra=$(get_mdc_stats $mdtidx req_active)
24005         local rw=$(get_mdc_stats $mdtidx req_waittime)
24006
24007         [ -z $num ] || error "$num READ RPC occured"
24008         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
24009         echo "... DONE"
24010
24011         # compare content
24012         cmp $tmp $dom || error "file miscompare"
24013
24014         cancel_lru_locks mdc
24015         lctl set_param -n mdc.*.stats=clear
24016
24017         echo "Open and read file"
24018         cat $dom > /dev/null
24019         local num=$(get_mdc_stats $mdtidx ost_read)
24020         local ra=$(get_mdc_stats $mdtidx req_active)
24021         local rw=$(get_mdc_stats $mdtidx req_waittime)
24022
24023         [ -z $num ] || error "$num READ RPC occured"
24024         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
24025         echo "... DONE"
24026
24027         # compare content
24028         cmp $tmp $dom || error "file miscompare"
24029
24030         return 0
24031 }
24032 run_test 271d "DoM: read on open (1K file in reply buffer)"
24033
24034 test_271f() {
24035         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
24036                 skip "Need MDS version at least 2.10.57"
24037
24038         local dom=$DIR/$tdir/dom
24039         local tmp=$TMP/$tfile
24040         trap "cleanup_271def_tests $tmp" EXIT
24041
24042         mkdir -p $DIR/$tdir
24043
24044         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
24045
24046         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
24047
24048         cancel_lru_locks mdc
24049         dd if=/dev/urandom of=$tmp bs=265000 count=1
24050         dd if=$tmp of=$dom bs=265000 count=1
24051         cancel_lru_locks mdc
24052         cat /etc/hosts >> $tmp
24053         lctl set_param -n mdc.*.stats=clear
24054
24055         echo "Append to the same page"
24056         cat /etc/hosts >> $dom
24057         local num=$(get_mdc_stats $mdtidx ost_read)
24058         local ra=$(get_mdc_stats $mdtidx req_active)
24059         local rw=$(get_mdc_stats $mdtidx req_waittime)
24060
24061         [ -z $num ] || error "$num READ RPC occured"
24062         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
24063         echo "... DONE"
24064
24065         # compare content
24066         cmp $tmp $dom || error "file miscompare"
24067
24068         cancel_lru_locks mdc
24069         lctl set_param -n mdc.*.stats=clear
24070
24071         echo "Open and read file"
24072         cat $dom > /dev/null
24073         local num=$(get_mdc_stats $mdtidx ost_read)
24074         local ra=$(get_mdc_stats $mdtidx req_active)
24075         local rw=$(get_mdc_stats $mdtidx req_waittime)
24076
24077         [ -z $num ] && num=0
24078         [ $num -eq 1 ] || error "expect 1 READ RPC, $num occured"
24079         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
24080         echo "... DONE"
24081
24082         # compare content
24083         cmp $tmp $dom || error "file miscompare"
24084
24085         return 0
24086 }
24087 run_test 271f "DoM: read on open (200K file and read tail)"
24088
24089 test_271g() {
24090         [[ $($LCTL get_param mdc.*.import) =~ async_discard ]] ||
24091                 skip "Skipping due to old client or server version"
24092
24093         $LFS setstripe -E 1024K -L mdt -E EOF $DIR1/$tfile
24094         # to get layout
24095         $CHECKSTAT -t file $DIR1/$tfile
24096
24097         $MULTIOP $DIR1/$tfile Ow40960_w4096c &
24098         MULTIOP_PID=$!
24099         sleep 1
24100         #define OBD_FAIL_LDLM_CANCEL_BL_CB_RACE
24101         $LCTL set_param fail_loc=0x80000314
24102         rm $DIR1/$tfile || error "Unlink fails"
24103         RC=$?
24104         kill -USR1 $MULTIOP_PID && wait $MULTIOP_PID || error "multiop failure"
24105         [ $RC -eq 0 ] || error "Failed write to stale object"
24106 }
24107 run_test 271g "Discard DoM data vs client flush race"
24108
24109 test_272a() {
24110         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
24111                 skip "Need MDS version at least 2.11.50"
24112
24113         local dom=$DIR/$tdir/dom
24114         mkdir -p $DIR/$tdir
24115
24116         $LFS setstripe -E 256K -L mdt -E -1 -c1 $dom
24117         dd if=/dev/urandom of=$dom bs=512K count=1 ||
24118                 error "failed to write data into $dom"
24119         local old_md5=$(md5sum $dom)
24120
24121         $LFS migrate -E 256K -L mdt -E -1 -c2 $dom ||
24122                 error "failed to migrate to the same DoM component"
24123
24124         local new_md5=$(md5sum $dom)
24125
24126         [ "$old_md5" == "$new_md5" ] ||
24127                 error "md5sum differ: $old_md5, $new_md5"
24128
24129         [ $($LFS getstripe -c $dom) -eq 2 ] ||
24130                 error "bad final stripe count: $($LFS getstripe -c $dom) != 2"
24131 }
24132 run_test 272a "DoM migration: new layout with the same DOM component"
24133
24134 test_272b() {
24135         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
24136                 skip "Need MDS version at least 2.11.50"
24137
24138         local dom=$DIR/$tdir/dom
24139         mkdir -p $DIR/$tdir
24140         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
24141         stack_trap "rm -rf $DIR/$tdir"
24142
24143         local mdtidx=$($LFS getstripe -m $dom)
24144         local mdtname=MDT$(printf %04x $mdtidx)
24145         local facet=mds$((mdtidx + 1))
24146
24147         local mdtfree1=$(do_facet $facet \
24148                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24149         dd if=/dev/urandom of=$dom bs=2M count=1 ||
24150                 error "failed to write data into $dom"
24151         local old_md5=$(md5sum $dom)
24152         cancel_lru_locks mdc
24153         local mdtfree1=$(do_facet $facet \
24154                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24155
24156         $LFS migrate -c2 $dom ||
24157                 error "failed to migrate to the new composite layout"
24158         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
24159                 error "MDT stripe was not removed"
24160
24161         cancel_lru_locks mdc
24162         local new_md5=$(md5sum $dom)
24163         [ "$old_md5" == "$new_md5" ] ||
24164                 error "$old_md5 != $new_md5"
24165
24166         # Skip free space checks with ZFS
24167         if [ "$(facet_fstype $facet)" != "zfs" ]; then
24168                 local mdtfree2=$(do_facet $facet \
24169                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24170                 [ $mdtfree2 -gt $mdtfree1 ] ||
24171                         error "MDT space is not freed after migration"
24172         fi
24173         return 0
24174 }
24175 run_test 272b "DoM migration: DOM file to the OST-striped file (plain)"
24176
24177 test_272c() {
24178         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
24179                 skip "Need MDS version at least 2.11.50"
24180
24181         local dom=$DIR/$tdir/$tfile
24182         mkdir -p $DIR/$tdir
24183         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
24184         stack_trap "rm -rf $DIR/$tdir"
24185
24186         local mdtidx=$($LFS getstripe -m $dom)
24187         local mdtname=MDT$(printf %04x $mdtidx)
24188         local facet=mds$((mdtidx + 1))
24189
24190         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
24191                 error "failed to write data into $dom"
24192         local old_md5=$(md5sum $dom)
24193         cancel_lru_locks mdc
24194         local mdtfree1=$(do_facet $facet \
24195                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24196
24197         $LFS migrate -E 2M -c1 -E -1 -c2 $dom ||
24198                 error "failed to migrate to the new composite layout"
24199         [ $($LFS getstripe -L $dom) == 'mdt' ] &&
24200                 error "MDT stripe was not removed"
24201
24202         cancel_lru_locks mdc
24203         local new_md5=$(md5sum $dom)
24204         [ "$old_md5" == "$new_md5" ] ||
24205                 error "$old_md5 != $new_md5"
24206
24207         # Skip free space checks with ZFS
24208         if [ "$(facet_fstype $facet)" != "zfs" ]; then
24209                 local mdtfree2=$(do_facet $facet \
24210                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24211                 [ $mdtfree2 -gt $mdtfree1 ] ||
24212                         error "MDS space is not freed after migration"
24213         fi
24214         return 0
24215 }
24216 run_test 272c "DoM migration: DOM file to the OST-striped file (composite)"
24217
24218 test_272d() {
24219         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
24220                 skip "Need MDS version at least 2.12.55"
24221
24222         local dom=$DIR/$tdir/$tfile
24223         mkdir -p $DIR/$tdir
24224         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
24225
24226         local mdtidx=$($LFS getstripe -m $dom)
24227         local mdtname=MDT$(printf %04x $mdtidx)
24228         local facet=mds$((mdtidx + 1))
24229
24230         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
24231                 error "failed to write data into $dom"
24232         local old_md5=$(md5sum $dom)
24233         cancel_lru_locks mdc
24234         local mdtfree1=$(do_facet $facet \
24235                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24236
24237         $LFS mirror extend -N -E 2M -c1 -E -1 -c2 $dom ||
24238                 error "failed mirroring to the new composite layout"
24239         $LFS mirror resync $dom ||
24240                 error "failed mirror resync"
24241         $LFS mirror split --mirror-id 1 -d $dom ||
24242                 error "failed mirror split"
24243
24244         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
24245                 error "MDT stripe was not removed"
24246
24247         cancel_lru_locks mdc
24248         local new_md5=$(md5sum $dom)
24249         [ "$old_md5" == "$new_md5" ] ||
24250                 error "$old_md5 != $new_md5"
24251
24252         # Skip free space checks with ZFS
24253         if [ "$(facet_fstype $facet)" != "zfs" ]; then
24254                 local mdtfree2=$(do_facet $facet \
24255                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24256                 [ $mdtfree2 -gt $mdtfree1 ] ||
24257                         error "MDS space is not freed after DOM mirror deletion"
24258         fi
24259         return 0
24260 }
24261 run_test 272d "DoM mirroring: OST-striped mirror to DOM file"
24262
24263 test_272e() {
24264         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
24265                 skip "Need MDS version at least 2.12.55"
24266
24267         local dom=$DIR/$tdir/$tfile
24268         mkdir -p $DIR/$tdir
24269         $LFS setstripe -c 2 $dom
24270
24271         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
24272                 error "failed to write data into $dom"
24273         local old_md5=$(md5sum $dom)
24274         cancel_lru_locks
24275
24276         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 $dom ||
24277                 error "failed mirroring to the DOM layout"
24278         $LFS mirror resync $dom ||
24279                 error "failed mirror resync"
24280         $LFS mirror split --mirror-id 1 -d $dom ||
24281                 error "failed mirror split"
24282
24283         [[ $($LFS getstripe -L --component-start=0 $dom) == 'mdt' ]] ||
24284                 error "MDT stripe wasn't set"
24285
24286         cancel_lru_locks
24287         local new_md5=$(md5sum $dom)
24288         [ "$old_md5" == "$new_md5" ] ||
24289                 error "$old_md5 != $new_md5"
24290
24291         return 0
24292 }
24293 run_test 272e "DoM mirroring: DOM mirror to the OST-striped file"
24294
24295 test_272f() {
24296         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
24297                 skip "Need MDS version at least 2.12.55"
24298
24299         local dom=$DIR/$tdir/$tfile
24300         mkdir -p $DIR/$tdir
24301         $LFS setstripe -c 2 $dom
24302
24303         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
24304                 error "failed to write data into $dom"
24305         local old_md5=$(md5sum $dom)
24306         cancel_lru_locks
24307
24308         $LFS migrate -E 1M -L mdt -E eof -c2 -v $dom ||
24309                 error "failed migrating to the DOM file"
24310
24311         [[ $($LFS getstripe -L --component-start=0 $dom) == 'mdt' ]] ||
24312                 error "MDT stripe wasn't set"
24313
24314         cancel_lru_locks
24315         local new_md5=$(md5sum $dom)
24316         [ "$old_md5" != "$new_md5" ] &&
24317                 error "$old_md5 != $new_md5"
24318
24319         return 0
24320 }
24321 run_test 272f "DoM migration: OST-striped file to DOM file"
24322
24323 test_273a() {
24324         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
24325                 skip "Need MDS version at least 2.11.50"
24326
24327         # Layout swap cannot be done if either file has DOM component,
24328         # this will never be supported, migration should be used instead
24329
24330         local dom=$DIR/$tdir/$tfile
24331         mkdir -p $DIR/$tdir
24332
24333         $LFS setstripe -c2 ${dom}_plain
24334         $LFS setstripe -E 1M -L mdt -E -1 -c2 ${dom}_dom
24335         $LFS swap_layouts ${dom}_plain ${dom}_dom &&
24336                 error "can swap layout with DoM component"
24337         $LFS swap_layouts ${dom}_dom ${dom}_plain &&
24338                 error "can swap layout with DoM component"
24339
24340         $LFS setstripe -E 1M -c1 -E -1 -c2 ${dom}_comp
24341         $LFS swap_layouts ${dom}_comp ${dom}_dom &&
24342                 error "can swap layout with DoM component"
24343         $LFS swap_layouts ${dom}_dom ${dom}_comp &&
24344                 error "can swap layout with DoM component"
24345         return 0
24346 }
24347 run_test 273a "DoM: layout swapping should fail with DOM"
24348
24349 test_273b() {
24350         mkdir -p $DIR/$tdir
24351         $LFS setstripe -E 1M -L mdt -E -1 -c -1 $DIR/$tdir
24352
24353 #define OBD_FAIL_MDS_COMMITRW_DELAY      0x16b
24354         do_facet mds1 $LCTL set_param fail_loc=0x8000016b fail_val=2
24355
24356         $MULTIOP $DIR/$tdir/$tfile Ouw2097152c
24357 }
24358 run_test 273b "DoM: race writeback and object destroy"
24359
24360 test_273c() {
24361         mkdir -p $DIR/$tdir
24362         $LFS setstripe -E 1M -E-1 -c-1 $DIR/$tdir
24363
24364         #define OBD_FAIL_OFD_COMMITRW_DELAY      0x1e1
24365         do_facet ost1 $LCTL set_param fail_loc=0x800001e1 fail_val=2
24366
24367         $MULTIOP $DIR/$tdir/$tfile Ouw2097152c
24368 }
24369 run_test 273c "race writeback and object destroy"
24370
24371 test_275() {
24372         remote_ost_nodsh && skip "remote OST with nodsh"
24373         [ $OST1_VERSION -lt $(version_code 2.10.57) ] &&
24374                 skip "Need OST version >= 2.10.57"
24375
24376         local file=$DIR/$tfile
24377         local oss
24378
24379         oss=$(comma_list $(osts_nodes))
24380
24381         dd if=/dev/urandom of=$file bs=1M count=2 ||
24382                 error "failed to create a file"
24383         stack_trap "rm -f $file"
24384         cancel_lru_locks osc
24385
24386         #lock 1
24387         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
24388                 error "failed to read a file"
24389
24390 #define OBD_FAIL_LDLM_PAUSE_CANCEL2      0x31f
24391         $LCTL set_param fail_loc=0x8000031f
24392
24393         cancel_lru_locks osc &
24394         sleep 1
24395
24396 #define OBD_FAIL_LDLM_PROLONG_PAUSE      0x32b
24397         do_nodes $oss $LCTL set_param fail_loc=0x8000032b
24398         #IO takes another lock, but matches the PENDING one
24399         #and places it to the IO RPC
24400         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
24401                 error "failed to read a file with PENDING lock"
24402 }
24403 run_test 275 "Read on a canceled duplicate lock"
24404
24405 test_276() {
24406         remote_ost_nodsh && skip "remote OST with nodsh"
24407         local pid
24408
24409         do_facet ost1 "(while true; do \
24410                 $LCTL get_param obdfilter.*.filesfree > /dev/null 2>&1; \
24411                 done) & pid=\\\$!; echo \\\$pid > $TMP/sanity_276_pid" &
24412         pid=$!
24413
24414         for LOOP in $(seq 20); do
24415                 stop ost1
24416                 start ost1 $(ostdevname 1) $OST_MOUNT_OPTS
24417         done
24418         kill -9 $pid
24419         do_facet ost1 "pid=\\\$(cat $TMP/sanity_276_pid); kill -9 \\\$pid; \
24420                 rm $TMP/sanity_276_pid"
24421 }
24422 run_test 276 "Race between mount and obd_statfs"
24423
24424 test_277() {
24425         $LCTL set_param ldlm.namespaces.*.lru_size=0
24426         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
24427         local cached_mb=$($LCTL get_param llite.*.max_cached_mb |
24428                         grep ^used_mb | awk '{print $2}')
24429         [ $cached_mb -eq 1 ] || error "expected mb 1 got $cached_mb"
24430         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 \
24431                 oflag=direct conv=notrunc
24432         cached_mb=$($LCTL get_param llite.*.max_cached_mb |
24433                         grep ^used_mb | awk '{print $2}')
24434         [ $cached_mb -eq 0 ] || error "expected mb 0 got $cached_mb"
24435 }
24436 run_test 277 "Direct IO shall drop page cache"
24437
24438 test_278() {
24439         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
24440         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
24441         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] &&
24442                 skip "needs the same host for mdt1 mdt2" && return
24443
24444         local pid1
24445         local pid2
24446
24447 #define OBD_FAIL_OBD_STOP_MDS_RACE     0x60b
24448         do_facet mds2 $LCTL set_param fail_loc=0x8000060c
24449         stop mds2 &
24450         pid2=$!
24451
24452         stop mds1
24453
24454         echo "Starting MDTs"
24455         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
24456         wait $pid2
24457 #For the error assertion will happen. lu_env_get_key(..., &mdt_thread_key)
24458 #will return NULL
24459         do_facet mds2 $LCTL set_param fail_loc=0
24460
24461         start mds2 $(mdsdevname 2) $MDS_MOUNT_OPTS
24462         wait_recovery_complete mds2
24463 }
24464 run_test 278 "Race starting MDS between MDTs stop/start"
24465
24466 test_280() {
24467         [ $MGS_VERSION -lt $(version_code 2.13.52) ] &&
24468                 skip "Need MGS version at least 2.13.52"
24469         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24470         combined_mgs_mds || skip "needs combined MGS/MDT"
24471
24472         umount_client $MOUNT
24473 #define OBD_FAIL_MDS_LLOG_UMOUNT_RACE   0x15e
24474         do_facet mgs $LCTL set_param fail_loc=0x8000015e fail_val=0
24475
24476         mount_client $MOUNT &
24477         sleep 1
24478         stop mgs || error "stop mgs failed"
24479         #for a race mgs would crash
24480         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
24481         # make sure we unmount client before remounting
24482         wait
24483         umount_client $MOUNT
24484         mount_client $MOUNT || error "mount client failed"
24485 }
24486 run_test 280 "Race between MGS umount and client llog processing"
24487
24488 cleanup_test_300() {
24489         trap 0
24490         umask $SAVE_UMASK
24491 }
24492 test_striped_dir() {
24493         local mdt_index=$1
24494         local stripe_count
24495         local stripe_index
24496
24497         mkdir -p $DIR/$tdir
24498
24499         SAVE_UMASK=$(umask)
24500         trap cleanup_test_300 RETURN EXIT
24501
24502         $LFS setdirstripe -i $mdt_index -c 2 -H all_char -o 755 \
24503                                                 $DIR/$tdir/striped_dir ||
24504                 error "set striped dir error"
24505
24506         local mode=$(stat -c%a $DIR/$tdir/striped_dir)
24507         [ "$mode" = "755" ] || error "expect 755 got $mode"
24508
24509         $LFS getdirstripe $DIR/$tdir/striped_dir > /dev/null 2>&1 ||
24510                 error "getdirstripe failed"
24511         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir)
24512         if [ "$stripe_count" != "2" ]; then
24513                 error "1:stripe_count is $stripe_count, expect 2"
24514         fi
24515         stripe_count=$($LFS getdirstripe -T $DIR/$tdir/striped_dir)
24516         if [ "$stripe_count" != "2" ]; then
24517                 error "2:stripe_count is $stripe_count, expect 2"
24518         fi
24519
24520         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir)
24521         if [ "$stripe_index" != "$mdt_index" ]; then
24522                 error "stripe_index is $stripe_index, expect $mdt_index"
24523         fi
24524
24525         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
24526                 error "nlink error after create striped dir"
24527
24528         mkdir $DIR/$tdir/striped_dir/a
24529         mkdir $DIR/$tdir/striped_dir/b
24530
24531         stat $DIR/$tdir/striped_dir/a ||
24532                 error "create dir under striped dir failed"
24533         stat $DIR/$tdir/striped_dir/b ||
24534                 error "create dir under striped dir failed"
24535
24536         [ $(stat -c%h $DIR/$tdir/striped_dir) == '4' ] ||
24537                 error "nlink error after mkdir"
24538
24539         rmdir $DIR/$tdir/striped_dir/a
24540         [ $(stat -c%h $DIR/$tdir/striped_dir) == '3' ] ||
24541                 error "nlink error after rmdir"
24542
24543         rmdir $DIR/$tdir/striped_dir/b
24544         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
24545                 error "nlink error after rmdir"
24546
24547         chattr +i $DIR/$tdir/striped_dir
24548         createmany -o $DIR/$tdir/striped_dir/f 10 &&
24549                 error "immutable flags not working under striped dir!"
24550         chattr -i $DIR/$tdir/striped_dir
24551
24552         rmdir $DIR/$tdir/striped_dir ||
24553                 error "rmdir striped dir error"
24554
24555         cleanup_test_300
24556
24557         true
24558 }
24559
24560 test_300a() {
24561         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
24562                 skip "skipped for lustre < 2.7.0"
24563         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24564         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24565
24566         test_striped_dir 0 || error "failed on striped dir on MDT0"
24567         test_striped_dir 1 || error "failed on striped dir on MDT0"
24568 }
24569 run_test 300a "basic striped dir sanity test"
24570
24571 test_300b() {
24572         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
24573                 skip "skipped for lustre < 2.7.0"
24574         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24575         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24576
24577         local i
24578         local mtime1
24579         local mtime2
24580         local mtime3
24581
24582         test_mkdir $DIR/$tdir || error "mkdir fail"
24583         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
24584                 error "set striped dir error"
24585         for i in {0..9}; do
24586                 mtime1=$(stat -c %Y $DIR/$tdir/striped_dir)
24587                 sleep 1
24588                 touch $DIR/$tdir/striped_dir/file_$i || error "touch error $i"
24589                 mtime2=$(stat -c %Y $DIR/$tdir/striped_dir)
24590                 [ $mtime1 -eq $mtime2 ] && error "mtime unchanged after create"
24591                 sleep 1
24592                 rm -f $DIR/$tdir/striped_dir/file_$i || error "unlink error $i"
24593                 mtime3=$(stat -c %Y $DIR/$tdir/striped_dir)
24594                 [ $mtime2 -eq $mtime3 ] && error "mtime unchanged after unlink"
24595         done
24596         true
24597 }
24598 run_test 300b "check ctime/mtime for striped dir"
24599
24600 test_300c() {
24601         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
24602                 skip "skipped for lustre < 2.7.0"
24603         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24604         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24605
24606         local file_count
24607
24608         mkdir_on_mdt0 $DIR/$tdir
24609         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir ||
24610                 error "set striped dir error"
24611
24612         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/striped_dir ||
24613                 error "chown striped dir failed"
24614
24615         $RUNAS createmany -o $DIR/$tdir/striped_dir/f 5000 ||
24616                 error "create 5k files failed"
24617
24618         file_count=$(ls $DIR/$tdir/striped_dir | wc -l)
24619
24620         [ "$file_count" = 5000 ] || error "file count $file_count != 5000"
24621
24622         rm -rf $DIR/$tdir
24623 }
24624 run_test 300c "chown && check ls under striped directory"
24625
24626 test_300d() {
24627         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
24628                 skip "skipped for lustre < 2.7.0"
24629         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24630         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24631
24632         local stripe_count
24633         local file
24634
24635         mkdir -p $DIR/$tdir
24636         $LFS setstripe -c 2 $DIR/$tdir
24637
24638         #local striped directory
24639         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
24640                 error "set striped dir error"
24641         #look at the directories for debug purposes
24642         ls -l $DIR/$tdir
24643         $LFS getdirstripe $DIR/$tdir
24644         ls -l $DIR/$tdir/striped_dir
24645         $LFS getdirstripe $DIR/$tdir/striped_dir
24646         createmany -o $DIR/$tdir/striped_dir/f 10 ||
24647                 error "create 10 files failed"
24648
24649         #remote striped directory
24650         $LFS setdirstripe -i 1 -c 2 $DIR/$tdir/remote_striped_dir ||
24651                 error "set striped dir error"
24652         #look at the directories for debug purposes
24653         ls -l $DIR/$tdir
24654         $LFS getdirstripe $DIR/$tdir
24655         ls -l $DIR/$tdir/remote_striped_dir
24656         $LFS getdirstripe $DIR/$tdir/remote_striped_dir
24657         createmany -o $DIR/$tdir/remote_striped_dir/f 10 ||
24658                 error "create 10 files failed"
24659
24660         for file in $(find $DIR/$tdir); do
24661                 stripe_count=$($LFS getstripe -c $file)
24662                 [ $stripe_count -eq 2 ] ||
24663                         error "wrong stripe $stripe_count for $file"
24664         done
24665
24666         rm -rf $DIR/$tdir
24667 }
24668 run_test 300d "check default stripe under striped directory"
24669
24670 test_300e() {
24671         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24672                 skip "Need MDS version at least 2.7.55"
24673         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24674         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24675
24676         local stripe_count
24677         local file
24678
24679         mkdir -p $DIR/$tdir
24680
24681         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
24682                 error "set striped dir error"
24683
24684         touch $DIR/$tdir/striped_dir/a
24685         touch $DIR/$tdir/striped_dir/b
24686         touch $DIR/$tdir/striped_dir/c
24687
24688         mkdir $DIR/$tdir/striped_dir/dir_a
24689         mkdir $DIR/$tdir/striped_dir/dir_b
24690         mkdir $DIR/$tdir/striped_dir/dir_c
24691
24692         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_a ||
24693                 error "set striped adir under striped dir error"
24694
24695         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_b ||
24696                 error "set striped bdir under striped dir error"
24697
24698         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_c ||
24699                 error "set striped cdir under striped dir error"
24700
24701         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir/dir_b ||
24702                 error "rename dir under striped dir fails"
24703
24704         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir/stp_b ||
24705                 error "rename dir under different stripes fails"
24706
24707         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir/c ||
24708                 error "rename file under striped dir should succeed"
24709
24710         mrename $DIR/$tdir/striped_dir/dir_b $DIR/$tdir/striped_dir/dir_c ||
24711                 error "rename dir under striped dir should succeed"
24712
24713         rm -rf $DIR/$tdir
24714 }
24715 run_test 300e "check rename under striped directory"
24716
24717 test_300f() {
24718         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24719         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24720         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24721                 skip "Need MDS version at least 2.7.55"
24722
24723         local stripe_count
24724         local file
24725
24726         rm -rf $DIR/$tdir
24727         mkdir -p $DIR/$tdir
24728
24729         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
24730                 error "set striped dir error"
24731
24732         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir1 ||
24733                 error "set striped dir error"
24734
24735         touch $DIR/$tdir/striped_dir/a
24736         mkdir $DIR/$tdir/striped_dir/dir_a
24737         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_a ||
24738                 error "create striped dir under striped dir fails"
24739
24740         touch $DIR/$tdir/striped_dir1/b
24741         mkdir $DIR/$tdir/striped_dir1/dir_b
24742         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_b ||
24743                 error "create striped dir under striped dir fails"
24744
24745         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir1/dir_b ||
24746                 error "rename dir under different striped dir should fail"
24747
24748         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir1/stp_b ||
24749                 error "rename striped dir under diff striped dir should fail"
24750
24751         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir1/a ||
24752                 error "rename file under diff striped dirs fails"
24753
24754         rm -rf $DIR/$tdir
24755 }
24756 run_test 300f "check rename cross striped directory"
24757
24758 test_300_check_default_striped_dir()
24759 {
24760         local dirname=$1
24761         local default_count=$2
24762         local default_index=$3
24763         local stripe_count
24764         local stripe_index
24765         local dir_stripe_index
24766         local dir
24767
24768         echo "checking $dirname $default_count $default_index"
24769         $LFS setdirstripe -D -c $default_count -i $default_index \
24770                                 -H all_char $DIR/$tdir/$dirname ||
24771                 error "set default stripe on striped dir error"
24772         stripe_count=$($LFS getdirstripe -D -c $DIR/$tdir/$dirname)
24773         [ $stripe_count -eq $default_count ] ||
24774                 error "expect $default_count get $stripe_count for $dirname"
24775
24776         stripe_index=$($LFS getdirstripe -D -i $DIR/$tdir/$dirname)
24777         [ $stripe_index -eq $default_index ] ||
24778                 error "expect $default_index get $stripe_index for $dirname"
24779
24780         mkdir $DIR/$tdir/$dirname/{test1,test2,test3,test4} ||
24781                                                 error "create dirs failed"
24782
24783         createmany -o $DIR/$tdir/$dirname/f- 10 || error "create files failed"
24784         unlinkmany $DIR/$tdir/$dirname/f- 10    || error "unlink files failed"
24785         for dir in $(find $DIR/$tdir/$dirname/*); do
24786                 stripe_count=$($LFS getdirstripe -c $dir)
24787                 (( $stripe_count == $default_count )) ||
24788                 (( $stripe_count == $MDSCOUNT && $default_count == -1 )) ||
24789                 (( $stripe_count == 0 )) || (( $default_count == 1 )) ||
24790                 error "stripe count $default_count != $stripe_count for $dir"
24791
24792                 stripe_index=$($LFS getdirstripe -i $dir)
24793                 [ $default_index -eq -1 ] ||
24794                         [ $stripe_index -eq $default_index ] ||
24795                         error "$stripe_index != $default_index for $dir"
24796
24797                 #check default stripe
24798                 stripe_count=$($LFS getdirstripe -D -c $dir)
24799                 [ $stripe_count -eq $default_count ] ||
24800                 error "default count $default_count != $stripe_count for $dir"
24801
24802                 stripe_index=$($LFS getdirstripe -D -i $dir)
24803                 [ $stripe_index -eq $default_index ] ||
24804                 error "default index $default_index != $stripe_index for $dir"
24805         done
24806         rmdir $DIR/$tdir/$dirname/* || error "rmdir failed"
24807 }
24808
24809 test_300g() {
24810         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24811         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24812                 skip "Need MDS version at least 2.7.55"
24813
24814         local dir
24815         local stripe_count
24816         local stripe_index
24817
24818         mkdir_on_mdt0 $DIR/$tdir
24819         mkdir $DIR/$tdir/normal_dir
24820
24821         #Checking when client cache stripe index
24822         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
24823         $LFS setdirstripe -D -i1 $DIR/$tdir/striped_dir ||
24824                 error "create striped_dir failed"
24825
24826         $LFS setdirstripe -i0 $DIR/$tdir/striped_dir/dir0 ||
24827                 error "create dir0 fails"
24828         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir0)
24829         [ $stripe_index -eq 0 ] ||
24830                 error "dir0 expect index 0 got $stripe_index"
24831
24832         mkdir $DIR/$tdir/striped_dir/dir1 ||
24833                 error "create dir1 fails"
24834         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir1)
24835         [ $stripe_index -eq 1 ] ||
24836                 error "dir1 expect index 1 got $stripe_index"
24837
24838         #check default stripe count/stripe index
24839         test_300_check_default_striped_dir normal_dir $MDSCOUNT 1
24840         test_300_check_default_striped_dir normal_dir 1 0
24841         test_300_check_default_striped_dir normal_dir -1 1
24842         test_300_check_default_striped_dir normal_dir 2 -1
24843
24844         #delete default stripe information
24845         echo "delete default stripeEA"
24846         $LFS setdirstripe -d $DIR/$tdir/normal_dir ||
24847                 error "set default stripe on striped dir error"
24848
24849         mkdir -p $DIR/$tdir/normal_dir/{test1,test2,test3,test4}
24850         for dir in $(find $DIR/$tdir/normal_dir/*); do
24851                 stripe_count=$($LFS getdirstripe -c $dir)
24852                 [ $stripe_count -eq 0 ] ||
24853                         error "expect 1 get $stripe_count for $dir"
24854         done
24855 }
24856 run_test 300g "check default striped directory for normal directory"
24857
24858 test_300h() {
24859         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24860         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24861                 skip "Need MDS version at least 2.7.55"
24862
24863         local dir
24864         local stripe_count
24865
24866         mkdir $DIR/$tdir
24867         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
24868                 error "set striped dir error"
24869
24870         test_300_check_default_striped_dir striped_dir $MDSCOUNT 1
24871         test_300_check_default_striped_dir striped_dir 1 0
24872         test_300_check_default_striped_dir striped_dir -1 1
24873         test_300_check_default_striped_dir striped_dir 2 -1
24874
24875         #delete default stripe information
24876         $LFS setdirstripe -d $DIR/$tdir/striped_dir ||
24877                 error "set default stripe on striped dir error"
24878
24879         mkdir -p $DIR/$tdir/striped_dir/{test1,test2,test3,test4}
24880         for dir in $(find $DIR/$tdir/striped_dir/*); do
24881                 stripe_count=$($LFS getdirstripe -c $dir)
24882                 [ $stripe_count -eq 0 ] ||
24883                         error "expect 1 get $stripe_count for $dir"
24884         done
24885 }
24886 run_test 300h "check default striped directory for striped directory"
24887
24888 test_300i() {
24889         [[ $PARALLEL == "yes" ]] && skip "skip parallel run"
24890         (( $MDSCOUNT >= 2 )) || skip_env "needs >= 2 MDTs"
24891         (( $MDS1_VERSION >= $(version_code 2.7.55) )) ||
24892                 skip "Need MDS version at least 2.7.55"
24893
24894         local stripe_count
24895         local file
24896
24897         mkdir $DIR/$tdir
24898
24899         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
24900                 error "set striped dir error"
24901
24902         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
24903                 error "create files under striped dir failed"
24904
24905         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir ||
24906                 error "set striped hashdir error"
24907
24908         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir/d0 ||
24909                 error "create dir0 under hash dir failed"
24910         $LFS setdirstripe -i0 -c$MDSCOUNT -H fnv_1a_64 $DIR/$tdir/hashdir/d1 ||
24911                 error "create dir1 under hash dir failed"
24912         $LFS setdirstripe -i0 -c$MDSCOUNT -H crush $DIR/$tdir/hashdir/d2 ||
24913                 error "create dir2 under hash dir failed"
24914
24915         # unfortunately, we need to umount to clear dir layout cache for now
24916         # once we fully implement dir layout, we can drop this
24917         umount_client $MOUNT || error "umount failed"
24918         mount_client $MOUNT || error "mount failed"
24919
24920         $LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir
24921         local dircnt=$($LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir | wc -l)
24922         (( $dircnt == 2 )) || error "lfs find striped dir got $dircnt != 2"
24923
24924         if (( $MDS1_VERSION > $(version_code 2.15.0) )); then
24925                 $LFS mkdir -i0 -c$MDSCOUNT -H crush2 $DIR/$tdir/hashdir/d3 ||
24926                         error "create crush2 dir $tdir/hashdir/d3 failed"
24927                 $LFS find -H crush2 $DIR/$tdir/hashdir
24928                 dircnt=$($LFS find -H crush2 $DIR/$tdir/hashdir | wc -l)
24929                 (( $dircnt == 1 )) || error "find crush2 dir got $dircnt != 1"
24930
24931                 # mkdir with an invalid hash type (hash=fail_val) from client
24932                 # should be replaced on MDS with a valid (default) hash type
24933                 #define OBD_FAIL_LMV_UNKNOWN_STRIPE     0x1901
24934                 $LCTL set_param fail_loc=0x1901 fail_val=99
24935                 $LFS mkdir -c2 $DIR/$tdir/hashdir/d99
24936
24937                 local hash=$($LFS getdirstripe -H $DIR/$tdir/hashdir/d99)
24938                 local expect=$(do_facet mds1 \
24939                         $LCTL get_param -n lod.$FSNAME-MDT0000-mdtlov.mdt_hash)
24940                 [[ $hash == $expect ]] ||
24941                         error "d99 hash '$hash' != expected hash '$expect'"
24942         fi
24943
24944         #set the stripe to be unknown hash type on read
24945         #define OBD_FAIL_LMV_UNKNOWN_STRIPE     0x1901
24946         $LCTL set_param fail_loc=0x1901 fail_val=99
24947         for ((i = 0; i < 10; i++)); do
24948                 $CHECKSTAT -t file $DIR/$tdir/striped_dir/f-$i ||
24949                         error "stat f-$i failed"
24950                 rm $DIR/$tdir/striped_dir/f-$i || error "unlink f-$i failed"
24951         done
24952
24953         touch $DIR/$tdir/striped_dir/f0 &&
24954                 error "create under striped dir with unknown hash should fail"
24955
24956         $LCTL set_param fail_loc=0
24957
24958         umount_client $MOUNT || error "umount failed"
24959         mount_client $MOUNT || error "mount failed"
24960
24961         return 0
24962 }
24963 run_test 300i "client handle unknown hash type striped directory"
24964
24965 test_300j() {
24966         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24967         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24968         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24969                 skip "Need MDS version at least 2.7.55"
24970
24971         local stripe_count
24972         local file
24973
24974         mkdir $DIR/$tdir
24975
24976         #define OBD_FAIL_SPLIT_UPDATE_REC       0x1702
24977         $LCTL set_param fail_loc=0x1702
24978         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
24979                 error "set striped dir error"
24980
24981         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
24982                 error "create files under striped dir failed"
24983
24984         $LCTL set_param fail_loc=0
24985
24986         rm -rf $DIR/$tdir || error "unlink striped dir fails"
24987
24988         return 0
24989 }
24990 run_test 300j "test large update record"
24991
24992 test_300k() {
24993         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24994         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24995         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24996                 skip "Need MDS version at least 2.7.55"
24997
24998         # this test needs a huge transaction
24999         local kb
25000         kb=$(do_facet $SINGLEMDS "$LCTL get_param -n \
25001              osd*.$FSNAME-MDT0000.kbytestotal")
25002         [ $kb -lt $((1024*1024)) ] && skip "MDT0 too small: $kb"
25003
25004         local stripe_count
25005         local file
25006
25007         mkdir $DIR/$tdir
25008
25009         #define OBD_FAIL_LARGE_STRIPE   0x1703
25010         $LCTL set_param fail_loc=0x1703
25011         $LFS setdirstripe -i 0 -c192 $DIR/$tdir/striped_dir ||
25012                 error "set striped dir error"
25013         $LCTL set_param fail_loc=0
25014
25015         $LFS getdirstripe $DIR/$tdir/striped_dir ||
25016                 error "getstripeddir fails"
25017         rm -rf $DIR/$tdir/striped_dir ||
25018                 error "unlink striped dir fails"
25019
25020         return 0
25021 }
25022 run_test 300k "test large striped directory"
25023
25024 test_300l() {
25025         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25026         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25027         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25028                 skip "Need MDS version at least 2.7.55"
25029
25030         local stripe_index
25031
25032         test_mkdir -p $DIR/$tdir/striped_dir
25033         chown $RUNAS_ID $DIR/$tdir/striped_dir ||
25034                         error "chown $RUNAS_ID failed"
25035         $LFS setdirstripe -i 1 -D $DIR/$tdir/striped_dir ||
25036                 error "set default striped dir failed"
25037
25038         #define OBD_FAIL_MDS_STALE_DIR_LAYOUT    0x158
25039         $LCTL set_param fail_loc=0x80000158
25040         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir || error "create dir fails"
25041
25042         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/test_dir)
25043         [ $stripe_index -eq 1 ] ||
25044                 error "expect 1 get $stripe_index for $dir"
25045 }
25046 run_test 300l "non-root user to create dir under striped dir with stale layout"
25047
25048 test_300m() {
25049         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25050         [ $MDSCOUNT -ge 2 ] && skip_env "Only for single MDT"
25051         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25052                 skip "Need MDS version at least 2.7.55"
25053
25054         mkdir -p $DIR/$tdir/striped_dir
25055         $LFS setdirstripe -D -c 1 $DIR/$tdir/striped_dir ||
25056                 error "set default stripes dir error"
25057
25058         mkdir $DIR/$tdir/striped_dir/a || error "mkdir a fails"
25059
25060         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/a)
25061         [ $stripe_count -eq 0 ] ||
25062                         error "expect 0 get $stripe_count for a"
25063
25064         $LFS setdirstripe -D -c 2 $DIR/$tdir/striped_dir ||
25065                 error "set default stripes dir error"
25066
25067         mkdir $DIR/$tdir/striped_dir/b || error "mkdir b fails"
25068
25069         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/b)
25070         [ $stripe_count -eq 0 ] ||
25071                         error "expect 0 get $stripe_count for b"
25072
25073         $LFS setdirstripe -D -c1 -i2 $DIR/$tdir/striped_dir ||
25074                 error "set default stripes dir error"
25075
25076         mkdir $DIR/$tdir/striped_dir/c &&
25077                 error "default stripe_index is invalid, mkdir c should fails"
25078
25079         rm -rf $DIR/$tdir || error "rmdir fails"
25080 }
25081 run_test 300m "setstriped directory on single MDT FS"
25082
25083 cleanup_300n() {
25084         local list=$(comma_list $(mdts_nodes))
25085
25086         trap 0
25087         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
25088 }
25089
25090 test_300n() {
25091         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25092         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25093         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25094                 skip "Need MDS version at least 2.7.55"
25095         remote_mds_nodsh && skip "remote MDS with nodsh"
25096
25097         local stripe_index
25098         local list=$(comma_list $(mdts_nodes))
25099
25100         trap cleanup_300n RETURN EXIT
25101         mkdir -p $DIR/$tdir
25102         chmod 777 $DIR/$tdir
25103         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT \
25104                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
25105                 error "create striped dir succeeds with gid=0"
25106
25107         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
25108         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
25109                 error "create striped dir fails with gid=-1"
25110
25111         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
25112         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D \
25113                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
25114                 error "set default striped dir succeeds with gid=0"
25115
25116
25117         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
25118         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D $DIR/$tdir/striped_dir ||
25119                 error "set default striped dir fails with gid=-1"
25120
25121
25122         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
25123         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir ||
25124                                         error "create test_dir fails"
25125         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir1 ||
25126                                         error "create test_dir1 fails"
25127         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir2 ||
25128                                         error "create test_dir2 fails"
25129         cleanup_300n
25130 }
25131 run_test 300n "non-root user to create dir under striped dir with default EA"
25132
25133 test_300o() {
25134         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25135         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25136         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25137                 skip "Need MDS version at least 2.7.55"
25138
25139         local numfree1
25140         local numfree2
25141
25142         mkdir -p $DIR/$tdir
25143
25144         numfree1=$(lctl get_param -n mdc.*MDT0000*.filesfree)
25145         numfree2=$(lctl get_param -n mdc.*MDT0001*.filesfree)
25146         if [ $numfree1 -lt 66000 ] || [ $numfree2 -lt 66000 ]; then
25147                 skip "not enough free inodes $numfree1 $numfree2"
25148         fi
25149
25150         numfree1=$(lctl get_param -n mdc.*MDT0000-mdc-*.kbytesfree)
25151         numfree2=$(lctl get_param -n mdc.*MDT0001-mdc-*.kbytesfree)
25152         if [ $numfree1 -lt 300000 ] || [ $numfree2 -lt 300000 ]; then
25153                 skip "not enough free space $numfree1 $numfree2"
25154         fi
25155
25156         $LFS setdirstripe -c2 $DIR/$tdir/striped_dir ||
25157                 error "setdirstripe fails"
25158
25159         createmany -d $DIR/$tdir/striped_dir/d 131000 ||
25160                 error "create dirs fails"
25161
25162         $LCTL set_param ldlm.namespaces.*mdc-*.lru_size=0
25163         ls $DIR/$tdir/striped_dir > /dev/null ||
25164                 error "ls striped dir fails"
25165         unlinkmany -d $DIR/$tdir/striped_dir/d 131000 ||
25166                 error "unlink big striped dir fails"
25167 }
25168 run_test 300o "unlink big sub stripe(> 65000 subdirs)"
25169
25170 test_300p() {
25171         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25172         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25173         remote_mds_nodsh && skip "remote MDS with nodsh"
25174
25175         mkdir_on_mdt0 $DIR/$tdir
25176
25177         #define OBD_FAIL_OUT_ENOSPC     0x1704
25178         do_facet mds2 lctl set_param fail_loc=0x80001704
25179         $LFS setdirstripe -i 0 -c2 $DIR/$tdir/bad_striped_dir > /dev/null 2>&1 \
25180                  && error "create striped directory should fail"
25181
25182         [ -e $DIR/$tdir/bad_striped_dir ] && error "striped dir exists"
25183
25184         $LFS setdirstripe -c2 $DIR/$tdir/bad_striped_dir
25185         true
25186 }
25187 run_test 300p "create striped directory without space"
25188
25189 test_300q() {
25190         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25191         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25192
25193         local fd=$(free_fd)
25194         local cmd="exec $fd<$tdir"
25195         cd $DIR
25196         $LFS mkdir -c $MDSCOUNT $tdir || error "create $tdir fails"
25197         eval $cmd
25198         cmd="exec $fd<&-"
25199         trap "eval $cmd" EXIT
25200         cd $tdir || error "cd $tdir fails"
25201         rmdir  ../$tdir || error "rmdir $tdir fails"
25202         mkdir local_dir && error "create dir succeeds"
25203         $LFS setdirstripe -i1 remote_dir && error "create remote dir succeeds"
25204         eval $cmd
25205         return 0
25206 }
25207 run_test 300q "create remote directory under orphan directory"
25208
25209 test_300r() {
25210         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25211                 skip "Need MDS version at least 2.7.55" && return
25212         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
25213
25214         mkdir $DIR/$tdir
25215
25216         $LFS setdirstripe -i 0 -c -1 $DIR/$tdir/striped_dir ||
25217                 error "set striped dir error"
25218
25219         $LFS getdirstripe $DIR/$tdir/striped_dir ||
25220                 error "getstripeddir fails"
25221
25222         local stripe_count
25223         stripe_count=$($LFS getdirstripe $DIR/$tdir/striped_dir |
25224                       awk '/lmv_stripe_count:/ { print $2 }')
25225
25226         [ $MDSCOUNT -ne $stripe_count ] &&
25227                 error "wrong stripe count $stripe_count expected $MDSCOUNT"
25228
25229         rm -rf $DIR/$tdir/striped_dir ||
25230                 error "unlink striped dir fails"
25231 }
25232 run_test 300r "test -1 striped directory"
25233
25234 test_300s_helper() {
25235         local count=$1
25236
25237         local stripe_dir=$DIR/$tdir/striped_dir.$count
25238
25239         $LFS mkdir -c $count $stripe_dir ||
25240                 error "lfs mkdir -c error"
25241
25242         $LFS getdirstripe $stripe_dir ||
25243                 error "lfs getdirstripe fails"
25244
25245         local stripe_count
25246         stripe_count=$($LFS getdirstripe $stripe_dir |
25247                       awk '/lmv_stripe_count:/ { print $2 }')
25248
25249         [ $count -ne $stripe_count ] &&
25250                 error_noexit "bad stripe count $stripe_count expected $count"
25251
25252         local dupe_stripes
25253         dupe_stripes=$($LFS getdirstripe $stripe_dir |
25254                 awk '/0x/ {count[$1] += 1}; END {
25255                         for (idx in count) {
25256                                 if (count[idx]>1) {
25257                                         print "index " idx " count " count[idx]
25258                                 }
25259                         }
25260                 }')
25261
25262         if [[ -n "$dupe_stripes" ]] ; then
25263                 lfs getdirstripe $stripe_dir
25264                 error_noexit "Dupe MDT above: $dupe_stripes "
25265         fi
25266
25267         rm -rf $stripe_dir ||
25268                 error_noexit "unlink $stripe_dir fails"
25269 }
25270
25271 test_300s() {
25272         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25273                 skip "Need MDS version at least 2.7.55" && return
25274         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
25275
25276         mkdir $DIR/$tdir
25277         for count in $(seq 2 $MDSCOUNT); do
25278                 test_300s_helper $count
25279         done
25280 }
25281 run_test 300s "test lfs mkdir -c without -i"
25282
25283 test_300t() {
25284         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
25285                 skip "need MDS 2.14.55 or later"
25286         (( $MDSCOUNT >= 2 )) || skip "needs at least 2 MDTs"
25287
25288         local testdir="$DIR/$tdir/striped_dir"
25289         local dir1=$testdir/dir1
25290         local dir2=$testdir/dir2
25291
25292         mkdir -p $testdir
25293
25294         $LFS setdirstripe -D -c -1 --max-inherit=3 $testdir ||
25295                 error "failed to set default stripe count for $testdir"
25296
25297         mkdir $dir1
25298         local stripe_count=$($LFS getdirstripe -c $dir1)
25299
25300         (( $stripe_count == $MDSCOUNT )) || error "wrong stripe count"
25301
25302         local max_count=$((MDSCOUNT - 1))
25303         local mdts=$(comma_list $(mdts_nodes))
25304
25305         do_nodes $mdts $LCTL set_param lod.*.max_mdt_stripecount=$max_count
25306         stack_trap "do_nodes $mdts $LCTL set_param lod.*.max_mdt_stripecount=0"
25307
25308         mkdir $dir2
25309         stripe_count=$($LFS getdirstripe -c $dir2)
25310
25311         (( $stripe_count == $max_count )) || error "wrong stripe count"
25312 }
25313 run_test 300t "test max_mdt_stripecount"
25314
25315 prepare_remote_file() {
25316         mkdir $DIR/$tdir/src_dir ||
25317                 error "create remote source failed"
25318
25319         cp /etc/hosts $DIR/$tdir/src_dir/a ||
25320                  error "cp to remote source failed"
25321         touch $DIR/$tdir/src_dir/a
25322
25323         $LFS mkdir -i 1 $DIR/$tdir/tgt_dir ||
25324                 error "create remote target dir failed"
25325
25326         touch $DIR/$tdir/tgt_dir/b
25327
25328         mrename $DIR/$tdir/src_dir/a $DIR/$tdir/tgt_dir/b ||
25329                 error "rename dir cross MDT failed!"
25330
25331         $CHECKSTAT -t file $DIR/$tdir/src_dir/a &&
25332                 error "src_child still exists after rename"
25333
25334         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/b ||
25335                 error "missing file(a) after rename"
25336
25337         diff /etc/hosts $DIR/$tdir/tgt_dir/b ||
25338                 error "diff after rename"
25339 }
25340
25341 test_310a() {
25342         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
25343         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25344
25345         local remote_file=$DIR/$tdir/tgt_dir/b
25346
25347         mkdir -p $DIR/$tdir
25348
25349         prepare_remote_file || error "prepare remote file failed"
25350
25351         #open-unlink file
25352         $OPENUNLINK $remote_file $remote_file ||
25353                 error "openunlink $remote_file failed"
25354         $CHECKSTAT -a $remote_file || error "$remote_file exists"
25355 }
25356 run_test 310a "open unlink remote file"
25357
25358 test_310b() {
25359         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
25360         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25361
25362         local remote_file=$DIR/$tdir/tgt_dir/b
25363
25364         mkdir -p $DIR/$tdir
25365
25366         prepare_remote_file || error "prepare remote file failed"
25367
25368         ln $remote_file $DIR/$tfile || error "link failed for remote file"
25369         $MULTIOP $DIR/$tfile Ouc || error "mulitop failed"
25370         $CHECKSTAT -t file $remote_file || error "check file failed"
25371 }
25372 run_test 310b "unlink remote file with multiple links while open"
25373
25374 test_310c() {
25375         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25376         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
25377
25378         local remote_file=$DIR/$tdir/tgt_dir/b
25379
25380         mkdir -p $DIR/$tdir
25381
25382         prepare_remote_file || error "prepare remote file failed"
25383
25384         ln $remote_file $DIR/$tfile || error "link failed for remote file"
25385         multiop_bg_pause $remote_file O_uc ||
25386                         error "mulitop failed for remote file"
25387         MULTIPID=$!
25388         $MULTIOP $DIR/$tfile Ouc
25389         kill -USR1 $MULTIPID
25390         wait $MULTIPID
25391 }
25392 run_test 310c "open-unlink remote file with multiple links"
25393
25394 #LU-4825
25395 test_311() {
25396         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25397         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
25398         [ $MDS1_VERSION -lt $(version_code 2.8.54) ] &&
25399                 skip "lustre < 2.8.54 does not contain LU-4825 fix"
25400         remote_mds_nodsh && skip "remote MDS with nodsh"
25401
25402         local old_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
25403         local mdts=$(comma_list $(mdts_nodes))
25404
25405         mkdir -p $DIR/$tdir
25406         $LFS setstripe -i 0 -c 1 $DIR/$tdir
25407         createmany -o $DIR/$tdir/$tfile. 1000
25408
25409         # statfs data is not real time, let's just calculate it
25410         old_iused=$((old_iused + 1000))
25411
25412         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
25413                         osp.*OST0000*MDT0000.create_count")
25414         local max_count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
25415                                 osp.*OST0000*MDT0000.max_create_count")
25416         do_nodes $mdts "$LCTL set_param -n osp.*OST0000*.max_create_count=0"
25417
25418         $LFS setstripe -i 0 $DIR/$tdir/$tfile || error "setstripe failed"
25419         local index=$($LFS getstripe -i $DIR/$tdir/$tfile)
25420         [ $index -ne 0 ] || error "$tfile stripe index is 0"
25421
25422         unlinkmany $DIR/$tdir/$tfile. 1000
25423
25424         do_nodes $mdts "$LCTL set_param -n \
25425                         osp.*OST0000*.max_create_count=$max_count"
25426         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
25427                 do_nodes $mdts "$LCTL set_param -n \
25428                                 osp.*OST0000*.create_count=$count"
25429         do_nodes $mdts "$LCTL get_param osp.*OST0000*.create_count" |
25430                         grep "=0" && error "create_count is zero"
25431
25432         local new_iused
25433         for i in $(seq 120); do
25434                 new_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
25435                 # system may be too busy to destroy all objs in time, use
25436                 # a somewhat small value to not fail autotest
25437                 [ $((old_iused - new_iused)) -gt 400 ] && break
25438                 sleep 1
25439         done
25440
25441         echo "waited $i sec, old Iused $old_iused, new Iused $new_iused"
25442         [ $((old_iused - new_iused)) -gt 400 ] ||
25443                 error "objs not destroyed after unlink"
25444 }
25445 run_test 311 "disable OSP precreate, and unlink should destroy objs"
25446
25447 zfs_get_objid()
25448 {
25449         local ost=$1
25450         local tf=$2
25451         local fid=($($LFS getstripe $tf | grep 0x))
25452         local seq=${fid[3]#0x}
25453         local objid=${fid[1]}
25454
25455         local vdevdir=$(dirname $(facet_vdevice $ost))
25456         local cmd="$ZDB -e -p $vdevdir -ddddd $(facet_device $ost)"
25457         local zfs_zapid=$(do_facet $ost $cmd |
25458                           grep -w "/O/$seq/d$((objid%32))" -C 5 |
25459                           awk '/Object/{getline; print $1}')
25460         local zfs_objid=$(do_facet $ost $cmd $zfs_zapid |
25461                           awk "/$objid = /"'{printf $3}')
25462
25463         echo $zfs_objid
25464 }
25465
25466 zfs_object_blksz() {
25467         local ost=$1
25468         local objid=$2
25469
25470         local vdevdir=$(dirname $(facet_vdevice $ost))
25471         local cmd="$ZDB -e -p $vdevdir -dddd $(facet_device $ost)"
25472         local blksz=$(do_facet $ost $cmd $objid |
25473                       awk '/dblk/{getline; printf $4}')
25474
25475         case "${blksz: -1}" in
25476                 k|K) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024)) ;;
25477                 m|M) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024*1024)) ;;
25478                 *) ;;
25479         esac
25480
25481         echo $blksz
25482 }
25483
25484 test_312() { # LU-4856
25485         remote_ost_nodsh && skip "remote OST with nodsh"
25486         [[ "$ost1_FSTYPE" == "zfs" ]] || skip "the test only applies to zfs"
25487
25488         local max_blksz=$(do_facet ost1 \
25489                           $ZFS get -p recordsize $(facet_device ost1) |
25490                           awk '!/VALUE/{print $3}')
25491         local tf=$DIR/$tfile
25492
25493         $LFS setstripe -c1 $tf
25494         local facet="ost$(($($LFS getstripe -i $tf) + 1))"
25495
25496         # Get ZFS object id
25497         local zfs_objid=$(zfs_get_objid $facet $tf)
25498         # block size change by sequential overwrite
25499         local bs
25500
25501         for ((bs=$PAGE_SIZE; bs <= max_blksz; bs *= 4)) ; do
25502                 dd if=/dev/zero of=$tf bs=$bs count=1 oflag=sync conv=notrunc
25503
25504                 local blksz=$(zfs_object_blksz $facet $zfs_objid)
25505                 [[ $blksz -eq $bs ]] || error "blksz error: $blksz, expected: $bs"
25506         done
25507         rm -f $tf
25508
25509         $LFS setstripe -c1 $tf
25510         facet="ost$(($($LFS getstripe -i $tf) + 1))"
25511
25512         # block size change by sequential append write
25513         dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=1 oflag=sync conv=notrunc
25514         zfs_objid=$(zfs_get_objid $facet $tf)
25515         local count
25516
25517         for ((count = 1; count < $((max_blksz / PAGE_SIZE)); count *= 2)); do
25518                 dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=$count seek=$count \
25519                         oflag=sync conv=notrunc
25520
25521                 blksz=$(zfs_object_blksz $facet $zfs_objid)
25522                 (( $blksz == 2 * count * PAGE_SIZE )) ||
25523                         error "blksz error, actual $blksz, " \
25524                                 "expected: 2 * $count * $PAGE_SIZE"
25525         done
25526         rm -f $tf
25527
25528         # random write
25529         $LFS setstripe -c1 $tf
25530         facet="ost$(($($LFS getstripe -i $tf) + 1))"
25531         zfs_objid=$(zfs_get_objid $facet $tf)
25532
25533         dd if=/dev/zero of=$tf bs=1K count=1 oflag=sync conv=notrunc
25534         blksz=$(zfs_object_blksz $facet $zfs_objid)
25535         (( blksz == PAGE_SIZE )) ||
25536                 error "blksz error: $blksz, expected: $PAGE_SIZE"
25537
25538         dd if=/dev/zero of=$tf bs=64K count=1 oflag=sync conv=notrunc seek=128
25539         blksz=$(zfs_object_blksz $facet $zfs_objid)
25540         (( blksz == 65536 )) || error "blksz error: $blksz, expected: 64k"
25541
25542         dd if=/dev/zero of=$tf bs=1M count=1 oflag=sync conv=notrunc
25543         blksz=$(zfs_object_blksz $facet $zfs_objid)
25544         (( blksz == 65536 )) || error "rewrite error: $blksz, expected: 64k"
25545 }
25546 run_test 312 "make sure ZFS adjusts its block size by write pattern"
25547
25548 test_313() {
25549         remote_ost_nodsh && skip "remote OST with nodsh"
25550
25551         local file=$DIR/$tfile
25552
25553         rm -f $file
25554         $LFS setstripe -c 1 -i 0 $file || error "setstripe failed"
25555
25556         # define OBD_FAIL_TGT_RCVD_EIO           0x720
25557         do_facet ost1 "$LCTL set_param fail_loc=0x720"
25558         dd if=/dev/zero of=$file bs=$PAGE_SIZE oflag=direct count=1 &&
25559                 error "write should failed"
25560         do_facet ost1 "$LCTL set_param fail_loc=0"
25561         rm -f $file
25562 }
25563 run_test 313 "io should fail after last_rcvd update fail"
25564
25565 test_314() {
25566         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
25567
25568         $LFS setstripe -c 2 -i 0 $DIR/$tfile || error "setstripe failed"
25569         do_facet ost1 "$LCTL set_param fail_loc=0x720"
25570         rm -f $DIR/$tfile
25571         wait_delete_completed
25572         do_facet ost1 "$LCTL set_param fail_loc=0"
25573 }
25574 run_test 314 "OSP shouldn't fail after last_rcvd update failure"
25575
25576 test_315() { # LU-618
25577         [ -f /proc/$$/io ] || skip_env "no IO accounting in kernel"
25578
25579         local file=$DIR/$tfile
25580         rm -f $file
25581
25582         $MULTIOP $file oO_CREAT:O_DIRECT:O_RDWR:w4063232c ||
25583                 error "multiop file write failed"
25584         $MULTIOP $file oO_RDONLY:r4063232_c &
25585         PID=$!
25586
25587         sleep 2
25588
25589         local rbytes=$(awk '/read_bytes/ { print $2 }' /proc/$PID/io)
25590         kill -USR1 $PID
25591
25592         [ $rbytes -gt 4000000 ] || error "read is not accounted ($rbytes)"
25593         rm -f $file
25594 }
25595 run_test 315 "read should be accounted"
25596
25597 test_316() {
25598         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
25599         large_xattr_enabled || skip "ea_inode feature disabled"
25600
25601         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
25602         mkdir $DIR/$tdir/d || error "mkdir $tdir/d failed"
25603         chown nobody $DIR/$tdir/d || error "chown $tdir/d failed"
25604         touch $DIR/$tdir/d/$tfile || error "touch $tdir/d/$tfile failed"
25605
25606         $LFS migrate -m1 $DIR/$tdir/d || error "lfs migrate -m1 failed"
25607 }
25608 run_test 316 "lfs migrate of file with large_xattr enabled"
25609
25610 test_317() {
25611         [ $MDS1_VERSION -lt $(version_code 2.11.53) ] &&
25612                 skip "Need MDS version at least 2.11.53"
25613         if [ "$ost1_FSTYPE" == "zfs" ]; then
25614                 skip "LU-10370: no implementation for ZFS"
25615         fi
25616
25617         local trunc_sz
25618         local grant_blk_size
25619
25620         grant_blk_size=$($LCTL get_param osc.$FSNAME*.import |
25621                         awk '/grant_block_size:/ { print $2; exit; }')
25622         #
25623         # Create File of size 5M. Truncate it to below size's and verify
25624         # blocks count.
25625         #
25626         dd if=/dev/zero of=$DIR/$tfile bs=5M count=1 conv=fsync ||
25627                 error "Create file $DIR/$tfile failed"
25628         stack_trap "rm -f $DIR/$tfile" EXIT
25629
25630         for trunc_sz in 2097152 4097 4000 509 0; do
25631                 $TRUNCATE $DIR/$tfile $trunc_sz ||
25632                         error "truncate $tfile to $trunc_sz failed"
25633                 local sz=$(stat --format=%s $DIR/$tfile)
25634                 local blk=$(stat --format=%b $DIR/$tfile)
25635                 local trunc_blk=$((((trunc_sz + (grant_blk_size - 1) ) /
25636                                      grant_blk_size) * 8))
25637
25638                 if [[ $blk -ne $trunc_blk ]]; then
25639                         $(which stat) $DIR/$tfile
25640                         error "Expected Block $trunc_blk got $blk for $tfile"
25641                 fi
25642
25643                 $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
25644                         error "Expected Size $trunc_sz got $sz for $tfile"
25645         done
25646
25647         #
25648         # sparse file test
25649         # Create file with a hole and write actual 65536 bytes which aligned
25650         # with 4K and 64K PAGE_SIZE. Block count must be 128.
25651         #
25652         local bs=65536
25653         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 seek=5 conv=fsync ||
25654                 error "Create file : $DIR/$tfile"
25655
25656         #
25657         # Truncate to size $trunc_sz bytes. Strip tail blocks and leave only 8
25658         # blocks. The block count must drop to 8.
25659         #
25660         trunc_sz=$(($(stat --format=%s $DIR/$tfile) -
25661                 ((bs - grant_blk_size) + 1)))
25662         $TRUNCATE $DIR/$tfile $trunc_sz ||
25663                 error "truncate $tfile to $trunc_sz failed"
25664
25665         local trunc_bsz=$((grant_blk_size / $(stat --format=%B $DIR/$tfile)))
25666         sz=$(stat --format=%s $DIR/$tfile)
25667         blk=$(stat --format=%b $DIR/$tfile)
25668
25669         if [[ $blk -ne $trunc_bsz ]]; then
25670                 $(which stat) $DIR/$tfile
25671                 error "Expected Block $trunc_bsz got $blk for $tfile"
25672         fi
25673
25674         $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
25675                 error "Expected Size $trunc_sz got $sz for $tfile"
25676 }
25677 run_test 317 "Verify blocks get correctly update after truncate"
25678
25679 test_318() {
25680         local llite_name="llite.$($LFS getname $MOUNT | awk '{print $1}')"
25681         local old_max_active=$($LCTL get_param -n \
25682                             ${llite_name}.max_read_ahead_async_active \
25683                             2>/dev/null)
25684
25685         $LCTL set_param llite.*.max_read_ahead_async_active=256
25686         local max_active=$($LCTL get_param -n \
25687                            ${llite_name}.max_read_ahead_async_active \
25688                            2>/dev/null)
25689         [ $max_active -ne 256 ] && error "expected 256 but got $max_active"
25690
25691         $LCTL set_param llite.*.max_read_ahead_async_active=0 ||
25692                 error "set max_read_ahead_async_active should succeed"
25693
25694         $LCTL set_param llite.*.max_read_ahead_async_active=512
25695         max_active=$($LCTL get_param -n \
25696                      ${llite_name}.max_read_ahead_async_active 2>/dev/null)
25697         [ $max_active -eq 512 ] || error "expected 512 but got $max_active"
25698
25699         # restore @max_active
25700         [ $old_max_active -ne 0 ] && $LCTL set_param \
25701                 llite.*.max_read_ahead_async_active=$old_max_active
25702
25703         local old_threshold=$($LCTL get_param -n \
25704                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
25705         local max_per_file_mb=$($LCTL get_param -n \
25706                 ${llite_name}.max_read_ahead_per_file_mb 2>/dev/null)
25707
25708         local invalid=$(($max_per_file_mb + 1))
25709         $LCTL set_param \
25710                 llite.*.read_ahead_async_file_threshold_mb=$invalid\
25711                         && error "set $invalid should fail"
25712
25713         local valid=$(($invalid - 1))
25714         $LCTL set_param \
25715                 llite.*.read_ahead_async_file_threshold_mb=$valid ||
25716                         error "set $valid should succeed"
25717         local threshold=$($LCTL get_param -n \
25718                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
25719         [ $threshold -eq $valid ] || error \
25720                 "expect threshold $valid got $threshold"
25721         $LCTL set_param \
25722                 llite.*.read_ahead_async_file_threshold_mb=$old_threshold
25723 }
25724 run_test 318 "Verify async readahead tunables"
25725
25726 test_319() {
25727         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
25728
25729         local before=$(date +%s)
25730         local evict
25731         local mdir=$DIR/$tdir
25732         local file=$mdir/xxx
25733
25734         $LFS mkdir -i0 $mdir || error "mkdir $mdir fails"
25735         touch $file
25736
25737 #define OBD_FAIL_LDLM_LOCAL_CANCEL_PAUSE 0x32c
25738         $LCTL set_param fail_val=5 fail_loc=0x8000032c
25739         $LFS migrate -m1 $mdir &
25740
25741         sleep 1
25742         dd if=$file of=/dev/null
25743         wait
25744         evict=$($LCTL get_param mdc.$FSNAME-MDT*.state |
25745           awk -F"[ [,]" '/EVICTED ]$/ { if (mx<$5) {mx=$5;} } END { print mx }')
25746
25747         [ -z "$evict" ] || [[ $evict -le $before ]] || error "eviction happened"
25748 }
25749 run_test 319 "lost lease lock on migrate error"
25750
25751 test_398a() { # LU-4198
25752         local ost1_imp=$(get_osc_import_name client ost1)
25753         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
25754                          cut -d'.' -f2)
25755
25756         $LFS setstripe -c 1 -i 0 $DIR/$tfile
25757         stack_trap "rm -f $DIR/$tfile"
25758         $LCTL set_param ldlm.namespaces.*.lru_size=clear
25759
25760         # request a new lock on client
25761         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
25762
25763         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
25764         local lock_count=$($LCTL get_param -n \
25765                            ldlm.namespaces.$imp_name.lru_size)
25766         [[ $lock_count -eq 0 ]] || error "lock should be cancelled by direct IO"
25767
25768         $LCTL set_param ldlm.namespaces.*-OST0000-osc-ffff*.lru_size=clear
25769
25770         # no lock cached, should use lockless DIO and not enqueue new lock
25771         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
25772         lock_count=$($LCTL get_param -n \
25773                      ldlm.namespaces.$imp_name.lru_size)
25774         [[ $lock_count -eq 0 ]] || error "no lock should be held by direct IO"
25775
25776         $LCTL set_param ldlm.namespaces.*-OST0000-osc-ffff*.lru_size=clear
25777
25778         # no lock cached, should use locked DIO append
25779         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct oflag=append \
25780                 conv=notrunc || error "DIO append failed"
25781         lock_count=$($LCTL get_param -n \
25782                      ldlm.namespaces.*-OST0000-osc-ffff*.lru_size)
25783         [[ $lock_count -ne 0 ]] || error "lock still must be held by DIO append"
25784 }
25785 run_test 398a "direct IO should cancel lock otherwise lockless"
25786
25787 test_398b() { # LU-4198
25788         local before=$(date +%s)
25789         local njobs=4
25790         local size=48
25791
25792         which fio || skip_env "no fio installed"
25793         $LFS setstripe -c -1 -S 1M $DIR/$tfile
25794         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size
25795
25796         # Single page, multiple pages, stripe size, 4*stripe size
25797         for bsize in $(( $PAGE_SIZE )) $(( 4*$PAGE_SIZE )) 1048576 4194304; do
25798                 echo "mix direct rw ${bsize} by fio with $njobs jobs..."
25799                 fio --name=rand-rw --rw=randrw --bs=$bsize --direct=1 \
25800                         --numjobs=$njobs --fallocate=none \
25801                         --iodepth=16 --allow_file_create=0 \
25802                         --size=$((size/njobs))M \
25803                         --filename=$DIR/$tfile &
25804                 bg_pid=$!
25805
25806                 echo "mix buffer rw ${bsize} by fio with $njobs jobs..."
25807                 fio --name=rand-rw --rw=randrw --bs=$bsize \
25808                         --numjobs=$njobs --fallocate=none \
25809                         --iodepth=16 --allow_file_create=0 \
25810                         --size=$((size/njobs))M \
25811                         --filename=$DIR/$tfile || true
25812                 wait $bg_pid
25813         done
25814
25815         evict=$(do_facet client $LCTL get_param \
25816                 osc.$FSNAME-OST*-osc-*/state |
25817             awk -F"[ [,]" '/EVICTED ]$/ { if (t<$5) {t=$5;} } END { print t }')
25818
25819         [ -z "$evict" ] || [[ $evict -le $before ]] ||
25820                 (do_facet client $LCTL get_param \
25821                         osc.$FSNAME-OST*-osc-*/state;
25822                     error "eviction happened: $evict before:$before")
25823
25824         rm -f $DIR/$tfile
25825 }
25826 run_test 398b "DIO and buffer IO race"
25827
25828 test_398c() { # LU-4198
25829         local ost1_imp=$(get_osc_import_name client ost1)
25830         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
25831                          cut -d'.' -f2)
25832
25833         which fio || skip_env "no fio installed"
25834
25835         saved_debug=$($LCTL get_param -n debug)
25836         $LCTL set_param debug=0
25837
25838         local size=$(lctl get_param -n osc.$FSNAME-OST0000*.kbytesavail | head -1)
25839         ((size /= 1024)) # by megabytes
25840         ((size /= 2)) # write half of the OST at most
25841         [ $size -gt 40 ] && size=40 #reduce test time anyway
25842
25843         $LFS setstripe -c 1 $DIR/$tfile
25844
25845         # it seems like ldiskfs reserves more space than necessary if the
25846         # writing blocks are not mapped, so it extends the file firstly
25847         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size && sync
25848         cancel_lru_locks osc
25849
25850         # clear and verify rpc_stats later
25851         $LCTL set_param osc.${FSNAME}-OST0000-osc-ffff*.rpc_stats=clear
25852
25853         local njobs=4
25854         echo "writing ${size}M to OST0 by fio with $njobs jobs..."
25855         fio --name=rand-write --rw=randwrite --bs=$PAGE_SIZE --direct=1 \
25856                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
25857                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
25858                 --filename=$DIR/$tfile
25859         [ $? -eq 0 ] || error "fio write error"
25860
25861         [ $($LCTL get_param -n ldlm.namespaces.$imp_name.lock_count) -eq 0 ] ||
25862                 error "Locks were requested while doing AIO"
25863
25864         # get the percentage of 1-page I/O
25865         pct=$($LCTL get_param osc.${imp_name}.rpc_stats |
25866                 grep -A 1 'pages per rpc' | grep -v 'pages per rpc' |
25867                 awk '{print $7}')
25868         [ $pct -le 50 ] || error "$pct% of I/O are 1-page"
25869
25870         echo "mix rw ${size}M to OST0 by fio with $njobs jobs..."
25871         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
25872                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
25873                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
25874                 --filename=$DIR/$tfile
25875         [ $? -eq 0 ] || error "fio mixed read write error"
25876
25877         echo "AIO with large block size ${size}M"
25878         fio --name=rand-rw --rw=randrw --bs=${size}M --direct=1 \
25879                 --numjobs=1 --fallocate=none --ioengine=libaio \
25880                 --iodepth=16 --allow_file_create=0 --size=${size}M \
25881                 --filename=$DIR/$tfile
25882         [ $? -eq 0 ] || error "fio large block size failed"
25883
25884         rm -f $DIR/$tfile
25885         $LCTL set_param debug="$saved_debug"
25886 }
25887 run_test 398c "run fio to test AIO"
25888
25889 test_398d() { #  LU-13846
25890         which aiocp || skip_env "no aiocp installed"
25891         local aio_file=$DIR/$tfile.aio
25892
25893         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
25894
25895         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=64
25896         aiocp -a $PAGE_SIZE -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file
25897         stack_trap "rm -f $DIR/$tfile $aio_file"
25898
25899         diff $DIR/$tfile $aio_file || error "file diff after aiocp"
25900
25901         # make sure we don't crash and fail properly
25902         aiocp -a 512 -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
25903                 error "aio not aligned with PAGE SIZE should fail"
25904
25905         rm -f $DIR/$tfile $aio_file
25906 }
25907 run_test 398d "run aiocp to verify block size > stripe size"
25908
25909 test_398e() {
25910         dd if=/dev/zero of=$DIR/$tfile bs=1234 count=1
25911         touch $DIR/$tfile.new
25912         dd if=$DIR/$tfile of=$DIR/$tfile.new bs=1M count=1 oflag=direct
25913 }
25914 run_test 398e "O_Direct open cleared by fcntl doesn't cause hang"
25915
25916 test_398f() { #  LU-14687
25917         which aiocp || skip_env "no aiocp installed"
25918         local aio_file=$DIR/$tfile.aio
25919
25920         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
25921
25922         dd if=/dev/zero of=$DIR/$tfile bs=1M count=64
25923         stack_trap "rm -f $DIR/$tfile $aio_file"
25924
25925         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
25926         $LCTL set_param fail_loc=0x1418
25927         # make sure we don't crash and fail properly
25928         aiocp -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
25929                 error "aio with page allocation failure succeeded"
25930         $LCTL set_param fail_loc=0
25931         diff $DIR/$tfile $aio_file
25932         [[ $? != 0 ]] || error "no diff after failed aiocp"
25933 }
25934 run_test 398f "verify aio handles ll_direct_rw_pages errors correctly"
25935
25936 # NB: To get the parallel DIO behavior in LU-13798, there must be > 1
25937 # stripe and i/o size must be > stripe size
25938 # Old style synchronous DIO waits after submitting each chunk, resulting in a
25939 # single RPC in flight.  This test shows async DIO submission is working by
25940 # showing multiple RPCs in flight.
25941 test_398g() { #  LU-13798
25942         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
25943
25944         # We need to do some i/o first to acquire enough grant to put our RPCs
25945         # in flight; otherwise a new connection may not have enough grant
25946         # available
25947         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
25948                 error "parallel dio failed"
25949         stack_trap "rm -f $DIR/$tfile"
25950
25951         # Reduce RPC size to 1M to avoid combination in to larger RPCs
25952         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
25953         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
25954         stack_trap "$LCTL set_param -n $pages_per_rpc"
25955
25956         # Recreate file so it's empty
25957         rm -f $DIR/$tfile
25958         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
25959         #Pause rpc completion to guarantee we see multiple rpcs in flight
25960         #define OBD_FAIL_OST_BRW_PAUSE_BULK
25961         do_facet ost1 $LCTL set_param fail_loc=0x214 fail_val=2
25962         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
25963
25964         # Clear rpc stats
25965         $LCTL set_param osc.*.rpc_stats=c
25966
25967         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
25968                 error "parallel dio failed"
25969         stack_trap "rm -f $DIR/$tfile"
25970
25971         $LCTL get_param osc.*-OST0000-*.rpc_stats
25972         pct=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
25973                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
25974                 grep "8:" | awk '{print $8}')
25975         # We look at the "8 rpcs in flight" field, and verify A) it is present
25976         # and B) it includes all RPCs.  This proves we had 8 RPCs in flight,
25977         # as expected for an 8M DIO to a file with 1M stripes.
25978         [ $pct -eq 100 ] || error "we should see 8 RPCs in flight"
25979
25980         # Verify turning off parallel dio works as expected
25981         # Clear rpc stats
25982         $LCTL set_param osc.*.rpc_stats=c
25983         $LCTL set_param llite.*.parallel_dio=0
25984         stack_trap '$LCTL set_param llite.*.parallel_dio=1'
25985
25986         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
25987                 error "dio with parallel dio disabled failed"
25988
25989         # Ideally, we would see only one RPC in flight here, but there is an
25990         # unavoidable race between i/o completion and RPC in flight counting,
25991         # so while only 1 i/o is in flight at a time, the RPC in flight counter
25992         # will sometimes exceed 1 (3 or 4 is not rare on VM testing).
25993         # So instead we just verify it's always < 8.
25994         $LCTL get_param osc.*-OST0000-*.rpc_stats
25995         ret=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
25996                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
25997                 grep '^$' -B1 | grep . | awk '{print $1}')
25998         [ $ret != "8:" ] ||
25999                 error "we should see fewer than 8 RPCs in flight (saw $ret)"
26000 }
26001 run_test 398g "verify parallel dio async RPC submission"
26002
26003 test_398h() { #  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         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct ||
26012                 error "parallel dio failed"
26013         diff $DIR/$tfile $dio_file
26014         [[ $? == 0 ]] || error "file diff after aiocp"
26015 }
26016 run_test 398h "verify correctness of read & write with i/o size >> stripe size"
26017
26018 test_398i() { #  LU-13798
26019         local dio_file=$DIR/$tfile.dio
26020
26021         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
26022
26023         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
26024         stack_trap "rm -f $DIR/$tfile $dio_file"
26025
26026         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
26027         $LCTL set_param fail_loc=0x1418
26028         # make sure we don't crash and fail properly
26029         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct &&
26030                 error "parallel dio page allocation failure succeeded"
26031         diff $DIR/$tfile $dio_file
26032         [[ $? != 0 ]] || error "no diff after failed aiocp"
26033 }
26034 run_test 398i "verify parallel dio handles ll_direct_rw_pages errors correctly"
26035
26036 test_398j() { #  LU-13798
26037         # Stripe size > RPC size but less than i/o size tests split across
26038         # stripes and RPCs for individual i/o op
26039         $LFS setstripe -o 0,0 -S 4M $DIR/$tfile $DIR/$tfile.2
26040
26041         # Reduce RPC size to 1M to guarantee split to multiple RPCs per stripe
26042         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
26043         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
26044         stack_trap "$LCTL set_param -n $pages_per_rpc"
26045
26046         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
26047                 error "parallel dio write failed"
26048         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.2"
26049
26050         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct ||
26051                 error "parallel dio read failed"
26052         diff $DIR/$tfile $DIR/$tfile.2
26053         [[ $? == 0 ]] || error "file diff after parallel dio read"
26054 }
26055 run_test 398j "test parallel dio where stripe size > rpc_size"
26056
26057 test_398k() { #  LU-13798
26058         wait_delete_completed
26059         wait_mds_ost_sync
26060
26061         # 4 stripe file; we will cause out of space on OST0
26062         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
26063
26064         # Fill OST0 (if it's not too large)
26065         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
26066                    head -n1)
26067         if [[ $ORIGFREE -gt $MAXFREE ]]; then
26068                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
26069         fi
26070         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
26071         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
26072                 error "dd should fill OST0"
26073         stack_trap "rm -f $DIR/$tfile.1"
26074
26075         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
26076         err=$?
26077
26078         ls -la $DIR/$tfile
26079         $CHECKSTAT -t file -s 0 $DIR/$tfile ||
26080                 error "file is not 0 bytes in size"
26081
26082         # dd above should not succeed, but don't error until here so we can
26083         # get debug info above
26084         [[ $err != 0 ]] ||
26085                 error "parallel dio write with enospc succeeded"
26086         stack_trap "rm -f $DIR/$tfile"
26087 }
26088 run_test 398k "test enospc on first stripe"
26089
26090 test_398l() { #  LU-13798
26091         wait_delete_completed
26092         wait_mds_ost_sync
26093
26094         # 4 stripe file; we will cause out of space on OST0
26095         # Note the 1M stripe size and the > 1M i/o size mean this ENOSPC
26096         # happens on the second i/o chunk we issue
26097         $LFS setstripe -o 1,0,1,0 -S 1M $DIR/$tfile $DIR/$tfile.2
26098
26099         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=2 oflag=direct
26100         stack_trap "rm -f $DIR/$tfile"
26101
26102         # Fill OST0 (if it's not too large)
26103         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
26104                    head -n1)
26105         if [[ $ORIGFREE -gt $MAXFREE ]]; then
26106                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
26107         fi
26108         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
26109         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
26110                 error "dd should fill OST0"
26111         stack_trap "rm -f $DIR/$tfile.1"
26112
26113         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 oflag=direct
26114         err=$?
26115         stack_trap "rm -f $DIR/$tfile.2"
26116
26117         # Check that short write completed as expected
26118         ls -la $DIR/$tfile.2
26119         $CHECKSTAT -t file -s 1048576 $DIR/$tfile.2 ||
26120                 error "file is not 1M in size"
26121
26122         # dd above should not succeed, but don't error until here so we can
26123         # get debug info above
26124         [[ $err != 0 ]] ||
26125                 error "parallel dio write with enospc succeeded"
26126
26127         # Truncate source file to same length as output file and diff them
26128         $TRUNCATE $DIR/$tfile 1048576
26129         diff $DIR/$tfile $DIR/$tfile.2
26130         [[ $? == 0 ]] || error "data incorrect after short write"
26131 }
26132 run_test 398l "test enospc on intermediate stripe/RPC"
26133
26134 test_398m() { #  LU-13798
26135         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
26136
26137         # Set up failure on OST0, the first stripe:
26138         #define OBD_FAIL_OST_BRW_WRITE_BULK     0x20e
26139         #NB: Fail val is ost # + 1, because we cannot use cfs_fail_val = 0
26140         # OST0 is on ost1, OST1 is on ost2.
26141         # So this fail_val specifies OST0
26142         do_facet ost1 $LCTL set_param fail_loc=0x20e fail_val=1
26143         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
26144
26145         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
26146                 error "parallel dio write with failure on first stripe succeeded"
26147         stack_trap "rm -f $DIR/$tfile"
26148         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
26149
26150         # Place data in file for read
26151         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
26152                 error "parallel dio write failed"
26153
26154         # Fail read on OST0, first stripe
26155         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
26156         do_facet ost1 $LCTL set_param fail_loc=0x20f fail_val=1
26157         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
26158                 error "parallel dio read with error on first stripe succeeded"
26159         rm -f $DIR/$tfile.2
26160         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
26161
26162         # Switch to testing on OST1, second stripe
26163         # Clear file contents, maintain striping
26164         echo > $DIR/$tfile
26165         # Set up failure on OST1, second stripe:
26166         do_facet ost2 $LCTL set_param fail_loc=0x20e fail_val=2
26167         stack_trap "do_facet ost2 $LCTL set_param fail_loc=0"
26168
26169         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
26170                 error "parallel dio write with failure on second stripe succeeded"
26171         stack_trap "rm -f $DIR/$tfile"
26172         do_facet ost2 $LCTL set_param fail_loc=0 fail_val=0
26173
26174         # Place data in file for read
26175         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
26176                 error "parallel dio write failed"
26177
26178         # Fail read on OST1, second stripe
26179         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
26180         do_facet ost2 $LCTL set_param fail_loc=0x20f fail_val=2
26181         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
26182                 error "parallel dio read with error on second stripe succeeded"
26183         rm -f $DIR/$tfile.2
26184         do_facet ost2 $LCTL set_param fail_loc=0 fail_val=0
26185 }
26186 run_test 398m "test RPC failures with parallel dio"
26187
26188 # Parallel submission of DIO should not cause problems for append, but it's
26189 # important to verify.
26190 test_398n() { #  LU-13798
26191         $LFS setstripe -C 2 -S 1M $DIR/$tfile
26192
26193         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 ||
26194                 error "dd to create source file failed"
26195         stack_trap "rm -f $DIR/$tfile"
26196
26197         dd if=$DIR/$tfile of=$DIR/$tfile.1 bs=8M count=8 oflag=direct oflag=append ||
26198                 error "parallel dio write with failure on second stripe succeeded"
26199         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.1"
26200         diff $DIR/$tfile $DIR/$tfile.1
26201         [[ $? == 0 ]] || error "data incorrect after append"
26202
26203 }
26204 run_test 398n "test append with parallel DIO"
26205
26206 test_398o() {
26207         directio rdwr $DIR/$tfile 0 1 1 || error "bad KMS"
26208 }
26209 run_test 398o "right kms with DIO"
26210
26211 test_398p()
26212 {
26213         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
26214         which aiocp || skip_env "no aiocp installed"
26215
26216         local stripe_size=$((1024 * 1024)) #1 MiB
26217         # Max i/o below is ~ 4 * stripe_size, so this gives ~5 i/os
26218         local file_size=$((25 * stripe_size))
26219
26220         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
26221         stack_trap "rm -f $DIR/$tfile*"
26222         # Just a bit bigger than the largest size in the test set below
26223         dd if=/dev/urandom bs=$file_size count=1 of=$DIR/$tfile.1 ||
26224                 error "buffered i/o to create file failed"
26225
26226         for bs in $PAGE_SIZE $((PAGE_SIZE * 4)) $stripe_size \
26227                 $((stripe_size * 4)); do
26228
26229                 $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.2
26230
26231                 echo "bs: $bs, file_size $file_size"
26232                 aiocp -a $PAGE_SIZE -b $bs -s $file_size -f O_DIRECT \
26233                         $DIR/$tfile.1 $DIR/$tfile.2 &
26234                 pid_dio1=$!
26235                 # Buffered I/O with similar but not the same block size
26236                 dd if=$DIR/$tfile.1 bs=$((bs * 2)) of=$DIR/$tfile.2 \
26237                         conv=notrunc &
26238                 pid_bio2=$!
26239                 wait $pid_dio1
26240                 rc1=$?
26241                 wait $pid_bio2
26242                 rc2=$?
26243                 if (( rc1 != 0 )); then
26244                         error "aio copy 1 w/bsize $bs failed: $rc1"
26245                 fi
26246                 if (( rc2 != 0 )); then
26247                         error "buffered copy 2 w/bsize $bs failed: $rc2"
26248                 fi
26249
26250                 $CHECKSTAT -t file -s $file_size $DIR/$tfile.2 ||
26251                         error "size incorrect"
26252                 cmp --verbose $DIR/$tfile.1 $DIR/$tfile.2 ||
26253                         error "files differ, bsize $bs"
26254                 rm -f $DIR/$tfile.2
26255         done
26256 }
26257 run_test 398p "race aio with buffered i/o"
26258
26259 test_fake_rw() {
26260         local read_write=$1
26261         if [ "$read_write" = "write" ]; then
26262                 local dd_cmd="dd if=/dev/zero of=$DIR/$tfile"
26263         elif [ "$read_write" = "read" ]; then
26264                 local dd_cmd="dd of=/dev/null if=$DIR/$tfile"
26265         else
26266                 error "argument error"
26267         fi
26268
26269         # turn off debug for performance testing
26270         local saved_debug=$($LCTL get_param -n debug)
26271         $LCTL set_param debug=0
26272
26273         $LFS setstripe -c 1 -i 0 $DIR/$tfile
26274
26275         # get ost1 size - $FSNAME-OST0000
26276         local ost1_avail_size=$($LFS df $DIR | awk /${ost1_svc}/'{ print $4 }')
26277         local blocks=$((ost1_avail_size/2/1024)) # half avail space by megabytes
26278         [ $blocks -gt 1000 ] && blocks=1000 # 1G in maximum
26279
26280         if [ "$read_write" = "read" ]; then
26281                 $TRUNCATE $DIR/$tfile $(expr 1048576 \* $blocks)
26282         fi
26283
26284         local start_time=$(date +%s.%N)
26285         $dd_cmd bs=1M count=$blocks oflag=sync ||
26286                 error "real dd $read_write error"
26287         local duration=$(bc <<< "$(date +%s.%N) - $start_time")
26288
26289         if [ "$read_write" = "write" ]; then
26290                 rm -f $DIR/$tfile
26291         fi
26292
26293         # define OBD_FAIL_OST_FAKE_RW           0x238
26294         do_facet ost1 $LCTL set_param fail_loc=0x238
26295
26296         local start_time=$(date +%s.%N)
26297         $dd_cmd bs=1M count=$blocks oflag=sync ||
26298                 error "fake dd $read_write error"
26299         local duration_fake=$(bc <<< "$(date +%s.%N) - $start_time")
26300
26301         if [ "$read_write" = "write" ]; then
26302                 # verify file size
26303                 cancel_lru_locks osc
26304                 $CHECKSTAT -t file -s $((blocks * 1024 * 1024)) $DIR/$tfile ||
26305                         error "$tfile size not $blocks MB"
26306         fi
26307         do_facet ost1 $LCTL set_param fail_loc=0
26308
26309         echo "fake $read_write $duration_fake vs. normal $read_write" \
26310                 "$duration in seconds"
26311         [ $(bc <<< "$duration_fake < $duration") -eq 1 ] ||
26312                 error_not_in_vm "fake write is slower"
26313
26314         $LCTL set_param -n debug="$saved_debug"
26315         rm -f $DIR/$tfile
26316 }
26317 test_399a() { # LU-7655 for OST fake write
26318         remote_ost_nodsh && skip "remote OST with nodsh"
26319
26320         test_fake_rw write
26321 }
26322 run_test 399a "fake write should not be slower than normal write"
26323
26324 test_399b() { # LU-8726 for OST fake read
26325         remote_ost_nodsh && skip "remote OST with nodsh"
26326         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
26327                 skip_env "ldiskfs only test"
26328         fi
26329
26330         test_fake_rw read
26331 }
26332 run_test 399b "fake read should not be slower than normal read"
26333
26334 test_400a() { # LU-1606, was conf-sanity test_74
26335         if ! which $CC > /dev/null 2>&1; then
26336                 skip_env "$CC is not installed"
26337         fi
26338
26339         local extra_flags=''
26340         local out=$TMP/$tfile
26341         local prefix=/usr/include/lustre
26342         local prog
26343
26344         # Oleg removes .c files in his test rig so test if any c files exist
26345         [[ -n "$(ls -A $LUSTRE_TESTS_API_DIR)" ]] ||
26346                 skip_env "Needed .c test files are missing"
26347
26348         if ! [[ -d $prefix ]]; then
26349                 # Assume we're running in tree and fixup the include path.
26350                 extra_flags+=" -I$LUSTRE/../lnet/include/uapi"
26351                 extra_flags+=" -I$LUSTRE/include/uapi -I$LUSTRE/include"
26352                 extra_flags+=" -L$LUSTRE/utils/.libs"
26353         fi
26354
26355         for prog in $LUSTRE_TESTS_API_DIR/*.c; do
26356                 $CC -Wall -Werror $extra_flags -o $out $prog -llustreapi ||
26357                         error "client api broken"
26358         done
26359         rm -f $out
26360 }
26361 run_test 400a "Lustre client api program can compile and link"
26362
26363 test_400b() { # LU-1606, LU-5011
26364         local header
26365         local out=$TMP/$tfile
26366         local prefix=/usr/include/linux/lustre
26367
26368         # We use a hard coded prefix so that this test will not fail
26369         # when run in tree. There are headers in lustre/include/lustre/
26370         # that are not packaged (like lustre_idl.h) and have more
26371         # complicated include dependencies (like config.h and lnet/types.h).
26372         # Since this test about correct packaging we just skip them when
26373         # they don't exist (see below) rather than try to fixup cppflags.
26374
26375         if ! which $CC > /dev/null 2>&1; then
26376                 skip_env "$CC is not installed"
26377         fi
26378
26379         for header in $prefix/*.h; do
26380                 if ! [[ -f "$header" ]]; then
26381                         continue
26382                 fi
26383
26384                 if [[ "$(basename $header)" == lustre_ioctl.h ]]; then
26385                         continue # lustre_ioctl.h is internal header
26386                 fi
26387
26388                 $CC -Wall -Werror -include $header -c -x c /dev/null -o $out ||
26389                         error "cannot compile '$header'"
26390         done
26391         rm -f $out
26392 }
26393 run_test 400b "packaged headers can be compiled"
26394
26395 test_401a() { #LU-7437
26396         local printf_arg=$(find -printf 2>&1 | grep "unrecognized:")
26397         [ -n "$printf_arg" ] && skip_env "find does not support -printf"
26398
26399         #count the number of parameters by "list_param -R"
26400         local params=$($LCTL list_param -R '*' 2>/dev/null | wc -l)
26401         #count the number of parameters by listing proc files
26402         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
26403         echo "proc_dirs='$proc_dirs'"
26404         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
26405         local procs=$(find -L $proc_dirs -mindepth 1 -printf '%P\n' 2>/dev/null|
26406                       sort -u | wc -l)
26407
26408         [ $params -eq $procs ] ||
26409                 error "found $params parameters vs. $procs proc files"
26410
26411         # test the list_param -D option only returns directories
26412         params=$($LCTL list_param -R -D '*' 2>/dev/null | wc -l)
26413         #count the number of parameters by listing proc directories
26414         procs=$(find -L $proc_dirs -mindepth 1 -type d -printf '%P\n' 2>/dev/null |
26415                 sort -u | wc -l)
26416
26417         [ $params -eq $procs ] ||
26418                 error "found $params parameters vs. $procs proc files"
26419 }
26420 run_test 401a "Verify if 'lctl list_param -R' can list parameters recursively"
26421
26422 test_401b() {
26423         # jobid_var may not allow arbitrary values, so use jobid_name
26424         # if available
26425         if $LCTL list_param jobid_name > /dev/null 2>&1; then
26426                 local testname=jobid_name tmp='testing%p'
26427         else
26428                 local testname=jobid_var tmp=testing
26429         fi
26430
26431         local save=$($LCTL get_param -n $testname)
26432
26433         $LCTL set_param foo=bar $testname=$tmp bar=baz &&
26434                 error "no error returned when setting bad parameters"
26435
26436         local jobid_new=$($LCTL get_param -n foe $testname baz)
26437         [[ "$jobid_new" == "$tmp" ]] || error "jobid tmp $jobid_new != $tmp"
26438
26439         $LCTL set_param -n fog=bam $testname=$save bat=fog
26440         local jobid_old=$($LCTL get_param -n foe $testname bag)
26441         [[ "$jobid_old" == "$save" ]] || error "jobid new $jobid_old != $save"
26442 }
26443 run_test 401b "Verify 'lctl {get,set}_param' continue after error"
26444
26445 test_401c() {
26446         # jobid_var may not allow arbitrary values, so use jobid_name
26447         # if available
26448         if $LCTL list_param jobid_name > /dev/null 2>&1; then
26449                 local testname=jobid_name
26450         else
26451                 local testname=jobid_var
26452         fi
26453
26454         local jobid_var_old=$($LCTL get_param -n $testname)
26455         local jobid_var_new
26456
26457         $LCTL set_param $testname= &&
26458                 error "no error returned for 'set_param a='"
26459
26460         jobid_var_new=$($LCTL get_param -n $testname)
26461         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
26462                 error "$testname was changed by setting without value"
26463
26464         $LCTL set_param $testname &&
26465                 error "no error returned for 'set_param a'"
26466
26467         jobid_var_new=$($LCTL get_param -n $testname)
26468         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
26469                 error "$testname was changed by setting without value"
26470 }
26471 run_test 401c "Verify 'lctl set_param' without value fails in either format."
26472
26473 test_401d() {
26474         # jobid_var may not allow arbitrary values, so use jobid_name
26475         # if available
26476         if $LCTL list_param jobid_name > /dev/null 2>&1; then
26477                 local testname=jobid_name new_value='foo=bar%p'
26478         else
26479                 local testname=jobid_var new_valuie=foo=bar
26480         fi
26481
26482         local jobid_var_old=$($LCTL get_param -n $testname)
26483         local jobid_var_new
26484
26485         $LCTL set_param $testname=$new_value ||
26486                 error "'set_param a=b' did not accept a value containing '='"
26487
26488         jobid_var_new=$($LCTL get_param -n $testname)
26489         [[ "$jobid_var_new" == "$new_value" ]] ||
26490                 error "'set_param a=b' failed on a value containing '='"
26491
26492         # Reset the $testname to test the other format
26493         $LCTL set_param $testname=$jobid_var_old
26494         jobid_var_new=$($LCTL get_param -n $testname)
26495         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
26496                 error "failed to reset $testname"
26497
26498         $LCTL set_param $testname $new_value ||
26499                 error "'set_param a b' did not accept a value containing '='"
26500
26501         jobid_var_new=$($LCTL get_param -n $testname)
26502         [[ "$jobid_var_new" == "$new_value" ]] ||
26503                 error "'set_param a b' failed on a value containing '='"
26504
26505         $LCTL set_param $testname $jobid_var_old
26506         jobid_var_new=$($LCTL get_param -n $testname)
26507         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
26508                 error "failed to reset $testname"
26509 }
26510 run_test 401d "Verify 'lctl set_param' accepts values containing '='"
26511
26512 test_401e() { # LU-14779
26513         $LCTL list_param -R "ldlm.namespaces.MGC*" ||
26514                 error "lctl list_param MGC* failed"
26515         $LCTL get_param "ldlm.namespaces.MGC*" || error "lctl get_param failed"
26516         $LCTL get_param "ldlm.namespaces.MGC*.lru_size" ||
26517                 error "lctl get_param lru_size failed"
26518 }
26519 run_test 401e "verify 'lctl get_param' works with NID in parameter"
26520
26521 test_402() {
26522         [[ $MDS1_VERSION -ge $(version_code 2.7.66) ]] ||
26523         [[ $MDS1_VERSION -ge $(version_code 2.7.18.4) &&
26524                 $MDS1_VERSION -lt $(version_code 2.7.50) ]] ||
26525         [[ $MDS1_VERSION -ge $(version_code 2.7.2) &&
26526                 $MDS1_VERSION -lt $(version_code 2.7.11) ]] ||
26527                 skip "Need MDS version 2.7.2+ or 2.7.18.4+ or 2.7.66+"
26528         remote_mds_nodsh && skip "remote MDS with nodsh"
26529
26530         $LFS setdirstripe -i 0 $DIR/$tdir || error "setdirstripe -i 0 failed"
26531 #define OBD_FAIL_MDS_FLD_LOOKUP 0x15c
26532         do_facet mds1 "lctl set_param fail_loc=0x8000015c"
26533         touch $DIR/$tdir/$tfile && error "touch should fail with ENOENT" ||
26534                 echo "Touch failed - OK"
26535 }
26536 run_test 402 "Return ENOENT to lod_generate_and_set_lovea"
26537
26538 test_403() {
26539         local file1=$DIR/$tfile.1
26540         local file2=$DIR/$tfile.2
26541         local tfile=$TMP/$tfile
26542
26543         rm -f $file1 $file2 $tfile
26544
26545         touch $file1
26546         ln $file1 $file2
26547
26548         # 30 sec OBD_TIMEOUT in ll_getattr()
26549         # right before populating st_nlink
26550         $LCTL set_param fail_loc=0x80001409
26551         stat -c %h $file1 > $tfile &
26552
26553         # create an alias, drop all locks and reclaim the dentry
26554         < $file2
26555         cancel_lru_locks mdc
26556         cancel_lru_locks osc
26557         sysctl -w vm.drop_caches=2
26558
26559         wait
26560
26561         [ $(cat $tfile) -gt 0 ] || error "wrong nlink count: $(cat $tfile)"
26562
26563         rm -f $tfile $file1 $file2
26564 }
26565 run_test 403 "i_nlink should not drop to zero due to aliasing"
26566
26567 test_404() { # LU-6601
26568         [[ $MDS1_VERSION -ge $(version_code 2.8.53) ]] ||
26569                 skip "Need server version newer than 2.8.52"
26570         remote_mds_nodsh && skip "remote MDS with nodsh"
26571
26572         local mosps=$(do_facet $SINGLEMDS $LCTL dl |
26573                 awk '/osp .*-osc-MDT/ { print $4}')
26574
26575         local osp
26576         for osp in $mosps; do
26577                 echo "Deactivate: " $osp
26578                 do_facet $SINGLEMDS $LCTL --device %$osp deactivate
26579                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
26580                         awk -vp=$osp '$4 == p { print $2 }')
26581                 [ $stat = IN ] || {
26582                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
26583                         error "deactivate error"
26584                 }
26585                 echo "Activate: " $osp
26586                 do_facet $SINGLEMDS $LCTL --device %$osp activate
26587                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
26588                         awk -vp=$osp '$4 == p { print $2 }')
26589                 [ $stat = UP ] || {
26590                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
26591                         error "activate error"
26592                 }
26593         done
26594 }
26595 run_test 404 "validate manual {de}activated works properly for OSPs"
26596
26597 test_405() {
26598         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
26599         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] ||
26600                 [ $CLIENT_VERSION -lt $(version_code 2.6.99) ] &&
26601                         skip "Layout swap lock is not supported"
26602
26603         check_swap_layouts_support
26604         check_swap_layout_no_dom $DIR
26605
26606         test_mkdir $DIR/$tdir
26607         swap_lock_test -d $DIR/$tdir ||
26608                 error "One layout swap locked test failed"
26609 }
26610 run_test 405 "Various layout swap lock tests"
26611
26612 test_406() {
26613         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26614         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
26615         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
26616         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26617         [ $MDS1_VERSION -lt $(version_code 2.8.50) ] &&
26618                 skip "Need MDS version at least 2.8.50"
26619
26620         local def_stripe_size=$($LFS getstripe -S $MOUNT)
26621         local test_pool=$TESTNAME
26622
26623         pool_add $test_pool || error "pool_add failed"
26624         pool_add_targets $test_pool 0 $(($OSTCOUNT - 1)) 1 ||
26625                 error "pool_add_targets failed"
26626
26627         save_layout_restore_at_exit $MOUNT
26628
26629         # parent set default stripe count only, child will stripe from both
26630         # parent and fs default
26631         $LFS setstripe -c 1 -i 1 -S $((def_stripe_size * 2)) -p $test_pool $MOUNT ||
26632                 error "setstripe $MOUNT failed"
26633         $LFS mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
26634         $LFS setstripe -c $OSTCOUNT $DIR/$tdir || error "setstripe $tdir failed"
26635         for i in $(seq 10); do
26636                 local f=$DIR/$tdir/$tfile.$i
26637                 touch $f || error "touch failed"
26638                 local count=$($LFS getstripe -c $f)
26639                 [ $count -eq $OSTCOUNT ] ||
26640                         error "$f stripe count $count != $OSTCOUNT"
26641                 local offset=$($LFS getstripe -i $f)
26642                 [ $offset -eq 1 ] || error "$f stripe offset $offset != 1"
26643                 local size=$($LFS getstripe -S $f)
26644                 [ $size -eq $((def_stripe_size * 2)) ] ||
26645                         error "$f stripe size $size != $((def_stripe_size * 2))"
26646                 local pool=$($LFS getstripe -p $f)
26647                 [ $pool == $test_pool ] || error "$f pool $pool != $test_pool"
26648         done
26649
26650         # change fs default striping, delete parent default striping, now child
26651         # will stripe from new fs default striping only
26652         $LFS setstripe -c 1 -S $def_stripe_size -i 0 $MOUNT ||
26653                 error "change $MOUNT default stripe failed"
26654         $LFS setstripe -c 0 $DIR/$tdir ||
26655                 error "delete $tdir default stripe failed"
26656         for i in $(seq 11 20); do
26657                 local f=$DIR/$tdir/$tfile.$i
26658                 touch $f || error "touch $f failed"
26659                 local count=$($LFS getstripe -c $f)
26660                 [ $count -eq 1 ] || error "$f stripe count $count != 1"
26661                 local offset=$($LFS getstripe -i $f)
26662                 [ $offset -eq 0 ] || error "$f stripe offset $offset != 0"
26663                 local size=$($LFS getstripe -S $f)
26664                 [ $size -eq $def_stripe_size ] ||
26665                         error "$f stripe size $size != $def_stripe_size"
26666                 local pool=$($LFS getstripe -p $f)
26667                 [ $pool == $test_pool ] || error "$f pool $pool isn't set"
26668         done
26669
26670         unlinkmany $DIR/$tdir/$tfile. 1 20
26671
26672         local f=$DIR/$tdir/$tfile
26673         pool_remove_all_targets $test_pool $f
26674         pool_remove $test_pool $f
26675 }
26676 run_test 406 "DNE support fs default striping"
26677
26678 test_407() {
26679         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26680         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
26681                 skip "Need MDS version at least 2.8.55"
26682         remote_mds_nodsh && skip "remote MDS with nodsh"
26683
26684         $LFS mkdir -i 0 -c 1 $DIR/$tdir.0 ||
26685                 error "$LFS mkdir -i 0 -c 1 $tdir.0 failed"
26686         $LFS mkdir -i 1 -c 1 $DIR/$tdir.1 ||
26687                 error "$LFS mkdir -i 1 -c 1 $tdir.1 failed"
26688         touch $DIR/$tdir.0/$tfile.0 || error "touch $tdir.0/$tfile.0 failed"
26689
26690         #define OBD_FAIL_DT_TXN_STOP    0x2019
26691         for idx in $(seq $MDSCOUNT); do
26692                 do_facet mds$idx "lctl set_param fail_loc=0x2019"
26693         done
26694         $LFS mkdir -c 2 $DIR/$tdir && error "$LFS mkdir -c 2 $tdir should fail"
26695         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1/$tfile.1 &&
26696                 error "mv $tdir.0/$tfile.0 $tdir.1/$tfile.1 should fail"
26697         true
26698 }
26699 run_test 407 "transaction fail should cause operation fail"
26700
26701 test_408() {
26702         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
26703
26704         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
26705         lctl set_param fail_loc=0x8000040a
26706         # let ll_prepare_partial_page() fail
26707         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 conv=notrunc || true
26708
26709         rm -f $DIR/$tfile
26710
26711         # create at least 100 unused inodes so that
26712         # shrink_icache_memory(0) should not return 0
26713         touch $DIR/$tfile-{0..100}
26714         rm -f $DIR/$tfile-{0..100}
26715         sync
26716
26717         echo 2 > /proc/sys/vm/drop_caches
26718 }
26719 run_test 408 "drop_caches should not hang due to page leaks"
26720
26721 test_409()
26722 {
26723         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
26724
26725         mkdir -p $DIR/$tdir || error "(0) Fail to mkdir"
26726         $LFS mkdir -i 1 -c 2 $DIR/$tdir/foo || error "(1) Fail to mkdir"
26727         touch $DIR/$tdir/guard || error "(2) Fail to create"
26728
26729         local PREFIX=$(str_repeat 'A' 128)
26730         echo "Create 1K hard links start at $(date)"
26731         createmany -l $DIR/$tdir/guard $DIR/$tdir/foo/${PREFIX}_ 1000 ||
26732                 error "(3) Fail to hard link"
26733
26734         echo "Links count should be right although linkEA overflow"
26735         stat $DIR/$tdir/guard || error "(4) Fail to stat"
26736         local linkcount=$(stat --format=%h $DIR/$tdir/guard)
26737         [ $linkcount -eq 1001 ] ||
26738                 error "(5) Unexpected hard links count: $linkcount"
26739
26740         echo "List all links start at $(date)"
26741         ls -l $DIR/$tdir/foo > /dev/null ||
26742                 error "(6) Fail to list $DIR/$tdir/foo"
26743
26744         echo "Unlink hard links start at $(date)"
26745         unlinkmany $DIR/$tdir/foo/${PREFIX}_ 1000 ||
26746                 error "(7) Fail to unlink"
26747         echo "Unlink hard links finished at $(date)"
26748 }
26749 run_test 409 "Large amount of cross-MDTs hard links on the same file"
26750
26751 test_410()
26752 {
26753         [[ $CLIENT_VERSION -lt $(version_code 2.9.59) ]] &&
26754                 skip "Need client version at least 2.9.59"
26755         [ -f $LUSTRE/tests/kernel/kinode.ko ] ||
26756                 skip "Need MODULES build"
26757
26758         # Create a file, and stat it from the kernel
26759         local testfile=$DIR/$tfile
26760         touch $testfile
26761
26762         local run_id=$RANDOM
26763         local my_ino=$(stat --format "%i" $testfile)
26764
26765         # Try to insert the module. This will always fail as the
26766         # module is designed to not be inserted.
26767         insmod $LUSTRE/tests/kernel/kinode.ko run_id=$run_id fname=$testfile \
26768             &> /dev/null
26769
26770         # Anything but success is a test failure
26771         dmesg | grep -q \
26772             "lustre_kinode_$run_id: inode numbers are identical: $my_ino" ||
26773             error "no inode match"
26774 }
26775 run_test 410 "Test inode number returned from kernel thread"
26776
26777 cleanup_test411_cgroup() {
26778         trap 0
26779         rmdir "$1"
26780 }
26781
26782 test_411() {
26783         local cg_basedir=/sys/fs/cgroup/memory
26784         # LU-9966
26785         test -f "$cg_basedir/memory.kmem.limit_in_bytes" ||
26786                 skip "no setup for cgroup"
26787
26788         dd if=/dev/zero of=$DIR/$tfile bs=1M count=100 conv=fsync ||
26789                 error "test file creation failed"
26790         cancel_lru_locks osc
26791
26792         # Create a very small memory cgroup to force a slab allocation error
26793         local cgdir=$cg_basedir/osc_slab_alloc
26794         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
26795         trap "cleanup_test411_cgroup $cgdir" EXIT
26796         echo 2M > $cgdir/memory.kmem.limit_in_bytes
26797         echo 1M > $cgdir/memory.limit_in_bytes
26798
26799         # Should not LBUG, just be killed by oom-killer
26800         # dd will return 0 even allocation failure in some environment.
26801         # So don't check return value
26802         bash -c "echo \$$ > $cgdir/tasks && dd if=$DIR/$tfile of=/dev/null"
26803         cleanup_test411_cgroup $cgdir
26804
26805         return 0
26806 }
26807 run_test 411 "Slab allocation error with cgroup does not LBUG"
26808
26809 test_412() {
26810         (( $MDSCOUNT > 1 )) || skip_env "needs >= 2 MDTs"
26811         (( $MDS1_VERSION >= $(version_code 2.10.55) )) ||
26812                 skip "Need server version at least 2.10.55"
26813
26814         $LFS mkdir -i $((MDSCOUNT - 1)),$((MDSCOUNT - 2)) $DIR/$tdir ||
26815                 error "mkdir failed"
26816         $LFS getdirstripe $DIR/$tdir
26817         local stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
26818         [ $stripe_index -eq $((MDSCOUNT - 1)) ] ||
26819                 error "expect $((MDSCOUT - 1)) get $stripe_index"
26820         local stripe_count=$($LFS getdirstripe -T $DIR/$tdir)
26821         [ $stripe_count -eq 2 ] ||
26822                 error "expect 2 get $stripe_count"
26823
26824         (( $MDS1_VERSION >= $(version_code 2.14.55) )) || return 0
26825
26826         local index
26827         local index2
26828
26829         # subdirs should be on the same MDT as parent
26830         for i in $(seq 0 $((MDSCOUNT - 1))); do
26831                 $LFS mkdir -i $i $DIR/$tdir/mdt$i || error "mkdir mdt$i failed"
26832                 mkdir $DIR/$tdir/mdt$i/sub || error "mkdir sub failed"
26833                 index=$($LFS getstripe -m $DIR/$tdir/mdt$i/sub)
26834                 (( index == i )) || error "mdt$i/sub on MDT$index"
26835         done
26836
26837         # stripe offset -1, ditto
26838         for i in {1..10}; do
26839                 $LFS mkdir -i -1 $DIR/$tdir/qos$i || error "mkdir qos$i failed"
26840                 index=$($LFS getstripe -m $DIR/$tdir/qos$i)
26841                 mkdir $DIR/$tdir/qos$i/sub || error "mkdir sub failed"
26842                 index2=$($LFS getstripe -m $DIR/$tdir/qos$i/sub)
26843                 (( index == index2 )) ||
26844                         error "qos$i on MDT$index, sub on MDT$index2"
26845         done
26846
26847         local testdir=$DIR/$tdir/inherit
26848
26849         $LFS mkdir -i 1 --max-inherit=3 $testdir || error "mkdir inherit failed"
26850         # inherit 2 levels
26851         for i in 1 2; do
26852                 testdir=$testdir/s$i
26853                 mkdir $testdir || error "mkdir $testdir failed"
26854                 index=$($LFS getstripe -m $testdir)
26855                 (( index == 1 )) ||
26856                         error "$testdir on MDT$index"
26857         done
26858
26859         # not inherit any more
26860         testdir=$testdir/s3
26861         mkdir $testdir || error "mkdir $testdir failed"
26862         getfattr -d -m dmv $testdir | grep dmv &&
26863                 error "default LMV set on $testdir" || true
26864 }
26865 run_test 412 "mkdir on specific MDTs"
26866
26867 TEST413_COUNT=${TEST413_COUNT:-200}
26868
26869 #
26870 # set_maxage() is used by test_413 only.
26871 # This is a helper function to set maxage. Does not return any value.
26872 # Input: maxage to set
26873 #
26874 set_maxage() {
26875         local lmv_qos_maxage
26876         local lod_qos_maxage
26877         local new_maxage=$1
26878
26879         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
26880         $LCTL set_param lmv.*.qos_maxage=$new_maxage
26881         stack_trap "$LCTL set_param \
26882                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null"
26883         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
26884                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
26885         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
26886                 lod.*.mdt_qos_maxage=$new_maxage
26887         stack_trap "do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
26888                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null"
26889 }
26890
26891 generate_uneven_mdts() {
26892         local threshold=$1
26893         local ffree
26894         local bavail
26895         local max
26896         local min
26897         local max_index
26898         local min_index
26899         local tmp
26900         local i
26901
26902         echo
26903         echo "Check for uneven MDTs: "
26904
26905         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
26906         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
26907         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
26908
26909         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
26910         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
26911         max_index=0
26912         min_index=0
26913         for ((i = 1; i < ${#ffree[@]}; i++)); do
26914                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
26915                 if [ $tmp -gt $max ]; then
26916                         max=$tmp
26917                         max_index=$i
26918                 fi
26919                 if [ $tmp -lt $min ]; then
26920                         min=$tmp
26921                         min_index=$i
26922                 fi
26923         done
26924
26925         (( min > 0 )) || skip "low space on MDT$min_index"
26926         (( ${ffree[min_index]} > 0 )) ||
26927                 skip "no free files on MDT$min_index"
26928         (( ${ffree[min_index]} < 10000000 )) ||
26929                 skip "too many free files on MDT$min_index"
26930
26931         # Check if we need to generate uneven MDTs
26932         local diff=$(((max - min) * 100 / min))
26933         local testdirp=$DIR/$tdir-fillmdt # parent fill folder
26934         local testdir # individual folder within $testdirp
26935         local start
26936         local cmd
26937
26938         # fallocate is faster to consume space on MDT, if available
26939         if check_fallocate_supported mds$((min_index + 1)); then
26940                 cmd="fallocate -l 128K "
26941         else
26942                 cmd="dd if=/dev/zero bs=128K count=1 of="
26943         fi
26944
26945         echo "using cmd $cmd"
26946         for (( i = 0; diff < threshold; i++ )); do
26947                 testdir=${testdirp}/$i
26948                 [ -d $testdir ] && continue
26949
26950                 (( i % 10 > 0 )) || { $LFS df; $LFS df -i; }
26951
26952                 mkdir -p $testdirp
26953                 # generate uneven MDTs, create till $threshold% diff
26954                 echo -n "weight diff=$diff% must be > $threshold% ..."
26955                 echo "Fill MDT$min_index with $TEST413_COUNT files: loop $i"
26956                 $LFS mkdir -i $min_index $testdir ||
26957                         error "mkdir $testdir failed"
26958                 $LFS setstripe -E 1M -L mdt $testdir ||
26959                         error "setstripe $testdir failed"
26960                 start=$SECONDS
26961                 for (( f = 0; f < TEST413_COUNT; f++ )); do
26962                         $cmd$testdir/f.$f &> /dev/null || error "$cmd $f failed"
26963                 done
26964                 sync; sleep 1; sync
26965
26966                 # wait for QOS to update
26967                 (( SECONDS < start + 2 )) && sleep $((start + 2 - SECONDS))
26968
26969                 ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-*.filesfree))
26970                 bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-*.kbytesavail))
26971                 max=$(((${ffree[max_index]} >> 8) *
26972                         (${bavail[max_index]} * bsize >> 16)))
26973                 min=$(((${ffree[min_index]} >> 8) *
26974                         (${bavail[min_index]} * bsize >> 16)))
26975                 (( min > 0 )) || skip "low space on MDT$min_index"
26976                 diff=$(((max - min) * 100 / min))
26977         done
26978
26979         echo "MDT filesfree available: ${ffree[*]}"
26980         echo "MDT blocks available: ${bavail[*]}"
26981         echo "weight diff=$diff%"
26982 }
26983
26984 test_qos_mkdir() {
26985         local mkdir_cmd=$1
26986         local stripe_count=$2
26987         local mdts=$(comma_list $(mdts_nodes))
26988
26989         local testdir
26990         local lmv_qos_prio_free
26991         local lmv_qos_threshold_rr
26992         local lod_qos_prio_free
26993         local lod_qos_threshold_rr
26994         local total
26995         local count
26996         local i
26997
26998         # @total is total directories created if it's testing plain
26999         # directories, otherwise it's total stripe object count for
27000         # striped directories test.
27001         # remote/striped directory unlinking is slow on zfs and may
27002         # timeout, test with fewer directories
27003         [ "$mds1_FSTYPE" = "zfs" ] && total=120 || total=240
27004
27005         lmv_qos_prio_free=$($LCTL get_param -n lmv.*.qos_prio_free | head -n1)
27006         lmv_qos_prio_free=${lmv_qos_prio_free%%%}
27007         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
27008                 head -n1)
27009         lmv_qos_threshold_rr=${lmv_qos_threshold_rr%%%}
27010         stack_trap "$LCTL set_param \
27011                 lmv.*.qos_prio_free=$lmv_qos_prio_free > /dev/null"
27012         stack_trap "$LCTL set_param \
27013                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null"
27014
27015         lod_qos_prio_free=$(do_facet mds1 $LCTL get_param -n \
27016                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_prio_free | head -n1)
27017         lod_qos_prio_free=${lod_qos_prio_free%%%}
27018         lod_qos_threshold_rr=$(do_facet mds1 $LCTL get_param -n \
27019                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_threshold_rr | head -n1)
27020         lod_qos_threshold_rr=${lod_qos_threshold_rr%%%}
27021         stack_trap "do_nodes $mdts $LCTL set_param \
27022                 lod.*.mdt_qos_prio_free=$lod_qos_prio_free > /dev/null"
27023         stack_trap "do_nodes $mdts $LCTL set_param \
27024                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null"
27025
27026         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
27027         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=100 > /dev/null
27028
27029         testdir=$DIR/$tdir-s$stripe_count/rr
27030
27031         local stripe_index=$($LFS getstripe -m $testdir)
27032         local test_mkdir_rr=true
27033
27034         getfattr -d -m dmv -e hex $testdir | grep dmv
27035         if (( $? == 0 && $MDS1_VERSION >= $(version_code 2.14.51) )); then
27036                 echo "defstripe: '$($LFS getdirstripe -D $testdir)'"
27037                 (( $($LFS getdirstripe -D --max-inherit-rr $testdir) == 0 )) &&
27038                         test_mkdir_rr=false
27039         fi
27040
27041         echo
27042         $test_mkdir_rr &&
27043                 echo "Mkdir (stripe_count $stripe_count) roundrobin:" ||
27044                 echo "Mkdir (stripe_count $stripe_count) on stripe $stripe_index"
27045
27046         stack_trap "unlinkmany -d $testdir/subdir $((total / stripe_count))"
27047         for (( i = 0; i < total / stripe_count; i++ )); do
27048                 eval $mkdir_cmd $testdir/subdir$i ||
27049                         error "$mkdir_cmd subdir$i failed"
27050         done
27051
27052         for (( i = 0; i < $MDSCOUNT; i++ )); do
27053                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
27054                 echo "$count directories created on MDT$i"
27055                 if $test_mkdir_rr; then
27056                         (( count == total / stripe_count / MDSCOUNT )) ||
27057                                 error "subdirs are not evenly distributed"
27058                 elif (( i == stripe_index )); then
27059                         (( count == total / stripe_count )) ||
27060                                 error "$count subdirs created on MDT$i"
27061                 else
27062                         (( count == 0 )) ||
27063                                 error "$count subdirs created on MDT$i"
27064                 fi
27065
27066                 if $test_mkdir_rr && [ $stripe_count -gt 1 ]; then
27067                         count=$($LFS getdirstripe $testdir/* |
27068                                 grep -c -P "^\s+$i\t")
27069                         echo "$count stripes created on MDT$i"
27070                         # deviation should < 5% of average
27071                         delta=$((count - total / MDSCOUNT))
27072                         (( ${delta#-} <= total / MDSCOUNT / 20 )) ||
27073                                 error "stripes are not evenly distributed"
27074                 fi
27075         done
27076
27077         echo
27078         echo "Check for uneven MDTs: "
27079
27080         local ffree
27081         local bavail
27082         local max
27083         local min
27084         local max_index
27085         local min_index
27086         local tmp
27087
27088         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
27089         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
27090         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
27091
27092         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
27093         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
27094         max_index=0
27095         min_index=0
27096         for ((i = 1; i < ${#ffree[@]}; i++)); do
27097                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
27098                 if [ $tmp -gt $max ]; then
27099                         max=$tmp
27100                         max_index=$i
27101                 fi
27102                 if [ $tmp -lt $min ]; then
27103                         min=$tmp
27104                         min_index=$i
27105                 fi
27106         done
27107         echo "stripe_count=$stripe_count min_idx=$min_index max_idx=$max_index"
27108
27109         (( min > 0 )) || skip "low space on MDT$min_index"
27110         (( ${ffree[min_index]} < 10000000 )) ||
27111                 skip "too many free files on MDT$min_index"
27112
27113         generate_uneven_mdts 120
27114
27115         echo "MDT filesfree available: ${ffree[*]}"
27116         echo "MDT blocks available: ${bavail[*]}"
27117         echo "weight diff=$(((max - min) * 100 / min))%"
27118         echo
27119         echo "Mkdir (stripe_count $stripe_count) with balanced space usage:"
27120
27121         $LCTL set_param lmv.*.qos_threshold_rr=0 > /dev/null
27122         $LCTL set_param lmv.*.qos_prio_free=100 > /dev/null
27123         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=0 > /dev/null
27124         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_prio_free=100 > /dev/null
27125         # decrease statfs age, so that it can be updated in time
27126         $LCTL set_param lmv.*.qos_maxage=1 > /dev/null
27127         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_maxage=1 > /dev/null
27128
27129         sleep 1
27130
27131         testdir=$DIR/$tdir-s$stripe_count/qos
27132
27133         stack_trap "unlinkmany -d $testdir/subdir $((total / stripe_count))"
27134         for (( i = 0; i < total / stripe_count; i++ )); do
27135                 eval $mkdir_cmd $testdir/subdir$i ||
27136                         error "$mkdir_cmd subdir$i failed"
27137         done
27138
27139         max=0
27140         for (( i = 0; i < $MDSCOUNT; i++ )); do
27141                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
27142                 (( count > max )) && max=$count
27143                 echo "$count directories created on MDT$i : curmax=$max"
27144         done
27145
27146         min=$($LFS getdirstripe -i $testdir/* | grep -c "^$min_index$")
27147
27148         # D-value should > 10% of average
27149         (( max - min > total / stripe_count / MDSCOUNT / 10 )) ||
27150                 error "subdirs shouldn't be evenly distributed: $max - $min <= $((total / stripe_count / MDSCOUNT / 10))"
27151
27152         # ditto for stripes
27153         if (( stripe_count > 1 )); then
27154                 max=0
27155                 for (( i = 0; i < $MDSCOUNT; i++ )); do
27156                         count=$($LFS getdirstripe $testdir/* |
27157                                 grep -c -P "^\s+$i\t")
27158                         (( count > max )) && max=$count
27159                         echo "$count stripes created on MDT$i"
27160                 done
27161
27162                 min=$($LFS getdirstripe $testdir/* |
27163                         grep -c -P "^\s+$min_index\t")
27164                 (( max - min > total / MDSCOUNT / 10 )) ||
27165                         error "stripes shouldn't be evenly distributed: $max - $min <= $((total / MDSCOUNT / 10))"
27166         fi
27167 }
27168
27169 most_full_mdt() {
27170         local ffree
27171         local bavail
27172         local bsize
27173         local min
27174         local min_index
27175         local tmp
27176
27177         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
27178         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
27179         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
27180
27181         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
27182         min_index=0
27183         for ((i = 1; i < ${#ffree[@]}; i++)); do
27184                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
27185                 (( tmp < min )) && min=$tmp && min_index=$i
27186         done
27187
27188         echo -n $min_index
27189 }
27190
27191 test_413a() {
27192         [ $MDSCOUNT -lt 2 ] &&
27193                 skip "We need at least 2 MDTs for this test"
27194
27195         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
27196                 skip "Need server version at least 2.12.52"
27197
27198         local stripe_max=$((MDSCOUNT - 1))
27199         local stripe_count
27200
27201         # let caller set maxage for latest result
27202         set_maxage 1
27203
27204         # fill MDT unevenly
27205         generate_uneven_mdts 120
27206
27207         # test 4-stripe directory at most, otherwise it's too slow
27208         # We are being very defensive. Although Autotest uses 4 MDTs.
27209         # We make sure stripe_max does not go over 4.
27210         (( stripe_max > 4 )) && stripe_max=4
27211         # unlinking striped directory is slow on zfs, and may timeout, only test
27212         # plain directory
27213         [ "$mds1_FSTYPE" == "zfs" ] && stripe_max=1
27214         for stripe_count in $(seq 1 $stripe_max); do
27215                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
27216                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
27217                 $LFS mkdir -i $(most_full_mdt) $DIR/$tdir-s$stripe_count/qos ||
27218                         error "mkdir failed"
27219                 test_qos_mkdir "$LFS mkdir -i -1 -c $stripe_count" $stripe_count
27220         done
27221 }
27222 run_test 413a "QoS mkdir with 'lfs mkdir -i -1'"
27223
27224 test_413b() {
27225         [ $MDSCOUNT -lt 2 ] &&
27226                 skip "We need at least 2 MDTs for this test"
27227
27228         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
27229                 skip "Need server version at least 2.12.52"
27230
27231         local stripe_max=$((MDSCOUNT - 1))
27232         local testdir
27233         local stripe_count
27234
27235         # let caller set maxage for latest result
27236         set_maxage 1
27237
27238         # fill MDT unevenly
27239         generate_uneven_mdts 120
27240
27241         # test 4-stripe directory at most, otherwise it's too slow
27242         # We are being very defensive. Although Autotest uses 4 MDTs.
27243         # We make sure stripe_max does not go over 4.
27244         (( stripe_max > 4 )) && stripe_max=4
27245         [ "$mds1_FSTYPE" == "zfs" ] && stripe_max=1
27246         for stripe_count in $(seq 1 $stripe_max); do
27247                 testdir=$DIR/$tdir-s$stripe_count
27248                 mkdir $testdir || error "mkdir $testdir failed"
27249                 mkdir $testdir/rr || error "mkdir rr failed"
27250                 $LFS mkdir -i $(most_full_mdt) $testdir/qos ||
27251                         error "mkdir qos failed"
27252                 $LFS setdirstripe -D -c $stripe_count --max-inherit-rr 2 \
27253                         $testdir/rr || error "setdirstripe rr failed"
27254                 $LFS setdirstripe -D -c $stripe_count $testdir/qos ||
27255                         error "setdirstripe failed"
27256                 test_qos_mkdir "mkdir" $stripe_count
27257         done
27258 }
27259 run_test 413b "QoS mkdir under dir whose default LMV starting MDT offset is -1"
27260
27261 test_413c() {
27262         (( $MDSCOUNT >= 2 )) ||
27263                 skip "We need at least 2 MDTs for this test"
27264
27265         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
27266                 skip "Need server version at least 2.14.51"
27267
27268         local testdir
27269         local inherit
27270         local inherit_rr
27271         local lmv_qos_maxage
27272         local lod_qos_maxage
27273
27274         # let caller set maxage for latest result
27275         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
27276         $LCTL set_param lmv.*.qos_maxage=1
27277         stack_trap "$LCTL set_param \
27278                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null" RETURN
27279         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
27280                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
27281         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
27282                 lod.*.mdt_qos_maxage=1
27283         stack_trap "do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
27284                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null" RETURN
27285
27286         # fill MDT unevenly
27287         generate_uneven_mdts 120
27288
27289         testdir=$DIR/${tdir}-s1
27290         mkdir $testdir || error "mkdir $testdir failed"
27291         mkdir $testdir/rr || error "mkdir rr failed"
27292         $LFS mkdir -i $(most_full_mdt) $testdir/qos || error "mkdir qos failed"
27293         # default max_inherit is -1, default max_inherit_rr is 0
27294         $LFS setdirstripe -D -c 1 $testdir/rr ||
27295                 error "setdirstripe rr failed"
27296         $LFS setdirstripe -D -c 1 -i -1 -X 2 --max-inherit-rr 1 $testdir/qos ||
27297                 error "setdirstripe qos failed"
27298         test_qos_mkdir "mkdir" 1
27299
27300         mkdir $testdir/rr/level1 || error "mkdir rr/level1 failed"
27301         inherit=$($LFS getdirstripe -D -X $testdir/rr/level1)
27302         (( $inherit == -1 )) || error "rr/level1 inherit $inherit != -1"
27303         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/rr/level1)
27304         (( $inherit_rr == 0 )) || error "rr/level1 inherit-rr $inherit_rr != 0"
27305
27306         mkdir $testdir/qos/level1 || error "mkdir qos/level1 failed"
27307         inherit=$($LFS getdirstripe -D -X $testdir/qos/level1)
27308         (( $inherit == 1 )) || error "qos/level1 inherit $inherit != 1"
27309         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/qos/level1)
27310         (( $inherit_rr == 0 )) || error "qos/level1 inherit-rr $inherit_rr != 0"
27311         mkdir $testdir/qos/level1/level2 || error "mkdir level2 failed"
27312         getfattr -d -m dmv -e hex $testdir/qos/level1/level2 | grep dmv &&
27313                 error "level2 shouldn't have default LMV" || true
27314 }
27315 run_test 413c "mkdir with default LMV max inherit rr"
27316
27317 test_413d() {
27318         (( MDSCOUNT >= 2 )) ||
27319                 skip "We need at least 2 MDTs for this test"
27320
27321         (( MDS1_VERSION >= $(version_code 2.14.51) )) ||
27322                 skip "Need server version at least 2.14.51"
27323
27324         local lmv_qos_threshold_rr
27325
27326         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
27327                 head -n1)
27328         stack_trap "$LCTL set_param \
27329                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null" EXIT
27330
27331         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
27332         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
27333         getfattr -d -m dmv -e hex $DIR/$tdir | grep dmv &&
27334                 error "$tdir shouldn't have default LMV"
27335         createmany -d $DIR/$tdir/sub $((100 * MDSCOUNT)) ||
27336                 error "mkdir sub failed"
27337
27338         local count=$($LFS getstripe -m $DIR/$tdir/* | grep -c ^0)
27339
27340         (( count == 100 )) || error "$count subdirs on MDT0"
27341 }
27342 run_test 413d "inherit ROOT default LMV"
27343
27344 test_413e() {
27345         (( MDSCOUNT >= 2 )) ||
27346                 skip "We need at least 2 MDTs for this test"
27347         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
27348                 skip "Need server version at least 2.14.55"
27349
27350         local testdir=$DIR/$tdir
27351         local tmpfile=$TMP/temp.setdirstripe.stderr.$$
27352         local max_inherit
27353         local sub_max_inherit
27354
27355         mkdir -p $testdir || error "failed to create $testdir"
27356
27357         # set default max-inherit to -1 if stripe count is 0 or 1
27358         $LFS setdirstripe -D -c 1 $testdir ||
27359                 error "failed to set default LMV"
27360         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
27361         (( max_inherit == -1 )) ||
27362                 error "wrong max_inherit value $max_inherit"
27363
27364         # set default max_inherit to a fixed value if stripe count is not 0 or 1
27365         $LFS setdirstripe -D -c -1 $testdir ||
27366                 error "failed to set default LMV"
27367         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
27368         (( max_inherit > 0 )) ||
27369                 error "wrong max_inherit value $max_inherit"
27370
27371         # and the subdir will decrease the max_inherit by 1
27372         mkdir -p $testdir/subdir-1 || error "failed to make subdir"
27373         sub_max_inherit=$($LFS getdirstripe -D --max-inherit $testdir/subdir-1)
27374         (( sub_max_inherit == max_inherit - 1)) ||
27375                 error "wrong max-inherit of subdir $sub_max_inherit"
27376
27377         # check specified --max-inherit and warning message
27378         stack_trap "rm -f $tmpfile"
27379         $LFS setdirstripe -D -c 2 --max-inherit=-1 $testdir 2> $tmpfile ||
27380                 error "failed to set default LMV"
27381         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
27382         (( max_inherit == -1 )) ||
27383                 error "wrong max_inherit value $max_inherit"
27384
27385         # check the warning messages
27386         if ! [[ $(cat $tmpfile) =~ "max-inherit=" ]]; then
27387                 error "failed to detect warning string"
27388         fi
27389 }
27390 run_test 413e "check default max-inherit value"
27391
27392 test_fs_dmv_inherit()
27393 {
27394         local testdir=$DIR/$tdir
27395
27396         local count
27397         local inherit
27398         local inherit_rr
27399
27400         for i in 1 2; do
27401                 mkdir $testdir || error "mkdir $testdir failed"
27402                 count=$($LFS getdirstripe -D -c $testdir)
27403                 (( count == 1 )) ||
27404                         error "$testdir default LMV count mismatch $count != 1"
27405                 inherit=$($LFS getdirstripe -D -X $testdir)
27406                 (( inherit == 3 - i )) ||
27407                         error "$testdir default LMV max-inherit $inherit != $((3 - i))"
27408                 inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir)
27409                 (( inherit_rr == 3 - i )) ||
27410                         error "$testdir default LMV max-inherit-rr $inherit_rr != $((3 - i))"
27411                 testdir=$testdir/sub
27412         done
27413
27414         mkdir $testdir || error "mkdir $testdir failed"
27415         count=$($LFS getdirstripe -D -c $testdir)
27416         (( count == 0 )) ||
27417                 error "$testdir default LMV count not zero: $count"
27418 }
27419
27420 test_413f() {
27421         (( MDSCOUNT >= 2 )) || skip "We need at least 2 MDTs for this test"
27422
27423         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
27424                 skip "Need server version at least 2.14.55"
27425
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         test_fs_dmv_inherit
27434 }
27435 run_test 413f "lfs getdirstripe -D list ROOT default LMV if it's not set on dir"
27436
27437 test_413g() {
27438         (( MDSCOUNT >= 2 )) || skip "We need at least 2 MDTs for this test"
27439
27440         mkdir -p $DIR/$tdir/l2/l3/l4 || error "mkdir $tdir/l1/l2/l3 failed"
27441         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
27442                 error "dump $DIR default LMV failed"
27443         stack_trap "setfattr --restore=$TMP/dmv.ea"
27444
27445         $LFS setdirstripe -D -i -1 -c 1 -X 3 --max-inherit-rr 3 $DIR ||
27446                 error "set $DIR default LMV failed"
27447
27448         FILESET="$FILESET/$tdir/l2/l3/l4" mount_client $MOUNT2 ||
27449                 error "mount $MOUNT2 failed"
27450         stack_trap "umount_client $MOUNT2"
27451
27452         local saved_DIR=$DIR
27453
27454         export DIR=$MOUNT2
27455
27456         stack_trap "export DIR=$saved_DIR"
27457
27458         # first check filesystem-wide default LMV inheritance
27459         test_fs_dmv_inherit || error "incorrect fs default LMV inheritance"
27460
27461         # then check subdirs are spread to all MDTs
27462         createmany -d $DIR/s $((MDSCOUNT * 100)) || error "createmany failed"
27463
27464         local count=$($LFS getstripe -m $DIR/s* | sort -u | wc -l)
27465
27466         (( $count == $MDSCOUNT )) || error "dirs are spread to $count MDTs"
27467 }
27468 run_test 413g "enforce ROOT default LMV on subdir mount"
27469
27470 test_413h() {
27471         (( MDSCOUNT >= 2 )) ||
27472                 skip "We need at least 2 MDTs for this test"
27473
27474         (( MDS1_VERSION >= $(version_code 2.15.50.6) )) ||
27475                 skip "Need server version at least 2.15.50.6"
27476
27477         local lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
27478
27479         stack_trap "$LCTL set_param \
27480                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null"
27481         $LCTL set_param lmv.*.qos_maxage=1
27482
27483         local depth=5
27484         local rr_depth=4
27485         local dir=$DIR/$tdir/l1/l2/l3/l4/l5
27486         local count=$((MDSCOUNT * 20))
27487
27488         generate_uneven_mdts 50
27489
27490         mkdir -p $dir || error "mkdir $dir failed"
27491         stack_trap "rm -rf $dir"
27492         $LFS setdirstripe -D -c 1 -i -1 --max-inherit=$depth \
27493                 --max-inherit-rr=$rr_depth $dir
27494
27495         for ((d=0; d < depth + 2; d++)); do
27496                 log "dir=$dir:"
27497                 for ((sub=0; sub < count; sub++)); do
27498                         mkdir $dir/d$sub
27499                 done
27500                 $LFS getdirstripe -i $dir/d* | sort | uniq -c | sort -nr
27501                 local num=($($LFS getdirstripe -i $dir/d* | sort | uniq -c))
27502                 # subdirs within $rr_depth should be created round-robin
27503                 if (( d < rr_depth )); then
27504                         (( ${num[0]} != count )) ||
27505                                 error "all objects created on MDT ${num[1]}"
27506                 fi
27507
27508                 dir=$dir/d0
27509         done
27510 }
27511 run_test 413h "don't stick to parent for round-robin dirs"
27512
27513 test_413i() {
27514         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
27515
27516         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
27517                 skip "Need server version at least 2.14.55"
27518
27519         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
27520                 error "dump $DIR default LMV failed"
27521         stack_trap "setfattr --restore=$TMP/dmv.ea"
27522
27523         local testdir=$DIR/$tdir
27524         local def_max_rr=1
27525         local def_max=3
27526         local count
27527
27528         $LFS setdirstripe -D -i-1 -c1 --max-inherit=$def_max \
27529                 --max-inherit-rr=$def_max_rr $DIR ||
27530                 error "set $DIR default LMV failed"
27531
27532         for i in $(seq 2 3); do
27533                 def_max=$((def_max - 1))
27534                 (( def_max_rr == 0 )) || def_max_rr=$((def_max_rr - 1))
27535
27536                 mkdir $testdir
27537                 # RR is decremented and keeps zeroed once exhausted
27538                 count=$($LFS getdirstripe -D --max-inherit-rr $testdir)
27539                 (( count == def_max_rr )) ||
27540                         error_noexit "$testdir: max-inherit-rr $count != $def_max_rr"
27541
27542                 # max-inherit is decremented
27543                 count=$($LFS getdirstripe -D --max-inherit $testdir)
27544                 (( count == def_max )) ||
27545                         error_noexit "$testdir: max-inherit $count != $def_max"
27546
27547                 testdir=$testdir/d$i
27548         done
27549
27550         # d3 is the last inherited from ROOT, no inheritance anymore
27551         # i.e. no the default layout anymore
27552         mkdir -p $testdir/d4/d5
27553         count=$($LFS getdirstripe -D --max-inherit $testdir)
27554         (( count == -1 )) ||
27555                 error_noexit "$testdir: max-inherit $count != -1"
27556
27557         local p_count=$($LFS getdirstripe -i $testdir)
27558
27559         for i in $(seq 4 5); do
27560                 testdir=$testdir/d$i
27561
27562                 # the root default layout is not applied once exhausted
27563                 count=$($LFS getdirstripe -i $testdir)
27564                 (( count == p_count )) ||
27565                         error_noexit "$testdir: stripe-offset $count != parent offset $p_count"
27566         done
27567
27568         $LFS setdirstripe -i 0 $DIR/d2
27569         count=$($LFS getdirstripe -D --max-inherit $DIR/d2)
27570         (( count == -1 )) ||
27571                 error_noexit "$DIR/d2: max-inherit non-striped default $count != -1"
27572 }
27573 run_test 413i "check default layout inheritance"
27574
27575 test_413z() {
27576         local pids=""
27577         local subdir
27578         local pid
27579
27580         for subdir in $(\ls -1 -d $DIR/d413*-fillmdt/*); do
27581                 unlinkmany $subdir/f. $TEST413_COUNT &
27582                 pids="$pids $!"
27583         done
27584
27585         for pid in $pids; do
27586                 wait $pid
27587         done
27588
27589         true
27590 }
27591 run_test 413z "413 test cleanup"
27592
27593 test_414() {
27594 #define OBD_FAIL_PTLRPC_BULK_ATTACH      0x521
27595         $LCTL set_param fail_loc=0x80000521
27596         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
27597         rm -f $DIR/$tfile
27598 }
27599 run_test 414 "simulate ENOMEM in ptlrpc_register_bulk()"
27600
27601 test_415() {
27602         [[ $PARALLEL == "yes" ]] && skip "skip parallel run"
27603         (( $MDS1_VERSION >= $(version_code 2.11.52) )) ||
27604                 skip "Need server version at least 2.11.52"
27605
27606         # LU-11102
27607         local total=500
27608         local max=120
27609
27610         # this test may be slow on ZFS
27611         [[ "$mds1_FSTYPE" == "zfs" ]] && total=50
27612
27613         # though this test is designed for striped directory, let's test normal
27614         # directory too since lock is always saved as CoS lock.
27615         test_mkdir $DIR/$tdir || error "mkdir $tdir"
27616         createmany -o $DIR/$tdir/$tfile. $total || error "createmany"
27617         stack_trap "unlinkmany $DIR/$tdir/$tfile. $total || true"
27618         # if looping with ONLY_REPEAT, wait for previous deletions to finish
27619         wait_delete_completed_mds
27620
27621         # run a loop without concurrent touch to measure rename duration.
27622         # only for test debug/robustness, NOT part of COS functional test.
27623         local start_time=$SECONDS
27624         for ((i = 0; i < total; i++)); do
27625                 mrename $DIR/$tdir/$tfile.$i $DIR/$tdir/$tfile-new.$i \
27626                         > /dev/null
27627         done
27628         local baseline=$((SECONDS - start_time))
27629         echo "rename $total files without 'touch' took $baseline sec"
27630
27631         (
27632                 while true; do
27633                         touch $DIR/$tdir
27634                 done
27635         ) &
27636         local setattr_pid=$!
27637
27638         # rename files back to original name so unlinkmany works
27639         start_time=$SECONDS
27640         for ((i = 0; i < total; i++)); do
27641                 mrename $DIR/$tdir/$tfile-new.$i $DIR/$tdir/$tfile.$i\
27642                         > /dev/null
27643         done
27644         local duration=$((SECONDS - start_time))
27645
27646         kill -9 $setattr_pid
27647
27648         echo "rename $total files with 'touch' took $duration sec"
27649         (( max > 2 * baseline )) || max=$((2 * baseline + 5))
27650         (( duration <= max )) ||
27651                 error_not_in_vm "rename took $duration > $max sec"
27652 }
27653 run_test 415 "lock revoke is not missing"
27654
27655 test_416() {
27656         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
27657                 skip "Need server version at least 2.11.55"
27658
27659         # define OBD_FAIL_OSD_TXN_START    0x19a
27660         do_facet mds1 lctl set_param fail_loc=0x19a
27661
27662         lfs mkdir -c $MDSCOUNT $DIR/$tdir
27663
27664         true
27665 }
27666 run_test 416 "transaction start failure won't cause system hung"
27667
27668 cleanup_417() {
27669         trap 0
27670         do_nodes $(comma_list $(mdts_nodes)) \
27671                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=1"
27672         do_nodes $(comma_list $(mdts_nodes)) \
27673                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=1"
27674         do_nodes $(comma_list $(mdts_nodes)) \
27675                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=1"
27676 }
27677
27678 test_417() {
27679         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
27680         [[ $MDS1_VERSION -lt $(version_code 2.11.56) ]] &&
27681                 skip "Need MDS version at least 2.11.56"
27682
27683         trap cleanup_417 RETURN EXIT
27684
27685         $LFS mkdir -i 1 $DIR/$tdir.1 || error "create remote dir $tdir.1 failed"
27686         do_nodes $(comma_list $(mdts_nodes)) \
27687                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=0"
27688         $LFS migrate -m 0 $DIR/$tdir.1 &&
27689                 error "migrate dir $tdir.1 should fail"
27690
27691         do_nodes $(comma_list $(mdts_nodes)) \
27692                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=0"
27693         $LFS mkdir -i 1 $DIR/$tdir.2 &&
27694                 error "create remote dir $tdir.2 should fail"
27695
27696         do_nodes $(comma_list $(mdts_nodes)) \
27697                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=0"
27698         $LFS mkdir -c 2 $DIR/$tdir.3 &&
27699                 error "create striped dir $tdir.3 should fail"
27700         true
27701 }
27702 run_test 417 "disable remote dir, striped dir and dir migration"
27703
27704 # Checks that the outputs of df [-i] and lfs df [-i] match
27705 #
27706 # usage: check_lfs_df <blocks | inodes> <mountpoint>
27707 check_lfs_df() {
27708         local dir=$2
27709         local inodes
27710         local df_out
27711         local lfs_df_out
27712         local count
27713         local passed=false
27714
27715         # blocks or inodes
27716         [ "$1" == "blocks" ] && inodes= || inodes="-i"
27717
27718         for count in {1..100}; do
27719                 do_nodes "$CLIENTS" \
27720                         $LCTL set_param ldlm.namespaces.*.lru_size=clear
27721                 sync; sleep 0.2
27722
27723                 # read the lines of interest
27724                 df_out=($(df -P $inodes $dir | tail -n +2)) ||
27725                         error "df $inodes $dir | tail -n +2 failed"
27726                 lfs_df_out=($($LFS df $inodes $dir | grep summary:)) ||
27727                         error "lfs df $inodes $dir | grep summary: failed"
27728
27729                 # skip first substrings of each output as they are different
27730                 # "<NID>:/<fsname>" for df, "filesystem_summary:" for lfs df
27731                 # compare the two outputs
27732                 passed=true
27733                 #  skip "available" on MDT until LU-13997 is fixed.
27734                 #for i in {1..5}; do
27735                 for i in 1 2 4 5; do
27736                         [ "${df_out[i]}" != "${lfs_df_out[i]}" ] && passed=false
27737                 done
27738                 $passed && break
27739         done
27740
27741         if ! $passed; then
27742                 df -P $inodes $dir
27743                 echo
27744                 lfs df $inodes $dir
27745                 error "df and lfs df $1 output mismatch: "      \
27746                       "df ${inodes}: ${df_out[*]}, "            \
27747                       "lfs df ${inodes}: ${lfs_df_out[*]}"
27748         fi
27749 }
27750
27751 test_418() {
27752         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27753
27754         local dir=$DIR/$tdir
27755         local numfiles=$((RANDOM % 4096 + 2))
27756         local numblocks=$((RANDOM % 256 + 1))
27757
27758         wait_delete_completed
27759         test_mkdir $dir
27760
27761         # check block output
27762         check_lfs_df blocks $dir
27763         # check inode output
27764         check_lfs_df inodes $dir
27765
27766         # create a single file and retest
27767         echo "Creating a single file and testing"
27768         createmany -o $dir/$tfile- 1 &>/dev/null ||
27769                 error "creating 1 file in $dir failed"
27770         check_lfs_df blocks $dir
27771         check_lfs_df inodes $dir
27772
27773         # create a random number of files
27774         echo "Creating $((numfiles - 1)) files and testing"
27775         createmany -o $dir/$tfile- 1 $((numfiles - 1)) &>/dev/null ||
27776                 error "creating $((numfiles - 1)) files in $dir failed"
27777
27778         # write a random number of blocks to the first test file
27779         echo "Writing $numblocks 4K blocks and testing"
27780         dd if=/dev/urandom of=$dir/${tfile}-0 bs=4K conv=fsync \
27781                 count=$numblocks &>/dev/null ||
27782                 error "dd to $dir/${tfile}-0 failed"
27783
27784         # retest
27785         check_lfs_df blocks $dir
27786         check_lfs_df inodes $dir
27787
27788         unlinkmany $dir/$tfile- $numfiles &>/dev/null ||
27789                 error "unlinking $numfiles files in $dir failed"
27790 }
27791 run_test 418 "df and lfs df outputs match"
27792
27793 test_419()
27794 {
27795         local dir=$DIR/$tdir
27796
27797         mkdir -p $dir
27798         touch $dir/file
27799
27800         cancel_lru_locks mdc
27801
27802         #OBD_FAIL_LLITE_OPEN_BY_NAME    0x1410
27803         $LCTL set_param fail_loc=0x1410
27804         cat $dir/file
27805         $LCTL set_param fail_loc=0
27806         rm -rf $dir
27807 }
27808 run_test 419 "Verify open file by name doesn't crash kernel"
27809
27810 test_420()
27811 {
27812         [[ $MDS1_VERSION -ge $(version_code 2.12.53) ]] ||
27813                 skip "Need MDS version at least 2.12.53"
27814
27815         local SAVE_UMASK=$(umask)
27816         local dir=$DIR/$tdir
27817         local uname=$(getent passwd $RUNAS_ID | cut -d: -f1)
27818
27819         mkdir -p $dir
27820         umask 0000
27821         mkdir -m03777 $dir/testdir
27822         ls -dn $dir/testdir
27823         # Need to remove trailing '.' when SELinux is enabled
27824         local dirperms=$(ls -dn $dir/testdir |
27825                          awk '{ sub(/\.$/, "", $1); print $1}')
27826         [ $dirperms == "drwxrwsrwt" ] ||
27827                 error "incorrect perms on $dir/testdir"
27828
27829         su - $uname -c "PATH=$LUSTRE/tests:\$PATH; \
27830                 openfile -f O_RDONLY:O_CREAT -m 02755 $dir/testdir/testfile"
27831         ls -n $dir/testdir/testfile
27832         local fileperms=$(ls -n $dir/testdir/testfile |
27833                           awk '{ sub(/\.$/, "", $1); print $1}')
27834         [ $fileperms == "-rwxr-xr-x" ] ||
27835                 error "incorrect perms on $dir/testdir/testfile"
27836
27837         umask $SAVE_UMASK
27838 }
27839 run_test 420 "clear SGID bit on non-directories for non-members"
27840
27841 test_421a() {
27842         local cnt
27843         local fid1
27844         local fid2
27845
27846         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
27847                 skip "Need MDS version at least 2.12.54"
27848
27849         test_mkdir $DIR/$tdir
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         $LFS rmfid $DIR $fid1 $fid2 || error "rmfid failed"
27857
27858         stat $DIR/$tdir/f1 && error "f1 still visible on the client"
27859         stat $DIR/$tdir/f2 && error "f2 still visible on the client"
27860
27861         cnt=$(ls -1 $DIR/$tdir | wc -l)
27862         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
27863
27864         rm -f $DIR/$tdir/f3 || error "can't remove f3"
27865         createmany -o $DIR/$tdir/f 3
27866         cnt=$(ls -1 $DIR/$tdir | wc -l)
27867         [ $cnt != 3 ] && error "unexpected #files: $cnt"
27868
27869         fid1=$(lfs path2fid $DIR/$tdir/f1)
27870         fid2=$(lfs path2fid $DIR/$tdir/f2)
27871         echo "remove using fsname $FSNAME"
27872         $LFS rmfid $FSNAME $fid1 $fid2 || error "rmfid with fsname failed"
27873
27874         cnt=$(ls -1 $DIR/$tdir | wc -l)
27875         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
27876 }
27877 run_test 421a "simple rm by fid"
27878
27879 test_421b() {
27880         local cnt
27881         local FID1
27882         local FID2
27883
27884         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
27885                 skip "Need MDS version at least 2.12.54"
27886
27887         test_mkdir $DIR/$tdir
27888         createmany -o $DIR/$tdir/f 3
27889         multiop_bg_pause $DIR/$tdir/f1 o_c || error "multiop failed to start"
27890         MULTIPID=$!
27891
27892         FID1=$(lfs path2fid $DIR/$tdir/f1)
27893         FID2=$(lfs path2fid $DIR/$tdir/f2)
27894         $LFS rmfid $DIR $FID1 $FID2 && error "rmfid didn't fail"
27895
27896         kill -USR1 $MULTIPID
27897         wait
27898
27899         cnt=$(ls $DIR/$tdir | wc -l)
27900         [ $cnt == 2 ] || error "unexpected #files after: $cnt"
27901 }
27902 run_test 421b "rm by fid on open file"
27903
27904 test_421c() {
27905         local cnt
27906         local FIDS
27907
27908         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
27909                 skip "Need MDS version at least 2.12.54"
27910
27911         test_mkdir $DIR/$tdir
27912         createmany -o $DIR/$tdir/f 3
27913         touch $DIR/$tdir/$tfile
27914         createmany -l$DIR/$tdir/$tfile $DIR/$tdir/h 180
27915         cnt=$(ls -1 $DIR/$tdir | wc -l)
27916         [ $cnt != 184 ] && error "unexpected #files: $cnt"
27917
27918         FID1=$(lfs path2fid $DIR/$tdir/$tfile)
27919         $LFS rmfid $DIR $FID1 || error "rmfid failed"
27920
27921         cnt=$(ls $DIR/$tdir | wc -l)
27922         [ $cnt == 3 ] || error "unexpected #files after: $cnt"
27923 }
27924 run_test 421c "rm by fid against hardlinked files"
27925
27926 test_421d() {
27927         local cnt
27928         local FIDS
27929
27930         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
27931                 skip "Need MDS version at least 2.12.54"
27932
27933         test_mkdir $DIR/$tdir
27934         createmany -o $DIR/$tdir/f 4097
27935         cnt=$(ls -1 $DIR/$tdir | wc -l)
27936         [ $cnt != 4097 ] && error "unexpected #files: $cnt"
27937
27938         FIDS=$(lfs path2fid $DIR/$tdir/f* | sed "s/[/][^:]*://g")
27939         $LFS rmfid $DIR $FIDS || error "rmfid failed"
27940
27941         cnt=$(ls $DIR/$tdir | wc -l)
27942         rm -rf $DIR/$tdir
27943         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
27944 }
27945 run_test 421d "rmfid en masse"
27946
27947 test_421e() {
27948         local cnt
27949         local FID
27950
27951         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
27952         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
27953                 skip "Need MDS version at least 2.12.54"
27954
27955         mkdir -p $DIR/$tdir
27956         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
27957         createmany -o $DIR/$tdir/striped_dir/f 512
27958         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
27959         [ $cnt != 512 ] && error "unexpected #files: $cnt"
27960
27961         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
27962                 sed "s/[/][^:]*://g")
27963         $LFS rmfid $DIR $FIDS || error "rmfid failed"
27964
27965         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
27966         rm -rf $DIR/$tdir
27967         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
27968 }
27969 run_test 421e "rmfid in DNE"
27970
27971 test_421f() {
27972         local cnt
27973         local FID
27974
27975         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
27976                 skip "Need MDS version at least 2.12.54"
27977
27978         test_mkdir $DIR/$tdir
27979         touch $DIR/$tdir/f
27980         cnt=$(ls -1 $DIR/$tdir | wc -l)
27981         [ $cnt != 1 ] && error "unexpected #files: $cnt"
27982
27983         FID=$(lfs path2fid $DIR/$tdir/f)
27984         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (1)"
27985         # rmfid should fail
27986         cnt=$(ls -1 $DIR/$tdir | wc -l)
27987         [ $cnt != 1 ] && error "unexpected #files after (2): $cnt"
27988
27989         chmod a+rw $DIR/$tdir
27990         ls -la $DIR/$tdir
27991         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (2)"
27992         # rmfid should fail
27993         cnt=$(ls -1 $DIR/$tdir | wc -l)
27994         [ $cnt != 1 ] && error "unexpected #files after (3): $cnt"
27995
27996         rm -f $DIR/$tdir/f
27997         $RUNAS touch $DIR/$tdir/f
27998         FID=$(lfs path2fid $DIR/$tdir/f)
27999         echo "rmfid as root"
28000         $LFS rmfid $DIR $FID || error "rmfid as root failed"
28001         cnt=$(ls -1 $DIR/$tdir | wc -l)
28002         [ $cnt == 0 ] || error "unexpected #files after (4): $cnt"
28003
28004         rm -f $DIR/$tdir/f
28005         $RUNAS touch $DIR/$tdir/f
28006         cnt=$(ls -1 $DIR/$tdir | wc -l)
28007         [ $cnt != 1 ] && error "unexpected #files (4): $cnt"
28008         FID=$(lfs path2fid $DIR/$tdir/f)
28009         # rmfid w/o user_fid2path mount option should fail
28010         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail(3)"
28011         cnt=$(ls -1 $DIR/$tdir | wc -l)
28012         [ $cnt == 1 ] || error "unexpected #files after (5): $cnt"
28013
28014         tmpdir=$(mktemp -d /tmp/lustre-XXXXXX)
28015         stack_trap "rmdir $tmpdir"
28016         mount_client $tmpdir "$MOUNT_OPTS,user_fid2path" ||
28017                 error "failed to mount client'"
28018         stack_trap "umount_client $tmpdir"
28019
28020         $RUNAS $LFS rmfid $tmpdir $FID || error "rmfid failed"
28021         # rmfid should succeed
28022         cnt=$(ls -1 $tmpdir/$tdir | wc -l)
28023         [ $cnt == 0 ] || error "unexpected #files after (6): $cnt"
28024
28025         # rmfid shouldn't allow to remove files due to dir's permission
28026         chmod a+rwx $tmpdir/$tdir
28027         touch $tmpdir/$tdir/f
28028         ls -la $tmpdir/$tdir
28029         FID=$(lfs path2fid $tmpdir/$tdir/f)
28030         $RUNAS $LFS rmfid $tmpdir $FID && error "rmfid didn't fail"
28031         return 0
28032 }
28033 run_test 421f "rmfid checks permissions"
28034
28035 test_421g() {
28036         local cnt
28037         local FIDS
28038
28039         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
28040         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
28041                 skip "Need MDS version at least 2.12.54"
28042
28043         mkdir -p $DIR/$tdir
28044         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
28045         createmany -o $DIR/$tdir/striped_dir/f 512
28046         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
28047         [ $cnt != 512 ] && error "unexpected #files: $cnt"
28048
28049         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
28050                 sed "s/[/][^:]*://g")
28051
28052         rm -f $DIR/$tdir/striped_dir/f1*
28053         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
28054         removed=$((512 - cnt))
28055
28056         # few files have been just removed, so we expect
28057         # rmfid to fail on their fids
28058         errors=$($LFS rmfid $DIR $FIDS 2>&1 | wc -l)
28059         [ $removed != $errors ] && error "$errors != $removed"
28060
28061         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
28062         rm -rf $DIR/$tdir
28063         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
28064 }
28065 run_test 421g "rmfid to return errors properly"
28066
28067 test_421h() {
28068         local mount_other
28069         local mount_ret
28070         local rmfid_ret
28071         local old_fid
28072         local fidA
28073         local fidB
28074         local fidC
28075         local fidD
28076
28077         (( MDS1_VERSION >= $(version_code 2.15.53) )) ||
28078                 skip "Need MDS version at least 2.15.53"
28079
28080         test_mkdir $DIR/$tdir
28081         test_mkdir $DIR/$tdir/subdir
28082         touch $DIR/$tdir/subdir/file0
28083         old_fid=$(lfs path2fid $DIR/$tdir/subdir/file0 | sed "s/[/][^:]*://g")
28084         echo File $DIR/$tdir/subdir/file0 FID $old_fid
28085         rm -f $DIR/$tdir/subdir/file0
28086         touch $DIR/$tdir/subdir/fileA
28087         fidA=$(lfs path2fid $DIR/$tdir/subdir/fileA | sed "s/[/][^:]*://g")
28088         echo File $DIR/$tdir/subdir/fileA FID $fidA
28089         touch $DIR/$tdir/subdir/fileB
28090         fidB=$(lfs path2fid $DIR/$tdir/subdir/fileB | sed "s/[/][^:]*://g")
28091         echo File $DIR/$tdir/subdir/fileB FID $fidB
28092         ln $DIR/$tdir/subdir/fileB $DIR/$tdir/subdir/fileB_hl
28093         touch $DIR/$tdir/subdir/fileC
28094         fidC=$(lfs path2fid $DIR/$tdir/subdir/fileC | sed "s/[/][^:]*://g")
28095         echo File $DIR/$tdir/subdir/fileC FID $fidC
28096         ln $DIR/$tdir/subdir/fileC $DIR/$tdir/fileC
28097         touch $DIR/$tdir/fileD
28098         fidD=$(lfs path2fid $DIR/$tdir/fileD | sed "s/[/][^:]*://g")
28099         echo File $DIR/$tdir/fileD FID $fidD
28100
28101         # mount another client mount point with subdirectory mount
28102         export FILESET=/$tdir/subdir
28103         mount_other=${MOUNT}_other
28104         mount_client $mount_other ${MOUNT_OPTS}
28105         mount_ret=$?
28106         export FILESET=""
28107         (( mount_ret == 0 )) || error "mount $mount_other failed"
28108
28109         echo Removing FIDs:
28110         echo $LFS rmfid $mount_other $old_fid $fidA $fidD $fidB $fidC
28111         $LFS rmfid $mount_other $old_fid $fidA $fidD $fidB $fidC
28112         rmfid_ret=$?
28113
28114         umount_client $mount_other || error "umount $mount_other failed"
28115
28116         (( rmfid_ret != 0 )) || error "rmfid should have failed"
28117
28118         # fileA should have been deleted
28119         stat $DIR/$tdir/subdir/fileA && error "fileA not deleted"
28120
28121         # fileB should have been deleted
28122         stat $DIR/$tdir/subdir/fileB && error "fileB not deleted"
28123
28124         # fileC should not have been deleted, fid also exists outside of fileset
28125         stat $DIR/$tdir/subdir/fileC || error "fileC deleted"
28126
28127         # fileD should not have been deleted, it exists outside of fileset
28128         stat $DIR/$tdir/fileD || error "fileD deleted"
28129 }
28130 run_test 421h "rmfid with fileset mount"
28131
28132 test_422() {
28133         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d1
28134         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d2
28135         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d3
28136         dd if=/dev/zero of=$DIR/$tdir/d1/file1 bs=1k count=1
28137         dd if=/dev/zero of=$DIR/$tdir/d2/file1 bs=1k count=1
28138
28139         local amc=$(at_max_get client)
28140         local amo=$(at_max_get mds1)
28141         local timeout=`lctl get_param -n timeout`
28142
28143         at_max_set 0 client
28144         at_max_set 0 mds1
28145
28146 #define OBD_FAIL_PTLRPC_PAUSE_REQ        0x50a
28147         do_facet mds1 $LCTL set_param fail_loc=0x8000050a \
28148                         fail_val=$(((2*timeout + 10)*1000))
28149         touch $DIR/$tdir/d3/file &
28150         sleep 2
28151 #define OBD_FAIL_TGT_REPLY_DATA_RACE     0x722
28152         do_facet mds1 $LCTL set_param fail_loc=0x80000722 \
28153                         fail_val=$((2*timeout + 5))
28154         mv $DIR/$tdir/d1/file1 $DIR/$tdir/d1/file2 &
28155         local pid=$!
28156         sleep 1
28157         kill -9 $pid
28158         sleep $((2 * timeout))
28159         echo kill $pid
28160         kill -9 $pid
28161         lctl mark touch
28162         touch $DIR/$tdir/d2/file3
28163         touch $DIR/$tdir/d2/file4
28164         touch $DIR/$tdir/d2/file5
28165
28166         wait
28167         at_max_set $amc client
28168         at_max_set $amo mds1
28169
28170         # LU-12838 - verify the ptlrpc thread watchdog is not always throttled
28171         do_facet mds1 "dmesg | grep 'Dumping the stack trace for debugging'" ||
28172                 error "Watchdog is always throttled"
28173 }
28174 run_test 422 "kill a process with RPC in progress"
28175
28176 stat_test() {
28177     df -h $MOUNT &
28178     df -h $MOUNT &
28179     df -h $MOUNT &
28180     df -h $MOUNT &
28181     df -h $MOUNT &
28182     df -h $MOUNT &
28183 }
28184
28185 test_423() {
28186     local _stats
28187     # ensure statfs cache is expired
28188     sleep 2;
28189
28190     _stats=$(stat_test | grep $MOUNT | sort -u | wc -l)
28191     [[ ${_stats} -ne 1 ]] && error "statfs wrong"
28192
28193     return 0
28194 }
28195 run_test 423 "statfs should return a right data"
28196
28197 test_424() {
28198 #define OBD_FAIL_PTLRPC_BULK_REPLY_ATTACH      0x522 | CFS_FAIL_ONCE
28199         $LCTL set_param fail_loc=0x80000522
28200         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
28201         rm -f $DIR/$tfile
28202 }
28203 run_test 424 "simulate ENOMEM in ptl_send_rpc bulk reply ME attach"
28204
28205 test_425() {
28206         test_mkdir -c -1 $DIR/$tdir
28207         $LFS setstripe -c -1 $DIR/$tdir
28208
28209         lru_resize_disable "" 100
28210         stack_trap "lru_resize_enable" EXIT
28211
28212         sleep 5
28213
28214         for i in $(seq $((MDSCOUNT * 125))); do
28215                 local t=$DIR/$tdir/$tfile_$i
28216
28217                 dd if=/dev/zero of=$t bs=4K count=1 > /dev/null 2>&1 ||
28218                         error_noexit "Create file $t"
28219         done
28220         stack_trap "rm -rf $DIR/$tdir" EXIT
28221
28222         for oscparam in $($LCTL list_param ldlm.namespaces.*osc-[-0-9a-f]*); do
28223                 local lru_size=$($LCTL get_param -n $oscparam.lru_size)
28224                 local lock_count=$($LCTL get_param -n $oscparam.lock_count)
28225
28226                 [ $lock_count -le $lru_size ] ||
28227                         error "osc lock count $lock_count > lru size $lru_size"
28228         done
28229
28230         for mdcparam in $($LCTL list_param ldlm.namespaces.*mdc-*); do
28231                 local lru_size=$($LCTL get_param -n $mdcparam.lru_size)
28232                 local lock_count=$($LCTL get_param -n $mdcparam.lock_count)
28233
28234                 [ $lock_count -le $lru_size ] ||
28235                         error "mdc lock count $lock_count > lru size $lru_size"
28236         done
28237 }
28238 run_test 425 "lock count should not exceed lru size"
28239
28240 test_426() {
28241         splice-test -r $DIR/$tfile
28242         splice-test -rd $DIR/$tfile
28243         splice-test $DIR/$tfile
28244         splice-test -d $DIR/$tfile
28245 }
28246 run_test 426 "splice test on Lustre"
28247
28248 test_427() {
28249         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
28250         (( $MDS1_VERSION >= $(version_code 2.12.4) )) ||
28251                 skip "Need MDS version at least 2.12.4"
28252         local log
28253
28254         mkdir $DIR/$tdir
28255         mkdir $DIR/$tdir/1
28256         mkdir $DIR/$tdir/2
28257         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/1/dir
28258         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/2/dir2
28259
28260         $LFS getdirstripe $DIR/$tdir/1/dir
28261
28262         #first setfattr for creating updatelog
28263         setfattr -n user.attr0 -v "some text" $DIR/$tdir/1/dir
28264
28265 #define OBD_FAIL_OUT_OBJECT_MISS        0x1708
28266         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param fail_loc=0x80001708
28267         setfattr -n user.attr1 -v "some text" $DIR/$tdir/1/dir &
28268         setfattr -n user.attr2 -v "another attr"  $DIR/$tdir/2/dir2 &
28269
28270         sleep 2
28271         fail mds2
28272         wait_recovery_complete mds2 $((2*TIMEOUT))
28273
28274         log=$(do_facet mds1 dmesg | tac | sed "/${TESTNAME//_/ }/,$ d")
28275         echo $log | grep "get update log failed" &&
28276                 error "update log corruption is detected" || true
28277 }
28278 run_test 427 "Failed DNE2 update request shouldn't corrupt updatelog"
28279
28280 test_428() {
28281         [ $PARALLEL == "yes" ] && skip "skip parallel run"
28282         local cache_limit=$CACHE_MAX
28283
28284         stack_trap "$LCTL set_param -n llite.*.max_cached_mb=$cache_limit"
28285         $LCTL set_param -n llite.*.max_cached_mb=64
28286
28287         mkdir $DIR/$tdir
28288         $LFS setstripe -c 1 $DIR/$tdir
28289         eval touch $DIR/$tdir/$tfile.{1..$OSTCOUNT}
28290         stack_trap "rm -f $DIR/$tdir/$tfile.*"
28291         #test write
28292         for f in $(seq 4); do
28293                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$f bs=128M count=1 &
28294         done
28295         wait
28296
28297         cancel_lru_locks osc
28298         # Test read
28299         for f in $(seq 4); do
28300                 dd if=$DIR/$tdir/$tfile.$f of=/dev/null bs=128M count=1 &
28301         done
28302         wait
28303 }
28304 run_test 428 "large block size IO should not hang"
28305
28306 test_429() { # LU-7915 / LU-10948
28307         local ll_opencache_threshold_count="llite.*.opencache_threshold_count"
28308         local testfile=$DIR/$tfile
28309         local mdc_rpcstats="mdc.$FSNAME-MDT0000-*.stats"
28310         local new_flag=1
28311         local first_rpc
28312         local second_rpc
28313         local third_rpc
28314
28315         $LCTL get_param $ll_opencache_threshold_count ||
28316                 skip "client does not have opencache parameter"
28317
28318         set_opencache $new_flag
28319         stack_trap "restore_opencache"
28320         [ $($LCTL get_param -n $ll_opencache_threshold_count) == $new_flag ] ||
28321                 error "enable opencache failed"
28322         touch $testfile
28323         # drop MDC DLM locks
28324         cancel_lru_locks mdc
28325         # clear MDC RPC stats counters
28326         $LCTL set_param $mdc_rpcstats=clear
28327
28328         # According to the current implementation, we need to run 3 times
28329         # open & close file to verify if opencache is enabled correctly.
28330         # 1st, RPCs are sent for lookup/open and open handle is released on
28331         #      close finally.
28332         # 2nd, RPC is sent for open, MDS_OPEN_LOCK is fetched automatically,
28333         #      so open handle won't be released thereafter.
28334         # 3rd, No RPC is sent out.
28335         $MULTIOP $testfile oc || error "multiop failed"
28336         first_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
28337         echo "1st: $first_rpc RPCs in flight"
28338
28339         $MULTIOP $testfile oc || error "multiop failed"
28340         second_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
28341         echo "2nd: $second_rpc RPCs in flight"
28342
28343         $MULTIOP $testfile oc || error "multiop failed"
28344         third_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
28345         echo "3rd: $third_rpc RPCs in flight"
28346
28347         #verify no MDC RPC is sent
28348         [[ $second_rpc == $third_rpc ]] || error "MDC RPC is still sent"
28349 }
28350 run_test 429 "verify if opencache flag on client side does work"
28351
28352 lseek_test_430() {
28353         local offset
28354         local file=$1
28355
28356         # data at [200K, 400K)
28357         dd if=/dev/urandom of=$file bs=256K count=1 seek=1 ||
28358                 error "256K->512K dd fails"
28359         # data at [2M, 3M)
28360         dd if=/dev/urandom of=$file bs=1M count=1 seek=2 ||
28361                 error "2M->3M dd fails"
28362         # data at [4M, 5M)
28363         dd if=/dev/urandom of=$file bs=1M count=1 seek=4 ||
28364                 error "4M->5M dd fails"
28365         echo "Data at 256K...512K, 2M...3M and 4M...5M"
28366         # start at first component hole #1
28367         printf "Seeking hole from 1000 ... "
28368         offset=$(lseek_test -l 1000 $file)
28369         echo $offset
28370         [[ $offset == 1000 ]] || error "offset $offset != 1000"
28371         printf "Seeking data from 1000 ... "
28372         offset=$(lseek_test -d 1000 $file)
28373         echo $offset
28374         [[ $offset == 262144 ]] || error "offset $offset != 262144"
28375
28376         # start at first component data block
28377         printf "Seeking hole from 300000 ... "
28378         offset=$(lseek_test -l 300000 $file)
28379         echo $offset
28380         [[ $offset == 524288 ]] || error "offset $offset != 524288"
28381         printf "Seeking data from 300000 ... "
28382         offset=$(lseek_test -d 300000 $file)
28383         echo $offset
28384         [[ $offset == 300000 ]] || error "offset $offset != 300000"
28385
28386         # start at the first component but beyond end of object size
28387         printf "Seeking hole from 1000000 ... "
28388         offset=$(lseek_test -l 1000000 $file)
28389         echo $offset
28390         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
28391         printf "Seeking data from 1000000 ... "
28392         offset=$(lseek_test -d 1000000 $file)
28393         echo $offset
28394         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
28395
28396         # start at second component stripe 2 (empty file)
28397         printf "Seeking hole from 1500000 ... "
28398         offset=$(lseek_test -l 1500000 $file)
28399         echo $offset
28400         [[ $offset == 1500000 ]] || error "offset $offset != 1500000"
28401         printf "Seeking data from 1500000 ... "
28402         offset=$(lseek_test -d 1500000 $file)
28403         echo $offset
28404         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
28405
28406         # start at second component stripe 1 (all data)
28407         printf "Seeking hole from 3000000 ... "
28408         offset=$(lseek_test -l 3000000 $file)
28409         echo $offset
28410         [[ $offset == 3145728 ]] || error "offset $offset != 3145728"
28411         printf "Seeking data from 3000000 ... "
28412         offset=$(lseek_test -d 3000000 $file)
28413         echo $offset
28414         [[ $offset == 3000000 ]] || error "offset $offset != 3000000"
28415
28416         dd if=/dev/urandom of=$file bs=640K count=1 seek=1 ||
28417                 error "2nd dd fails"
28418         echo "Add data block at 640K...1280K"
28419
28420         # start at before new data block, in hole
28421         printf "Seeking hole from 600000 ... "
28422         offset=$(lseek_test -l 600000 $file)
28423         echo $offset
28424         [[ $offset == 600000 ]] || error "offset $offset != 600000"
28425         printf "Seeking data from 600000 ... "
28426         offset=$(lseek_test -d 600000 $file)
28427         echo $offset
28428         [[ $offset == 655360 ]] || error "offset $offset != 655360"
28429
28430         # start at the first component new data block
28431         printf "Seeking hole from 1000000 ... "
28432         offset=$(lseek_test -l 1000000 $file)
28433         echo $offset
28434         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
28435         printf "Seeking data from 1000000 ... "
28436         offset=$(lseek_test -d 1000000 $file)
28437         echo $offset
28438         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
28439
28440         # start at second component stripe 2, new data
28441         printf "Seeking hole from 1200000 ... "
28442         offset=$(lseek_test -l 1200000 $file)
28443         echo $offset
28444         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
28445         printf "Seeking data from 1200000 ... "
28446         offset=$(lseek_test -d 1200000 $file)
28447         echo $offset
28448         [[ $offset == 1200000 ]] || error "offset $offset != 1200000"
28449
28450         # start beyond file end
28451         printf "Using offset > filesize ... "
28452         lseek_test -l 4000000 $file && error "lseek should fail"
28453         printf "Using offset > filesize ... "
28454         lseek_test -d 4000000 $file && error "lseek should fail"
28455
28456         printf "Done\n\n"
28457 }
28458
28459 test_430a() {
28460         $LCTL get_param mdc.*.import | grep -q 'connect_flags:.*seek' ||
28461                 skip "MDT does not support SEEK_HOLE"
28462
28463         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
28464                 skip "OST does not support SEEK_HOLE"
28465
28466         local file=$DIR/$tdir/$tfile
28467
28468         mkdir -p $DIR/$tdir
28469
28470         $LFS setstripe -E 1M -L mdt -E eof -c2 $file
28471         # OST stripe #1 will have continuous data at [1M, 3M)
28472         # OST stripe #2 is empty
28473         echo "Component #1: 1M DoM, component #2: EOF, 2 stripes 1M"
28474         lseek_test_430 $file
28475         rm $file
28476         $LFS setstripe -E 1M -c2 -S 64K -E 10M -c2 -S 1M $file
28477         echo "Component #1: 1M, 2 stripes 64K, component #2: EOF, 2 stripes 1M"
28478         lseek_test_430 $file
28479         rm $file
28480         $LFS setstripe -c2 -S 512K $file
28481         echo "Two stripes, stripe size 512K"
28482         lseek_test_430 $file
28483         rm $file
28484         # FLR with stale mirror
28485         $LFS setstripe -N -E 512K -c1 -S 64K -E eof -c2 -S 512K \
28486                        -N -c2 -S 1M $file
28487         echo "Mirrored file:"
28488         echo "Component #1: 512K, stripe 64K, component #2: EOF, 2 stripes 512K"
28489         echo "Plain 2 stripes 1M"
28490         lseek_test_430 $file
28491         rm $file
28492 }
28493 run_test 430a "lseek: SEEK_DATA/SEEK_HOLE basic functionality"
28494
28495 test_430b() {
28496         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
28497                 skip "OST does not support SEEK_HOLE"
28498
28499         local offset
28500         local file=$DIR/$tdir/$tfile
28501
28502         mkdir -p $DIR/$tdir
28503         # Empty layout lseek should fail
28504         $MCREATE $file
28505         # seek from 0
28506         printf "Seeking hole from 0 ... "
28507         lseek_test -l 0 $file && error "lseek should fail"
28508         printf "Seeking data from 0 ... "
28509         lseek_test -d 0 $file && error "lseek should fail"
28510         rm $file
28511
28512         # 1M-hole file
28513         $LFS setstripe -E 1M -c2 -E eof $file
28514         $TRUNCATE $file 1048576
28515         printf "Seeking hole from 1000000 ... "
28516         offset=$(lseek_test -l 1000000 $file)
28517         echo $offset
28518         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
28519         printf "Seeking data from 1000000 ... "
28520         lseek_test -d 1000000 $file && error "lseek should fail"
28521         rm $file
28522
28523         # full component followed by non-inited one
28524         $LFS setstripe -E 1M -c2 -E eof $file
28525         dd if=/dev/urandom of=$file bs=1M count=1
28526         printf "Seeking hole from 1000000 ... "
28527         offset=$(lseek_test -l 1000000 $file)
28528         echo $offset
28529         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
28530         printf "Seeking hole from 1048576 ... "
28531         lseek_test -l 1048576 $file && error "lseek should fail"
28532         # init second component and truncate back
28533         echo "123" >> $file
28534         $TRUNCATE $file 1048576
28535         printf "Seeking hole from 1000000 ... "
28536         offset=$(lseek_test -l 1000000 $file)
28537         echo $offset
28538         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
28539         printf "Seeking hole from 1048576 ... "
28540         lseek_test -l 1048576 $file && error "lseek should fail"
28541         # boundary checks for big values
28542         dd if=/dev/urandom of=$file.10g bs=1 count=1 seek=10G
28543         offset=$(lseek_test -d 0 $file.10g)
28544         [[ $offset == 10737418240 ]] || error "offset $offset != 10737418240"
28545         dd if=/dev/urandom of=$file.100g bs=1 count=1 seek=100G
28546         offset=$(lseek_test -d 0 $file.100g)
28547         [[ $offset == 107374182400 ]] || error "offset $offset != 107374182400"
28548         return 0
28549 }
28550 run_test 430b "lseek: SEEK_DATA/SEEK_HOLE special cases"
28551
28552 test_430c() {
28553         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
28554                 skip "OST does not support SEEK_HOLE"
28555
28556         local file=$DIR/$tdir/$tfile
28557         local start
28558
28559         mkdir -p $DIR/$tdir
28560         stack_trap "rm -f $file $file.tmp"
28561         dd if=/dev/urandom of=$file bs=1k count=1 seek=5M || error "dd failed"
28562
28563         # cp version 8.33+ prefers lseek over fiemap
28564         local ver=$(cp --version | awk '{ print $4; exit; }')
28565
28566         echo "cp $ver installed"
28567         if (( $(version_code $ver) >= $(version_code 8.33) )); then
28568                 start=$SECONDS
28569                 time cp -v $file $file.tmp || error "cp $file failed"
28570                 (( SECONDS - start < 5 )) || {
28571                         strace cp $file $file.tmp |&
28572                                 grep -E "open|read|seek|FIEMAP" |
28573                                 grep -A 100 $file
28574                         error "cp: too long runtime $((SECONDS - start))"
28575                 }
28576         else
28577                 echo "cp test skipped due to $ver < 8.33"
28578         fi
28579
28580         # tar version 1.29+ supports SEEK_HOLE/DATA
28581         ver=$(tar --version | awk '{ print $4; exit; }')
28582         echo "tar $ver installed"
28583         if (( $(version_code $ver) >= $(version_code 1.29) )); then
28584                 start=$SECONDS
28585                 time tar cvf $file.tmp --sparse $file || error "tar $file error"
28586                 (( SECONDS - start < 5 )) || {
28587                         strace tar cf $file.tmp --sparse $file |&
28588                                 grep -E "open|read|seek|FIEMAP" |
28589                                 grep -A 100 $file
28590                         error "tar: too long runtime $((SECONDS - start))"
28591                 }
28592         else
28593                 echo "tar test skipped due to $ver < 1.29"
28594         fi
28595 }
28596 run_test 430c "lseek: external tools check"
28597
28598 test_431() { # LU-14187
28599         local file=$DIR/$tdir/$tfile
28600
28601         mkdir -p $DIR/$tdir
28602         $LFS setstripe -c 1 -i 0 $file || error "lfs setstripe failed"
28603         dd if=/dev/urandom of=$file bs=4k count=1
28604         dd if=/dev/urandom of=$file bs=4k count=1 seek=10 conv=notrunc
28605         dd if=/dev/urandom of=$file bs=4k count=1 seek=12 conv=notrunc
28606         #define OBD_FAIL_OST_RESTART_IO 0x251
28607         do_facet ost1 "$LCTL set_param fail_loc=0x251"
28608         $LFS setstripe -c 1 -i 0 $file.0 || error "lfs setstripe failed"
28609         cp $file $file.0
28610         cancel_lru_locks
28611         sync_all_data
28612         echo 3 > /proc/sys/vm/drop_caches
28613         diff  $file $file.0 || error "data diff"
28614 }
28615 run_test 431 "Restart transaction for IO"
28616
28617 cleanup_test_432() {
28618         do_facet mgs $LCTL nodemap_activate 0
28619         wait_nm_sync active
28620 }
28621
28622 test_432() {
28623         local tmpdir=$TMP/dir432
28624
28625         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
28626                 skip "Need MDS version at least 2.14.52"
28627
28628         stack_trap cleanup_test_432 EXIT
28629         mkdir $DIR/$tdir
28630         mkdir $tmpdir
28631
28632         do_facet mgs $LCTL nodemap_activate 1
28633         wait_nm_sync active
28634         do_facet mgs $LCTL nodemap_modify --name default \
28635                 --property admin --value 1
28636         do_facet mgs $LCTL nodemap_modify --name default \
28637                 --property trusted --value 1
28638         cancel_lru_locks mdc
28639         wait_nm_sync default admin_nodemap
28640         wait_nm_sync default trusted_nodemap
28641
28642         if [ $(mv $tmpdir $DIR/$tdir/ 2>&1 |
28643                grep -ci "Operation not permitted") -ne 0 ]; then
28644                 error "mv $tmpdir $DIR/$tdir/ hits 'Operation not permitted'"
28645         fi
28646 }
28647 run_test 432 "mv dir from outside Lustre"
28648
28649 test_433() {
28650         [ $PARALLEL == "yes" ] && skip "skip parallel run"
28651
28652         [[ -n "$($LCTL list_param llite.*.inode_cache 2>/dev/null)" ]] ||
28653                 skip "inode cache not supported"
28654
28655         $LCTL set_param llite.*.inode_cache=0
28656         stack_trap "$LCTL set_param llite.*.inode_cache=1"
28657
28658         local count=256
28659         local before
28660         local after
28661
28662         cancel_lru_locks mdc
28663         test_mkdir $DIR/$tdir || error "mkdir $tdir"
28664         createmany -m $DIR/$tdir/f $count
28665         createmany -d $DIR/$tdir/d $count
28666         ls -l $DIR/$tdir > /dev/null
28667         stack_trap "rm -rf $DIR/$tdir"
28668
28669         before=$(num_objects)
28670         cancel_lru_locks mdc
28671         after=$(num_objects)
28672
28673         # sometimes even @before is less than 2 * count
28674         while (( before - after < count )); do
28675                 sleep 1
28676                 after=$(num_objects)
28677                 wait=$((wait + 1))
28678                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
28679                 if (( wait > 60 )); then
28680                         error "inode slab grew from $before to $after"
28681                 fi
28682         done
28683
28684         echo "lustre_inode_cache $before objs before lock cancel, $after after"
28685 }
28686 run_test 433 "ldlm lock cancel releases dentries and inodes"
28687
28688 test_434() {
28689         local file
28690         local getxattr_count
28691         local mdc_stat_param="mdc.$FSNAME-MDT0000*.md_stats"
28692         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
28693
28694         [[ $(getenforce) == "Disabled" ]] ||
28695                 skip "lsm selinux module have to be disabled for this test"
28696
28697         test_mkdir -i 0 -c1 $DIR/$tdir/ ||
28698                 error "fail to create $DIR/$tdir/ on MDT0000"
28699
28700         touch $DIR/$tdir/$tfile-{001..100}
28701
28702         # disable the xattr cache
28703         save_lustre_params client "llite.*.xattr_cache" > $p
28704         lctl set_param llite.*.xattr_cache=0
28705         stack_trap "restore_lustre_params < $p; rm -f $p" EXIT
28706
28707         # clear clients mdc stats
28708         clear_stats $mdc_stat_param ||
28709                 error "fail to clear stats on mdc MDT0000"
28710
28711         for file in $DIR/$tdir/$tfile-{001..100}; do
28712                 getfattr -n security.selinux $file |&
28713                         grep -q "Operation not supported" ||
28714                         error "getxattr on security.selinux should return EOPNOTSUPP"
28715         done
28716
28717         getxattr_count=$(calc_stats $mdc_stat_param "getxattr")
28718         (( getxattr_count < 100 )) ||
28719                 error "client sent $getxattr_count getxattr RPCs to the MDS"
28720 }
28721 run_test 434 "Client should not send RPCs for security.selinux with SElinux disabled"
28722
28723 test_440() {
28724         if [[ -f $LUSTRE/scripts/bash-completion/lustre ]]; then
28725                 source $LUSTRE/scripts/bash-completion/lustre
28726         elif [[ -f /usr/share/bash-completion/completions/lustre ]]; then
28727                 source /usr/share/bash-completion/completions/lustre
28728         else
28729                 skip "bash completion scripts not found"
28730         fi
28731
28732         local lctl_completions
28733         local lfs_completions
28734
28735         lctl_completions=$(_lustre_cmds lctl)
28736         if [[ ! $lctl_completions =~ "get_param" ]]; then
28737                 error "lctl bash completion failed"
28738         fi
28739
28740         lfs_completions=$(_lustre_cmds lfs)
28741         if [[ ! $lfs_completions =~ "setstripe" ]]; then
28742                 error "lfs bash completion failed"
28743         fi
28744 }
28745 run_test 440 "bash completion for lfs, lctl"
28746
28747 prep_801() {
28748         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
28749         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
28750                 skip "Need server version at least 2.9.55"
28751
28752         start_full_debug_logging
28753 }
28754
28755 post_801() {
28756         stop_full_debug_logging
28757 }
28758
28759 barrier_stat() {
28760         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
28761                 local st=$(do_facet mgs $LCTL barrier_stat $FSNAME |
28762                            awk '/The barrier for/ { print $7 }')
28763                 echo $st
28764         else
28765                 local st=$(do_facet mgs $LCTL barrier_stat -s $FSNAME)
28766                 echo \'$st\'
28767         fi
28768 }
28769
28770 barrier_expired() {
28771         local expired
28772
28773         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
28774                 expired=$(do_facet mgs $LCTL barrier_stat $FSNAME |
28775                           awk '/will be expired/ { print $7 }')
28776         else
28777                 expired=$(do_facet mgs $LCTL barrier_stat -t $FSNAME)
28778         fi
28779
28780         echo $expired
28781 }
28782
28783 test_801a() {
28784         prep_801
28785
28786         echo "Start barrier_freeze at: $(date)"
28787         #define OBD_FAIL_BARRIER_DELAY          0x2202
28788         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
28789         # Do not reduce barrier time - See LU-11873
28790         do_facet mgs $LCTL barrier_freeze $FSNAME 20 &
28791
28792         sleep 2
28793         local b_status=$(barrier_stat)
28794         echo "Got barrier status at: $(date)"
28795         [ "$b_status" = "'freezing_p1'" ] ||
28796                 error "(1) unexpected barrier status $b_status"
28797
28798         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
28799         wait
28800         b_status=$(barrier_stat)
28801         [ "$b_status" = "'frozen'" ] ||
28802                 error "(2) unexpected barrier status $b_status"
28803
28804         local expired=$(barrier_expired)
28805         echo "sleep $((expired + 3)) seconds, then the barrier will be expired"
28806         sleep $((expired + 3))
28807
28808         b_status=$(barrier_stat)
28809         [ "$b_status" = "'expired'" ] ||
28810                 error "(3) unexpected barrier status $b_status"
28811
28812         # Do not reduce barrier time - See LU-11873
28813         do_facet mgs $LCTL barrier_freeze $FSNAME 20 ||
28814                 error "(4) fail to freeze barrier"
28815
28816         b_status=$(barrier_stat)
28817         [ "$b_status" = "'frozen'" ] ||
28818                 error "(5) unexpected barrier status $b_status"
28819
28820         echo "Start barrier_thaw at: $(date)"
28821         #define OBD_FAIL_BARRIER_DELAY          0x2202
28822         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
28823         do_facet mgs $LCTL barrier_thaw $FSNAME &
28824
28825         sleep 2
28826         b_status=$(barrier_stat)
28827         echo "Got barrier status at: $(date)"
28828         [ "$b_status" = "'thawing'" ] ||
28829                 error "(6) unexpected barrier status $b_status"
28830
28831         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
28832         wait
28833         b_status=$(barrier_stat)
28834         [ "$b_status" = "'thawed'" ] ||
28835                 error "(7) unexpected barrier status $b_status"
28836
28837         #define OBD_FAIL_BARRIER_FAILURE        0x2203
28838         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2203
28839         do_facet mgs $LCTL barrier_freeze $FSNAME
28840
28841         b_status=$(barrier_stat)
28842         [ "$b_status" = "'failed'" ] ||
28843                 error "(8) unexpected barrier status $b_status"
28844
28845         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
28846         do_facet mgs $LCTL barrier_thaw $FSNAME
28847
28848         post_801
28849 }
28850 run_test 801a "write barrier user interfaces and stat machine"
28851
28852 test_801b() {
28853         prep_801
28854
28855         mkdir $DIR/$tdir || error "(1) fail to mkdir"
28856         createmany -d $DIR/$tdir/d 6 || error "(2) fail to mkdir"
28857         touch $DIR/$tdir/d2/f10 || error "(3) fail to touch"
28858         touch $DIR/$tdir/d3/f11 || error "(4) fail to touch"
28859         touch $DIR/$tdir/d4/f12 || error "(5) fail to touch"
28860
28861         cancel_lru_locks mdc
28862
28863         # 180 seconds should be long enough
28864         do_facet mgs $LCTL barrier_freeze $FSNAME 180
28865
28866         local b_status=$(barrier_stat)
28867         [ "$b_status" = "'frozen'" ] ||
28868                 error "(6) unexpected barrier status $b_status"
28869
28870         mkdir $DIR/$tdir/d0/d10 &
28871         mkdir_pid=$!
28872
28873         touch $DIR/$tdir/d1/f13 &
28874         touch_pid=$!
28875
28876         ln $DIR/$tdir/d2/f10 $DIR/$tdir/d2/f14 &
28877         ln_pid=$!
28878
28879         mv $DIR/$tdir/d3/f11 $DIR/$tdir/d3/f15 &
28880         mv_pid=$!
28881
28882         rm -f $DIR/$tdir/d4/f12 &
28883         rm_pid=$!
28884
28885         stat $DIR/$tdir/d5 || error "(7) stat should succeed"
28886
28887         # To guarantee taht the 'stat' is not blocked
28888         b_status=$(barrier_stat)
28889         [ "$b_status" = "'frozen'" ] ||
28890                 error "(8) unexpected barrier status $b_status"
28891
28892         # let above commands to run at background
28893         sleep 5
28894
28895         ps -p $mkdir_pid || error "(9) mkdir should be blocked"
28896         ps -p $touch_pid || error "(10) touch should be blocked"
28897         ps -p $ln_pid || error "(11) link should be blocked"
28898         ps -p $mv_pid || error "(12) rename should be blocked"
28899         ps -p $rm_pid || error "(13) unlink should be blocked"
28900
28901         b_status=$(barrier_stat)
28902         [ "$b_status" = "'frozen'" ] ||
28903                 error "(14) unexpected barrier status $b_status"
28904
28905         do_facet mgs $LCTL barrier_thaw $FSNAME
28906         b_status=$(barrier_stat)
28907         [ "$b_status" = "'thawed'" ] ||
28908                 error "(15) unexpected barrier status $b_status"
28909
28910         wait $mkdir_pid || error "(16) mkdir should succeed"
28911         wait $touch_pid || error "(17) touch should succeed"
28912         wait $ln_pid || error "(18) link should succeed"
28913         wait $mv_pid || error "(19) rename should succeed"
28914         wait $rm_pid || error "(20) unlink should succeed"
28915
28916         post_801
28917 }
28918 run_test 801b "modification will be blocked by write barrier"
28919
28920 test_801c() {
28921         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
28922
28923         prep_801
28924
28925         stop mds2 || error "(1) Fail to stop mds2"
28926
28927         do_facet mgs $LCTL barrier_freeze $FSNAME 30
28928
28929         local b_status=$(barrier_stat)
28930         [ "$b_status" = "'expired'" ] || [ "$b_status" = "'failed'" ] || {
28931                 do_facet mgs $LCTL barrier_thaw $FSNAME
28932                 error "(2) unexpected barrier status $b_status"
28933         }
28934
28935         do_facet mgs $LCTL barrier_rescan $FSNAME ||
28936                 error "(3) Fail to rescan barrier bitmap"
28937
28938         # Do not reduce barrier time - See LU-11873
28939         do_facet mgs $LCTL barrier_freeze $FSNAME 20
28940
28941         b_status=$(barrier_stat)
28942         [ "$b_status" = "'frozen'" ] ||
28943                 error "(4) unexpected barrier status $b_status"
28944
28945         do_facet mgs $LCTL barrier_thaw $FSNAME
28946         b_status=$(barrier_stat)
28947         [ "$b_status" = "'thawed'" ] ||
28948                 error "(5) unexpected barrier status $b_status"
28949
28950         local devname=$(mdsdevname 2)
28951
28952         start mds2 $devname $MDS_MOUNT_OPTS || error "(6) Fail to start mds2"
28953
28954         do_facet mgs $LCTL barrier_rescan $FSNAME ||
28955                 error "(7) Fail to rescan barrier bitmap"
28956
28957         post_801
28958 }
28959 run_test 801c "rescan barrier bitmap"
28960
28961 test_802b() {
28962         [ $PARALLEL == "yes" ] && skip "skip parallel run"
28963         remote_mds_nodsh && skip "remote MDS with nodsh"
28964
28965         do_facet $SINGLEMDS $LCTL get_param mdt.*.readonly ||
28966                 skip "readonly option not available"
28967
28968         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "(1) fail to mkdir"
28969
28970         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
28971                 error "(2) Fail to copy"
28972
28973         # write back all cached data before setting MDT to readonly
28974         cancel_lru_locks
28975         sync_all_data
28976
28977         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=1
28978         stack_trap "do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0" EXIT
28979
28980         echo "Modify should be refused"
28981         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
28982
28983         echo "Read should be allowed"
28984         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
28985                 error "(7) Read should succeed under ro mode"
28986
28987         # disable readonly
28988         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0
28989 }
28990 run_test 802b "be able to set MDTs to readonly"
28991
28992 test_803a() {
28993         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
28994         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
28995                 skip "MDS needs to be newer than 2.10.54"
28996
28997         mkdir_on_mdt0 $DIR/$tdir
28998         # Create some objects on all MDTs to trigger related logs objects
28999         for idx in $(seq $MDSCOUNT); do
29000                 $LFS mkdir -c $MDSCOUNT -i $((idx % $MDSCOUNT)) \
29001                         $DIR/$tdir/dir${idx} ||
29002                         error "Fail to create $DIR/$tdir/dir${idx}"
29003         done
29004
29005         wait_delete_completed # ensure old test cleanups are finished
29006         sleep 3
29007         echo "before create:"
29008         $LFS df -i $MOUNT
29009         local before_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
29010
29011         for i in {1..10}; do
29012                 $LFS mkdir -c 1 -i 1 $DIR/$tdir/foo$i ||
29013                         error "Fail to create $DIR/$tdir/foo$i"
29014         done
29015
29016         # sync ZFS-on-MDS to refresh statfs data
29017         wait_zfs_commit mds1
29018         sleep 3
29019         echo "after create:"
29020         $LFS df -i $MOUNT
29021         local after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
29022
29023         # allow for an llog to be cleaned up during the test
29024         [ $after_used -ge $((before_used + 10 - 1)) ] ||
29025                 error "before ($before_used) + 10 > after ($after_used)"
29026
29027         for i in {1..10}; do
29028                 rm -rf $DIR/$tdir/foo$i ||
29029                         error "Fail to remove $DIR/$tdir/foo$i"
29030         done
29031
29032         # sync ZFS-on-MDS to refresh statfs data
29033         wait_zfs_commit mds1
29034         wait_delete_completed
29035         sleep 3 # avoid MDT return cached statfs
29036         echo "after unlink:"
29037         $LFS df -i $MOUNT
29038         after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
29039
29040         # allow for an llog to be created during the test
29041         [ $after_used -le $((before_used + 1)) ] ||
29042                 error "after ($after_used) > before ($before_used) + 1"
29043 }
29044 run_test 803a "verify agent object for remote object"
29045
29046 test_803b() {
29047         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
29048         [ $MDS1_VERSION -lt $(version_code 2.13.56) ] &&
29049                 skip "MDS needs to be newer than 2.13.56"
29050         [ $PARALLEL == "yes" ] && skip "skip parallel run"
29051
29052         for i in $(seq 0 $((MDSCOUNT - 1))); do
29053                 $LFS mkdir -i $i $DIR/$tdir.$i || error "mkdir $tdir.$i"
29054         done
29055
29056         local before=0
29057         local after=0
29058
29059         local tmp
29060
29061         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
29062         for i in $(seq 0 $((MDSCOUNT - 1))); do
29063                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
29064                         awk '/getattr/ { print $2 }')
29065                 before=$((before + tmp))
29066         done
29067         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
29068         for i in $(seq 0 $((MDSCOUNT - 1))); do
29069                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
29070                         awk '/getattr/ { print $2 }')
29071                 after=$((after + tmp))
29072         done
29073
29074         [ $before -eq $after ] || error "getattr count $before != $after"
29075 }
29076 run_test 803b "remote object can getattr from cache"
29077
29078 test_804() {
29079         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
29080         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
29081                 skip "MDS needs to be newer than 2.10.54"
29082         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
29083
29084         mkdir -p $DIR/$tdir
29085         $LFS mkdir -c 1 -i 1 $DIR/$tdir/dir0 ||
29086                 error "Fail to create $DIR/$tdir/dir0"
29087
29088         local fid=$($LFS path2fid $DIR/$tdir/dir0)
29089         local dev=$(mdsdevname 2)
29090
29091         do_facet mds2 "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
29092                 grep ${fid} || error "NOT found agent entry for dir0"
29093
29094         $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir/dir1 ||
29095                 error "Fail to create $DIR/$tdir/dir1"
29096
29097         touch $DIR/$tdir/dir1/foo0 ||
29098                 error "Fail to create $DIR/$tdir/dir1/foo0"
29099         fid=$($LFS path2fid $DIR/$tdir/dir1/foo0)
29100         local rc=0
29101
29102         for idx in $(seq $MDSCOUNT); do
29103                 dev=$(mdsdevname $idx)
29104                 do_facet mds${idx} \
29105                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
29106                         grep ${fid} && rc=$idx
29107         done
29108
29109         mv $DIR/$tdir/dir1/foo0 $DIR/$tdir/dir1/foo1 ||
29110                 error "Fail to rename foo0 to foo1"
29111         if [ $rc -eq 0 ]; then
29112                 for idx in $(seq $MDSCOUNT); do
29113                         dev=$(mdsdevname $idx)
29114                         do_facet mds${idx} \
29115                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
29116                         grep ${fid} && rc=$idx
29117                 done
29118         fi
29119
29120         mv $DIR/$tdir/dir1/foo1 $DIR/$tdir/dir1/foo2 ||
29121                 error "Fail to rename foo1 to foo2"
29122         if [ $rc -eq 0 ]; then
29123                 for idx in $(seq $MDSCOUNT); do
29124                         dev=$(mdsdevname $idx)
29125                         do_facet mds${idx} \
29126                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
29127                         grep ${fid} && rc=$idx
29128                 done
29129         fi
29130
29131         [ $rc -ne 0 ] || error "NOT found agent entry for foo"
29132
29133         ln $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir0/guard ||
29134                 error "Fail to link to $DIR/$tdir/dir1/foo2"
29135         mv $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir1/foo0 ||
29136                 error "Fail to rename foo2 to foo0"
29137         unlink $DIR/$tdir/dir1/foo0 ||
29138                 error "Fail to unlink $DIR/$tdir/dir1/foo0"
29139         rm -rf $DIR/$tdir/dir0 ||
29140                 error "Fail to rm $DIR/$tdir/dir0"
29141
29142         for idx in $(seq $MDSCOUNT); do
29143                 rc=0
29144
29145                 stop mds${idx}
29146                 dev=$(mdsdevname $idx)
29147                 run_e2fsck $(facet_active_host mds$idx) $dev -n ||
29148                         rc=$?
29149                 start mds${idx} $dev $MDS_MOUNT_OPTS ||
29150                         error "mount mds$idx failed"
29151                 df $MOUNT > /dev/null 2>&1
29152
29153                 # e2fsck should not return error
29154                 [ $rc -eq 0 ] ||
29155                         error "e2fsck detected error on MDT${idx}: rc=$rc"
29156         done
29157 }
29158 run_test 804 "verify agent entry for remote entry"
29159
29160 cleanup_805() {
29161         do_facet $SINGLEMDS zfs set quota=$old $fsset
29162         unlinkmany $DIR/$tdir/f- 1000000
29163         trap 0
29164 }
29165
29166 test_805() {
29167         local zfs_version=$(do_facet mds1 cat /sys/module/zfs/version)
29168         [ "$mds1_FSTYPE" != "zfs" ] && skip "ZFS specific test"
29169         [ $(version_code $zfs_version) -lt $(version_code 0.7.2) ] &&
29170                 skip "netfree not implemented before 0.7"
29171         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
29172                 skip "Need MDS version at least 2.10.57"
29173
29174         local fsset
29175         local freekb
29176         local usedkb
29177         local old
29178         local quota
29179         local pref="osd-zfs.$FSNAME-MDT0000."
29180
29181         # limit available space on MDS dataset to meet nospace issue
29182         # quickly. then ZFS 0.7.2 can use reserved space if asked
29183         # properly (using netfree flag in osd_declare_destroy()
29184         fsset=$(do_facet $SINGLEMDS lctl get_param -n $pref.mntdev)
29185         old=$(do_facet $SINGLEMDS zfs get -H quota $fsset | \
29186                 gawk '{print $3}')
29187         freekb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytesfree)
29188         usedkb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytestotal)
29189         let "usedkb=usedkb-freekb"
29190         let "freekb=freekb/2"
29191         if let "freekb > 5000"; then
29192                 let "freekb=5000"
29193         fi
29194         do_facet $SINGLEMDS zfs set quota=$(((usedkb+freekb)*1024)) $fsset
29195         trap cleanup_805 EXIT
29196         mkdir_on_mdt0 $DIR/$tdir
29197         $LFS setstripe -E 1M -c2 -E 4M -c2 -E -1 -c2 $DIR/$tdir ||
29198                 error "Can't set PFL layout"
29199         createmany -m $DIR/$tdir/f- 1000000 && error "ENOSPC wasn't met"
29200         rm -rf $DIR/$tdir || error "not able to remove"
29201         do_facet $SINGLEMDS zfs set quota=$old $fsset
29202         trap 0
29203 }
29204 run_test 805 "ZFS can remove from full fs"
29205
29206 # Size-on-MDS test
29207 check_lsom_data()
29208 {
29209         local file=$1
29210         local expect=$(stat -c %s $file)
29211
29212         check_lsom_size $1 $expect
29213
29214         local blocks=$($LFS getsom -b $file)
29215         expect=$(stat -c %b $file)
29216         [[ $blocks == $expect ]] ||
29217                 error "$file expected blocks: $expect, got: $blocks"
29218 }
29219
29220 check_lsom_size()
29221 {
29222         local size
29223         local expect=$2
29224
29225         cancel_lru_locks mdc
29226
29227         size=$($LFS getsom -s $1)
29228         [[ $size == $expect ]] ||
29229                 error "$file expected size: $expect, got: $size"
29230 }
29231
29232 test_806() {
29233         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
29234                 skip "Need MDS version at least 2.11.52"
29235
29236         local bs=1048576
29237
29238         $LFS setstripe -c-1 $DIR/$tfile || error "setstripe $tfile failed"
29239
29240         disable_opencache
29241         stack_trap "restore_opencache"
29242
29243         # single-threaded write
29244         echo "Test SOM for single-threaded write"
29245         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 ||
29246                 error "write $tfile failed"
29247         check_lsom_size $DIR/$tfile $bs
29248
29249         local num=32
29250         local size=$(($num * $bs))
29251         local offset=0
29252         local i
29253
29254         echo "Test SOM for single client multi-threaded($num) write"
29255         $TRUNCATE $DIR/$tfile 0
29256         for ((i = 0; i < $num; i++)); do
29257                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
29258                 local pids[$i]=$!
29259                 offset=$((offset + $bs))
29260         done
29261         for (( i=0; i < $num; i++ )); do
29262                 wait ${pids[$i]}
29263         done
29264         check_lsom_size $DIR/$tfile $size
29265
29266         $TRUNCATE $DIR/$tfile 0
29267         for ((i = 0; i < $num; i++)); do
29268                 offset=$((offset - $bs))
29269                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
29270                 local pids[$i]=$!
29271         done
29272         for (( i=0; i < $num; i++ )); do
29273                 wait ${pids[$i]}
29274         done
29275         check_lsom_size $DIR/$tfile $size
29276
29277         # multi-client writes
29278         num=$(get_node_count ${CLIENTS//,/ })
29279         size=$(($num * $bs))
29280         offset=0
29281         i=0
29282
29283         echo "Test SOM for multi-client ($num) writes"
29284         $TRUNCATE $DIR/$tfile 0
29285         for client in ${CLIENTS//,/ }; do
29286                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
29287                 local pids[$i]=$!
29288                 i=$((i + 1))
29289                 offset=$((offset + $bs))
29290         done
29291         for (( i=0; i < $num; i++ )); do
29292                 wait ${pids[$i]}
29293         done
29294         check_lsom_size $DIR/$tfile $offset
29295
29296         i=0
29297         $TRUNCATE $DIR/$tfile 0
29298         for client in ${CLIENTS//,/ }; do
29299                 offset=$((offset - $bs))
29300                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
29301                 local pids[$i]=$!
29302                 i=$((i + 1))
29303         done
29304         for (( i=0; i < $num; i++ )); do
29305                 wait ${pids[$i]}
29306         done
29307         check_lsom_size $DIR/$tfile $size
29308
29309         # verify SOM blocks count
29310         echo "Verify SOM block count"
29311         $TRUNCATE $DIR/$tfile 0
29312         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w$((bs))YSc ||
29313                 error "failed to write file $tfile with fdatasync and fstat"
29314         check_lsom_data $DIR/$tfile
29315
29316         $TRUNCATE $DIR/$tfile 0
29317         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w$((bs * 2))Yc ||
29318                 error "failed to write file $tfile with fdatasync"
29319         check_lsom_data $DIR/$tfile
29320
29321         $TRUNCATE $DIR/$tfile 0
29322         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:O_SYNC:w$((bs * 3))c ||
29323                 error "failed to write file $tfile with sync IO"
29324         check_lsom_data $DIR/$tfile
29325
29326         # verify truncate
29327         echo "Test SOM for truncate"
29328         # use ftruncate to sync blocks on close request
29329         $MULTIOP $DIR/$tfile oO_WRONLY:T16384c
29330         check_lsom_size $DIR/$tfile 16384
29331         check_lsom_data $DIR/$tfile
29332
29333         $TRUNCATE $DIR/$tfile 1234
29334         check_lsom_size $DIR/$tfile 1234
29335         # sync blocks on the MDT
29336         $MULTIOP $DIR/$tfile oc
29337         check_lsom_data $DIR/$tfile
29338 }
29339 run_test 806 "Verify Lazy Size on MDS"
29340
29341 test_807() {
29342         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
29343         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
29344                 skip "Need MDS version at least 2.11.52"
29345
29346         # Registration step
29347         changelog_register || error "changelog_register failed"
29348         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
29349         changelog_users $SINGLEMDS | grep -q $cl_user ||
29350                 error "User $cl_user not found in changelog_users"
29351
29352         rm -rf $DIR/$tdir || error "rm $tdir failed"
29353         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
29354         touch $DIR/$tdir/trunc || error "touch $tdir/trunc failed"
29355         $TRUNCATE $DIR/$tdir/trunc 1024 || error "truncate $tdir/trunc failed"
29356         $TRUNCATE $DIR/$tdir/trunc 1048576 ||
29357                 error "truncate $tdir/trunc failed"
29358
29359         local bs=1048576
29360         echo "Test SOM for single-threaded write with fsync"
29361         dd if=/dev/zero of=$DIR/$tdir/single_dd bs=$bs count=1 ||
29362                 error "write $tfile failed"
29363         sync;sync;sync
29364
29365         # multi-client wirtes
29366         local num=$(get_node_count ${CLIENTS//,/ })
29367         local offset=0
29368         local i=0
29369
29370         echo "Test SOM for multi-client ($num) writes"
29371         touch $DIR/$tfile || error "touch $tfile failed"
29372         $TRUNCATE $DIR/$tfile 0
29373         for client in ${CLIENTS//,/ }; do
29374                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
29375                 local pids[$i]=$!
29376                 i=$((i + 1))
29377                 offset=$((offset + $bs))
29378         done
29379         for (( i=0; i < $num; i++ )); do
29380                 wait ${pids[$i]}
29381         done
29382
29383         do_rpc_nodes "$CLIENTS" cancel_lru_locks osc
29384         do_nodes "$CLIENTS" "sync ; sleep 5 ; sync"
29385         $LSOM_SYNC -u $cl_user -m $FSNAME-MDT0000 $MOUNT
29386         check_lsom_data $DIR/$tdir/trunc
29387         check_lsom_data $DIR/$tdir/single_dd
29388         check_lsom_data $DIR/$tfile
29389
29390         rm -rf $DIR/$tdir
29391         # Deregistration step
29392         changelog_deregister || error "changelog_deregister failed"
29393 }
29394 run_test 807 "verify LSOM syncing tool"
29395
29396 check_som_nologged()
29397 {
29398         local lines=$($LFS changelog $FSNAME-MDT0000 |
29399                 grep 'x=trusted.som' | wc -l)
29400         [ $lines -ne 0 ] && error "trusted.som xattr is logged in Changelogs"
29401 }
29402
29403 test_808() {
29404         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
29405                 skip "Need MDS version at least 2.11.55"
29406
29407         # Registration step
29408         changelog_register || error "changelog_register failed"
29409
29410         touch $DIR/$tfile || error "touch $tfile failed"
29411         check_som_nologged
29412
29413         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=1 ||
29414                 error "write $tfile failed"
29415         check_som_nologged
29416
29417         $TRUNCATE $DIR/$tfile 1234
29418         check_som_nologged
29419
29420         $TRUNCATE $DIR/$tfile 1048576
29421         check_som_nologged
29422
29423         # Deregistration step
29424         changelog_deregister || error "changelog_deregister failed"
29425 }
29426 run_test 808 "Check trusted.som xattr not logged in Changelogs"
29427
29428 check_som_nodata()
29429 {
29430         $LFS getsom $1
29431         [[ $? -eq 61 ]] || error "DoM-only file $1 has SOM xattr"
29432 }
29433
29434 test_809() {
29435         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
29436                 skip "Need MDS version at least 2.11.56"
29437
29438         $LFS setstripe -E 1M -L mdt $DIR/$tfile ||
29439                 error "failed to create DoM-only file $DIR/$tfile"
29440         touch $DIR/$tfile || error "touch $tfile failed"
29441         check_som_nodata $DIR/$tfile
29442
29443         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 ||
29444                 error "write $tfile failed"
29445         check_som_nodata $DIR/$tfile
29446
29447         $TRUNCATE $DIR/$tfile 1234
29448         check_som_nodata $DIR/$tfile
29449
29450         $TRUNCATE $DIR/$tfile 4097
29451         check_som_nodata $DIR/$file
29452 }
29453 run_test 809 "Verify no SOM xattr store for DoM-only files"
29454
29455 test_810() {
29456         [ $PARALLEL == "yes" ] && skip "skip parallel run"
29457         $GSS && skip_env "could not run with gss"
29458         [[ $OST1_VERSION -gt $(version_code 2.12.58) ]] ||
29459                 skip "OST < 2.12.58 doesn't align checksum"
29460
29461         set_checksums 1
29462         stack_trap "set_checksums $ORIG_CSUM" EXIT
29463         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
29464
29465         local csum
29466         local before
29467         local after
29468         for csum in $CKSUM_TYPES; do
29469                 #define OBD_FAIL_OSC_NO_GRANT   0x411
29470                 $LCTL set_param osc.*.checksum_type=$csum fail_loc=0x411
29471                 for i in "10240 0" "10000 0" "4000 1" "500 1"; do
29472                         eval set -- $i
29473                         dd if=/dev/urandom of=$DIR/$tfile bs=$1 count=2 seek=$2
29474                         before=$(md5sum $DIR/$tfile)
29475                         $LCTL set_param ldlm.namespaces.*osc*.lru_size=clear
29476                         after=$(md5sum $DIR/$tfile)
29477                         [ "$before" == "$after" ] ||
29478                                 error "$csum: $before != $after bs=$1 seek=$2"
29479                 done
29480         done
29481 }
29482 run_test 810 "partial page writes on ZFS (LU-11663)"
29483
29484 test_812a() {
29485         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
29486                 skip "OST < 2.12.51 doesn't support this fail_loc"
29487
29488         $LFS setstripe -c 1 -i 0 $DIR/$tfile
29489         # ensure ost1 is connected
29490         stat $DIR/$tfile >/dev/null || error "can't stat"
29491         wait_osc_import_state client ost1 FULL
29492         # no locks, no reqs to let the connection idle
29493         cancel_lru_locks osc
29494
29495         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
29496 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
29497         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
29498         wait_osc_import_state client ost1 CONNECTING
29499         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
29500
29501         stat $DIR/$tfile >/dev/null || error "can't stat file"
29502 }
29503 run_test 812a "do not drop reqs generated when imp is going to idle (LU-11951)"
29504
29505 test_812b() { # LU-12378
29506         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
29507                 skip "OST < 2.12.51 doesn't support this fail_loc"
29508
29509         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "setstripe failed"
29510         # ensure ost1 is connected
29511         stat $DIR/$tfile >/dev/null || error "can't stat"
29512         wait_osc_import_state client ost1 FULL
29513         # no locks, no reqs to let the connection idle
29514         cancel_lru_locks osc
29515
29516         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
29517 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
29518         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
29519         wait_osc_import_state client ost1 CONNECTING
29520         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
29521
29522         $LFS quota -u 0 $DIR/ || error "lfs quota should succeed"
29523         wait_osc_import_state client ost1 IDLE
29524 }
29525 run_test 812b "do not drop no resend request for idle connect"
29526
29527 test_812c() {
29528         local old
29529
29530         old=$($LCTL get_param -n osc.*.idle_timeout | head -n 1)
29531
29532         $LFS setstripe -c 1 -o 0 $DIR/$tfile
29533         $LFS getstripe $DIR/$tfile
29534         $LCTL set_param osc.*.idle_timeout=10
29535         stack_trap "$LCTL set_param osc.*.idle_timeout=$old" EXIT
29536         # ensure ost1 is connected
29537         stat $DIR/$tfile >/dev/null || error "can't stat"
29538         wait_osc_import_state client ost1 FULL
29539         # no locks, no reqs to let the connection idle
29540         cancel_lru_locks osc
29541
29542 #define OBD_FAIL_PTLRPC_IDLE_RACE        0x533
29543         $LCTL set_param fail_loc=0x80000533
29544         sleep 15
29545         dd if=/dev/zero of=$DIR/$tfile count=1 conv=sync || error "dd failed"
29546 }
29547 run_test 812c "idle import vs lock enqueue race"
29548
29549 test_813() {
29550         local file_heat_sav=$($LCTL get_param -n llite.*.file_heat 2>/dev/null)
29551         [ -z "$file_heat_sav" ] && skip "no file heat support"
29552
29553         local readsample
29554         local writesample
29555         local readbyte
29556         local writebyte
29557         local readsample1
29558         local writesample1
29559         local readbyte1
29560         local writebyte1
29561
29562         local period_second=$($LCTL get_param -n llite.*.heat_period_second)
29563         local decay_pct=$($LCTL get_param -n llite.*.heat_decay_percentage)
29564
29565         $LCTL set_param -n llite.*.file_heat=1
29566         echo "Turn on file heat"
29567         echo "Period second: $period_second, Decay percentage: $decay_pct"
29568
29569         echo "QQQQ" > $DIR/$tfile
29570         echo "QQQQ" > $DIR/$tfile
29571         echo "QQQQ" > $DIR/$tfile
29572         cat $DIR/$tfile > /dev/null
29573         cat $DIR/$tfile > /dev/null
29574         cat $DIR/$tfile > /dev/null
29575         cat $DIR/$tfile > /dev/null
29576
29577         local out=$($LFS heat_get $DIR/$tfile)
29578
29579         $LFS heat_get $DIR/$tfile
29580         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
29581         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
29582         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
29583         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
29584
29585         [ $readsample -le 4 ] || error "read sample ($readsample) is wrong"
29586         [ $writesample -le 3 ] || error "write sample ($writesample) is wrong"
29587         [ $readbyte -le 20 ] || error "read bytes ($readbyte) is wrong"
29588         [ $writebyte -le 15 ] || error "write bytes ($writebyte) is wrong"
29589
29590         sleep $((period_second + 3))
29591         echo "Sleep $((period_second + 3)) seconds..."
29592         # The recursion formula to calculate the heat of the file f is as
29593         # follow:
29594         # Hi+1(f) = (1-P)*Hi(f)+ P*Ci
29595         # Where Hi is the heat value in the period between time points i*I and
29596         # (i+1)*I; Ci is the access count in the period; the symbol P refers
29597         # to the weight of Ci.
29598         out=$($LFS heat_get $DIR/$tfile)
29599         $LFS heat_get $DIR/$tfile
29600         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
29601         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
29602         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
29603         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
29604
29605         [ $(bc <<< "$readsample <= 4 * $decay_pct / 100") -eq 1 ] ||
29606                 error "read sample ($readsample) is wrong"
29607         [ $(bc <<< "$writesample <= 3 * $decay_pct / 100") -eq 1 ] ||
29608                 error "write sample ($writesample) is wrong"
29609         [ $(bc <<< "$readbyte <= 20 * $decay_pct / 100") -eq 1 ] ||
29610                 error "read bytes ($readbyte) is wrong"
29611         [ $(bc <<< "$writebyte <= 15 * $decay_pct / 100") -eq 1 ] ||
29612                 error "write bytes ($writebyte) is wrong"
29613
29614         echo "QQQQ" > $DIR/$tfile
29615         echo "QQQQ" > $DIR/$tfile
29616         echo "QQQQ" > $DIR/$tfile
29617         cat $DIR/$tfile > /dev/null
29618         cat $DIR/$tfile > /dev/null
29619         cat $DIR/$tfile > /dev/null
29620         cat $DIR/$tfile > /dev/null
29621
29622         sleep $((period_second + 3))
29623         echo "Sleep $((period_second + 3)) seconds..."
29624
29625         out=$($LFS heat_get $DIR/$tfile)
29626         $LFS heat_get $DIR/$tfile
29627         readsample1=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
29628         writesample1=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
29629         readbyte1=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
29630         writebyte1=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
29631
29632         [ $(bc <<< "$readsample1 <= ($readsample * (100 - $decay_pct) + \
29633                 4 * $decay_pct) / 100") -eq 1 ] ||
29634                 error "read sample ($readsample1) is wrong"
29635         [ $(bc <<< "$writesample1 <= ($writesample * (100 - $decay_pct) + \
29636                 3 * $decay_pct) / 100") -eq 1 ] ||
29637                 error "write sample ($writesample1) is wrong"
29638         [ $(bc <<< "$readbyte1 <= ($readbyte * (100 - $decay_pct) + \
29639                 20 * $decay_pct) / 100") -eq 1 ] ||
29640                 error "read bytes ($readbyte1) is wrong"
29641         [ $(bc <<< "$writebyte1 <= ($writebyte * (100 - $decay_pct) + \
29642                 15 * $decay_pct) / 100") -eq 1 ] ||
29643                 error "write bytes ($writebyte1) is wrong"
29644
29645         echo "Turn off file heat for the file $DIR/$tfile"
29646         $LFS heat_set -o $DIR/$tfile
29647
29648         echo "QQQQ" > $DIR/$tfile
29649         echo "QQQQ" > $DIR/$tfile
29650         echo "QQQQ" > $DIR/$tfile
29651         cat $DIR/$tfile > /dev/null
29652         cat $DIR/$tfile > /dev/null
29653         cat $DIR/$tfile > /dev/null
29654         cat $DIR/$tfile > /dev/null
29655
29656         out=$($LFS heat_get $DIR/$tfile)
29657         $LFS heat_get $DIR/$tfile
29658         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
29659         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
29660         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
29661         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
29662
29663         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
29664         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
29665         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
29666         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
29667
29668         echo "Trun on file heat for the file $DIR/$tfile"
29669         $LFS heat_set -O $DIR/$tfile
29670
29671         echo "QQQQ" > $DIR/$tfile
29672         echo "QQQQ" > $DIR/$tfile
29673         echo "QQQQ" > $DIR/$tfile
29674         cat $DIR/$tfile > /dev/null
29675         cat $DIR/$tfile > /dev/null
29676         cat $DIR/$tfile > /dev/null
29677         cat $DIR/$tfile > /dev/null
29678
29679         out=$($LFS heat_get $DIR/$tfile)
29680         $LFS heat_get $DIR/$tfile
29681         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
29682         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
29683         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
29684         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
29685
29686         [ $readsample -gt 0 ] || error "read sample ($readsample) is wrong"
29687         [ $writesample -gt 0 ] || error "write sample ($writesample) is wrong"
29688         [ $readbyte -gt 0 ] || error "read bytes ($readbyte) is wrong"
29689         [ $writebyte -gt 0 ] || error "write bytes ($writebyte) is wrong"
29690
29691         $LFS heat_set -c $DIR/$tfile
29692         $LCTL set_param -n llite.*.file_heat=0
29693         echo "Turn off file heat support for the Lustre filesystem"
29694
29695         echo "QQQQ" > $DIR/$tfile
29696         echo "QQQQ" > $DIR/$tfile
29697         echo "QQQQ" > $DIR/$tfile
29698         cat $DIR/$tfile > /dev/null
29699         cat $DIR/$tfile > /dev/null
29700         cat $DIR/$tfile > /dev/null
29701         cat $DIR/$tfile > /dev/null
29702
29703         out=$($LFS heat_get $DIR/$tfile)
29704         $LFS heat_get $DIR/$tfile
29705         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
29706         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
29707         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
29708         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
29709
29710         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
29711         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
29712         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
29713         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
29714
29715         $LCTL set_param -n llite.*.file_heat=$file_heat_sav
29716         rm -f $DIR/$tfile
29717 }
29718 run_test 813 "File heat verfication"
29719
29720 test_814()
29721 {
29722         dd of=$DIR/$tfile seek=128 bs=1k < /dev/null
29723         echo -n y >> $DIR/$tfile
29724         cp --sparse=always $DIR/$tfile $DIR/${tfile}.cp || error "copy failed"
29725         diff $DIR/$tfile $DIR/${tfile}.cp || error "files should be same"
29726 }
29727 run_test 814 "sparse cp works as expected (LU-12361)"
29728
29729 test_815()
29730 {
29731         writeme -b 100 $DIR/$tfile || error "write 100 bytes failed"
29732         writeme -b 0 $DIR/$tfile || error "write 0 byte failed"
29733 }
29734 run_test 815 "zero byte tiny write doesn't hang (LU-12382)"
29735
29736 test_816() {
29737         local ost1_imp=$(get_osc_import_name client ost1)
29738         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
29739                          cut -d'.' -f2)
29740
29741         $LFS setstripe -c 1 -i 0 $DIR/$tfile
29742         # ensure ost1 is connected
29743
29744         stat $DIR/$tfile >/dev/null || error "can't stat"
29745         wait_osc_import_state client ost1 FULL
29746         # no locks, no reqs to let the connection idle
29747         cancel_lru_locks osc
29748         lru_resize_disable osc
29749         local before
29750         local now
29751         before=$($LCTL get_param -n \
29752                  ldlm.namespaces.$imp_name.lru_size)
29753
29754         wait_osc_import_state client ost1 IDLE
29755         dd if=/dev/null of=$DIR/$tfile bs=1k count=1 conv=sync
29756         now=$($LCTL get_param -n \
29757               ldlm.namespaces.$imp_name.lru_size)
29758         [ $before == $now ] || error "lru_size changed $before != $now"
29759 }
29760 run_test 816 "do not reset lru_resize on idle reconnect"
29761
29762 cleanup_817() {
29763         umount $tmpdir
29764         exportfs -u localhost:$DIR/nfsexp
29765         rm -rf $DIR/nfsexp
29766 }
29767
29768 test_817() {
29769         systemctl restart nfs-server.service || skip "failed to restart nfsd"
29770
29771         mkdir -p $DIR/nfsexp
29772         exportfs -orw,no_root_squash localhost:$DIR/nfsexp ||
29773                 error "failed to export nfs"
29774
29775         tmpdir=$(mktemp -d /tmp/nfs-XXXXXX)
29776         stack_trap cleanup_817 EXIT
29777
29778         mount -t nfs -orw localhost:$DIR/nfsexp $tmpdir ||
29779                 error "failed to mount nfs to $tmpdir"
29780
29781         cp /bin/true $tmpdir
29782         $DIR/nfsexp/true || error "failed to execute 'true' command"
29783 }
29784 run_test 817 "nfsd won't cache write lock for exec file"
29785
29786 test_818() {
29787         test_mkdir -i0 -c1 $DIR/$tdir
29788         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
29789         $LFS setstripe -c1 -i1 $DIR/$tdir/$tfile
29790         stop $SINGLEMDS
29791
29792         # restore osp-syn threads
29793         stack_trap "fail $SINGLEMDS"
29794
29795         #define OBD_FAIL_OSP_CANT_PROCESS_LLOG          0x2105
29796         do_facet $SINGLEMDS lctl set_param fail_loc=0x80002105
29797         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
29798                 error "start $SINGLEMDS failed"
29799         rm -rf $DIR/$tdir
29800
29801         local testid=$(echo $TESTNAME | tr '_' ' ')
29802
29803         do_facet mds1 dmesg | tac | sed "/$testid/,$ d" |
29804                 grep "run LFSCK" || error "run LFSCK is not suggested"
29805 }
29806 run_test 818 "unlink with failed llog"
29807
29808 test_819a() {
29809         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
29810         cancel_lru_locks osc
29811         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
29812         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
29813         dd if=$DIR/$tfile of=/dev/null bs=1M count=1
29814         rm -f $TDIR/$tfile
29815 }
29816 run_test 819a "too big niobuf in read"
29817
29818 test_819b() {
29819         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
29820         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
29821         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
29822         cancel_lru_locks osc
29823         sleep 1
29824         rm -f $TDIR/$tfile
29825 }
29826 run_test 819b "too big niobuf in write"
29827
29828
29829 function test_820_start_ost() {
29830         sleep 5
29831
29832         for num in $(seq $OSTCOUNT); do
29833                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS
29834         done
29835 }
29836
29837 test_820() {
29838         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
29839
29840         mkdir $DIR/$tdir
29841         umount_client $MOUNT || error "umount failed"
29842         for num in $(seq $OSTCOUNT); do
29843                 stop ost$num
29844         done
29845
29846         # mount client with no active OSTs
29847         # so that the client can't initialize max LOV EA size
29848         # from OSC notifications
29849         mount_client $MOUNT || error "mount failed"
29850         # delay OST starting to keep this 0 max EA size for a while
29851         test_820_start_ost &
29852
29853         # create a directory on MDS2
29854         test_mkdir -i 1 -c1 $DIR/$tdir/mds2 ||
29855                 error "Failed to create directory"
29856         # open intent should update default EA size
29857         # see mdc_update_max_ea_from_body()
29858         # notice this is the very first RPC to MDS2
29859         out=$(cp /etc/services $DIR/$tdir/mds2 2>&1)
29860         ret=$?
29861         echo $out
29862         # With SSK, this situation can lead to -EPERM being returned.
29863         # In that case, simply retry.
29864         if [ $ret -ne 0 ] && $SHARED_KEY; then
29865                 if echo "$out" | grep -q "not permitted"; then
29866                         cp /etc/services $DIR/$tdir/mds2
29867                         ret=$?
29868                 fi
29869         fi
29870         [ $ret -eq 0 ] || error "Failed to copy files to mds$n"
29871 }
29872 run_test 820 "update max EA from open intent"
29873
29874 test_823() {
29875         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
29876         local OST_MAX_PRECREATE=20000
29877
29878         (( $MDS1_VERSION >= $(version_code 2.14.56) )) ||
29879                 skip "Need MDS version at least 2.14.56"
29880
29881         save_lustre_params mds1 \
29882                 "osp.$FSNAME-OST*-osc-MDT0000.max_create_count" > $p
29883         do_facet $SINGLEMDS "$LCTL set_param -n \
29884                 osp.$FSNAME-OST*MDT0000.max_create_count=0"
29885         do_facet $SINGLEMDS "$LCTL set_param -n \
29886                 osp.$FSNAME-OST0000*MDT0000.max_create_count=$OST_MAX_PRECREATE"
29887
29888         stack_trap "restore_lustre_params < $p; rm $p"
29889
29890         do_facet $SINGLEMDS "$LCTL set_param -n \
29891                 osp.$FSNAME-OST*-osc-MDT*.create_count=100200"
29892
29893         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
29894                       osp.$FSNAME-OST0000*MDT0000.create_count")
29895         local max=$(do_facet $SINGLEMDS "$LCTL get_param -n \
29896                     osp.$FSNAME-OST0000*MDT0000.max_create_count")
29897         local expect_count=$(((($max/2)/256) * 256))
29898
29899         log "setting create_count to 100200:"
29900         log " -result- count: $count with max: $max, expecting: $expect_count"
29901
29902         [[ $count -eq expect_count ]] ||
29903                 error "Create count not set to max precreate."
29904 }
29905 run_test 823 "Setting create_count > OST_MAX_PRECREATE is lowered to maximum"
29906
29907 test_831() {
29908         [[ $MDS1_VERSION -lt $(version_code 2.14.56) ]] &&
29909                 skip "Need MDS version 2.14.56"
29910
29911         local sync_changes=$(do_facet $SINGLEMDS \
29912                 $LCTL get_param -n osp.$FSNAME-OST0000-osc-MDT0000.sync_changes)
29913
29914         [ "$sync_changes" -gt 100 ] &&
29915                 skip "Sync changes $sync_changes > 100 already"
29916
29917         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
29918
29919         $LFS mkdir -i 0 $DIR/$tdir
29920         $LFS setstripe -c 1 -i 0 $DIR/$tdir
29921
29922         save_lustre_params mds1 \
29923                 "osp.$FSNAME-OST*-osc-MDT0000.max_sync_changes" > $p
29924         save_lustre_params mds1 \
29925                 "osp.$FSNAME-OST*-osc-MDT0000.max_rpcs_in_progress" >> $p
29926
29927         do_facet mds1 "$LCTL set_param -n \
29928                 osp.$FSNAME-OST*-osc-MDT0000.max_sync_changes=100 \
29929                 osp.$FSNAME-OST*-osc-MDT0000.max_rpcs_in_progress=128"
29930         stack_trap "restore_lustre_params < $p" EXIT
29931
29932         createmany -o $DIR/$tdir/f- 1000
29933         unlinkmany $DIR/$tdir/f- 1000 &
29934         local UNLINK_PID=$!
29935
29936         while sleep 1; do
29937                 sync_changes=$(do_facet mds1 \
29938                 $LCTL get_param -n osp.$FSNAME-OST0000-osc-MDT0000.sync_changes)
29939                 # the check in the code is racy, fail the test
29940                 # if the value above the limit by 10.
29941                 [ $sync_changes -gt 110 ] && {
29942                         kill -2 $UNLINK_PID
29943                         wait
29944                         error "osp changes throttling failed, $sync_changes>110"
29945                 }
29946                 kill -0 $UNLINK_PID 2> /dev/null || break
29947         done
29948         wait
29949 }
29950 run_test 831 "throttling unlink/setattr queuing on OSP"
29951
29952 test_832() {
29953         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
29954         (( $MDS1_VERSION >= $(version_code 2.15.52) )) ||
29955                 skip "Need MDS version 2.15.52+"
29956         is_rmentry_supported || skip "rm_entry not supported"
29957
29958         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
29959         mkdir $DIR/$tdir/local_dir || error "mkdir local_dir failed"
29960         mkdir_on_mdt -i 1 $DIR/$tdir/remote_dir ||
29961                 error "mkdir remote_dir failed"
29962         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/striped_dir ||
29963                 error "mkdir striped_dir failed"
29964         touch $DIR/$tdir/file || error "touch file failed"
29965         $LFS rm_entry $DIR/$tdir/* || error "lfs rm_entry $tdir/* failed"
29966         [ -z "$(ls -A $DIR/$tdir)" ] || error "$tdir not empty"
29967 }
29968 run_test 832 "lfs rm_entry"
29969
29970 #
29971 # tests that do cleanup/setup should be run at the end
29972 #
29973
29974 test_900() {
29975         [ $PARALLEL == "yes" ] && skip "skip parallel run"
29976         local ls
29977
29978         #define OBD_FAIL_MGC_PAUSE_PROCESS_LOG   0x903
29979         $LCTL set_param fail_loc=0x903
29980
29981         cancel_lru_locks MGC
29982
29983         FAIL_ON_ERROR=true cleanup
29984         FAIL_ON_ERROR=true setup
29985 }
29986 run_test 900 "umount should not race with any mgc requeue thread"
29987
29988 # LUS-6253/LU-11185
29989 test_901() {
29990         local old
29991         local count
29992         local oldc
29993         local newc
29994         local olds
29995         local news
29996         [ $PARALLEL == "yes" ] && skip "skip parallel run"
29997
29998         # some get_param have a bug to handle dot in param name
29999         cancel_lru_locks MGC
30000         old=$(mount -t lustre | wc -l)
30001         # 1 config+sptlrpc
30002         # 2 params
30003         # 3 nodemap
30004         # 4 IR
30005         old=$((old * 4))
30006         oldc=0
30007         count=0
30008         while [ $old -ne $oldc ]; do
30009                 oldc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
30010                 sleep 1
30011                 ((count++))
30012                 if [ $count -ge $TIMEOUT ]; then
30013                         error "too large timeout"
30014                 fi
30015         done
30016         umount_client $MOUNT || error "umount failed"
30017         mount_client $MOUNT || error "mount failed"
30018         cancel_lru_locks MGC
30019         newc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
30020
30021         [ $oldc -lt $newc ] && error "mgc lock leak ($oldc != $newc)"
30022
30023         return 0
30024 }
30025 run_test 901 "don't leak a mgc lock on client umount"
30026
30027 # LU-13377
30028 test_902() {
30029         [ $CLIENT_VERSION -lt $(version_code 2.13.52) ] &&
30030                 skip "client does not have LU-13377 fix"
30031         #define OBD_FAIL_LLITE_SHORT_COMMIT 0x1415
30032         $LCTL set_param fail_loc=0x1415
30033         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
30034         cancel_lru_locks osc
30035         rm -f $DIR/$tfile
30036 }
30037 run_test 902 "test short write doesn't hang lustre"
30038
30039 # LU-14711
30040 test_903() {
30041         $LFS setstripe -i 0 -c 1 $DIR/$tfile $DIR/${tfile}-2
30042         echo "blah" > $DIR/${tfile}-2
30043         dd if=/dev/zero of=$DIR/$tfile bs=1M count=6 conv=fsync
30044         #define OBD_FAIL_OSC_SLOW_PAGE_EVICT 0x417
30045         $LCTL set_param fail_loc=0x417 fail_val=20
30046
30047         mv $DIR/${tfile}-2 $DIR/$tfile # Destroys the big object
30048         sleep 1 # To start the destroy
30049         wait_destroy_complete 150 || error "Destroy taking too long"
30050         cat $DIR/$tfile > /dev/null || error "Evicted"
30051 }
30052 run_test 903 "Test long page discard does not cause evictions"
30053
30054 test_904() {
30055         [ "$mds1_FSTYPE" == "ldiskfs" ] || skip "ldiskfs only test"
30056         do_facet mds1 $DEBUGFS -R features $(mdsdevname 1) |
30057                 grep -q project || skip "skip project quota not supported"
30058
30059         local testfile="$DIR/$tdir/$tfile"
30060         local xattr="trusted.projid"
30061         local projid
30062         local mdts=$(comma_list $(mdts_nodes))
30063         local saved=$(do_facet mds1 $LCTL get_param -n \
30064                 osd-ldiskfs.*MDT0000.enable_projid_xattr)
30065
30066         do_nodes $mdts $LCTL set_param osd-ldiskfs.*MDT*.enable_projid_xattr=0
30067         stack_trap "do_nodes $mdts $LCTL set_param \
30068                 osd-ldiskfs.*MDT*.enable_projid_xattr=$saved"
30069
30070         mkdir -p $DIR/$tdir
30071         touch $testfile
30072         #hide projid xattr on server
30073         $LFS project -p 1 $testfile ||
30074                 error "set $testfile project id failed"
30075         getfattr -m - $testfile | grep $xattr &&
30076                 error "do not show trusted.projid when disabled on server"
30077         do_nodes $mdts $LCTL set_param osd-ldiskfs.*MDT*.enable_projid_xattr=1
30078         #should be hidden when projid is 0
30079         $LFS project -p 0 $testfile ||
30080                 error "set $testfile project id failed"
30081         getfattr -m - $testfile | grep $xattr &&
30082                 error "do not show trusted.projid with project ID 0"
30083
30084         #still can getxattr explicitly
30085         projid=$(getfattr -n $xattr $testfile |
30086                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
30087         [ $projid == "0" ] ||
30088                 error "projid expected 0 not $projid"
30089
30090         #set the projid via setxattr
30091         setfattr -n $xattr -v "1000" $testfile ||
30092                 error "setattr failed with $?"
30093         projid=($($LFS project $testfile))
30094         [ ${projid[0]} == "1000" ] ||
30095                 error "projid expected 1000 not $projid"
30096
30097         #check the new projid via getxattr
30098         $LFS project -p 1001 $testfile ||
30099                 error "set $testfile project id failed"
30100         getfattr -m - $testfile | grep $xattr ||
30101                 error "should show trusted.projid when project ID != 0"
30102         projid=$(getfattr -n $xattr $testfile |
30103                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
30104         [ $projid == "1001" ] ||
30105                 error "projid expected 1001 not $projid"
30106
30107         #try to set invalid projid
30108         setfattr -n $xattr -v "4294967295" $testfile &&
30109                 error "set invalid projid should fail"
30110
30111         #remove the xattr means setting projid to 0
30112         setfattr -x $xattr $testfile ||
30113                 error "setfattr failed with $?"
30114         projid=($($LFS project $testfile))
30115         [ ${projid[0]} == "0" ] ||
30116                 error "projid expected 0 not $projid"
30117
30118         #should be hidden when parent has inherit flag and same projid
30119         $LFS project -srp 1002 $DIR/$tdir ||
30120                 error "set $tdir project id failed"
30121         getfattr -m - $testfile | grep $xattr &&
30122                 error "do not show trusted.projid with inherit flag"
30123
30124         #still can getxattr explicitly
30125         projid=$(getfattr -n $xattr $testfile |
30126                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
30127         [ $projid == "1002" ] ||
30128                 error "projid expected 1002 not $projid"
30129 }
30130 run_test 904 "virtual project ID xattr"
30131
30132 # LU-8582
30133 test_905() {
30134         (( $OST1_VERSION >= $(version_code 2.8.54) )) ||
30135                 skip "lustre < 2.8.54 does not support ladvise"
30136
30137         remote_ost_nodsh && skip "remote OST with nodsh"
30138         $LFS setstripe -c -1 -i 0 $DIR/$tfile || error "setstripe failed"
30139
30140         $LFS ladvise -a willread $DIR/$tfile || error "ladvise does not work"
30141
30142         #define OBD_FAIL_OST_OPCODE 0x253
30143         # OST_LADVISE = 21
30144         do_facet ost1 "$LCTL set_param fail_val=21 fail_loc=0x0253"
30145         $LFS ladvise -a willread $DIR/$tfile &&
30146                 error "unexpected success of ladvise with fault injection"
30147         $LFS ladvise -a willread $DIR/$tfile |&
30148                 grep -q "Operation not supported"
30149         (( $? == 0 )) || error "unexpected stderr of ladvise with fault injection"
30150 }
30151 run_test 905 "bad or new opcode should not stuck client"
30152
30153 test_906() {
30154         grep -q io_uring_setup /proc/kallsyms ||
30155                 skip "Client OS does not support io_uring I/O engine"
30156         io_uring_probe || skip "kernel does not support io_uring fully"
30157         which fio || skip_env "no fio installed"
30158         fio --enghelp | grep -q io_uring ||
30159                 skip_env "fio does not support io_uring I/O engine"
30160
30161         local file=$DIR/$tfile
30162         local ioengine="io_uring"
30163         local numjobs=2
30164         local size=50M
30165
30166         fio --name=seqwrite --ioengine=$ioengine        \
30167                 --bs=$PAGE_SIZE --direct=1 --numjobs=$numjobs   \
30168                 --iodepth=64 --size=$size --filename=$file --rw=write ||
30169                 error "fio seqwrite $file failed"
30170
30171         fio --name=seqread --ioengine=$ioengine \
30172                 --bs=$PAGE_SIZE --direct=1 --numjobs=$numjobs   \
30173                 --iodepth=64 --size=$size --filename=$file --rw=read ||
30174                 error "fio seqread $file failed"
30175
30176         rm -f $file || error "rm -f $file failed"
30177 }
30178 run_test 906 "Simple test for io_uring I/O engine via fio"
30179
30180 complete $SECONDS
30181 [ -f $EXT2_DEV ] && rm $EXT2_DEV || true
30182 check_and_cleanup_lustre
30183 if [ "$I_MOUNTED" != "yes" ]; then
30184         lctl set_param debug="$OLDDEBUG" 2> /dev/null || true
30185 fi
30186 exit_status